SMA Percent Band

1. The SPY closes above its upper band, buy
2. If the SPY closes below its lower band, sell your long position.

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(1900, 1, 1)
#start = datetime.datetime.strptime(pf.SP500_BEGIN, '%Y-%m-%d')
end = datetime.datetime.now()

Include dividends? (If yes, set to True)


In [4]:
use_adj = True

Define high low trade periods


In [5]:
sma_period = 200
percent_band = 3.5

Run Strategy


In [6]:
s = strategy.Strategy(symbol, capital, start, end, use_adj, sma_period, percent_band)
s.run()

Retrieve log DataFrames


In [7]:
rlog, tlog, dbal = s.get_logs()
stats = s.get_stats()

In [8]:
tlog.tail(10)


Out[8]:
entry_date entry_price exit_date exit_price pl_points pl_cash qty cumul_total direction symbol
37 1998-11-04 1118.67 1999-10-15 1247.41 128.74 100159.71 778 960793.53 LONG ^GSPC
38 1999-10-29 1362.93 2000-10-10 1387.02 24.09 17152.06 712 977945.59 LONG ^GSPC
39 2003-04-22 911.37 2004-08-06 1063.97 152.60 165418.37 1084 1143363.96 LONG ^GSPC
40 2004-11-04 1161.67 2007-11-21 1416.77 255.10 253059.18 992 1396423.14 LONG ^GSPC
41 2009-06-12 946.21 2010-06-04 1064.88 118.67 176343.59 1486 1572766.73 LONG ^GSPC
42 2010-10-05 1160.75 2011-08-04 1200.07 39.32 53593.09 1363 1626359.82 LONG ^GSPC
43 2012-01-18 1308.04 2015-08-21 1970.89 662.85 829225.32 1251 2455585.14 LONG ^GSPC
44 2016-04-18 2094.34 2018-10-24 2656.10 561.76 661191.53 1177 3116776.67 LONG ^GSPC
45 2019-03-21 2854.88 2020-03-09 2746.56 -108.32 -118610.21 1095 2998166.46 LONG ^GSPC
46 2020-06-03 3122.87 2020-07-17 3224.73 101.86 98091.05 963 3096257.51 LONG ^GSPC

In [9]:
dbal.tail()


Out[9]:
high low close shares cash leverage state
date
2020-07-13 3116455.76 3033743.56 3039319.37 963 842.54 1.00 -
2020-07-14 3083357.34 3012779.03 3080054.32 963 842.54 1.00 -
2020-07-15 3119306.21 3083174.43 3108019.88 963 842.54 1.00 -
2020-07-16 3102078.01 3081084.79 3097436.51 963 842.54 1.00 -
2020-07-17 3106257.51 3106257.51 3106257.51 0 3106257.51 1.00 X

Generate strategy stats - display all available stats


In [10]:
pf.print_full(stats)


start                                                  1928-10-16
end                                                    2020-07-17
beginning_balance                                           10000
ending_balance                                         3106257.51
total_net_profit                                       3096257.51
gross_profit                                           3262282.89
gross_loss                                             -166025.38
profit_factor                                               19.65
return_on_initial_capital                                30962.58
annual_return_rate                                           6.45
trading_period                           91 years 9 months 1 days
pct_time_in_market                                          67.09
margin                                                          1
avg_leverage                                                 1.00
max_leverage                                                 1.00
min_leverage                                                 1.00
total_num_trades                                               47
trades_per_year                                              0.51
num_winning_trades                                             31
num_losing_trades                                              16
num_even_trades                                                 0
pct_profitable_trades                                       65.96
avg_profit_per_trade                                     65877.82
avg_profit_per_winning_trade                            105234.93
avg_loss_per_losing_trade                               -10376.59
ratio_avg_profit_win_loss                                   10.14
largest_profit_winning_trade                            829225.32
largest_loss_losing_trade                              -118610.21
num_winning_points                                        2962.00
num_losing_points                                         -151.19
total_net_points                                          2810.81
avg_points                                                  59.80
largest_points_winning_trade                               662.85
largest_points_losing_trade                               -108.32
avg_pct_gain_per_trade                                      15.57
largest_pct_winning_trade                                  100.00
largest_pct_losing_trade                                   -16.08
max_consecutive_winning_trades                                 10
max_consecutive_losing_trades                                   5
avg_bars_winning_trades                                    450.10
avg_bars_losing_trades                                      97.19
max_closed_out_drawdown                                    -56.58
max_closed_out_drawdown_start_date                     1929-09-16
max_closed_out_drawdown_end_date                       1933-03-21
max_closed_out_drawdown_recovery_date                  1936-07-20
drawdown_recovery                                           -3.51
drawdown_annualized_return                                  -8.77
max_intra_day_drawdown                                     -56.58
avg_yearly_closed_out_drawdown                              -9.18
max_yearly_closed_out_drawdown                             -55.86
avg_monthly_closed_out_drawdown                             -2.34
max_monthly_closed_out_drawdown                            -29.84
avg_weekly_closed_out_drawdown                              -0.89
max_weekly_closed_out_drawdown                             -21.05
avg_yearly_closed_out_runup                                 17.45
max_yearly_closed_out_runup                                 70.80
avg_monthly_closed_out_runup                                 2.85
max_monthly_closed_out_runup                                32.99
avg_weekly_closed_out_runup                                  1.03
max_weekly_closed_out_runup                                 16.07
pct_profitable_years                                        61.79
best_year                                                   64.79
worst_year                                                 -46.28
avg_year                                                     7.22
annual_std                                                  13.53
pct_profitable_months                                       43.71
best_month                                                  27.01
worst_month                                                -29.72
avg_month                                                    0.56
monthly_std                                                  3.43
pct_profitable_weeks                                        39.19
best_week                                                   15.91
worst_week                                                 -21.05
avg_week                                                     0.14
weekly_std                                                   1.73
sharpe_ratio                                                 0.57
sortino_ratio                                                0.58
dtype: object

Run Benchmark, Retrieve benchmark logs, and Generate benchmark stats


In [11]:
benchmark = pf.Benchmark(symbol, capital, s._start, s._end, s._use_adj)
benchmark.run()
benchmark.tlog, benchmark.dbal = benchmark.get_logs()
benchmark.stats = benchmark.get_stats()


1928-10-16 00:00:00 BUY  460 ^GSPC @ 21.72
2020-07-17 00:00:00 SELL 460 ^GSPC @ 3224.73

Plot Equity Curves: Strategy vs Benchmark


In [12]:
pf.plot_equity_curve(dbal, benchmark=benchmark.dbal)


Plot Trades


In [13]:
pf.plot_trades(dbal, benchmark=benchmark.dbal)



In [14]:
print('trading period:  {} to {}'.format(stats['start'], stats['end']))
df = pf.summary(stats, benchmark.stats, metrics=pf.currency_metrics)
df


trading period:  1928-10-16 to 2020-07-17
Out[14]:
strategy benchmark
beginning_balance $10,000.00 $10,000.00
ending_balance $3,106,257.51 $1,483,384.59
total_net_profit $3,096,257.51 $1,473,384.59
gross_profit $3,262,282.89 $1,473,384.59
gross_loss -$166,025.38 $0.00

Bar Graph: Strategy vs Benchmark


In [15]:
df = pf.plot_bar_graph(stats, benchmark.stats)
df


Out[15]:
strategy benchmark
annual_return_rate 6.45 5.60
max_closed_out_drawdown -56.58 -86.14
drawdown_annualized_return -8.77 -15.38
drawdown_recovery -3.51 -2.71
best_month 27.01 61.27
worst_month -29.72 -42.17
sharpe_ratio 0.57 0.38
sortino_ratio 0.58 0.48
monthly_std 3.43 5.35

Print the raw transaction log


In [16]:
pd.set_option('display.max_rows', len(rlog))
rlog


