def test_exchange_with_wallets_feed(): ex1 = Exchange("coinbase", service=execute_order)(Array("USD-BTC", [7000, 7500, 8300]), Array("USD-ETH", [200, 212, 400])) ex2 = Exchange("binance", service=execute_order)(Array("USD-BTC", [7005, 7600, 8200]), Array("USD-ETH", [201, 208, 402]), Array("USD-LTC", [56, 52, 60])) wallet_btc = Wallet(ex1, 10 * BTC) wallet_btc_ds = create_wallet_source(wallet_btc) wallet_usd = Wallet(ex2, 1000 * USD) wallet_usd -= 400 * USD wallet_usd += Quantity(USD, 400, path_id="fake_id") wallet_usd_ds = create_wallet_source(wallet_usd, include_worth=False) feed = DataFeed([ex1, ex2, wallet_btc_ds, wallet_usd_ds]) assert feed.next() == { "coinbase:/USD-BTC": 7000, "coinbase:/USD-ETH": 200, "coinbase:/BTC:/free": 10, "coinbase:/BTC:/locked": 0, "coinbase:/BTC:/total": 10, "coinbase:/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 test_price_ds(): btc_price = Stream("USD-BTC", [7000, 7500, 8300]) eth_price = Stream("USD-ETH", [200, 212, 400]) feed = DataFeed()(btc_price, eth_price) assert feed.next() == {"USD-BTC": 7000, "USD-ETH": 200}
def test_exchange_feed(): btc_price = Stream("USD-BTC", [7000, 7500, 8300]) eth_price = Stream("USD-ETH", [200, 212, 400]) exchange = Exchange("coinbase", service=execute_order)(btc_price, eth_price) feed = DataFeed([exchange]) assert feed.next() == {"coinbase:/USD-BTC": 7000, "coinbase/USD-ETH": 200}
def test_stream_adding(): a1 = Stream([1, 2, 3]).rename("a1") a2 = Stream([4, 5, 6]).rename("a2") t1 = BinOp(np.add)(a1, a2).rename("a1+a2") feed = DataFeed([t1, a1, a2]) output = feed.next() assert output == {'a1': 1, 'a2': 4, 'a1+a2': 5}
def test_stream_adding(): a1 = Array('a1', [1, 2, 3]) a2 = Array('a2', [4, 5, 6]) t1 = BinOp("a1+a2", operator.add)(a1, a2) feed = DataFeed([a1, a2, t1]) output = feed.next() assert output == {'a1': 1, 'a2': 4, 'a1+a2': 5}
def test_select(): a3 = Stream("a3", [3, 2, 1]) with Module("world") as a: a1 = Stream("a1", [7, 8, 9]) a2 = Stream("a2", [3, 2, 1]) t1 = BinOp("t1", operator.mul)(a1, a3) s = Select("world:/a1")(t1, a) feed = DataFeed()(s) assert feed.next() == {"world:/a1": 7}
def test_select(): a3 = Stream([3, 2, 1]).rename("a3") with Module("world") as a: a1 = Stream([7, 8, 9]).rename("a1") a2 = Stream([3, 2, 1]).rename("a2") t1 = BinOp(np.multiply)(a1, a3).rename("t1") s = Select("world:/a1")(t1, a) feed = DataFeed([s]) assert feed.next() == {"world:/a1": 7}
def test_simulated_from_config(): class NoSlippage(SlippageModel): def adjust_trade(self, trade: Trade, **kwargs) -> Trade: pass config = { 'base_instrument': 'EURO', 'instruments': ['BTC', 'ETH'], 'exchanges': { 'commission': 0.5, 'base_precision': 0.3, 'instrument_precision': 10, 'min_trade_price': 1e-7, 'max_trade_price': 1e7, 'min_trade_size': 1e-4, 'max_trade_size': 1e4, 'initial_balance': 1e5, 'window_size': 5, 'should_pretransform_obs': True, 'max_allowed_slippage_percent': 3.0, 'slippage_model': NoSlippage } } with TradingContext(**config): df = pd.Source([[900, 849, 9023, 94039, 943]], columns=["open", "high", "low", "close", "volume"]) exchange_ds = DataFrameSource('prices', df) data_feed = DataFeed([exchange_ds]) exchange = Exchange('Exchange', lambda x: {EUR / ETH: x['close']}) assert exchange._base_instrument == 'EURO' assert exchange._commission == 0.5
def test_init(): sources = [ Stream([1, 2, 3]).rename("a1"), Stream([4, 5, 6]).rename("a2"), Stream([7, 8, 9]).rename("a3") ] feed = DataFeed(sources) assert feed
def test_init(): sources = [ Array('a1', [1, 2, 3]), Array('a2', [4, 5, 6]), Array('a3', [7, 8, 9]) ] feed = DataFeed(sources) assert feed
def test_select(): a1 = Array("a1", [7, 8, 9]) a2 = Array("a2", [3, 2, 1]) t1 = BinOp("t1", operator.mul)(a1, a2) a = Namespace("world")(a1, a2) s = Select("world:/a1")(t1, a) feed = DataFeed([s]) print(a1.name, a1.inbound, a1.outbound) print(a2.name, a2.inbound, a2.outbound) print(t1.name, t1.inbound, t1.outbound) print(a.name, a.inbound, a.outbound) print(s.name, s.inbound, s.outbound) print(feed.inputs) assert feed.next() == {"world:/a1": 7}
def test_init(): sources = [ Stream('a1', [1, 2, 3]), Stream('a2', [4, 5, 6]), Stream('a3', [7, 8, 9]) ] feed = DataFeed()(*sources) assert feed
def test_namespace(): a = Stream([1, 2, 3]).rename("a") with Module("world") as world: a1 = Stream([4, 5, 6]).rename("a1") a2 = Stream([7, 8, 9]).rename("a2") with Module("sub-world") as sub_world: a3 = Stream([10, 11, 12]).rename("a3") a4 = Stream([13, 14, 15]).rename("a4") t3 = BinOp(np.add)(a2, a4).rename("t3") t1 = BinOp(np.multiply)(a, t3).rename("t1") feed = DataFeed([t1, world, sub_world]) assert feed.next() == { "world:/a1": 4, "world:/a2": 7, "world:/sub-world:/a3": 10, "world:/sub-world:/a4": 13, "world:/sub-world:/t3": 20, "t1": 20 } feed.reset() assert feed.next() == { "world:/a1": 4, "world:/a2": 7, "world:/sub-world:/a3": 10, "world:/sub-world:/a4": 13, "world:/sub-world:/t3": 20, "t1": 20 }
def test_namespace(): a = Stream("a", [1, 2, 3]) with Module("world") as world: a1 = Stream("a1", [4, 5, 6]) a2 = Stream("a2", [7, 8, 9]) with Module("sub-world") as sub_world: a3 = Stream("a3", [10, 11, 12]) a4 = Stream("a4", [13, 14, 15]) t3 = BinOp("t3", operator.add)(a2, a4) t1 = BinOp("t1", operator.mul)(a, t3) feed = DataFeed()(t1, world, sub_world) assert feed.next() == { "world:/a1": 4, "world:/a2": 7, "world:/sub-world:/a3": 10, "world:/sub-world:/a4": 13, "world:/sub-world:/t3": 20, "t1": 20 } feed.reset() assert feed.next() == { "world:/a1": 4, "world:/a2": 7, "world:/sub-world:/a3": 10, "world:/sub-world:/a4": 13, "world:/sub-world:/t3": 20, "t1": 20 }
def create_env(): def fetch_data(exchange_name, symbol, timeframe): url = "https://www.cryptodatadownload.com/cdd/" filename = "{}_{}USD_{}.csv".format(exchange_name, symbol, timeframe) volume_column = "Volume {}".format(symbol) new_volume_column = "Volume_{}".format(symbol) df = pd.read_csv(url + filename, skiprows=1) df = df[::-1] df = df.drop(["Symbol"], axis=1) df = df.rename( { "Volume USD": "volume", volume_column: new_volume_column }, axis=1) df = df.set_index("Date") df.columns = [symbol + ":" + name.lower() for name in df.columns] return df ssl._create_default_https_context = ssl._create_unverified_context # Only used if pandas gives a SSLError coinbase_data = pd.concat([ fetch_data("Coinbase", "BTC", "1h"), fetch_data("Coinbase", "ETH", "1h") ], axis=1) coinbase = Exchange("coinbase", service=execute_order)( Stream("USD-BTC", list(coinbase_data['BTC:close'])), Stream("USD-ETH", list(coinbase_data['ETH:close']))) with Module("coinbase") as coinbase_ns: nodes = [ Stream(name, list(coinbase_data[name])) for name in coinbase_data.columns ] feed = DataFeed([coinbase_ns]) portfolio = Portfolio(USD, [ Wallet(coinbase, 10000 * USD), Wallet(coinbase, 10 * BTC), Wallet(coinbase, 5 * ETH), ]) env = TradingEnvironment(feed=feed, portfolio=portfolio, action_scheme='managed-risk', reward_scheme='risk-adjusted', window_size=20) return env
def create_internal_feed(portfolio: 'Portfolio'): base_symbol = portfolio.base_instrument.symbol sources = [] for wallet in portfolio.wallets: symbol = wallet.instrument.symbol sources += [wallet.exchange] sources += [create_wallet_source(wallet, include_worth=(symbol != base_symbol))] worth_nodes = Condition( "worths", lambda node: node.name.endswith(base_symbol + ":/total") or node.name.endswith("worth") )(*sources) net_worth = Reduce("net_worth", func=operator.add)(worth_nodes) sources += [net_worth] feed = DataFeed()(*sources) feed.attach(portfolio) return feed
def create_internal_feed(portfolio: 'Portfolio'): base_symbol = portfolio.base_instrument.symbol sources = [] for wallet in portfolio.wallets: symbol = wallet.instrument.symbol sources += [wallet.exchange] sources += [ create_wallet_source(wallet, include_worth=(symbol != base_symbol)) ] net_worth = Reduce(name="net_worth", selector=lambda k: k.endswith(base_symbol + ":/total") or k.endswith("worth"), func=operator.add)(*sources) sources += [net_worth] feed = DataFeed(sources) feed.attach(portfolio) return feed
def test_runs_with__external_feed_only(portfolio): df = pd.read_csv("tests/data/input/coinbase_(BTC,ETH)USD_d.csv").tail(100) df = df.rename({"Unnamed: 0": "date"}, axis=1) df = df.set_index("date") coinbase_btc = df.loc[:, [name.startswith("BTC") for name in df.columns]] coinbase_eth = df.loc[:, [name.startswith("ETH") for name in df.columns]] ta.add_all_ta_features( coinbase_btc, colprefix="BTC:", **{k: "BTC:" + k for k in ['open', 'high', 'low', 'close', 'volume']} ) ta.add_all_ta_features( coinbase_eth, colprefix="ETH:", **{k: "ETH:" + k for k in ['open', 'high', 'low', 'close', 'volume']} ) nodes = [] with Module("coinbase") as coinbase: for name in coinbase_btc.columns: nodes += [Stream(name, list(coinbase_btc[name]))] for name in coinbase_eth.columns: nodes += [Stream(name, list(coinbase_eth[name]))] feed = DataFeed()(coinbase) action_scheme = ManagedRiskOrders() reward_scheme = SimpleProfit() env = TradingEnvironment( portfolio=portfolio, action_scheme=action_scheme, reward_scheme=reward_scheme, feed=feed, window_size=50, use_internal=False, enable_logger=False ) done = False obs = env.reset() while not done: action = env.action_space.sample() obs, reward, done, info = env.step(action) n_features = coinbase_btc.shape[1] + coinbase_eth.shape[1] assert obs.shape == (50, n_features)
def trading(agent_path, n_step = len(test),): from tensortrade.exchanges import Exchange from tensortrade.exchanges.services.execution.simulated import execute_order from tensortrade.data import Stream, DataFeed, Module from tensortrade.instruments import USD, BTC from tensortrade.wallets import Wallet, Portfolio coinbase = Exchange("coinbase", service=execute_order)( Stream("USD-BTC", price_history['close'].tolist()) ) portfolio = Portfolio(USD, [ Wallet(coinbase, 10000 * USD), Wallet(coinbase, 10 * BTC), ]) with Module("coinbase") as coinbase_ns: nodes = [Stream(name, test[name].tolist()) for name in test.columns] feed = DataFeed([coinbase_ns]) from tensortrade.environments import TradingEnvironment env = TradingEnvironment( feed=feed, portfolio=portfolio, action_scheme='managed-risk', reward_scheme='risk-adjusted', window_size=20 ) agent = DQNAgent(env) agent.restore() action = agent.env.action_space.sample() state, reward, done, info = agent.env.step(action) action = agent.get_action(state) action = agent.env.action_space.sample() step = 0 while not done and (step < n_steps): state, reward, done, info = agent.env.step(action) action = agent.get_action(state) print('step:', step, '-- action:', action) step += 1 env.portfolio.performance.plot(figsize=(16, 10)) env.portfolio.performance.net_worth.plot(figsize=(16, 10))
def test_exchange_with_data_source(): data = np.array([[13863.13, 13889., 12952.5, 13480.01, 11484.01], [13480.01, 15275., 13005., 14781.51, 23957.87], [14781.51, 15400., 14628., 15098.14, 16584.63], [15098.14, 15400., 14230., 15144.99, 17980.39], [15144.99, 17178., 14824.05, 16960.01, 20781.65]]) index = pd.Index( ['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05'], name="date") columns = ["open", "high", "low", "close", "volume"] data_frame = pd.Source(data, index=index, columns=columns) data_frame_ds = DataFrameSource('a1', data_frame) data_feed = DataFeed([data_frame_ds])
def test_apply(): s1 = Stream([1, 4, 9, 16, 25], "s1") lag = s1.apply(np.sqrt).rename("apply") feed = DataFeed([lag]) feed.compile() values = [] while feed.has_next(): values += [feed.next()["apply"]] assert values == [1, 2, 3, 4, 5]
def test_namespace(): a1 = Array("a1", [7, 8, 9]) a2 = Array("a2", [3, 2, 1]) t1 = BinOp("t1", operator.mul)(a1, a2) a = Namespace("world")(a1, a2) feed = DataFeed([t1, a]) assert feed.next() == {"world:/a1": 7, "world:/a2": 3, "t1": 21} feed.reset() assert feed.next() == {"world:/a1": 7, "world:/a2": 3, "t1": 21}
def test_fillna(): s = Stream([1, np.nan, -3, np.nan, 5], "s") m = s.fillna(-1).rename("fill") feed = DataFeed([m]) feed.compile() expected = [1, -1, -3, -1, 5] actual = [] while feed.has_next(): actual += [feed.next()["fill"]] assert actual == expected
def test_clamp_max(): s = Stream([1, -2, -3, 0, 5], "s") m = s.clamp_max(0).rename("clamp_max") feed = DataFeed([m]) feed.compile() expected = [0, -2, -3, 0, 0] actual = [] while feed.has_next(): actual += [feed.next()["clamp_max"]] assert actual == expected
def test_max(): s1 = Stream([1, 2, 3, 4], "s1") s2 = Stream([1, 4, 3, 2], "s2") m = s1.max(s2).rename("max") feed = DataFeed([m]) feed.compile() expected = [1, 4, 3, 4] actual = [] while feed.has_next(): actual += [feed.next()["max"]] assert actual == expected
def test_lag(): s1 = Stream([1, 2, 3, 4, 5]).rename("stream") assert s1.name == "stream" lag = s1.lag() assert lag.name == "Lag(stream,1)" feed = DataFeed([lag]) feed.compile() values = [] while feed.has_next(): values += [feed.next()["Lag(stream,1)"]] assert values == [np.nan, 1, 2, 3, 4]
def test_multi_step_adding(): a1 = Array('a1', [1, 2, 3]) a2 = Array('a2', [4, 5, 6]) t1 = BinOp('t1', operator.add)(a1, a2) t2 = BinOp('t2', operator.add)(t1, a2) feed = DataFeed([a1, a2, t1, t2]) output = feed.next() assert output == {'a1': 1, 'a2': 4, 't1': 5, 't2': 9} feed = DataFeed([a1, a2, t2]) output = feed.next() assert output == {'a1': 1, 'a2': 4, 't2': 9}
def test_multi_step_adding(): a1 = Stream([1, 2, 3]).rename("a1") a2 = Stream([4, 5, 6]).rename("a2") t1 = BinOp(np.add)(a1, a2).rename("t1") t2 = BinOp(np.add)(t1, a2).rename("t2") feed = DataFeed([a1, a2, t1, t2]) output = feed.next() assert output == {'a1': 1, 'a2': 4, 't1': 5, 't2': 9} feed = DataFeed([a1, a2, t2]) output = feed.next() assert output == {'a1': 1, 'a2': 4, 't2': 9}
def test_emwmv_unbiased(): # bias: True v = [np.nan, 2, np.nan, 6, 8, 5] s = Stream(v, "s") specs = [{ "alpha": 0.68, "adjust": True, "ignore_na": True, "min_periods": 3 }, { "alpha": 0.68, "adjust": True, "ignore_na": False, "min_periods": 3 }, { "alpha": 0.68, "adjust": False, "ignore_na": True, "min_periods": 3 }, { "alpha": 0.68, "adjust": False, "ignore_na": False, "min_periods": 3 }] for spec in specs: d = spec.copy() d["warmup"] = d["min_periods"] del d["min_periods"] var = s.ewm(**d).var(bias=False).rename("var") feed = DataFeed([var]) feed.compile() expected = list(pd.Series(v).ewm(**spec).var(bias=False)) actual = [] while feed.has_next(): actual += [feed.next()["var"]] assert all(np.isclose(actual, expected))
def test_sub(): s1 = Stream([2, 3, 4, 5, 6], "s1") assert s1.name == "s1" s2 = Stream([1, 2, 3, 4, 5], "s2") assert s2.name == "s2" s = s1 - s2 assert s.name == "Subtract(s1,s2)" feed = DataFeed([s]) feed.compile() values = [] while feed.has_next(): values += [feed.next()["Subtract(s1,s2)"]] assert values == [1, 1, 1, 1, 1]