DOC: updated examples/buy_and_hodl.py. Added Example Algos and Utilities pages to the documentation

This commit is contained in:
Victor Grau Serrat
2017-11-19 23:51:57 -07:00
parent 5d4bc99097
commit 698b19c8fa
4 changed files with 326 additions and 21 deletions
+3 -21
View File
@@ -16,7 +16,6 @@
# limitations under the License.
import pandas as pd
from catalyst import run_algorithm
from catalyst.api import (
order_target_value,
symbol,
@@ -27,15 +26,10 @@ from catalyst.api import (
def initialize(context):
context.ASSET_NAME = 'BTC_USDT'
context.ASSET_NAME = 'btc_usdt'
context.TARGET_HODL_RATIO = 0.8
context.RESERVE_RATIO = 1.0 - context.TARGET_HODL_RATIO
# 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.is_buying = True
context.asset = symbol(context.ASSET_NAME)
@@ -91,7 +85,7 @@ def analyze(context=None, results=None):
ax2 = plt.subplot(612, sharex=ax1)
ax2.set_ylabel('{asset} (USD)'.format(asset=context.ASSET_NAME))
(context.TICK_SIZE * results[['price']]).plot(ax=ax2)
results[['price']].plot(ax=ax2)
trans = results.ix[[t != [] for t in results.transactions]]
buys = trans.ix[
@@ -99,7 +93,7 @@ def analyze(context=None, results=None):
]
ax2.plot(
buys.index,
context.TICK_SIZE * results.price[buys.index],
results.price[buys.index],
'^',
markersize=10,
color='g',
@@ -141,15 +135,3 @@ def analyze(context=None, results=None):
plt.gcf().set_size_inches(18, 8)
plt.show()
run_algorithm(
capital_base=10000,
data_frequency='minute',
initialize=initialize,
handle_data=handle_data,
analyze=analyze,
exchange_name='poloniex',
base_currency='usd',
start=pd.to_datetime('2017-10-1', utc=True),
end=pd.to_datetime('2017-11-10', utc=True),
)
+172
View File
@@ -0,0 +1,172 @@
|
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 <https://github.com/enigmampc/catalyst/blob/master/catalyst/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()
+2
View File
@@ -12,6 +12,8 @@ Table of Contents
jupyter
live-trading
naming-convention
example-algos
utilities
videos
resources
development-guidelines
+149
View File
@@ -0,0 +1,149 @@
Utilities
=========
This section covers a variety of utilites that provide complimentary
functionality to your trading algorithms. These are code snippets that you can
add to any algorithm to add the desired functionality.
If you are looking for example trading algorithms, see the corresponding section.
Output to CSV file
~~~~~~~~~~~~~~~~~~
Add this script to the analyze method to create and save a CSV file with the
results from the trading algorithm. This file will include the default
parameters of the results DataFrame plus any recorded variables and will be
saved in the same location where your trading algorithm is saved. The exact
script that you need to use depends on the interface that you are using to run
your trading algorithm, which could be the CLI or a Python Interpreter.
1. Script to use with CLI:
.. code-block:: python
def analyze(context=None, results=None):
import sys
import os
from os.path import basename
# Save results in CSV file
filename = os.path.splitext(basename(sys.argv[3]))[0]
results.to_csv(filename + '.csv')
2. Script to use with Python Interpreter:
.. code-block:: python
def analyze(context=None, results=None):
import os
from os.path import basename
# Save results in CSV file
filename = os.path.splitext(os.path.basename(__file__))[0]
results.to_csv(filename + '.csv')
Extracting market data
~~~~~~~~~~~~~~~~~~~~~~
Use this script to save the price and volume data of one cryptoasset in a CSV
file, which will be saved in the same location and with the same name as your
Python file. To get custom data, simply modify the asset's symbol and the dates.
Run this script directly from your development environment: python scriptname.py,
where the contents of 'scriptname.py' are as follows. Two different version are
provided as an example for daily- and minute-resolution data respectively:
Simpler case for daily data
.. code-block:: python
import os
import pytz
from datetime import datetime
from catalyst.api import record, symbol, symbols
from catalyst.utils.run_algo import run_algorithm
def initialize(context):
# Portfolio assets list
context.asset = symbol('btc_usdt') # Bitcoin on Poloniex
def handle_data(context, data):
# Variables to record for a given asset: price and volume
price = data.current(context.asset, 'price')
volume = data.current(context.asset, 'volume')
record(price=price, volume=volume)
def analyze(context=None, results=None):
# Generate DataFrame with Price and Volume only
data = results[['price','volume']]
# Save results in CSV file
filename = os.path.splitext(os.path.basename(__file__))[0]
data.to_csv(filename + '.csv')
''' Bitcoin data is available on Poloniex since 2015-3-1.
Dates vary for other tokens. In the example below, we choose the
full month of July of 2017.
'''
start = datetime(2017, 1, 1, 0, 0, 0, 0, pytz.utc)
end = datetime(2017, 7, 31, 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=10000,
base_currency = 'usdt')
More versatile case for minute data
.. code-block:: python
import os
import csv
import pytz
from datetime import datetime
from catalyst.api import record, symbol, symbols
from catalyst.utils.run_algo import run_algorithm
def initialize(context):
# Portfolio assets list
context.asset = symbol('btc_usdt') # Bitcoin on Poloniex
# Creates a .CSV file with the same name as this script to store results
context.csvfile = open(os.path.splitext(
os.path.basename(__file__))[0]+'.csv', 'w+')
context.csvwriter = csv.writer(context.csvfile)
def handle_data(context, data):
# Variables to record for a given asset: price and volume
# Other options include 'open', 'high', 'open', 'close'
# Please note that 'price' equals 'close'
date = context.blotter.current_dt # current time in each iteration
price = data.current(context.asset, 'price')
volume = data.current(context.asset, 'volume')
# Writes one line to CSV on each iteration with the chosen variables
context.csvwriter.writerow([date,price,volume])
def analyze(context=None, results=None):
# Close open file properly at the end
context.csvfile.close()
# Bitcoin data is available from 2015-3-2. Dates vary for other tokens.
start = datetime(2017, 7, 30, 0, 0, 0, 0, pytz.utc)
end = datetime(2017, 7, 31, 0, 0, 0, 0, pytz.utc)
results = run_algorithm(initialize=initialize,
handle_data=handle_data,
analyze=analyze,
start=start,
end=end,
exchange_name='poloniex',
data_frequency='minute',
base_currency ='usdt',
capital_base=10000 )