In [1]:
import pandas as pd
import numpy as np
import tradingWithPython as twp
import tradingWithPython.lib.yahooFinance as yf # yahoo finance module
twp.extra.setNotebookStyle()
import ffn
In [2]:
data = twp.yahooFinance.getHistoricData('SPY')
Got 4660 days of data
In [3]:
data.head()
Out[3]:
open high low close adj_close volume
Date
1999-12-31 146.84 147.50 146.25 146.88 103.95 3172700
2000-01-03 148.25 148.25 143.88 145.44 102.93 8164300
2000-01-04 143.53 144.06 139.64 139.75 98.91 8089800
2000-01-05 139.94 141.53 137.25 140.00 99.08 12177900
2000-01-06 139.62 141.50 137.75 137.75 97.49 6227200
In [4]:
close=data['close']
close.plot()
Out[4]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a0bd1fc50>
In [5]:
data['SMAslow']=data['close'].rolling(window=252).mean()
data['SMAfast']=close.rolling(window=42).mean()
In [6]:
data.tail()
Out[6]:
open high low close adj_close volume SMAslow SMAfast
Date
2018-07-03 272.87 272.98 270.42 270.90 270.90 42187100 262.49 273.16
2018-07-05 272.17 273.18 270.96 273.11 273.11 56925900 262.61 273.33
2018-07-06 273.14 275.84 272.71 275.42 275.42 66493700 262.75 273.53
2018-07-09 276.55 277.96 276.50 277.90 277.90 50401600 262.89 273.79
2018-07-10 278.41 279.01 278.08 278.12 278.12 29520229 263.03 273.99
In [7]:
data[['close','SMAfast','SMAslow']].plot()
Out[7]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a0ca314a8>
In [13]:
data['signal'] = data['SMAfast'] - data['SMAslow']
In [14]:
data.tail()
Out[14]:
open high low close adj_close volume SMAslow SMAfast signal Stance
Date
2018-07-03 272.87 272.98 270.42 270.90 270.90 42187100 262.49 273.16 10.67 10
2018-07-05 272.17 273.18 270.96 273.11 273.11 56925900 262.61 273.33 10.72 10
2018-07-06 273.14 275.84 272.71 275.42 275.42 66493700 262.75 273.53 10.78 10
2018-07-09 276.55 277.96 276.50 277.90 277.90 50401600 262.89 273.79 10.90 10
2018-07-10 278.41 279.01 278.08 278.12 278.12 29520229 263.03 273.99 10.97 10
In [24]:
X = 0 
data['Stance'] = np.where(data['signal'] > X, 1, 0) 
data['Stance'] = np.where(data['signal'] < X, -1, data['Stance'])
data['Stance'].value_counts()
Out[24]:
 1    3072
-1    1337
 0     251
Name: Stance, dtype: int64
In [25]:
data.tail()
Out[25]:
open high low close adj_close volume SMAslow SMAfast signal Stance Market Returns Strateg equity
Date
2018-07-03 272.87 272.98 270.42 270.90 270.90 42187100 262.49 273.16 10.67 1 -3.54e-03 -3.54e-02 114.44
2018-07-05 272.17 273.18 270.96 273.11 273.11 56925900 262.61 273.33 10.72 1 8.12e-03 8.12e-02 114.52
2018-07-06 273.14 275.84 272.71 275.42 275.42 66493700 262.75 273.53 10.78 1 8.42e-03 8.42e-02 114.61
2018-07-09 276.55 277.96 276.50 277.90 277.90 50401600 262.89 273.79 10.90 1 8.96e-03 8.96e-02 114.70
2018-07-10 278.41 279.01 278.08 278.12 278.12 29520229 263.03 273.99 10.97 1 7.91e-04 7.91e-03 114.70
In [26]:
data['Stance'].plot()
Out[26]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a0bdaea20>
In [27]:
data['Market Returns'] = np.log(data['close'] / data['close'].shift(1))
data['Strateg']=data['Market Returns']*data['Stance'].shift(1)
In [28]:
data
Out[28]:
open high low close adj_close volume SMAslow SMAfast signal Stance Market Returns Strateg equity
Date
1999-12-31 146.84 147.50 146.25 146.88 103.95 3172700 NaN NaN NaN 0 NaN NaN NaN
2000-01-03 148.25 148.25 143.88 145.44 102.93 8164300 NaN NaN NaN 0 -9.85e-03 -0.00e+00 100.00
2000-01-04 143.53 144.06 139.64 139.75 98.91 8089800 NaN NaN NaN 0 -3.99e-02 -0.00e+00 100.00
2000-01-05 139.94 141.53 137.25 140.00 99.08 12177900 NaN NaN NaN 0 1.79e-03 0.00e+00 100.00
2000-01-06 139.62 141.50 137.75 137.75 97.49 6227200 NaN NaN NaN 0 -1.62e-02 -0.00e+00 100.00
... ... ... ... ... ... ... ... ... ... ... ... ... ...
2018-07-03 272.87 272.98 270.42 270.90 270.90 42187100 262.49 273.16 10.67 1 -3.54e-03 -3.54e-03 114.44
2018-07-05 272.17 273.18 270.96 273.11 273.11 56925900 262.61 273.33 10.72 1 8.12e-03 8.12e-03 114.52
2018-07-06 273.14 275.84 272.71 275.42 275.42 66493700 262.75 273.53 10.78 1 8.42e-03 8.42e-03 114.61
2018-07-09 276.55 277.96 276.50 277.90 277.90 50401600 262.89 273.79 10.90 1 8.96e-03 8.96e-03 114.70
2018-07-10 278.41 279.01 278.08 278.12 278.12 29520229 263.03 273.99 10.97 1 7.91e-04 7.91e-04 114.70

