import pytz
from collections import OrderedDict
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.figsize(14,8)
from zipline.algorithm import TradingAlgorithm
from zipline.transforms import MovingAverage, batch_transform
class DualMovingAverage(TradingAlgorithm):
"""Dual Moving Average Crossover algorithm.
This algorithm buys apple once its short moving average crosses
its long moving average (indicating upwards momentum) and sells
its shares once the averages cross again (indicating downwards
momentum).
"""
def initialize(self, short_window=10, long_window=20):
# Add 2 mavg transforms, one with a long window, one
# with a short window.
self.add_transform(MovingAverage, 'short_mavg', ['open'],
window_length=short_window)
self.add_transform(MovingAverage, 'long_mavg', ['open'],
window_length=long_window)
# To keep track of whether we invested in the stock or not
self.invested = False
def handle_data(self, data):
self.short_mavg = data['BTC'].short_mavg['open']
self.long_mavg = data['BTC'].long_mavg['open']
self.buy = False
self.sell = False
if self.short_mavg > self.long_mavg and not self.invested:
print "{dt}: Buying 100 BTC shares.".format(dt=data['BTC'].datetime)
self.order('BTC', 100)
self.invested = True
self.buy = True
elif self.short_mavg < self.long_mavg and self.invested:
print "{dt}: Selling 100 BTC shares.".format(dt=data['BTC'].datetime)
self.order('BTC', -100)
self.invested = False
self.sell = True
self.record(short_mavg=self.short_mavg,
long_mavg=self.long_mavg,
buy=self.buy,
sell=self.sell)
data = OrderedDict()
#data['BTC'] = pd.DataFrame.from_csv('http://www.quandl.com/api/v1/datasets/BITCOIN/MTGOXUSD.csv?trim_start=2012-01-01&sort_order=asc')
#http://bitcoincharts.com/charts/chart.json?m=mtgoxUSD&r=30&i=15-min&c=1&s=2013-01-01&e=2013-01-31
#http://bitcoincharts.com/charts/chart.json?m=mtgoxUSD
data['BTC'] = pd.DataFrame.from_csv('MTGOXUSD.csv')
data['BTC'] = data['BTC'].rename(columns={'Weighted Price': 'price',
'High':'high',
'Low':'low',
'Open':'open',
'Close':'close',
'Volume (BTC)':'volume',
'Volume (Currency)':'volume_quote'
})
data['BTC'] = data['BTC'].fillna(method='ffill')
panel = pd.Panel(data)
panel.minor_axis = ['open', 'high', 'low', 'close', 'volume', 'volume_quote', 'price']
panel.major_axis = panel.major_axis.tz_localize(pytz.utc)
panel['BTC'].plot()
<matplotlib.axes.AxesSubplot at 0x10eab6110>
dma = DualMovingAverage()
results = dma.run(panel)
[2013-05-13 01:01] INFO: Transform: Running StatefulTransform [short_mavg] [2013-05-13 01:01] INFO: Transform: Running StatefulTransform [long_mavg]
2012-01-18 00:00:00+00:00: Buying 100 BTC shares. 2012-01-30 00:00:00+00:00: Selling 100 BTC shares. 2012-03-08 00:00:00+00:00: Buying 100 BTC shares. 2012-03-29 00:00:00+00:00: Selling 100 BTC shares. 2012-04-14 00:00:00+00:00: Buying 100 BTC shares. 2012-05-09 00:00:00+00:00: Selling 100 BTC shares. 2012-05-25 00:00:00+00:00: Buying 100 BTC shares. 2012-08-28 00:00:00+00:00: Selling 100 BTC shares. 2012-09-14 00:00:00+00:00: Buying 100 BTC shares. 2012-10-15 00:00:00+00:00: Selling 100 BTC shares. 2012-11-19 00:00:00+00:00: Buying 100 BTC shares. 2013-01-01 00:00:00+00:00: Selling 100 BTC shares. 2013-01-10 00:00:00+00:00: Buying 100 BTC shares. 2013-04-24 00:00:00+00:00: Selling 100 BTC shares.
[2013-05-13 01:01] INFO: Transform: Finished StatefulTransform [long_mavg] [2013-05-13 01:01] INFO: Transform: Finished StatefulTransform [short_mavg] [2013-05-13 01:01] INFO: Performance: Simulated 340 trading days out of 340. [2013-05-13 01:01] INFO: Performance: first open: 2012-01-03 14:30:00+00:00 [2013-05-13 01:01] INFO: Performance: last close: 2013-05-10 20:00:00+00:00
2013-05-02 00:00:00+00:00: Buying 100 BTC shares. 2013-05-11 00:00:00+00:00: Selling 100 BTC shares.
fig = plt.figure()
ax1 = fig.add_subplot(211, ylabel='portfolio value')
results.portfolio_value.plot(ax=ax1)
ax2 = fig.add_subplot(212)
panel['BTC']['open'].plot(ax=ax2, color='r')
results[['short_mavg', 'long_mavg']].plot(ax=ax2)
ax2.plot(results.ix[results.buy].index, results.short_mavg[results.buy],
'^', markersize=10, color='m')
ax2.plot(results.ix[results.sell].index, results.short_mavg[results.sell],
'v', markersize=10, color='k')
plt.legend(loc=0)
plt.show()
from zipline.finance import trading
from zipline.utils.factory import create_returns_from_list
from zipline.finance.risk import RiskMetricsBase
start = results.first_valid_index().replace(tzinfo=pytz.utc)
end = results.last_valid_index().replace(tzinfo=pytz.utc)
env = trading.SimulationParameters(start, end)
returns_risk = create_returns_from_list(results.returns, env)
risk = RiskMetricsBase(start, end, returns_risk)
print risk
algorithm_period_returns:0.158502432668 benchmark_period_returns:0.279874764082 excess_return:0.154990651846 trading_days:339 benchmark_volatility:0.1419582861 algorithm_volatility:0.103094511858 sharpe:1.50338411864 sortino:27.828150627 information:-0.0318579328888 algorithm_covariance:-1.29736191032e-06 benchmark_variance:5.94458849332e-05 beta:-0.0218242509432 alpha:0.161022066944 max_drawdown:0.123740609874 algorithm_returns:2012-01-04 00:00:00+00:00 0.000000 2012-01-05 00:00:00+00:00 0.000000 2012-01-06 00:00:00+00:00 0.000000 2012-01-09 00:00:00+00:00 0.000000 2012-01-10 00:00:00+00:00 0.000000 2012-01-11 00:00:00+00:00 0.000000 2012-01-12 00:00:00+00:00 0.000000 2012-01-13 00:00:00+00:00 0.000000 2012-01-17 00:00:00+00:00 0.000000 2012-01-18 00:00:00+00:00 0.000000 2012-01-19 00:00:00+00:00 -0.000030 2012-01-20 00:00:00+00:00 0.000254 2012-01-23 00:00:00+00:00 -0.000126 2012-01-24 00:00:00+00:00 -0.000010 2012-01-25 00:00:00+00:00 -0.000425 ... 2013-04-22 00:00:00+00:00 0.003421 2013-04-23 00:00:00+00:00 0.010217 2013-04-24 00:00:00+00:00 0.015476 2013-04-25 00:00:00+00:00 -0.007890 2013-04-26 00:00:00+00:00 0.000000 2013-04-29 00:00:00+00:00 0.000000 2013-04-30 00:00:00+00:00 0.000000 2013-05-01 00:00:00+00:00 0.000000 2013-05-02 00:00:00+00:00 0.000000 2013-05-03 00:00:00+00:00 -0.000026 2013-05-06 00:00:00+00:00 0.022928 2013-05-07 00:00:00+00:00 -0.009144 2013-05-08 00:00:00+00:00 0.005761 2013-05-09 00:00:00+00:00 -0.001446 2013-05-10 00:00:00+00:00 0.002517 Length: 339 benchmark_returns:2012-01-04 00:00:00+00:00 0.000211 2012-01-05 00:00:00+00:00 0.002944 2012-01-06 00:00:00+00:00 -0.002436 2012-01-09 00:00:00+00:00 0.002246 2012-01-10 00:00:00+00:00 0.008831 2012-01-11 00:00:00+00:00 0.000356 2012-01-12 00:00:00+00:00 0.002337 2012-01-13 00:00:00+00:00 -0.004425 2012-01-17 00:00:00+00:00 0.002674 2012-01-18 00:00:00+00:00 0.011124 2012-01-19 00:00:00+00:00 0.004916 2012-01-20 00:00:00+00:00 0.000677 2012-01-23 00:00:00+00:00 0.000540 2012-01-24 00:00:00+00:00 -0.000995 2012-01-25 00:00:00+00:00 0.008871 ... 2013-04-22 00:00:00+00:00 0.004662 2013-04-23 00:00:00+00:00 0.010419 2013-04-24 00:00:00+00:00 0.000006 2013-04-25 00:00:00+00:00 0.003946 2013-04-26 00:00:00+00:00 -0.001842 2013-04-29 00:00:00+00:00 0.007122 2013-04-30 00:00:00+00:00 0.002504 2013-05-01 00:00:00+00:00 -0.009295 2013-05-02 00:00:00+00:00 0.009363 2013-05-03 00:00:00+00:00 0.010528 2013-05-06 00:00:00+00:00 0.001920 2013-05-07 00:00:00+00:00 0.005199 2013-05-08 00:00:00+00:00 0.004145 2013-05-09 00:00:00+00:00 -0.003687 2013-05-10 00:00:00+00:00 0.004309 Length: 339 condition_number:1.90158565535 eigen_values:[ 3.12926583e-05 5.95056702e-05]