def create_env_for_predicting(config): t = price_history['Close'] p = Stream.source(t.tolist(), dtype="float").rename("USD-BTC") bitfinex = Exchange("bitfinex", service=execute_order)(Stream.source( price_history['Close'].tolist(), dtype="float").rename("USD-BTC")) cash = Wallet(bitfinex, 100000 * USD) asset = Wallet(bitfinex, 0 * BTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.rolling(window=10).mean().rename("fast"), p.rolling(window=50).mean().rename("medium"), p.rolling(window=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = PBR(price=p) action_scheme = BSH(cash=cash, asset=asset).attach(reward_scheme) renderer_feed = DataFeed([ Stream.source(price_history['Close'].tolist(), dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) environment = default.create(feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer=PositionChangeChart(), window_size=config["window_size"], max_allowed_loss=0.6) return environment
def create_env(config): x = np.arange(0, 2 * np.pi, 2 * np.pi / 1000) p = Stream.source(50 * np.sin(3 * x) + 100, dtype="float").rename("USD-TTC") bitfinex = Exchange("bitfinex", service=execute_order)(p) cash = Wallet(bitfinex, 100000 * USD) asset = Wallet(bitfinex, 0 * TTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.rolling(window=10).mean().rename("fast"), p.rolling(window=50).mean().rename("medium"), p.rolling(window=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = default.rewards.PBR(price=p) action_scheme = default.actions.BSH(cash=cash, asset=asset).attach(reward_scheme) env = default.create(feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, window_size=config["window_size"], max_allowed_loss=0.6) return env
def create_env(config): x = np.arange(0, 2 * np.pi, 2 * np.pi / 1001) y = 50 * np.sin(3 * x) + 100 x = np.arange(0, 2 * np.pi, 2 * np.pi / 1000) p = Stream.source(y, dtype="float").rename("USD-TTC") coinbase = Exchange("coinbase", service=execute_order)(p) cash = Wallet(coinbase, 100000 * USD) asset = Wallet(coinbase, 0 * TTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.rolling(window=10).mean().rename("fast"), p.rolling(window=50).mean().rename("medium"), p.rolling(window=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = PBR(price=p) action_scheme = BSH(cash=cash, asset=asset).attach(reward_scheme) renderer_feed = DataFeed([ Stream.source(y, dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) chart_renderer = PlotlyTradingChart( display=True, # show the chart on screen (default) height= 800, # affects both displayed and saved file height. None for 100% height. save_format="html", # save the chart to an HTML file auto_open_html=True, # open the saved HTML chart in a new browser tab ) import uuid uid = uuid.uuid4() callback = LoggingCallback(f'/Users/vkrot/callback-{uid}', chart_renderer) environment = default.create( feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, # renderer=PositionChangeChart(), renderer=PositionChangeChart(), window_size=config["window_size"], max_allowed_loss=0.6, callback=callback) return environment
def create_trade_env(quotes, observations, symbol): # Add features features = [] #exclude "date/Column [0]" from observation - start from column 1 for c in data.columns[0:]: s = Stream.source(list(data[c]), dtype="float").rename(data[c].name) features += [s] feed = DataFeed(features) feed.compile() # define exchange - needs to specify Price-Quote Stream exchange = Exchange("sim-exchange", service=execute_order)( Stream.source(list(quotes["close"]), dtype="float").rename(str("USD-{}").format(symbol))) # add current cash, initial-asset cash = Wallet(exchange, 10000 * USD) asset = Wallet(exchange, 0 * Instrument(symbol, 2, symbol)) # initialize portfolio - base currency USD portfolio = Portfolio(base_instrument=USD, wallets=[cash, asset]) # add element for rendered feed renderer_feed = DataFeed([ Stream.source(list(data.index)).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close") #Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) reward_scheme = default.rewards.SimpleProfit() action_scheme = default.actions.SimpleOrders(trade_sizes=1) ''' # define reward-scheme # define action-scheme action_scheme = default.actions.BSH( cash=cash, asset=asset ) ''' # create env env = default.create( portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, feed=feed, renderer_feed=renderer_feed, #renderer="screen-log", #window_size=20, max_allowed_loss=0.6) return env
def Environment(portfolio, data_stream, renderer_stream): env = default.create(portfolio=portfolio, action_scheme="managed-risk", reward_scheme="risk-adjusted", feed=data_stream, renderer_feed=renderer_stream, renderer=render.file_logger, window_size=20) return env
def create_env(envs_config=None): features = [] for c in data.columns[5:]: s = Stream.source(list(data[c][-100:]), dtype="float").rename(data[c].name) features += [s] cp = Stream.select(features, lambda s: s.name == "close") features = [cp.log().diff().fillna(0).rename("lr")] + features[1:] feed = DataFeed(features) feed.compile() bitstamp = Exchange("bitstamp", service=execute_order)(Stream.source( list(data["close"]), dtype="float").rename("USD-BTC")) portfolio = Portfolio( USD, [Wallet(bitstamp, 10000 * USD), Wallet(bitstamp, 10 * BTC)]) renderer_feed = DataFeed([ Stream.source(list(data["date"])).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close"), Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) # reward_scheme = RiskAdjustedReturns( # return_algorithm='sortino', # risk_free_rate=0.025, # target_returns=0.1, # window_size=200 # ) reward_scheme = SimpleProfit(window_size=200) #PBR(price=cp) # action_scheme = BSH( # cash=portfolio.wallets[0], # asset=portfolio.wallets[1] # ).attach(reward_scheme) env = default.create( portfolio=portfolio, action_scheme="managed-risk", reward_scheme=reward_scheme, #"risk-adjusted", feed=feed, renderer_feed=renderer_feed, renderer=default.renderers.PlotlyTradingChart(display=False, save_format='html', path='./agents/charts/'), window_size=40) return env
def test_runs_with_external_feed_only(portfolio): df = pd.read_csv("tests/data/input/bitfinex_(BTC,ETH)USD_d.csv").tail(100) df = df.rename({"Unnamed: 0": "date"}, axis=1) df = df.set_index("date") bitfinex_btc = df.loc[:, [name.startswith("BTC") for name in df.columns]] bitfinex_eth = df.loc[:, [name.startswith("ETH") for name in df.columns]] ta.add_all_ta_features( bitfinex_btc, colprefix="BTC:", **{k: "BTC:" + k for k in ['open', 'high', 'low', 'close', 'volume']}) ta.add_all_ta_features( bitfinex_eth, colprefix="ETH:", **{k: "ETH:" + k for k in ['open', 'high', 'low', 'close', 'volume']}) streams = [] with NameSpace("bitfinex"): for name in bitfinex_btc.columns: streams += [ Stream.source(list(bitfinex_btc[name]), dtype="float").rename(name) ] for name in bitfinex_eth.columns: streams += [ Stream.source(list(bitfinex_eth[name]), dtype="float").rename(name) ] feed = DataFeed(streams) action_scheme = ManagedRiskOrders() reward_scheme = SimpleProfit() env = default.create(portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, feed=feed, window_size=50, enable_logger=False) done = False obs = env.reset() while not done: action = env.action_space.sample() obs, reward, done, info = env.step(action) assert obs.shape[0] == 50
def create_env_sin(config): x = np.arange(0, 2 * np.pi, 2 * np.pi / 1001) y = 50 * np.sin(3 * x) + 100 x = np.arange(0, 2 * np.pi, 2 * np.pi / 1000) p = Stream.source(y, dtype="float").rename("USD-TTC") bitfinex = Exchange("bitfinex", service=execute_order)(p) cash = Wallet(bitfinex, 10000 * USD) asset = Wallet(bitfinex, 0 * TTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.rolling(window=10).mean().rename("fast"), p.rolling(window=50).mean().rename("medium"), p.rolling(window=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = default.rewards.PBREX(price=p) #action_scheme = default.actions.BSHEX( # cash=cash, # asset=asset #).attach(reward_scheme) action_scheme = default.actions.SimpleOrders( trade_sizes=3).attach(reward_scheme) renderer_feed = DataFeed([ Stream.source(y, dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) environment = default.create(feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer=PositionChangeChart(), window_size=config["window_size"], max_allowed_loss=0.6) return environment
def create_env(config): df = load_csv('btc_usdt_m5_history.csv') y = df['close'].tolist() p = Stream.source(y, dtype="float").rename("USD-TTC") bitfinex = Exchange("bitfinex", service=execute_order)(p) cash = Wallet(bitfinex, 100000 * USD) asset = Wallet(bitfinex, 0 * TTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.rolling(window=10).mean().rename("fast"), p.rolling(window=50).mean().rename("medium"), p.rolling(window=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = SimpleProfit(window_size=12) action_scheme = ManagedRiskOrders() renderer_feed = DataFeed([ Stream.source(y, dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) environment = default.create( feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer=default.renderers.PlotlyTradingChart(), window_size=config["window_size"], max_allowed_loss=0.6) return environment
def create_env(config): x = np.arange(0, 2 * np.pi, 2 * np.pi / 1001) y = 50 * np.sin(3 * x) + 100 p = Stream.source(y, dtype="float").rename("USD-TTC") coinbase = Exchange("coinbase", service=execute_order)(p) cash = Wallet(coinbase, 10000 * USD) asset = Wallet(coinbase, 0 * TTC) portfolio = Portfolio(USD, [cash, asset]) feed = DataFeed([ p, p.ewm(span=10).mean().rename("fast"), p.ewm(span=50).mean().rename("medium"), p.ewm(span=100).mean().rename("slow"), p.log().diff().fillna(0).rename("lr") ]) reward_scheme = PBR(price=p) action_scheme = BSH(cash=cash, asset=asset).attach(reward_scheme) renderer_feed = DataFeed([ Stream.source(y, dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) environment = default.create(feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer=PositionChangeChart(), window_size=config["window_size"], max_allowed_loss=0.6) return environment
def create_env(config, save_path='./agents/charts/', is_eval=False): # Load data k = -3000 w = -200 if is_eval: k = -200 w = None y = data['Close'][k:w].to_numpy() features = [] for c in data.columns[5:]: s = Stream.source(list(data[c][k:w]), dtype="float").rename(data[c].name) features += [s] cp = Stream.source(y, dtype="float").rename("EUR-USD") coinbase = Exchange("coinbase", service=execute_order, options=ExchangeOptions(commission=0.00005))(cp) feature_add = [ cp, cp.ewm(span=10).mean().rename("fast"), cp.ewm(span=50).mean().rename("medium"), cp.ewm(span=100).mean().rename("slow"), cp.log().diff().fillna(0).rename("lr") ] features = features + feature_add feed = DataFeed(features) feed.compile() cash = Wallet(coinbase, 10000 * EUR) asset = Wallet(coinbase, 10000 * USD) portfolio = Portfolio(EUR, [cash, asset]) reward_scheme = PBR(price=cp) # reward_scheme = SimpleProfit(window_size=500) action_scheme = BSH(cash=cash, asset=asset).attach(reward_scheme) # renderer_feed = DataFeed([ # Stream.source(y, dtype="float").rename("price"), # Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") # ]) renderer_feed = DataFeed([ Stream.source(list(data["Date"][k:w])).rename("date"), Stream.source(list(data["Open"][k:w]), dtype="float").rename("open"), Stream.source(list(data["High"][k:w]), dtype="float").rename("high"), Stream.source(list(data["Low"][k:w]), dtype="float").rename("low"), Stream.source(list(data["Close"][k:w]), dtype="float").rename("close"), Stream.source(list(data["Volume"][k:w]), dtype="float").rename("volume") ]) environment = default.create( feed=feed, portfolio=portfolio, action_scheme=action_scheme, #"managed-risk", reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer=default.renderers.PlotlyTradingChart(display=False, save_format='html', path=save_path), # renderer=PositionChangeChart(), window_size=config["window_size"], max_allowed_loss=0.6) return environment
def create_trade_env(quotes, observations, symbol): # Add features features = [] #exclude "date/Column [0]" from observation - start from column 1 #for c in data.columns[0:]: # s = Stream.source(list(data[c]), dtype="float").rename(data[c].name) # features += [s] cp = eToroClose(symbol_id=32, field_name='close') features = [ #cp.log().diff().rename("lr"), cp.rename("close"), eToroClose(symbol_id=32, field_name='high').rename('high'), eToroClose(symbol_id=32, field_name='open').rename('open'), eToroClose(symbol_id=32, field_name='low').rename('low'), #rsi(cp, period=20).rename("rsi"), #macd(cp, fast=10, slow=50, signal=5).rename("macd") ] feed = DataFeed(features) feed.compile() # define exchange - needs to specify Price-Quote Stream exchange = Exchange("etoro-exchange", service=execute_order)(cp.rename( str("USD-{}").format(symbol))) # add current cash, initial-asset cash = Wallet(exchange, 100000 * USD) asset = Wallet(exchange, 0 * Instrument(symbol, 2, symbol)) # initialize portfolio - base currency USD portfolio = Portfolio(base_instrument=USD, wallets=[cash, asset]) ''' # add element for rendered feed renderer_feed = DataFeed([ Stream.source(list(data.index)).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close") #Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) ''' # define reward-scheme reward_scheme = default.rewards.SimpleProfit() # define action-scheme action_scheme = default.actions.SimpleOrders(trade_sizes=1) # create env env = default.create( portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, feed=feed, #renderer_feed=renderer_feed, #renderer="screen-log", #window_size=20, max_allowed_loss=0.6) return env
) with NameSpace("coinbase"): streams = [ Stream.source(df[c].tolist(), dtype="float").rename(c) for c in df.columns ] feed = DataFeed(streams) print(feed.next()) # # Screen log env = default.create( portfolio=portfolio, action_scheme="managed-risk", reward_scheme="risk-adjusted", feed=feed, renderer="screen-log", # ScreenLogger used with default settings window_size=20, ) print(env.observation_space) print(env.action_space) # model = A2C(MlpLstmPolicy, env, verbose=1) # # model.learn(total_timesteps=25000) # obs = env.reset() # done = False # while not done: # action, _states = model.predict(obs) # obs, rewards, done, info = env.step(action) # env.render()
def create_env(config): # Use config param to decide which data set to use # Reserve 50 rows of data to fill in NaN values if config["train"] == True: df = data[50:-dataEnd] envData = candles[50:-dataEnd] taData = data[:-dataEnd] else: df = data[-dataEnd:] envData = candles[-dataEnd:] taData = data[-dataEnd - 50:] # === OBSERVER === p = Stream.source(df[(coin + ':close')].tolist(), dtype="float").rename(("USD-" + coin)) # === EXCHANGE === # Commission on Binance is 0.075% on the lowest level, using BNB (https://www.binance.com/en/fee/schedule) binance_options = ExchangeOptions(commission=0.0075, min_trade_price=10.0) binance = Exchange("binance", service=execute_order, options=binance_options)(p) # === ORDER MANAGEMENT SYSTEM === # Start with 100.000 usd and 0 assets cash = Wallet(binance, 100000 * USD) asset = Wallet(binance, 0 * coinInstrument) portfolio = Portfolio(USD, [cash, asset]) # === OBSERVER === dataset = pd.DataFrame() # Use log-returns instead of raw OHLCV. This is a refined version of naive standarization # log(current_price / previous_price) = log(current_price) - log(previous_price) # If log value below 0 current_price > previous_price # Above 0 means current_price < previous_price dataset['log_open'] = np.log(taData[(coin + ':open')]) - np.log( taData[(coin + ':open')].shift(1)) dataset['log_low'] = np.log(taData[(coin + ':low')]) - np.log( taData[(coin + ':low')].shift(1)) dataset['log_high'] = np.log(taData[(coin + ':high')]) - np.log( taData[(coin + ':high')].shift(1)) dataset['log_close'] = np.log(taData[(coin + ':close')]) - np.log( taData[(coin + ':close')].shift(1)) dataset['log_vol'] = np.log(taData[(coin + ':volume')]) - np.log( taData[(coin + ':volume')].shift(1)) # === TECHNICAL ANALYSIS === # Extra features not described in research, therefore not used. #BB_low = ta.volatility.BollingerBands(close = taData[(coin + ':close')], window = 20).bollinger_lband() #BB_mid = ta.volatility.BollingerBands(close = taData[(coin + ':close')], window = 20).bollinger_mavg() #BB_high = ta.volatility.BollingerBands(close = taData[(coin + ':close')], window = 20).bollinger_hband() # Difference between close price and bollinger band #dataset['BB_low'] = np.log(BB_low) - np.log(taData[(coin + ':close')]) #dataset['BB_mid'] = np.log(BB_mid) - np.log(taData[(coin + ':close')]) #dataset['BB_high'] = np.log(BB_high) - np.log(taData[(coin + ':close')]) # Take log-returns to standardize # Log-returns can not be used if value is 0 or smaller. # Use pct_change() instead # IDEA: Maybe use volume or close to standardize # This line is necessary otherwise read only errors shows up taData = taData.copy() # For some reasons there are erros when using pct_change() for these indicators adi = ta.volume.AccDistIndexIndicator( high=taData[(coin + ':high')], low=taData[(coin + ':low')], close=taData[(coin + ':close')], volume=taData[(coin + ':volume')]).acc_dist_index() dataset['adi'] = adi.pct_change() fi = ta.volume.ForceIndexIndicator( close=taData[(coin + ':close')], volume=taData[(coin + ':volume')]).force_index() dataset['fi'] = fi.pct_change() macd_diff = ta.trend.MACD(close=taData[(coin + ':close')]).macd_diff() dataset['macd_diff'] = macd_diff.pct_change() dpo = ta.trend.DPOIndicator(close=taData[(coin + ':close')]).dpo() dataset['dpo'] = dpo.pct_change() # Too many outliers in the dataset #vpt = ta.volume.VolumePriceTrendIndicator(close=taData[(coin + ':close')], volume=taData[(coin + ':volume')]).volume_price_trend() #dataset['vpt'] = vpt.pct_change() #em = ta.volume.EaseOfMovementIndicator(high=taData[(coin + ':high')], low=taData[(coin + ':low')], volume=taData[(coin + ':volume')]).ease_of_movement() #dataset['em'] = em.pct_change() kst_sig = ta.trend.KSTIndicator(close=taData[(coin + ':close')]).kst_sig() dataset['kst_sig'] = kst_sig.pct_change() kst_diff = ta.trend.KSTIndicator(close=taData[(coin + ':close')]).kst_diff() dataset['kst_diff'] = kst_diff.pct_change() nvi = ta.volume.NegativeVolumeIndexIndicator( close=taData[(coin + ':close')], volume=taData[(coin + ':volume')]).negative_volume_index() dataset['nvi'] = np.log(nvi) - np.log(nvi.shift(1)) bbw = ta.volatility.BollingerBands( close=taData[(coin + ':close')]).bollinger_wband() dataset['bbw'] = np.log(bbw) - np.log(bbw.shift(1)) kcw = ta.volatility.KeltnerChannel( high=taData[(coin + ':high')], low=taData[(coin + ':low')], close=taData[(coin + ':close')]).keltner_channel_wband() dataset['kcw'] = np.log(kcw) - np.log(kcw.shift(1)) dcw = ta.volatility.DonchianChannel( high=taData[(coin + ':high')], low=taData[(coin + ':low')], close=taData[(coin + ':close')]).donchian_channel_wband() dataset['dcw'] = np.log(dcw) - np.log(dcw.shift(1)) psar_up = ta.trend.PSARIndicator(high=taData[(coin + ':high')], low=taData[(coin + ':low')], close=taData[(coin + ':close')]).psar_up() dataset['psar_up'] = np.log(psar_up) - np.log(psar_up.shift(1)) # These indicators have a mean independent of the OHLCV data # IDEA: Use log-returns on these as an extra indicator # Has a mean of 0 dataset['cmf'] = ta.volume.ChaikinMoneyFlowIndicator( high=taData[(coin + ':high')], low=taData[(coin + ':low')], close=taData[(coin + ':close')], volume=taData[(coin + ':volume')]).chaikin_money_flow() dataset['ppo'] = ta.momentum.PercentagePriceOscillator( close=taData[(coin + ':close')]).ppo() dataset['ppo_signal'] = ta.momentum.PercentagePriceOscillator( close=taData[(coin + ':close')]).ppo_signal() dataset['ppo_hist'] = ta.momentum.PercentagePriceOscillator( close=taData[(coin + ':close')]).ppo_hist() dataset['ui'] = ta.volatility.UlcerIndex( close=taData[(coin + ':close')]).ulcer_index() dataset['aroon_ind'] = ta.trend.AroonIndicator( close=taData[(coin + ':close')]).aroon_indicator() # Indicator, so has value 0 or 1 dataset['bbhi'] = ta.volatility.BollingerBands( close=taData[(coin + ':close')]).bollinger_hband_indicator() dataset['bbli'] = ta.volatility.BollingerBands( close=taData[(coin + ':close')]).bollinger_lband_indicator() dataset['kchi'] = ta.volatility.KeltnerChannel( high=taData[(coin + ':high')], low=taData[(coin + ':low')], close=taData[(coin + ':close')]).keltner_channel_hband_indicator() dataset['kcli'] = ta.volatility.KeltnerChannel( high=taData[(coin + ':high')], low=taData[(coin + ':low')], close=taData[(coin + ':close')]).keltner_channel_lband_indicator() # Has a mean of 50 dataset['stoch_rsi'] = ta.momentum.StochRSIIndicator( close=taData[(coin + ':close')]).stochrsi() dataset['stoch_rsi_d'] = ta.momentum.StochRSIIndicator( close=taData[(coin + ':close')]).stochrsi_d() dataset['stoch_rsi_k'] = ta.momentum.StochRSIIndicator( close=taData[(coin + ':close')]).stochrsi_k() dataset['uo'] = ta.momentum.UltimateOscillator( high=taData[(coin + ':high')], low=taData[(coin + ':low')], close=taData[(coin + ':close')]).ultimate_oscillator() dataset['adx'] = ta.trend.ADXIndicator(high=taData[(coin + ':high')], low=taData[(coin + ':low')], close=taData[(coin + ':close')]).adx() dataset['mass_index'] = ta.trend.MassIndex( high=taData[(coin + ':high')], low=taData[(coin + ':low')]).mass_index() dataset['aroon_up'] = ta.trend.AroonIndicator( close=taData[(coin + ':close')]).aroon_up() dataset['aroon_down'] = ta.trend.AroonIndicator( close=taData[(coin + ':close')]).aroon_down() dataset['stc'] = ta.trend.STCIndicator(close=taData[(coin + ':close')]).stc() # Lot of NaN values #ta.trend.PSARIndicator(high=df[(coin + ':high')], low=df[(coin + ':low')], close=df[(coin + ':close')]).psar_down() dataset = dataset.add_prefix(coin + ":") # Drop first 50 rows from dataset dataset = dataset.iloc[50:] with NameSpace("binance"): streams = [ Stream.source(dataset[c].tolist(), dtype="float").rename(c) for c in dataset.columns ] # This is everything the agent gets to see, when making decisions feed = DataFeed(streams) # Compiles all the given stream together feed.compile() # Print feed for debugging #print(feed.next()) #print(feed.next()) #print(feed.next()) # === REWARDSCHEME === # RiskAdjustedReturns rewards depends on return_algorithm and its parameters. # The risk-free rate is the return that you can expect from taking on zero risk. # A target return is what an investor would want to make from any capital invested in the asset. # SimpleProfit() or RiskAdjustedReturns() or PBR() #reward_scheme = RiskAdjustedReturns(return_algorithm='sortino')#, risk_free_rate=0, target_returns=0) #reward_scheme = RiskAdjustedReturns(return_algorithm='sharpe', risk_free_rate=0, target_returns=0, window_size=config["window_size"]) reward_scheme = SimpleProfit(window_size=config["window_size"]) #reward_scheme = PBR(price=p) # === ACTIONSCHEME === # SimpleOrders() or ManagedRiskOrders() or BSH() # ManagedRiskOrders is bad, with default settings! # To use ManagedRiskOrders use settings like these: # ManagedRiskOrders(stop = [0.02], take = [0.03], trade_sizes=2,) action_scheme = ManagedRiskOrders(durations=[100]) #action_scheme = SimpleOrders() #BSH only works with PBR as reward_scheme #action_scheme = BSH(cash=cash,asset=asset).attach(reward_scheme) # === RENDERER === # Uses the OHCLV data passed to envData renderer_feed = DataFeed([ Stream.source(envData[c].tolist(), dtype="float").rename(c) for c in envData ]) # === RESULT === environment = default.create( feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer=PlotlyTradingChart(), #PositionChangeChart() window_size=config["window_size"], #part of OBSERVER max_allowed_loss=config["max_allowed_loss"] #STOPPER ) return environment
def create_env(config, train="train"): cdd = CryptoDataDownload() data = cdd.fetch("Bitstamp", "USD", "BTC", "1h") if False: data.close = data.close / 20 + range(len(data)) print("genenrating fake increase") if train == "train": data = data[0:int(len(data) / 2)] # training print("using first half for training") elif train == "eval": data = data[int(len(data) / 2):] # validation print("using second half for eval") else: print("using all data") pclose = Stream.source(list(data.close), dtype="float").rename("USD-BTC") pmin = Stream.source(list(data.low), dtype="float").rename("USD-BTClow") pmax = Stream.source(list(data.high), dtype="float").rename("USD-BTChigh") pmin = Stream.source(list(data.low), dtype="float").rename("USD-BTClow") pmax = Stream.source(list(data.high), dtype="float").rename("USD-BTChigh") pmin3 = pmin.rolling(window=3).min() pmin10 = pmin.rolling(window=10).min() pmin20 = pmin.rolling(window=20).min() pmax3 = pmax.rolling(window=3).max() pmax10 = pmax.rolling(window=10).max() pmax20 = pmax.rolling(window=20).max() eo = ExchangeOptions(commission=0.002) # coinbase = Exchange("coinbase", service=execute_order, options=eo)( pclose ) cash = Wallet(coinbase, 100000 * USD) asset = Wallet(coinbase, 0 * BTC) portfolio = Portfolio(USD, [ cash, asset ]) feed = DataFeed([ (pclose.log() - pmin3.log()).fillna(0).rename("relmin3"), (pclose.log() - pmin10.log()).fillna(0).rename("relmin10"), (pclose.log() - pmin20.log()).fillna(0).rename("relmin20"), (pclose.log() - pmax3.log()).fillna(0).rename("relmax3"), (pclose.log() - pmax10.log()).fillna(0).rename("relmax10"), (pclose.log() - pmax20.log()).fillna(0).rename("relmax20"), ]) action_scheme = BSH(cash=cash, asset=asset) renderer_feed = DataFeed([ Stream.source(list(data.close), dtype="float").rename("price"), Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") # only works for BSH ]) environment = default.create( feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme="simple", renderer_feed=renderer_feed, renderer=PositionChangeChart(), window_size=config["window_size"], min_periods=20, max_allowed_loss=0.6 ) return environment
def create_env(config): cdd = CryptoDataDownload() # Head for beginning of data # Tail for end of data if config["train"] == True: df = cdd.fetch("Bitfinex", "USD", "BTC", "d")[-600:-100] else: #for testing df = cdd.fetch("Bitfinex", "USD", "BTC", "d")[-100:] price_history = df[['date', 'open', 'high', 'low', 'close', 'volume']] # chart data # OBSERVER p = Stream.source(price_history['close'].tolist(), dtype="float").rename("USD-BTC") bitfinex = Exchange("bitfinex", service=execute_order)( p ) # ORDER MANAGEMENT SYSTEM #start with 100.000 usd and 0 assets cash = Wallet(bitfinex, 100000 * USD) asset = Wallet(bitfinex, 0 * BTC) portfolio = Portfolio(USD, [ cash, asset ]) # OBSERVER df.drop(columns=['date', 'open', 'high', 'low', 'close', 'volume'], inplace=True) with NameSpace("bitfinex"): streams = [Stream.source(df[c].tolist(), dtype="float").rename(c) for c in df.columns] feed = DataFeed(streams) # REWARDSCHEME #use PBR as reward_scheme #'SimpleProfit' object has no attribute 'on_action' reward_scheme = PBR(price=p) #SimpleProfit()#RiskAdjustedReturns() # ACTIONSCHEME #use BSH as action_scheme action_scheme = BSH(#ManagedRiskOrders() cash=cash, asset=asset ).attach(reward_scheme) # RENDERER renderer_feed = DataFeed( [Stream.source(price_history[c].tolist(), dtype="float").rename(c) for c in price_history] ) #create the environment environment = default.create( feed=feed, portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed, renderer= PlotlyTradingChart(), #PositionChangeChart(), # window_size=config["window_size"], #part of OBSERVER max_allowed_loss=config["max_allowed_loss"] #STOPPER ) return environment
Wallet(bitstamp, 0 * BTC)]) renderer_feed = DataFeed([ Stream.source(list(data["date"])).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close"), Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) env = default.create( portfolio=portfolio, action_scheme=default.actions.ManagedRiskOrders( stop=[0.02, 0.05, 0.1], take=[0.02, 0.05, 0.1, 0.125, 0.15, 0.2]), reward_scheme=default.rewards.RiskAdjustedReturns(window_size=40), feed=feed, renderer_feed=renderer_feed, renderer=default.renderers.ScreenLogger(), window_size=40) # %% env.observer.feed.next() # %% agent = DQNAgent(env) agent.train(n_steps=200, n_episodes=10) # %% portfolio.ledger.as_frame() # %%
crypto_position(ticker) * BTC) ]) feed = DataFeed(robinhood_stream) feed.compile() renderer_feed = DataFeed([ Stream.source(list(data["date"])).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close"), Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) env = default.create( portfolio=portfolio, action_scheme="managed-risk", reward_scheme="risk-adjusted", feed=feed, renderer_feed=renderer_feed, renderer=default.renderers.PlotlyTradingChart(), window_size=20, ) env.observer.feed.next() agent = DQNAgent(env) agent.train(n_episodes=2, n_steps=288, render_interval=288)
Wallet(exchange, 0 * AAPL)]) renderer_feed = DataFeed([ Stream.source(list(data["date"])).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close"), Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) # %% env = default.create(portfolio=portfolio, action_scheme="managed-risk", reward_scheme="risk-adjusted", feed=feed, renderer_feed=renderer_feed, renderer="screen-log", window_size=20) # %% env.observer.feed.next() # %% [markdown] # ## Setup and Train DQN Agent # %% from tensortrade.agents import DQNAgent agent = DQNAgent(env) reward = agent.train(n_steps=100, save_path="agents/", n_episodes=100)
renderer_feed = DataFeed([ Stream.source(list(data["date"])).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close"), Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) env = default.create( portfolio=portfolio, action_scheme="simple", reward_scheme="simple", feed=feed, renderer_feed=renderer_feed, renderer=default.renderers.ScreenLogger(), window_size=40 ) # %% env.observer.feed.next() # %% agent = DQNAgent(env) agent.train(n_steps=200, n_episodes=1000) # %% portfolio.ledger.as_frame() # %%
USD, [Wallet(bitstamp, 100000 * USD), Wallet(bitstamp, 10 * BTC)]) renderer_feed = DataFeed([ Stream.source(list(data["date"])).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close"), Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) env = default.create(portfolio=portfolio, action_scheme="managed-risk", reward_scheme="risk-adjusted", feed=feed, renderer_feed=renderer_feed, renderer=default.renderers.ScreenLogger(), window_size=40) # %% env.observer.feed.next() # %% agent = DQNAgent(env) agent.train(n_steps=200, n_episodes=1000) # %% portfolio.ledger.as_frame() # %% portfolio.performance[0]
def create_env(config): df = load_csv('btc_usdt_m5_history.csv') from ta.trend import ( MACD, ADXIndicator, AroonIndicator, CCIIndicator, DPOIndicator, EMAIndicator, IchimokuIndicator, KSTIndicator, MassIndex, PSARIndicator, SMAIndicator, STCIndicator, TRIXIndicator, VortexIndicator, ) colprefix = "" # MACD indicator_macd = MACD(close=df['close'], window_slow=26, window_fast=12, window_sign=9, fillna=True) df[f"{colprefix}trend_macd"] = indicator_macd.macd() df[f"{colprefix}trend_macd_signal"] = indicator_macd.macd_signal() df[f"{colprefix}trend_macd_diff"] = indicator_macd.macd_diff() #df = ta.add_trend_ta(df,'high', 'low', 'close', fillna=True) #df = ta.add_volume_ta(df,'high', 'low', 'close', 'volume', fillna=True) #df = ta.add_volume_ta(df, 'high', 'low', 'close', 'volume', fillna=True) #df = ta.add_volatility_ta(df, 'high', 'low', 'close', fillna=True) price_history = df[['date', 'open', 'high', 'low', 'close', 'volume']] # chart data df.drop(columns=['date', 'open', 'high', 'low', 'close', 'volume'], inplace=True) print(df.head(5)) with NameSpace("bitfinex"): streams = [ Stream.source(df[c].tolist(), dtype="float").rename(c) for c in df.columns ] feed_ta_features = DataFeed(streams) price_list = price_history['close'].tolist() p = Stream.source(price_list, dtype="float").rename("USD-BTC") bitfinex = Exchange("bitfinex", service=execute_order)(p) cash = Wallet(bitfinex, 10000 * USD) asset = Wallet(bitfinex, 0 * BTC) portfolio = Portfolio(USD, [cash, asset]) reward_scheme = default.rewards.SimpleProfit(window_size=1) #action_scheme = default.actions.BSHEX( # cash=cash, # asset=asset #).attach(reward_scheme) action_scheme = default.actions.SimpleOrders(trade_sizes=3) renderer_feed_ptc = DataFeed([ Stream.source(list(price_history["date"])).rename("date"), Stream.source(list(price_history["open"]), dtype="float").rename("open"), Stream.source(list(price_history["high"]), dtype="float").rename("high"), Stream.source(list(price_history["low"]), dtype="float").rename("low"), Stream.source(list(price_history["close"]), dtype="float").rename("close"), Stream.source(list(price_history["volume"]), dtype="float").rename("volume") ]) env = default.create( feed=feed_ta_features, portfolio=portfolio, #renderer=PositionChangeChart(), renderer=default.renderers.PlotlyTradingChart(), action_scheme=action_scheme, reward_scheme=reward_scheme, renderer_feed=renderer_feed_ptc, window_size=config["window_size"], max_allowed_loss=0.1) return env
Wallet(bitstamp, 5 * BTC), Wallet(bitstamp, 20 * ETH), Wallet(bitstamp, 3 * LTC), ], ) feed = DataFeed([ Stream.source(list(bitstamp_eth["volume"][-100:]), dtype="float").rename("volume:/USD-ETH"), Stream.source(list(bitstamp_ltc["volume"][-100:]), dtype="float").rename("volume:/USD-LTC"), ]) env = default.create( portfolio=portfolio, action_scheme=default.actions.SimpleOrders(), reward_scheme=default.rewards.SimpleProfit(), feed=feed, ) done = False obs = env.reset() while not done: action = env.action_space.sample() obs, reward, done, info = env.step(action) print("action: {}".format(action)) head = portfolio.ledger.as_frame().head(7) print(head) # ManagedRiskOrders
def build_env(config): worker_index = 1 if hasattr(config, 'worker_index'): worker_index = config.worker_index raw_data = pd.read_csv(btc_usd_file, sep=';') raw_data['date'] = pd.to_datetime(raw_data['time'], unit='ms') data = compute_features(raw_data) features = [] for c in data.columns: if c not in raw_data.columns: s = Stream.source(list(data[c]), dtype="float").rename(data[c].name) features += [s] comm = 0.00001 coinbase = Exchange("coinbase", service=execute_order, options=ExchangeOptions(commission=comm))( Stream.source(list(data["close"]), dtype="float").rename("USD-BTC")) cash = Wallet(coinbase, 10000 * USD) asset = Wallet(coinbase, 0 * BTC) portfolio = Portfolio(USD, [cash, asset]) renderer_feed = DataFeed([ Stream.source(list(data["date"])).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close"), Stream.source(list(data["volume"]), dtype="float").rename("volume") ]) # reward_scheme = rewards.SimpleProfit() rsi = Stream.select(features, lambda x: x.name == "rsi") reward_scheme = SparseReward(rsi=rsi, window_size=10) action_scheme = BuySellHoldActionSchemes(cash, asset) action_scheme.attach(reward_scheme) plotly = PlotlyTradingChart(display=True, height=700, save_format="html") class EpisodeStopper(Stopper): def stop(self, env: 'TradingEnv') -> bool: return env.clock.num_steps > 1000 open_position = Stream.sensor(asset, lambda a: asset.total_balance.as_float() > 0) # open_position = Stream.sensor( # action_scheme, lambda action_scheme: action_scheme.has_asset # ) features.append(open_position) feed = DataFeed(features) feed.compile() env = default.create( portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, feed=feed, renderer_feed=renderer_feed, renderer=plotly, window_size=20, max_allowed_loss=0.5, stopper=EpisodeStopper(), callback=(LoggingCallback('http://165.227.193.153:8050', plotly) if worker_index == 1 else None)) import logging import os LOGGER = logging.getLogger(__name__) logging.basicConfig( level=logging.INFO, format= '%(asctime)s - %(name)s [%(threadName)s] - %(levelname)s - %(message)s', ) LOGGER.info('env created logger') LOGGER.info(f'env: {os.environ}') print(f'env: {os.environ}') print('env created') return env
def create_env(data, config): features = [] for c in data.columns[1:]: s = Stream.source(list(data[c]), dtype="float").rename(data[c].name) features += [s] cp = Stream.select(features, lambda s: s.name == "close") high_price = data['high'] low_price = data['low'] close_price = data['close'] # print(data['volume']) try: data['date'] except KeyError: data['date'] = data.index features = [ cp.rename('USD/BTC'), cp.log().diff().rename("lr"), rsi(cp, period=14).rename("rsi"), macd(cp, fast=10, slow=50, signal=5).rename("macd"), Stream.source(ta.cci(high_price, low_price, close_price)).rename('cci') # cp.rolling(window=10).mean().rename("fast"), # cp.rolling(window=50).mean().rename("medium"), # cp.rolling(window=100).mean().rename("slow") ] feed = DataFeed(features) feed.compile() # for i in range(5): # print(feed.next()) coinbase = Exchange("coinbase", service=execute_order)(cp) cash = Wallet(coinbase, 100000 * USD) asset = Wallet(coinbase, 10 * BTC) portfolio = Portfolio(USD, [cash, asset]) # reward_scheme = PBR(price=cp) reward_scheme = RiskAdjustedReturns() # action_scheme = BSH(cash=cash, asset=asset).attach(reward_scheme) action_scheme = ManagedRiskOrders() renderer_feed = DataFeed([ Stream.source(list(data["date"])).rename("date"), Stream.source(list(data["open"]), dtype="float").rename("open"), Stream.source(list(data["high"]), dtype="float").rename("high"), Stream.source(list(data["low"]), dtype="float").rename("low"), Stream.source(list(data["close"]), dtype="float").rename("close"), Stream.source(list(data["volume"]), dtype="float").rename("volume"), #Stream.sensor(action_scheme, lambda s: s.action, dtype="float").rename("action") ]) renderer = PlotlyTradingChart() environment = default.create( feed=feed, portfolio=portfolio, action_scheme=action_scheme, # The DQN example uses action_scheme="managed-risk" reward_scheme=reward_scheme, # The DQN uses reward_scheme="risk-adjusted" renderer_feed=renderer_feed, renderer=renderer, window_size=config["window_size"], max_allowed_loss=0.6 ) return environment