def portfolio(): df1 = pd.read_csv("tests/data/input/bitfinex_(BTC,ETH)USD_d.csv").tail(100) df1 = df1.rename({"Unnamed: 0": "date"}, axis=1) df1 = df1.set_index("date") df2 = pd.read_csv("tests/data/input/bitstamp_(BTC,ETH,LTC)USD_d.csv").tail( 100) df2 = df2.rename({"Unnamed: 0": "date"}, axis=1) df2 = df2.set_index("date") ex1 = Exchange("bitfinex", service=execute_order)( Stream.source(list(df1['BTC:close']), dtype="float").rename("USD-BTC"), Stream.source(list(df1['ETH:close']), dtype="float").rename("USD-ETH")) ex2 = Exchange("binance", service=execute_order)( Stream.source(list(df2['BTC:close']), dtype="float").rename("USD-BTC"), Stream.source(list(df2['ETH:close']), dtype="float").rename("USD-ETH"), Stream.source(list(df2['LTC:close']), dtype="float").rename("USD-LTC")) p = Portfolio(USD, [ Wallet(ex1, 10000 * USD), Wallet(ex1, 10 * BTC), Wallet(ex1, 5 * ETH), Wallet(ex2, 1000 * USD), Wallet(ex2, 5 * BTC), Wallet(ex2, 20 * ETH), Wallet(ex2, 3 * LTC), ]) return p
def test_exchange_feed(): btc_price = Stream.source([7000, 7500, 8300], dtype="float").rename("USD-BTC") eth_price = Stream.source([200, 212, 400], dtype="float").rename("USD-ETH") exchange = Exchange("bitfinex", service=execute_order)(btc_price, eth_price) feed = DataFeed(exchange.streams()) assert feed.next() == {"bitfinex:/USD-BTC": 7000, "bitfinex:/USD-ETH": 200}
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 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 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 test_exchange_with_wallets_feed(): ex1 = Exchange("bitfinex", service=execute_order)( Stream.source([7000, 7500, 8300], dtype="float").rename("USD-BTC"), Stream.source([200, 212, 400], dtype="float").rename("USD-ETH")) ex2 = Exchange("binance", service=execute_order)( Stream.source([7005, 7600, 8200], dtype="float").rename("USD-BTC"), Stream.source([201, 208, 402], dtype="float").rename("USD-ETH"), Stream.source([56, 52, 60], dtype="float").rename("USD-LTC")) wallet_btc = Wallet(ex1, 10 * BTC) wallet_btc_ds = _create_wallet_source(wallet_btc) wallet_usd = Wallet(ex2, 1000 * USD) wallet_usd.withdraw(quantity=400 * USD, reason="test") wallet_usd.deposit(quantity=Quantity(USD, 400, path_id="fake_id"), reason="test") wallet_usd_ds = _create_wallet_source(wallet_usd, include_worth=False) streams = ex1.streams() + ex2.streams() + wallet_btc_ds + wallet_usd_ds feed = DataFeed(streams) assert feed.next() == { "bitfinex:/USD-BTC": 7000, "bitfinex:/USD-ETH": 200, "bitfinex:/BTC:/free": 10, "bitfinex:/BTC:/locked": 0, "bitfinex:/BTC:/total": 10, "bitfinex:/BTC:/worth": 70000, "binance:/USD-BTC": 7005, "binance:/USD-ETH": 201, "binance:/USD-LTC": 56, "binance:/USD:/free": 600, "binance:/USD:/locked": 400, "binance:/USD:/total": 1000 }
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
v = Stream.select(features, lambda s: s.name == 'volume') features = [ cp.log().diff().rename("lr"), op.log().diff().rename("op"), hp.log().diff().rename("hp"), lp.log().diff().rename("lp"), v.log().diff().rename("v"), rsi(cp, period=20).rename("rsi"), macd(cp, fast=10, slow=50, signal=5).rename("macd"), ] 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, 100000 * USD), 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(
import pytest import unittest.mock as mock from decimal import Decimal from tensortrade.core.exceptions import InsufficientFunds, IncompatibleInstrumentOperation from tensortrade.oms.exchanges import Exchange from tensortrade.oms.wallets import Wallet from tensortrade.oms.instruments import USD, BTC, Quantity, ExchangePair path_id = "f4cfeeae-a3e4-42e9-84b9-a24ccd2eebeb" other_id = "7f3de243-0474-48d9-bf44-ca55ae07a70e" exchange = Exchange('Exchange', lambda x: x) def test_init(): wallet = Wallet(exchange, 10000*USD) assert wallet.balance == 10000*USD assert wallet.exchange == exchange assert wallet.instrument == USD assert len(wallet.locked) == 0 def test_from_tuple(): wallet_tuple = (exchange, USD, 10000)
'Low':'low', 'High':'high', 'Volume':'volume' }, inplace = True) df_USD = df_USD[df_USD['close'].notnull()] dataset = ta.add_all_ta_features(df_USD, 'open', 'high', 'low', 'close', 'volume', fillna=True) price_history = dataset[['date', 'open', 'high', 'low', 'close', 'volume']] # chart data dataset.drop(columns=['date', 'open', 'high', 'low', 'close', 'volume'], inplace=True) micex = Exchange("MICEX", service=execute_order, options=ExchangeOptions(commission = 0.0003, #0.003, min_trade_size = 1e-6, max_trade_size = 1e6, min_trade_price = 1e-8, max_trade_price= 1e8, is_live=False) )( Stream.source(price_history['close'].tolist(), dtype="float").rename("RUR-USD")) portfolio = Portfolio(RUR, [ Wallet(micex, 0 * USD), Wallet(micex, 73000 * RUR), ]) with NameSpace("MICEX"): streams = [Stream.source(dataset[c].tolist(), dtype="float").rename(c) for c in dataset.columns] feed = DataFeed(streams) feed.next()
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
# %% features = [] for c in data.columns[1:]: s = Stream.source(list(data[c]), dtype="float").rename(data[c].name) features += [s] feed = DataFeed(features) feed.compile() for i in range(5): print(feed.next()) # %% [markdown] # ## Setup Trading Environment # %% # Make a stream of closing prices to make orders on exchange = Exchange("sim-exchange", service=execute_order)(Stream.source( list(data["close"]), dtype="float").rename("USD-AAPL")) portfolio = Portfolio( base_instrument=USD, wallets=[Wallet(exchange, 10000 * USD), 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") ])
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
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
def BinanceExchange(data): exchange = Exchange("binance", service=execute_order)(Stream.source( list(data['close']), dtype="float").rename("USD-BTC")) return exchange
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
bitstamp_btc.to_csv("data/bitstamp_btc_hourly.csv") bitstamp_eth.to_csv("data/bitstamp_eth_hourly.csv") bitstamp_ltc.to_csv("data/bitstamp_ltc_hourly.csv") bitstamp_btc = pandas.read_csv("data/bitstamp_btc_hourly.csv") bitstamp_eth = pandas.read_csv("data/bitstamp_eth_hourly.csv") bitstamp_ltc = pandas.read_csv("data/bitstamp_ltc_hourly.csv") # Inspec transactions of Simple orders bitstamp = Exchange("bitstamp", service=execute_order)( Stream.source(list(bitstamp_btc["close"][-100:]), dtype="float").rename("USD-BTC"), Stream.source(list(bitstamp_eth["close"][-100:]), dtype="float").rename("USD-ETH"), Stream.source(list(bitstamp_ltc["close"][-100:]), dtype="float").rename("USD-LTC"), ) portfolio = Portfolio( USD, [ Wallet(bitstamp, 1000 * USD), Wallet(bitstamp, 5 * BTC), Wallet(bitstamp, 20 * ETH), Wallet(bitstamp, 3 * LTC), ], )
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
float(key['open_price']), 'high': float(key['high_price']), 'low': float(key['low_price']), 'close': float(key['close_price']), 'volume': float(key['volume']) } btc_data.append(data) data = pd.DataFrame.from_dict(btc_data) robinhood_btc_data = data.add_prefix('BTC:') robinhood = Exchange("robinhood", service=execute_order)(Stream.source( list(robinhood_btc_data['BTC:close']), dtype="float").rename("USD-BTC")) robinhood_btc = robinhood_btc_data.loc[:, [ name.startswith("BTC") for name in robinhood_btc_data.columns ]] ta.add_all_ta_features( robinhood_btc, colprefix="BTC:", **{k: "BTC:" + k for k in ['open', 'high', 'low', 'close', 'volume']}) with NameSpace("robinhood"): robinhood_stream = [ Stream.source(list(robinhood_btc[c]), dtype="float").rename(c) for c in robinhood_btc.columns
"high", "low", "close", "volume", fillna=True) df = df + 1 - 2 * df.min() # Make positive log_and_diff(df, df.columns) df.drop(0, inplace=True) prices.drop(0, inplace=True) # df.plot() # plt.show() # Process # print(df[["open", "high", "low", "volume"]].head()) # # Setup trading env coinbase = Exchange("coinbase", service=execute_order)(Stream.source( prices["close"].tolist(), dtype="float").rename("USD-BTC")) portfolio = Portfolio( USD, [Wallet(coinbase, 10000 * USD)], ) 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
def test_create_internal_data_feed(): ex1 = Exchange("bitfinex", service=execute_order)( Stream.source([7000, 7500, 8300], dtype="float").rename("USD-BTC"), Stream.source([200, 212, 400], dtype="float").rename("USD-ETH")) ex2 = Exchange("binance", service=execute_order)( Stream.source([7005, 7600, 8200], dtype="float").rename("USD-BTC"), Stream.source([201, 208, 402], dtype="float").rename("USD-ETH"), Stream.source([56, 52, 60], dtype="float").rename("USD-LTC")) portfolio = Portfolio(USD, [ Wallet(ex1, 10000 * USD), Wallet(ex1, 10 * BTC), Wallet(ex1, 5 * ETH), Wallet(ex2, 1000 * USD), Wallet(ex2, 5 * BTC), Wallet(ex2, 20 * ETH), Wallet(ex2, 3 * LTC), ]) feed = DataFeed(_create_internal_streams(portfolio)) data = { "bitfinex:/USD-BTC": 7000, "bitfinex:/USD-ETH": 200, "bitfinex:/USD:/free": 10000, "bitfinex:/USD:/locked": 0, "bitfinex:/USD:/total": 10000, "bitfinex:/BTC:/free": 10, "bitfinex:/BTC:/locked": 0, "bitfinex:/BTC:/total": 10, "bitfinex:/BTC:/worth": 7000 * 10, "bitfinex:/ETH:/free": 5, "bitfinex:/ETH:/locked": 0, "bitfinex:/ETH:/total": 5, "bitfinex:/ETH:/worth": 200 * 5, "binance:/USD-BTC": 7005, "binance:/USD-ETH": 201, "binance:/USD-LTC": 56, "binance:/USD:/free": 1000, "binance:/USD:/locked": 0, "binance:/USD:/total": 1000, "binance:/BTC:/free": 5, "binance:/BTC:/locked": 0, "binance:/BTC:/total": 5, "binance:/BTC:/worth": 7005 * 5, "binance:/ETH:/free": 20, "binance:/ETH:/locked": 0, "binance:/ETH:/total": 20, "binance:/ETH:/worth": 201 * 20, "binance:/LTC:/free": 3, "binance:/LTC:/locked": 0, "binance:/LTC:/total": 3, "binance:/LTC:/worth": 56 * 3, } bitfinex_net_worth = 10000 + (10 * 7000) + (5 * 200) binance_net_worth = 1000 + (5 * 7005) + (20 * 201) + (3 * 56) data['net_worth'] = sum( data[k] if k.endswith("worth") or k.endswith("USD:/total") else 0 for k in data.keys()) assert feed.next() == data
'Volume', fillna=True) price_history = dataset[['Date', 'Open', 'High', 'Low', 'Close', 'Volume']] # chart dataset.drop(columns=['Date', 'Open', 'High', 'Low', 'Close', 'Volume'], inplace=True) from tensortrade.oms.instruments import USD, BTC, ETH from tensortrade.feed.core import Stream, DataFeed, NameSpace from tensortrade.oms.exchanges import Exchange from tensortrade.oms.services.execution.simulated import execute_order from tensortrade.oms.instruments import USD, BTC from tensortrade.oms.wallets import Wallet, Portfolio bitfinex = Exchange("bitfinex", service=execute_order)(Stream.source( price_history['Close'].tolist(), dtype="float").rename("USD-BTC")) portfolio = Portfolio(USD, [ Wallet(bitfinex, 10000 * USD), Wallet(bitfinex, 10 * BTC), ]) with NameSpace("bitfinex"): streams = [ Stream.source(dataset[c].tolist(), dtype="float").rename(c) for c in dataset.columns ] feed = DataFeed(streams) feed.next() def create_env(config): p = Stream.source(price_history['Close'].tolist(),
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