Out[16]:
date price shares entry_exit direction symbol
0 1928-10-16 21.72 460 entry LONG ^GSPC
1 1929-10-24 25.75 460 exit LONG ^GSPC
2 1932-08-10 7.65 1549 entry LONG ^GSPC
3 1932-10-10 6.42 1549 exit LONG ^GSPC
4 1932-10-19 7.40 1344 entry LONG ^GSPC
5 1932-11-02 6.52 1344 exit LONG ^GSPC
6 1932-11-07 7.24 1210 entry LONG ^GSPC
7 1932-12-02 6.47 1210 exit LONG ^GSPC
8 1932-12-09 7.08 1106 entry LONG ^GSPC
9 1933-02-14 6.32 1106 exit LONG ^GSPC
10 1933-03-15 6.81 1026 entry LONG ^GSPC
11 1933-03-21 6.20 1026 exit LONG ^GSPC
12 1933-04-19 7.14 891 entry LONG ^GSPC
13 1934-05-07 9.81 891 exit LONG ^GSPC
14 1935-04-22 9.41 929 entry LONG ^GSPC
15 1937-04-26 16.16 929 exit LONG ^GSPC
16 1938-06-29 11.72 1281 entry LONG ^GSPC
17 1939-03-22 11.75 1281 exit LONG ^GSPC
18 1939-09-05 12.64 1191 entry LONG ^GSPC
19 1940-05-10 11.76 1191 exit LONG ^GSPC
20 1940-11-07 11.39 1229 entry LONG ^GSPC
21 1941-01-30 10.04 1229 exit LONG ^GSPC
22 1941-09-17 10.47 1179 entry LONG ^GSPC
23 1941-10-16 9.58 1179 exit LONG ^GSPC
24 1942-09-23 8.75 1291 entry LONG ^GSPC
25 1943-11-15 11.25 1291 exit LONG ^GSPC
26 1944-03-15 12.28 1182 entry LONG ^GSPC
27 1946-08-27 16.92 1182 exit LONG ^GSPC
28 1947-07-03 15.60 1282 entry LONG ^GSPC
29 1948-01-21 14.54 1282 exit LONG ^GSPC
30 1948-04-22 15.68 1189 entry LONG ^GSPC
31 1948-11-09 15.01 1189 exit LONG ^GSPC
32 1949-08-08 15.51 1151 entry LONG ^GSPC
33 1953-04-23 24.19 1151 exit LONG ^GSPC
34 1954-01-15 25.43 1095 entry LONG ^GSPC
35 1956-10-01 44.70 1095 exit LONG ^GSPC
36 1957-05-31 47.43 1031 entry LONG ^GSPC
37 1957-08-26 43.89 1031 exit LONG ^GSPC
38 1958-05-06 44.01 1029 entry LONG ^GSPC
39 1960-01-29 55.61 1029 exit LONG ^GSPC
40 1960-12-28 57.78 990 entry LONG ^GSPC
41 1962-04-27 66.30 990 exit LONG ^GSPC
42 1962-12-20 62.82 1045 entry LONG ^GSPC
43 1965-06-25 83.06 1045 exit LONG ^GSPC
44 1965-09-15 89.52 969 entry LONG ^GSPC
45 1966-05-09 86.32 969 exit LONG ^GSPC
46 1967-01-20 86.07 972 entry LONG ^GSPC
47 1968-02-09 89.86 972 exit LONG ^GSPC
48 1968-04-18 97.08 900 entry LONG ^GSPC
49 1969-06-12 98.26 900 exit LONG ^GSPC
50 1970-10-05 86.47 1023 entry LONG ^GSPC
51 1971-10-22 95.57 1023 exit LONG ^GSPC
52 1972-01-05 103.06 948 entry LONG ^GSPC
53 1973-04-25 108.34 948 exit LONG ^GSPC
54 1975-02-12 79.92 1286 entry LONG ^GSPC
55 1977-03-25 99.06 1286 exit LONG ^GSPC
56 1978-04-26 96.82 1315 entry LONG ^GSPC
57 1978-10-31 93.15 1315 exit LONG ^GSPC
58 1979-04-05 103.26 1186 entry LONG ^GSPC
59 1980-03-17 102.26 1186 exit LONG ^GSPC
60 1980-05-27 111.40 1089 entry LONG ^GSPC
61 1981-07-06 127.37 1089 exit LONG ^GSPC
62 1982-08-31 119.51 1161 entry LONG ^GSPC
63 1984-02-06 158.08 1161 exit LONG ^GSPC
64 1984-08-09 165.54 1108 entry LONG ^GSPC
65 1987-10-16 282.70 1108 exit LONG ^GSPC
66 1988-06-14 274.30 1142 entry LONG ^GSPC
67 1990-01-30 322.98 1142 exit LONG ^GSPC
68 1990-05-14 354.75 1040 entry LONG ^GSPC
69 1990-08-16 332.39 1040 exit LONG ^GSPC
70 1991-02-04 348.34 992 entry LONG ^GSPC
71 1994-04-04 438.92 992 exit LONG ^GSPC
72 1995-02-03 478.65 909 entry LONG ^GSPC
73 1998-08-31 957.28 909 exit LONG ^GSPC
74 1998-11-04 1118.67 778 entry LONG ^GSPC
75 1999-10-15 1247.41 778 exit LONG ^GSPC
76 1999-10-29 1362.93 712 entry LONG ^GSPC
77 2000-10-10 1387.02 712 exit LONG ^GSPC
78 2003-04-22 911.37 1084 entry LONG ^GSPC
79 2004-08-06 1063.97 1084 exit LONG ^GSPC
80 2004-11-04 1161.67 992 entry LONG ^GSPC
81 2007-11-21 1416.77 992 exit LONG ^GSPC
82 2009-06-12 946.21 1486 entry LONG ^GSPC
83 2010-06-04 1064.88 1486 exit LONG ^GSPC
84 2010-10-05 1160.75 1363 entry LONG ^GSPC
85 2011-08-04 1200.07 1363 exit LONG ^GSPC
86 2012-01-18 1308.04 1251 entry LONG ^GSPC
87 2015-08-21 1970.89 1251 exit LONG ^GSPC
88 2016-04-18 2094.34 1177 entry LONG ^GSPC
89 2018-10-24 2656.10 1177 exit LONG ^GSPC
90 2019-03-21 2854.88 1095 entry LONG ^GSPC
91 2020-03-09 2746.56 1095 exit LONG ^GSPC
92 2020-06-03 3122.87 963 entry LONG ^GSPC
93 2020-07-17 3224.73 963 exit LONG ^GSPC

In [ ]: