In [1]:
import pandas as pd
import matplotlib.pyplot as plt
import datetime
from talib.abstract import *
import pinkfish as pf
# format price data
pd.options.display.float_format = '{:0.2f}'.format
%matplotlib inline
In [2]:
# set size of inline plots
'''note: rcParams can't be in same cell as import matplotlib
or %matplotlib inline
%matplotlib notebook: will lead to interactive plots embedded within
the notebook, you can zoom and resize the figure
%matplotlib inline: only draw static images in the notebook
'''
plt.rcParams["figure.figsize"] = (10, 7)
In [3]:
pf.DEBUG = False
Some global data
In [4]:
#symbol = '^GSPC'
symbol = 'SPY'
#symbol = 'DIA'
#symbol = 'QQQ'
#symbol = 'IWM'
#symbol = 'TLT'
#symbol = 'GLD'
#symbol = 'AAPL'
#symbol = 'BBRY'
capital = 10000
#start = datetime.datetime(1900, 1, 1)
start = datetime.datetime.strptime(pf.SP500_BEGIN, '%Y-%m-%d')
end = datetime.datetime.now()
Define target_percent and band
In [5]:
target_percent = 50
band = 3
sma200_band = 3.5
Define Strategy Class
In [6]:
class Strategy:
def __init__(self, symbol, capital, start, end):
self._symbol = symbol
self._capital = capital
self._start = start
self._end = end
def _algo(self):
pf.TradeLog.cash = self._capital
for i, row in enumerate(self._ts.itertuples()):
date = row.Index.to_pydatetime()
high = row.high; low = row.low; close = row.close;
end_flag = pf.is_last_row(self._ts, i)
shares = 0
# adjust shares
if ((self._tlog.share_percent(close) > target_percent+band or
self._tlog.share_percent(close) < target_percent-band)
and row.regime > 0
and not end_flag):
# adjust shares to target_percent
shares = self._tlog.adjust_percent(date, close, target_percent)
# close out
elif (row.regime < 0
or end_flag):
# adjust shares to 0
shares = self._tlog.adjust_percent(date, close, 0)
if shares > 0:
pf.DBG("{0} BUY {1} {2} @ {3:.2f}".format(
date, shares, self._symbol, close))
elif shares < 0:
pf.DBG("{0} SELL {1} {2} @ {3:.2f}".format(
date, -shares, self._symbol, close))
# record daily balance
self._dbal.append(date, high, low, close)
def run(self):
self._ts = pf.fetch_timeseries(self._symbol)
self._ts = pf.select_tradeperiod(self._ts, self._start, self._end, use_adj=True)
# Add technical indicator: 200 sma regime filter
self._ts['regime'] = \
pf.CROSSOVER(self._ts, timeperiod_fast=1, timeperiod_slow=200, band=sma200_band)
self._ts, self._start = pf.finalize_timeseries(self._ts, self._start)
self._tlog = pf.TradeLog(self._symbol)
self._dbal = pf.DailyBal()
self._algo()
def get_logs(self):
""" return DataFrames """
self.rlog = self._tlog.get_log_raw()
self.tlog = self._tlog.get_log()
self.dbal = self._dbal.get_log(self.tlog)
return self.rlog, self.tlog, self.dbal
def get_stats(self):
stats = pf.stats(self._ts, self.tlog, self.dbal, self._capital)
return stats
Run Strategy
In [7]:
s = Strategy(symbol, capital, start, end)
s.run()
Retrieve log DataFrames
In [8]:
rlog, tlog, dbal = s.get_logs()
stats = s.get_stats()
In [9]:
rlog.tail(10)
Out[9]:
In [10]:
tlog.tail(10)
Out[10]:
In [11]:
dbal.tail()
Out[11]:
Generate strategy stats - display all available stats
In [12]:
pf.print_full(stats)
Run Benchmark
In [13]:
benchmark = pf.Benchmark(symbol, capital, s._start, s._end)
benchmark.run()
Retrieve benchmark logs
In [14]:
benchmark.tlog, benchmark.dbal = benchmark.get_logs()
Generate benchmark stats
In [15]:
benchmark.stats = benchmark.get_stats()
pf.print_full(benchmark.stats)
Plot Equity Curves: Strategy vs Benchmark
In [16]:
pf.plot_equity_curve(dbal, benchmark=benchmark.dbal)
Plot Trades
In [17]:
pf.plot_trades(dbal, benchmark=benchmark.dbal)
Bar Graph: Strategy vs Benchmark
In [18]:
df = pf.plot_bar_graph(stats, benchmark.stats)
df
Out[18]: