예제 #1
0
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
    }
예제 #2
0
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}
예제 #3
0
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}
예제 #4
0
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}
예제 #5
0
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}
예제 #6
0
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}
예제 #7
0
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}
예제 #8
0
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
예제 #9
0
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
예제 #10
0
def test_init():
    sources = [
        Array('a1', [1, 2, 3]),
        Array('a2', [4, 5, 6]),
        Array('a3', [7, 8, 9])
    ]
    feed = DataFeed(sources)

    assert feed
예제 #11
0
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}
예제 #12
0
def test_init():
    sources = [
        Stream('a1', [1, 2, 3]),
        Stream('a2', [4, 5, 6]),
        Stream('a3', [7, 8, 9])
    ]
    feed = DataFeed()(*sources)

    assert feed
예제 #13
0
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
    }
예제 #14
0
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
    }
예제 #15
0
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
예제 #16
0
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
예제 #17
0
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))
예제 #20
0
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]
예제 #22
0
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]
예제 #27
0
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}
예제 #28
0
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]