In [1]:
import os
os.chdir('C:\\users\\scuba\\pycharmprojects\\simplebacktester')
os.getcwd()
import pandas as pd
import ffn
import seaborn
%matplotlib inline
from backtest_helpers.compute_weights_RS_DM import compute_weights_RS_DM
from backtest_helpers.compute_weights_PMA import compute_weights_PMA
from backtest_helpers.monthly_return_table import monthly_return_table
portfolios = {
'RS0001': { 'symbols': ['VCVSX','VWEHX','VFIIX','FGOVX','VWAHX'],
'rs_lookback': 1, 'risk_lookback': 1, 'n_top': 2, 'frequency': 'm',
'cash_proxy': 'CASHX', 'risk_free': 0},
'RS0002': {'symbols': ['MMHYX','FAGIX','VFIIX'],
'rs_lookback': 3, 'risk_lookback': 2, 'n_top': 1, 'frequency': 'm',
'cash_proxy': 'CASHX', 'risk_free': 0},
'RS0003': {'symbols': ['MMHYX','FAGIX','VFIIX'],
'rs_lookback': 1, 'risk_lookback': 1, 'n_top': 1, 'frequency': 'q',
'cash_proxy': 'CASHX', 'risk_free': 0},
'DM0001': {'symbols': ['VCVSX','VWINX','VWEHX','VGHCX','VUSTX','VFIIX','VWAHX','FGOVX','FFXSX'],
'rs_lookback': 1, 'risk_lookback': 1, 'n_top': 3, 'frequency': 'm',
'cash_proxy': 'CASHX', 'risk_free': 'FFXSX'},
'DM0002': {'symbols': ['VCVSX','VUSTX','VWEHX','VFIIX','VGHCX','FRESX'],
'rs_lookback': 1, 'risk_lookback': 1, 'n_top': 5, 'frequency': 'm',
'cash_proxy': 'VFIIX', 'risk_free': 'FFXSX'},
'PMA001': {'symbols': ['VCVSX', 'VFIIX'],
'risk_lookback': 3, 'frequency': 'm', 'allocations': [0.6, 0.4],
'cash_proxy': 'VUSTX'},
'PMA002': {'symbols': ['VCVSX', 'VWINX', 'VWEHX'],
'risk_lookback': 3, 'frequency': 'm', 'allocations': [0.6, 0.2, 0.2],
'cash_proxy': 'VUSTX'},
'PMA003': {'symbols': ['VCVSX', 'FAGIX', 'VGHCX'],
'risk_lookback': 2, 'frequency': 'm', 'allocations': [1./3., 1./3., 1./3.],
'cash_proxy': 'VUSTX'}
}
In [2]:
name = 'RS0001'
if 'PMA' in name :
p_value, p_holdings, p_weights = compute_weights_PMA (name, portfolios[name])
else :
p_value, p_holdings, p_weights = compute_weights_RS_DM (name, portfolios[name])
p_value.plot(figsize=(15, 10), grid=True)
RS0001
VCVSX
VWEHX
VFIIX
FGOVX
VWAHX
FIRST BUY DATE = 1986-07-31 00:00:00
Out[2]:
<matplotlib.axes._subplots.AxesSubplot at 0xaa760b8>
In [3]:
ffn.calc_perf_stats(p_value).display()
Stats for None from 1986-07-31 00:00:00 - 2016-11-29 00:00:00
Annual risk-free rate considered: 0.00%
Summary:
Total Return Sharpe CAGR Max Drawdown
-------------- -------- ------ --------------
1304.96% 2.02 9.10% -5.64%
Annualized Returns:
mtd 3m 6m ytd 1y 3y 5y 10y incep.
------ ------ ----- ----- ----- ----- ----- ----- --------
-0.68% -0.53% 1.44% 7.33% 8.09% 4.10% 6.47% 8.93% 9.10%
Periodic:
daily monthly yearly
------ ------- --------- --------
sharpe 2.02 1.74 1.41
mean 8.80% 8.87% 9.29%
vol 4.35% 5.10% 6.58%
skew -0.06 0.48 1.66
kurt 5.46 2.39 4.78
best 1.93% 8.13% 32.82%
worst -2.74% -3.83% -0.97%
Drawdowns:
max avg # days
------ ------ --------
-5.64% -0.72% 20.76
Misc:
--------------- ------
avg. up month 1.39%
avg. down month -0.86%
up year % 96.67%
12m up % 98.31%
--------------- ------
G:\Anaconda3\lib\site-packages\ffn\core.py:190: FutureWarning: how in .resample() is deprecated
the new syntax is .resample(...).last()
self.monthly_prices = obj.resample('M', how='last')
G:\Anaconda3\lib\site-packages\ffn\core.py:193: FutureWarning: how in .resample() is deprecated
the new syntax is .resample(...).last()
self.yearly_prices = obj.resample('A', how='last')
In [4]:
def highlight_pos_neg (s) :
is_positive = s > 0
return ['background-color : rgb(127,255,0)' if v else 'background-color : rgb(255,99,71)' for v in is_positive]
df = monthly_return_table (p_value)
df.style.\
apply(highlight_pos_neg)
C:\users\scuba\pycharmprojects\simplebacktester\backtest_helpers\monthly_return_table.py:5: FutureWarning: how in .resample() is deprecated
the new syntax is .resample(...).last()
monthly_returns = daily_prices.resample('M', how='last').pct_change()
C:\users\scuba\pycharmprojects\simplebacktester\backtest_helpers\monthly_return_table.py:11: FutureWarning: how in .resample() is deprecated
the new syntax is .resample(...).last()
annual_returns = daily_prices.resample('12M', how='last').pct_change()[1:].values.round(4) * 100
Out[4]:
Data
Data
Data
Data
Data
Data
Data
Data
Data
Data
Data
Data
Annual Returns
1
2
3
4
5
6
7
8
9
10
11
12
Year
1986
0
0
0
0
0
0
0
2.27
-2.46
1.89
1.02
0.18
5.42
1987
1.87
3.02
0.38
-3.63
0
0
0.97
1.25
-3.17
0
0.78
2.04
5.24
1988
3.89
0.97
-0.31
0
-0.65
1.16
-0.67
0.42
1.74
2.3
-1.8
0.4
13.36
1989
2.62
-0.52
-0.25
1.93
3.25
0.81
1.81
1.05
-0.9
2.13
1
0.7
6.14
1990
-1.24
0
1.47
-1.48
1.19
0.41
1.73
-3.83
0
1.31
3.27
1.84
16.58
1991
3.67
2.45
3.59
2.85
1.81
-2.42
1.21
2.76
1.59
1.17
-0.79
2.17
18.81
1992
1.6
1.76
-0.78
0.84
1.93
1.55
3.65
-0.6
1.02
0.17
1.53
1.43
8.89
1993
2.24
2.34
-0.62
-0.75
0.1
1
0.75
1.95
0.8
1.73
-0.55
0
5.08
1994
1.39
-0.93
0
0
0.68
-0.53
0.45
0.08
-0.38
0
-2.27
0.57
9.31
1995
2.31
2.95
0.96
0.04
2.81
-0.36
2.35
0
0.66
1.25
1.67
0.34
9.02
1996
1.01
0.88
-0.08
2.18
0.88
-0.62
0.53
0.66
3.81
-0.58
1.61
0.49
11.8
1997
0.38
0.39
-1.52
0
0.89
1.85
3.36
-0.43
2.09
-1.05
0.39
1.57
8.83
1998
1.43
0.12
2.36
0.05
0.87
0.71
0.45
-1.42
1.85
-1.05
2.26
2.08
5.18
1999
2
-2.71
0
0.87
-0.2
2.07
-0.53
-1.12
-0.7
0.39
3.39
4.74
15.43
2000
0.84
5.29
1.5
-0.32
-0.6
1.87
-0.59
1.63
-1.42
0.75
1.16
1.66
7.13
2001
4.27
-2.52
0.71
-0.45
0.41
-0.94
1.82
0.88
0.25
1.88
1.13
-0.2
6.25
2002
-1.04
1.07
-1.66
0.52
0.67
0.95
1.68
1.46
0.63
-1.61
3.67
0.43
11.62
2003
-0.43
0.24
-0.3
4.19
2.51
0.39
0.02
0.68
2
-0.73
1.73
1.69
6.26
2004
2.62
0.13
0.15
-1.84
0
0.2
-0.45
1.86
0.66
0.78
-0.01
1.57
6.87
2005
-0.68
-0.39
-2.34
0
0.99
1.57
2.74
0.32
-0.8
-0.49
0
1.82
5.5
2006
2.54
0.81
0.89
-0.17
0.1
-0.23
0.63
1.57
1.02
1.48
1.64
0.59
9.92
2007
0.97
1.19
0.11
1.33
1.6
-0.93
-1.03
1.32
1.74
2.31
-0.07
0.11
6.39
2008
0.84
0.72
0.42
0.04
0.71
-2.04
0.19
1.05
0.47
-1.17
0
2.31
28.11
2009
3.29
-0.98
0.65
8.13
4.37
1.18
6.17
1.37
5.11
-2.83
1.01
1.76
11.49
2010
-0.45
0.35
2.37
1.23
-2.21
1.42
2.03
-0.86
0.01
2.86
-0.65
2.44
12.58
2011
2.12
1.87
0.1
1.38
1.34
0.23
1.13
-0.58
0.74
-0.36
-2.03
1.29
7.38
2012
2.82
2.44
0.15
-0.17
1.2
-0.1
1.85
0.59
1.7
0.24
1.28
0.3
8.44
2013
2.43
0.3
-0.15
1.37
0.85
-0.74
0
-1.25
0
1.36
0.22
0.92
4.56
2014
0.7
0.88
0
1.03
1.38
0.9
-1.62
0.75
-0.81
0.38
0.02
0.13
0.53
2015
1.37
-1.16
0.31
0.32
0.67
-1.42
0
0.08
0.34
0.13
-0.72
0.48
7.12
2016
1.17
0.5
1.54
2.11
0.72
0.47
0.09
1.19
0.73
-0.72
-0.68
0
0.51
In [18]:
frame = df['Annual Returns'].to_frame()
frame['positive'] = df['Annual Returns'] >= 0
frame['Annual Returns'].plot(figsize=(15,10),kind='bar',color=frame.positive.map({True: 'g', False: 'r'}), grid=True)
Out[18]:
<matplotlib.axes._subplots.AxesSubplot at 0xca69ac8>
In [4]:
p_value1, p_holdings1, p_weights1 = compute_weights_RS_DM ('RS0001', portfolios['RS0001'])
p_value1.plot(figsize=(15, 10), grid=True)
RS0001
VCVSX
VWEHX
VFIIX
FGOVX
VWAHX
FIRST BUY DATE = 1986-07-31 00:00:00
Out[4]:
<matplotlib.axes._subplots.AxesSubplot at 0xb51b748>
In [5]:
p_value2, p_holdings2, p_weights2 = compute_weights_RS_DM ('RS0002', portfolios['RS0002'])
p_value2.plot(figsize=(15, 10), grid=True)
RS0002
MMHYX
FAGIX
VFIIX
FIRST BUY DATE = 1984-05-31 00:00:00
Out[5]:
<matplotlib.axes._subplots.AxesSubplot at 0x72a2d68>
In [6]:
p_value3, p_holdings3, p_weights3 = compute_weights_RS_DM ('RS0003', portfolios['RS0003'])
p_value3.plot(figsize=(15, 10), grid=True)
RS0003
MMHYX
FAGIX
VFIIX
FIRST BUY DATE = 1984-05-31 00:00:00
Out[6]:
<matplotlib.axes._subplots.AxesSubplot at 0x751a7f0>
In [7]:
p_value4, p_holdings4, p_weights4 = compute_weights_RS_DM ('DM0001', portfolios['DM0001'])
p_value4.plot(figsize=(15, 10), grid=True)
DM0001
VWAHX
VCVSX
VGHCX
VUSTX
FFXSX
FGOVX
VWEHX
VWINX
VFIIX
FIRST BUY DATE = 1986-12-31 00:00:00
Out[7]:
<matplotlib.axes._subplots.AxesSubplot at 0xb64d2b0>
In [8]:
p_value5, p_holdings5, p_weights5 = compute_weights_RS_DM ('DM0002', portfolios['DM0002'])
p_value5.plot(figsize=(15, 10), grid=True)
DM0002
VCVSX
VGHCX
FRESX
VUSTX
FFXSX
VWEHX
VFIIX
FIRST BUY DATE = 1986-12-31 00:00:00
Out[8]:
<matplotlib.axes._subplots.AxesSubplot at 0xbdc5c18>
In [9]:
p_value6, p_holdings6, p_weights6 = compute_weights_PMA ('PMA001', portfolios['PMA001'])
p_value6.plot(figsize=(15, 10), grid=True)
PMA001
VCVSX
VFIIX
VUSTX
FIRST BUY DATE = 1986-08-29 00:00:00
Out[9]:
<matplotlib.axes._subplots.AxesSubplot at 0xbe96898>
In [10]:
p_value7, p_holdings7, p_weights7 = compute_weights_PMA ('PMA002', portfolios['PMA002'])
p_value7.plot(figsize=(15, 10), grid=True)
PMA002
VWEHX
VCVSX
VWINX
VUSTX
FIRST BUY DATE = 1986-08-29 00:00:00
Out[10]:
<matplotlib.axes._subplots.AxesSubplot at 0xc9ebd68>
In [11]:
p_value8, p_holdings8, p_weights8 = compute_weights_PMA ('PMA003', portfolios['PMA003'])
p_value8.plot(figsize=(15, 10), grid=True)
PMA003
FAGIX
VCVSX
VGHCX
VUSTX
FIRST BUY DATE = 1986-07-31 00:00:00
Out[11]:
<matplotlib.axes._subplots.AxesSubplot at 0xc9a4ef0>