In [ ]:
import gc
gc.collect()

import sys
sys.path.insert(0, '../')
import logging
logging.basicConfig(level=logging.ERROR)

from datetime import datetime, timedelta

from cryptotrader.exchange_api.poloniex import Poloniex
from cryptotrader.envs.trading import BacktestDataFeed, BacktestEnvironment
from cryptotrader.envs.utils import make_balance, convert_to
from cryptotrader.agents import apriori
from cryptotrader.utils import array_normalize, simplex_proj

from bokeh.io import output_notebook
output_notebook()
%matplotlib inline
# %load_ext line_profiler

In [ ]:
# Simulation Params
test_name = 'Momentum_agent'
obs_steps = 200 # Observation steps, number of candles required by the agent for calculations
period = 120 # Observation period in minutes, also trading frequency
pairs = ["USDT_BTC", "USDT_ETH", "USDT_LTC", "USDT_XRP", "USDT_XMR", "USDT_ETC", "USDT_ZEC", "USDT_DASH"] # Universe, some survivor bias here...
fiat_symbol = 'USDT' # Quote symbol
init_funds = make_balance(crypto=1 / len(pairs), fiat=0.0, pairs=pairs) # Initial equally distributed portfolio
data_dir = './data' # Data directory for offline testing

In [ ]:
## Environment setup
# Data feed setup
tapi = Poloniex()
tapi = BacktestDataFeed(tapi, period, pairs=pairs, balance=init_funds, load_dir=data_dir)

# Download new data from the exchange
# tapi.download_data(end=datetime.timestamp(datetime.utcnow() - timedelta(days=100)),
#                        start=datetime.timestamp(datetime.utcnow() - timedelta(days=300)))

# # And save it to disk, if you want to
# tapi.save_data(data_dir + '/train')

# Or load data from disk
tapi.load_data('/train')

# Environment setup
env = BacktestEnvironment(period, obs_steps, tapi, fiat_symbol, test_name)
obs = env.reset()

# Agent setup
agent = apriori.MomentumTrader(ma_span=[3,50], std_span=50, activation=simplex_proj)

In [ ]:
# Training run
# Optimization params
nb_steps = 1000
batch_size = 1
nb_max_episode_steps = 12

# Params search space
hp = {
    'ma1': [2, env.obs_steps],
    'ma2': [2, env.obs_steps],
    'std_span': [2, env.obs_steps],
    'alpha_up': [1e-1, 1],
    'alpha_down': [1e-1, 1]
    }

search_space = {'mean_type':{'simple': hp,
                             'exp': hp,
                             'kama': hp
                             }
                }

# Params constrains
constrains = [lambda mean_type, ma1, ma2, std_span, alpha_up, alpha_down: ma1 < ma2]

# Optimization session, this may take some time
opt_params, info = agent.fit(env, nb_steps, batch_size, search_space, constrains, nb_max_episode_steps=nb_max_episode_steps)
print("\n", opt_params,"\n", env.status)

# Saved previous found params for comparison...
# {'mean_type': 'kama', 'alpha_down': 0.4128425807825884, 'alpha_up': 0.37140222586733046, 'ma1': 133, 'ma2': 234, 'std_span': 39}

# Run on training data
agent.test(env, verbose=True)
# Display results
env.plot_results();

In [ ]:
# Validation run
# Download data
# tapi.download_data(end=datetime.timestamp(datetime.now() - timedelta(days=50)),
#                        start=datetime.timestamp(datetime.now() - timedelta(days=100)))

# And save it to disk, if you want to
# tapi.save_data(data_dir + '/eval')

# or load from disk
env.tapi.load_data('/eval')

# Run evaluation
agent.test(env, verbose=True)
# Show results
env.plot_results();

In [ ]:
# Test run
# Download data
# tapi.download_data(end=datetime.timestamp(datetime.now()),
#                        start=datetime.timestamp(datetime.now() - timedelta(days=50)))

# And save it to disk, if you want to
# tapi.save_data(data_dir + '/test')

# Or load form disk
env.tapi.load_data('/test')
# Run test
agent.test(env, verbose=True)
# Show results
env.plot_results();