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 with full capital.
3. If the SPY closes at a X-day high, sell some.
   If it sets further highs, sell some more, etc...
4. If you have free cash, use it all when fresh lows are set.

(optimize for number of positions)

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

Some global data


In [3]:
#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(2000, 1, 1)
#end = datetime.datetime(2010, 12, 1)
end = datetime.datetime.now()

Define high low trade periods


In [4]:
period = 7

Define max number of positions to scale into


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

Run Strategy


In [6]:
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()
    strategies[p].stats = strategies[p].get_stats()


1 2 3 4 5 6 7 8 9 

Summarize results


In [7]:
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',
           'pct_profitable_trades')

df = strategy.summary(strategies, metrics)
df


Out[7]:
1 2 3 4 5 6 7 8 9
annual_return_rate 9.09 7.35 7.19 7.63 7.86 8.04 8.07 7.90 7.63
max_closed_out_drawdown -36.26 -36.26 -37.82 -42.06 -43.47 -45.30 -46.42 -47.79 -48.71
drawdown_annualized_return -3.99 -4.93 -5.26 -5.51 -5.53 -5.64 -5.75 -6.05 -6.38
drawdown_recovery -0.02 -0.02 -3.52 -3.52 -3.52 -3.52 -3.13 -3.13 -3.13
best_month 38.43 38.51 43.11 47.85 50.70 52.57 53.94 54.88 55.69
worst_month -30.31 -30.07 -30.07 -29.54 -29.04 -29.84 -30.42 -30.83 -31.17
sharpe_ratio 0.52 0.44 0.42 0.44 0.44 0.44 0.44 0.43 0.42
sortino_ratio 0.33 0.31 0.33 0.36 0.39 0.40 0.42 0.42 0.42
monthly_std 4.19 4.38 4.69 5.02 5.25 5.47 5.67 5.84 5.97
pct_time_in_market 22.29 29.94 35.79 40.81 45.56 48.79 51.60 54.65 55.99
total_num_trades 90.00 184.00 255.00 312.00 356.00 396.00 429.00 455.00 471.00
pct_profitable_trades 70.00 66.85 64.71 63.78 64.61 63.64 63.64 63.74 62.63
avg_points 0.49 0.42 0.41 0.44 0.58 0.63 0.71 0.75 0.79
pct_profitable_trades 70.00 66.85 64.71 63.78 64.61 63.64 63.64 63.74 62.63

Bar graphs


In [8]:
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 [9]:
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()


2007-03-08 00:00:00 BUY  260 GDX @ 38.35
2020-06-22 00:00:00 SELL 260 GDX @ 34.87

Equity curve


In [10]:
pf.plot_equity_curve(strategies['1'].dbal, benchmark=benchmark.dbal)