| Example Algorithms ================== This section documents a small number of example algorithms to complement the beginner tutorial, and show how other trading algorithms can be implemented using Catalyst: Buy and Hodl ~~~~~~~~~~~~ source: `examples/buy_and_hodl.py `_ First ingest the historical pricing data needed to run this algorithm: .. code-block:: bash catalyst ingest-exchange -x poloniex -f daily -i btc_usdt Then, you can run the code below with the following command: .. code-block:: bash catalyst run -f buy_and_hodl.py --start 2015-3-1 --end 2017-10-31 --capital-base 100000 -x poloniex -c btc -o bah.pickle This command will run the trading algorithm in the specified time range and plot the resulting performance using the matplotlib library. You can choose any date interval with the ``--start`` and ``--end`` parameters, but bear in mind that 2015-3-1 is the earliest date that Catalyst supports (if you choose an earlier date, you'll get an error), and the most recent date you can choose is one day prior to the current date. .. code-block:: python #!/usr/bin/env python # # Copyright 2017 Enigma MPC, Inc. # Copyright 2015 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. import pandas as pd from catalyst.api import ( order_target_value, symbol, record, cancel_order, get_open_orders, ) def initialize(context): context.ASSET_NAME = 'btc_usdt' context.TARGET_HODL_RATIO = 0.8 context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO context.is_buying = True context.asset = symbol(context.ASSET_NAME) context.i = 0 def handle_data(context, data): context.i += 1 starting_cash = context.portfolio.starting_cash target_hodl_value = context.TARGET_HODL_RATIO * starting_cash reserve_value = context.RESERVE_RATIO * starting_cash # Cancel any outstanding orders orders = get_open_orders(context.asset) or [] for order in orders: cancel_order(order) # Stop buying after passing the reserve threshold cash = context.portfolio.cash if cash <= reserve_value: context.is_buying = False # Retrieve current asset price from pricing data price = data.current(context.asset, 'price') # Check if still buying and could (approximately) afford another purchase if context.is_buying and cash > price: # Place order to make position in asset equal to target_hodl_value order_target_value( context.asset, target_hodl_value, limit_price=price * 1.1, stop_price=price * 0.9, ) record( price=price, volume=data.current(context.asset, 'volume'), cash=cash, starting_cash=context.portfolio.starting_cash, leverage=context.account.leverage, ) 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)) results[['price']].plot(ax=ax2) trans = results.ix[[t != [] for t in results.transactions]] buys = trans.ix[ [t[0]['amount'] > 0 for t in trans.transactions] ] ax2.plot( buys.index, results.price[buys.index], '^', markersize=10, color='g', ) ax3 = plt.subplot(613, sharex=ax1) results[['leverage', 'alpha', 'beta']].plot(ax=ax3) ax3.set_ylabel('Leverage ') ax4 = plt.subplot(614, sharex=ax1) results[['starting_cash', '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 (mCoins/5min)') plt.legend(loc=3) # Show the plot. plt.gcf().set_size_inches(18, 8) plt.show()