Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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
Exemplo n.º 5
0
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
Exemplo n.º 7
0
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
Exemplo n.º 8
0
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
Exemplo n.º 9
0
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
Exemplo n.º 10
0
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
Exemplo n.º 11
0
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
Exemplo n.º 12
0
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
Exemplo n.º 13
0
)

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()
Exemplo n.º 14
0
    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
Exemplo n.º 15
0
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
Exemplo n.º 16
0
    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
Exemplo n.º 17
0
          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()

# %%
Exemplo n.º 18
0
           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)
Exemplo n.º 19
0
             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)
Exemplo n.º 20
0
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()

# %%
Exemplo n.º 21
0
    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]
Exemplo n.º 22
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
Exemplo n.º 23
0
        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
Exemplo n.º 24
0
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
Exemplo n.º 25
0
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