4660 rows × 13 columns

In [29]:
data[['Market Returns','Strateg']].cumsum().plot()
Out[29]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a0c7cc860>
In [30]:
data['equity']=data['Strateg'].cumsum()+100
In [31]:
data
Out[31]:
open high low close adj_close volume SMAslow SMAfast signal Stance Market Returns Strateg equity
Date
1999-12-31 146.84 147.50 146.25 146.88 103.95 3172700 NaN NaN NaN 0 NaN NaN NaN
2000-01-03 148.25 148.25 143.88 145.44 102.93 8164300 NaN NaN NaN 0 -9.85e-03 -0.00e+00 100.00
2000-01-04 143.53 144.06 139.64 139.75 98.91 8089800 NaN NaN NaN 0 -3.99e-02 -0.00e+00 100.00
2000-01-05 139.94 141.53 137.25 140.00 99.08 12177900 NaN NaN NaN 0 1.79e-03 0.00e+00 100.00
2000-01-06 139.62 141.50 137.75 137.75 97.49 6227200 NaN NaN NaN 0 -1.62e-02 -0.00e+00 100.00
... ... ... ... ... ... ... ... ... ... ... ... ... ...
2018-07-03 272.87 272.98 270.42 270.90 270.90 42187100 262.49 273.16 10.67 1 -3.54e-03 -3.54e-03 101.44
2018-07-05 272.17 273.18 270.96 273.11 273.11 56925900 262.61 273.33 10.72 1 8.12e-03 8.12e-03 101.45
2018-07-06 273.14 275.84 272.71 275.42 275.42 66493700 262.75 273.53 10.78 1 8.42e-03 8.42e-03 101.46
2018-07-09 276.55 277.96 276.50 277.90 277.90 50401600 262.89 273.79 10.90 1 8.96e-03 8.96e-03 101.47
2018-07-10 278.41 279.01 278.08 278.12 278.12 29520229 263.03 273.99 10.97 1 7.91e-04 7.91e-04 101.47

4660 rows × 13 columns

In [32]:
writer = pd.ExcelWriter('output.xlsx')
data.to_excel(writer,'Sheet1')
writer.save()
In [33]:
perf = data['equity'].calc_stats()
/Users/ludeksk/anaconda3/lib/python3.6/site-packages/ffn/core.py:2054: RuntimeWarning: invalid value encountered in minimum
  negative_returns = np.minimum(returns, 0.)
In [34]:
ffn.core.PerformanceStats
Out[34]:
ffn.core.PerformanceStats
In [35]:
perf.plot()
Out[35]:
<matplotlib.axes._subplots.AxesSubplot at 0x1a1764ab00>
In [36]:
perf.display()
Stats for equity from 1999-12-31 00:00:00 - 2018-07-10 00:00:00
Annual risk-free rate considered: 0.00%
Summary:
Total Return      Sharpe  CAGR    Max Drawdown
--------------  --------  ------  --------------
-                   0.43  0.08%   -0.54%

Annualized Returns:
mtd    3m     6m     ytd    1y     3y      5y     10y    incep.
-----  -----  -----  -----  -----  ------  -----  -----  --------
0.02%  0.05%  0.01%  0.04%  0.14%  -0.00%  0.04%  0.05%  0.08%

Periodic:
        daily    monthly    yearly
------  -------  ---------  --------
sharpe  0.43     0.57       0.53
mean    0.08%    0.08%      0.08%
vol     0.18%    0.14%      0.15%
skew    -0.27    0.08       0.93
kurt    12.32    2.01       1.72
best    0.10%    0.18%      0.48%
worst   -0.13%   -0.13%     -0.15%

Drawdowns:
max     avg       # days
------  ------  --------
-0.54%  -0.04%     70.69

Misc:
---------------  ------
avg. up month    0.03%
avg. down month  -0.03%
up year %        68.42%
12m up %         77.00%
---------------  ------
In [ ]:
 
In [ ]:
 
In [ ]: