Double 7's (Short Term Trading Strategies that Work)

1. The SPY is above its 200-day moving average
2. The SPY closes at a X-day low, buy some shares.
   If it falls further, buy some more, etc...
3. If the SPY closes at a X-day high, sell your entire long position.

(optimize for number of positions)

In [11]:
import pandas as pd
import matplotlib.pyplot as plt
import datetime
from talib.abstract import *

import pinkfish as pf
import strategy

# format price data
pd.options.display.float_format = '{:0.2f}'.format

%matplotlib inline

In [12]:
# 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)

Some global data


In [13]:
#symbol = '^GSPC'
symbol = 'SPY'
#symbol = 'DIA'
#symbol = 'QQQ'
#symbol = 'IWM'
#symbol = 'TLT'
#symbol = 'GLD'
#symbol = 'AAPL'
#symbol = 'BBRY'
#symbol = 'GDX'
capital = 10000
start = datetime.datetime(1900, 1, 1)
#end = datetime.datetime(2010, 12, 1)
end = datetime.datetime.now()

Define high low trade periods


In [14]:
period = 7

Define max number of positions to scale into


In [15]:
pos = range(1, 10)
pos = [str(p) for p in pos]

Run Strategy


In [16]:
strategies = pd.Series(dtype=object)
for p in pos:
    print("{0}".format(p), end=" ")
    strategies[p] = strategy.Strategy(symbol, capital, start, end, period=period, max_positions=int(p))
    strategies[p].run()
    _, strategies[p].tlog, strategies[p].dbal = strategies[p].get_logs(merge_trades=True)
    strategies[p].stats = strategies[p].get_stats()


1 2 3 4 5 6 7 8 9 

Summarize results


In [17]:
metrics = ('annual_return_rate',
           'max_closed_out_drawdown',
           'drawdown_annualized_return',
           'drawdown_recovery',
           'best_month',
           'worst_month',
           'sharpe_ratio',
           'sortino_ratio',
           'monthly_std',
           'pct_time_in_market',
           'total_num_trades',
           'pct_profitable_trades',
           'avg_points')

df = strategy.summary(strategies, metrics)
df


Out[17]:
1 2 3 4 5 6 7 8 9
annual_return_rate 7.21 6.70 5.79 5.01 4.33 3.64 3.16 2.77 2.49
max_closed_out_drawdown -14.63 -14.59 -13.67 -13.42 -10.66 -9.45 -8.91 -7.78 -6.88
drawdown_annualized_return -2.03 -2.18 -2.36 -2.68 -2.46 -2.60 -2.82 -2.81 -2.76
drawdown_recovery -1.84 -1.78 -0.05 -0.05 -0.05 -0.07 -0.07 -0.07 -0.07
best_month 12.88 10.68 8.10 7.42 6.16 6.13 6.16 5.30 4.64
worst_month -13.54 -13.29 -12.87 -12.46 -9.87 -8.19 -7.52 -6.57 -5.92
sharpe_ratio 0.75 0.78 0.77 0.75 0.76 0.73 0.72 0.71 0.72
sortino_ratio 0.55 0.55 0.52 0.49 0.49 0.47 0.46 0.45 0.46
monthly_std 2.10 1.87 1.59 1.35 1.15 0.99 0.87 0.76 0.67
pct_time_in_market 29.71 29.71 29.71 29.71 29.71 29.71 29.71 29.71 29.71
total_num_trades 265.00 265.00 265.00 265.00 265.00 265.00 265.00 265.00 265.00
pct_profitable_trades 78.11 80.00 82.64 85.28 86.42 86.79 86.79 87.17 87.17
avg_points 0.89 1.59 2.10 2.48 2.75 2.82 2.87 2.90 2.94

Bar graphs


In [18]:
strategy.plot_bar_graph(df, 'annual_return_rate')
strategy.plot_bar_graph(df, 'sharpe_ratio')
strategy.plot_bar_graph(df, 'max_closed_out_drawdown')


Run Benchmark


In [19]:
s = strategies[pos[0]]
benchmark = pf.Benchmark(symbol, capital, s._start, s._end)
benchmark.run()
benchmark.tlog, benchmark.dbal = benchmark.get_logs()
benchmark.stats = benchmark.get_stats()


1993-11-11 00:00:00 BUY  215 SPY @ 46.38
2020-07-15 00:00:00 SELL 215 SPY @ 321.85

Equity curve


In [20]:
pf.plot_equity_curve(strategies['5'].dbal, benchmark=benchmark.dbal)