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>

EACH STRATEGY SEPARATELY


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>