From d41d9095a162e37b3461f195e11bb2efc8c385ee Mon Sep 17 00:00:00 2001 From: Frederic Fortier Date: Tue, 12 Dec 2017 15:13:57 -0500 Subject: [PATCH] BLD: adjusted the example algorithms --- catalyst/examples/buy_low_sell_high_live.py | 2 +- catalyst/examples/dual_vwap.py | 190 -------------------- catalyst/examples/mean_reversion_simple.py | 2 +- catalyst/examples/portfolio_optimization.py | 43 ++--- catalyst/examples/rsi_profit_target.py | 42 ++--- catalyst/examples/simple_loop.py | 37 ++-- 6 files changed, 53 insertions(+), 263 deletions(-) delete mode 100644 catalyst/examples/dual_vwap.py diff --git a/catalyst/examples/buy_low_sell_high_live.py b/catalyst/examples/buy_low_sell_high_live.py index cfd5854c..34b1e5f6 100644 --- a/catalyst/examples/buy_low_sell_high_live.py +++ b/catalyst/examples/buy_low_sell_high_live.py @@ -152,7 +152,7 @@ if __name__ == '__main__': initialize=initialize, handle_data=handle_data, analyze=analyze, - exchange_name='bittrex', + exchange_name='binance', live=True, algo_namespace=algo_namespace, base_currency='btc', diff --git a/catalyst/examples/dual_vwap.py b/catalyst/examples/dual_vwap.py deleted file mode 100644 index 7059b865..00000000 --- a/catalyst/examples/dual_vwap.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2017 Enigma MPC, Inc. -# Copyright 2014 Quantopian, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from catalyst.api import ( - order_target_percent, - record, - symbol, - get_open_orders, - set_max_leverage, - schedule_function, - date_rules, - attach_pipeline, - pipeline_output, -) - -from catalyst.pipeline import Pipeline -from catalyst.pipeline.data import CryptoPricing -from catalyst.pipeline.factors.crypto import VWAP - - -def initialize(context): - context.ASSET_NAME = 'USDT_BTC' - context.TARGET_INVESTMENT_RATIO = 0.8 - context.SHORT_WINDOW = 30 - context.LONG_WINDOW = 100 - - # For all trading pairs in the poloniex bundle, the default denomination - # currently supported by Catalyst is 1/1000th of a full coin. Use this - # constant to scale the price of up to that of a full coin if desired. - context.TICK_SIZE = 1000.0 - - context.i = 0 - context.asset = symbol(context.ASSET_NAME) - - set_max_leverage(1.0) - - attach_pipeline(make_pipeline(context), 'vwap_pipeline') - - schedule_function( - rebalance, - time_rules=date_rules.every_minute(), - ) - - -def before_trading_start(context, data): - context.pipeline_data = pipeline_output('vwap_pipeline') - - -def make_pipeline(context): - return Pipeline( - columns={ - 'price': CryptoPricing.open.latest, - 'volume': CryptoPricing.volume.latest, - 'short_mavg': VWAP(window_length=context.SHORT_WINDOW), - 'long_mavg': VWAP(window_length=context.LONG_WINDOW), - } - ) - - -def rebalance(context, data): - context.i += 1 - - # skip first LONG_WINDOW bars to fill windows - if context.i < context.LONG_WINDOW: - return - - # get pipeline data for asset of interest - pipeline_data = context.pipeline_data - pipeline_data = pipeline_data[pipeline_data.index == context.asset].iloc[0] - - # retrieve long and short moving averages from pipeline - short_mavg = pipeline_data.short_mavg - long_mavg = pipeline_data.long_mavg - price = pipeline_data.price - volume = pipeline_data.volume - - # check that order has not already been placed - open_orders = get_open_orders() - if context.asset not in open_orders: - # check that the asset of interest can currently be traded - if data.can_trade(context.asset): - # adjust portfolio based on comparison of long and short vwap - if short_mavg > long_mavg: - order_target_percent( - context.asset, - context.TARGET_INVESTMENT_RATIO, - ) - elif short_mavg < long_mavg: - order_target_percent( - context.asset, - 0.0, - ) - - record( - price=price, - cash=context.portfolio.cash, - leverage=context.account.leverage, - short_mavg=short_mavg, - long_mavg=long_mavg, - volume=volume, - ) - - -def analyze(context=None, results=None): - import matplotlib.pyplot as plt - - # Plot the portfolio and asset data. - ax1 = plt.subplot(611) - results[['portfolio_value']].plot(ax=ax1) - ax1.set_ylabel('Portfolio value (USD)') - - ax2 = plt.subplot(612, sharex=ax1) - ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME)) - (context.TICK_SIZE*results[['price', - 'short_mavg', - 'long_mavg']]).plot(ax=ax2) - - trans = results.ix[[t != [] for t in results.transactions]] - - buys = trans.ix[ - [t[0]['amount'] > 0 for t in trans.transactions] - ] - sells = trans.ix[ - [t[0]['amount'] < 0 for t in trans.transactions] - ] - - ax2.plot( - buys.index, - context.TICK_SIZE * results.price[buys.index], - '^', - markersize=10, - color='g', - ) - ax2.plot( - sells.index, - context.TICK_SIZE * results.price[sells.index], - 'v', - markersize=10, - color='r', - ) - - ax3 = plt.subplot(613, sharex=ax1) - results[['leverage', 'alpha', 'beta']].plot(ax=ax3) - ax3.set_ylabel('Leverage (USD)') - - ax4 = plt.subplot(614, sharex=ax1) - results[['cash']].plot(ax=ax4) - ax4.set_ylabel('Cash (USD)') - - results[[ - 'treasury', - 'algorithm', - 'benchmark', - ]] = results[[ - 'treasury_period_return', - 'algorithm_period_return', - 'benchmark_period_return', - ]] - - ax5 = plt.subplot(615, sharex=ax1) - results[[ - 'treasury', - 'algorithm', - 'benchmark', - ]].plot(ax=ax5) - ax5.set_ylabel('Percent Change') - - ax6 = plt.subplot(616, sharex=ax1) - results[['volume']].plot(ax=ax6) - ax6.set_ylabel('Volume (mBTC/day)') - - plt.legend(loc=3) - - # Show the plot. - plt.gcf().set_size_inches(18, 8) - plt.show() diff --git a/catalyst/examples/mean_reversion_simple.py b/catalyst/examples/mean_reversion_simple.py index ca03baf0..b3fb7934 100644 --- a/catalyst/examples/mean_reversion_simple.py +++ b/catalyst/examples/mean_reversion_simple.py @@ -245,7 +245,7 @@ def analyze(context=None, perf=None): if __name__ == '__main__': # The execution mode: backtest or live - MODE = 'live' + MODE = 'backtest' if MODE == 'backtest': folder = os.path.join( diff --git a/catalyst/examples/portfolio_optimization.py b/catalyst/examples/portfolio_optimization.py index e93b2daf..37f8a55d 100644 --- a/catalyst/examples/portfolio_optimization.py +++ b/catalyst/examples/portfolio_optimization.py @@ -43,14 +43,14 @@ def handle_data(context, data): if context.i == 0 or context.i % context.rebalance_period == 0: n = context.window prices = data.history(context.assets, fields='price', - bar_count=n+1, frequency='1d') + bar_count=n + 1, frequency='1d') pr = np.asmatrix(prices) - t_prices = prices.iloc[1:n+1] + t_prices = prices.iloc[1:n + 1] t_val = t_prices.values tminus_prices = prices.iloc[0:n] tminus_val = tminus_prices.values # Compute daily returns (r) - r = np.asmatrix(t_val/tminus_val-1) + r = np.asmatrix(t_val / tminus_val - 1) # Compute the expected returns of each asset with the average # daily return for the selected time window m = np.asmatrix(np.mean(r, axis=0)) @@ -59,20 +59,20 @@ def handle_data(context, data): # Compute excess returns matrix (xr) xr = r - m # Matrix algebra to get variance-covariance matrix - cov_m = np.dot(np.transpose(xr), xr)/n + cov_m = np.dot(np.transpose(xr), xr) / n # Compute asset correlation matrix (informative only) - corr_m = cov_m/np.dot(np.transpose(stds), stds) + corr_m = cov_m / np.dot(np.transpose(stds), stds) # Define portfolio optimization parameters n_portfolios = 50000 - results_array = np.zeros((3+context.nassets, n_portfolios)) + results_array = np.zeros((3 + context.nassets, n_portfolios)) for p in xrange(n_portfolios): weights = np.random.random(context.nassets) weights /= np.sum(weights) w = np.asmatrix(weights) - p_r = np.sum(np.dot(w, np.transpose(m)))*365 + p_r = np.sum(np.dot(w, np.transpose(m))) * 365 p_std = np.sqrt(np.dot(np.dot(w, cov_m), - np.transpose(w)))*np.sqrt(365) + np.transpose(w))) * np.sqrt(365) # store results in results array results_array[0, p] = p_r @@ -82,13 +82,13 @@ def handle_data(context, data): results_array[2, p] = results_array[0, p] / results_array[1, p] i = 0 for iw in weights: - results_array[3+i, p] = weights[i] + results_array[3 + i, p] = weights[i] i += 1 # convert results array to Pandas DataFrame results_frame = pd.DataFrame(np.transpose(results_array), columns=['r', 'stdev', 'sharpe'] - + context.assets) + + context.assets) # locate position of portfolio with highest Sharpe Ratio max_sharpe_port = results_frame.iloc[results_frame['sharpe'].idxmax()] # locate positon of portfolio with minimum standard deviation @@ -129,20 +129,21 @@ def handle_data(context, data): def analyze(context=None, results=None): # Form DataFrame with selected data data = results[['pr', 'r', 'm', 'stds', 'max_sharpe_port', 'corr_m', - 'portfolio_value']] + 'portfolio_value']] # Save results in CSV file filename = os.path.splitext(os.path.basename(__file__))[0] data.to_csv(filename + '.csv') -# Bitcoin data is available from 2015-3-2. Dates vary for other tokens. -start = datetime(2017, 1, 1, 0, 0, 0, 0, pytz.utc) -end = datetime(2017, 8, 16, 0, 0, 0, 0, pytz.utc) -results = run_algorithm(initialize=initialize, - handle_data=handle_data, - analyze=analyze, - start=start, - end=end, - exchange_name='poloniex', - capital_base=100000, ) +if __name__ == '__main__': + # Bitcoin data is available from 2015-3-2. Dates vary for other tokens. + start = datetime(2017, 1, 1, 0, 0, 0, 0, pytz.utc) + end = datetime(2017, 8, 16, 0, 0, 0, 0, pytz.utc) + results = run_algorithm(initialize=initialize, + handle_data=handle_data, + analyze=analyze, + start=start, + end=end, + exchange_name='poloniex', + capital_base=100000, ) diff --git a/catalyst/examples/rsi_profit_target.py b/catalyst/examples/rsi_profit_target.py index 7b8ac868..a07d63f7 100644 --- a/catalyst/examples/rsi_profit_target.py +++ b/catalyst/examples/rsi_profit_target.py @@ -114,7 +114,7 @@ def _handle_data_rsi_only(context, data): prices = data.history( context.asset, fields='price', - bar_count=17, + bar_count=20, frequency='30T' ) except Exception as e: @@ -156,7 +156,7 @@ def handle_data(context, data): dt = data.current_dt if context.last_bar is None or ( - context.last_bar + timedelta(minutes=15)) <= dt: + context.last_bar + timedelta(minutes=15)) <= dt: context.last_bar = dt else: return @@ -249,27 +249,17 @@ def analyze(context=None, results=None): pass -# run_algorithm( -# initialize=initialize, -# handle_data=handle_data, -# analyze=analyze, -# exchange_name='bittrex', -# live=True, -# algo_namespace=algo_namespace, -# base_currency='btc', -# live_graph=False -# ) - -# Backtest -run_algorithm( - capital_base=0.5, - data_frequency='minute', - initialize=initialize, - handle_data=handle_data, - analyze=analyze, - exchange_name='poloniex', - algo_namespace=algo_namespace, - base_currency='btc', - start=pd.to_datetime('2017-9-1', utc=True), - end=pd.to_datetime('2017-10-1', utc=True), -) +if __name__ == '__main__': + # Backtest + run_algorithm( + capital_base=0.5, + data_frequency='minute', + initialize=initialize, + handle_data=handle_data, + analyze=analyze, + exchange_name='poloniex', + algo_namespace=algo_namespace, + base_currency='btc', + start=pd.to_datetime('2017-9-1', utc=True), + end=pd.to_datetime('2017-10-1', utc=True), + ) diff --git a/catalyst/examples/simple_loop.py b/catalyst/examples/simple_loop.py index ce977e0a..51ea435c 100644 --- a/catalyst/examples/simple_loop.py +++ b/catalyst/examples/simple_loop.py @@ -110,27 +110,16 @@ def analyze(context, perf): pass -# run_algorithm( -# capital_base=250, -# start=pd.to_datetime('2017-11-9 0:00', utc=True), -# end=pd.to_datetime('2017-11-10 23:59', utc=True), -# data_frequency='minute', -# initialize=initialize, -# handle_data=handle_data, -# analyze=analyze, -# exchange_name='bitfinex', -# algo_namespace='simple_loop', -# base_currency='usd' -# ) -run_algorithm( - capital_base=1, - initialize=initialize, - handle_data=handle_data, - analyze=None, - exchange_name='poloniex', - live=True, - algo_namespace='simple_loop', - base_currency='eth', - live_graph=False, - simulate_orders=True -) +if __name__ == '__main__': + run_algorithm( + capital_base=1, + initialize=initialize, + handle_data=handle_data, + analyze=None, + exchange_name='poloniex', + live=True, + algo_namespace='simple_loop', + base_currency='eth', + live_graph=False, + simulate_orders=True + )