We examine economic and financial time series where Holt-Winters is used to forecast one-year ahead. Daily data for bonds, equity, and gold is then analyzed.
The focus is on geometric mean returns because they optimally express mean-variance under logarithmic utility.
Dependencies:
- Linux, bash
- Python: matplotlib, pandas
- Modules: yi_1tool, yi_plot, yi_timeseries, yi_fred
CHANGE LOG
2015-05-26 Code revision using template v14.12.21.
2014-10-11 Code review. Template 2014-09-28.
2014-09-01 First version.
# NOTEBOOK settings and system details: [00-tpl v14.12.21]
# Assume that the backend is LINUX (our particular distro is Ubuntu, running bash shell):
print '\n :: TIMESTAMP of last notebook execution:'
!date
print '\n :: IPython version:'
!ipython --version
# Automatically reload modified modules:
%load_ext autoreload
%autoreload 2
# 0 disables autoreload.
# Generate plots inside notebook:
%matplotlib inline
# DISPLAY options
from IPython.display import Image
# e.g. Image(filename='holt-winters-equations.png', embed=True) # url= also works
from IPython.display import YouTubeVideo
# e.g. YouTubeVideo('1j_HxD4iLn8', start='43', width=600, height=400)
from IPython.display import HTML # useful for snippets
# e.g. HTML('<iframe src=http://en.mobile.wikipedia.org/?useformat=mobile width=700 height=350></iframe>')
import pandas as pd
print '\n :: pandas version:'
print pd.__version__
# pandas DataFrames are represented as text by default; enable HTML representation:
# [Deprecated: pd.core.format.set_printoptions( notebook_repr_html=True ) ]
pd.set_option( 'display.notebook_repr_html', False )
# MATH display, use %%latex, rather than the following:
# from IPython.display import Math
# from IPython.display import Latex
print '\n :: Working directory (set as $workd):'
workd, = !pwd
print workd + '\n'
:: TIMESTAMP of last notebook execution: Thu Jun 25 20:35:28 PDT 2015 :: IPython version: 2.3.0 :: pandas version: 0.15.0 :: Working directory (set as $workd): /home/yaya/Dropbox/share/git/nous/fecon235/nb
from yi_1tools import *
from yi_plot import *
from yi_timeseries import *
from yi_fred import *
We shall retrieve the following data of monthly frequency: (aggregated) inflation, bonds (zero coupon equivalent of 10-y Treasury), equities (S&P 500), and gold (London PM fix) -- all denominated in US dollars -- then lastly, the real trade-weighted USD index (Federal Reserve) and US home prices (per Case-Shiller). The details for each series is given in their respective notebooks.
Home prices will create a 3-month lag, due to their release cycle.
# Specify monthly series of interest as ms list:
ms = [ m4infl, m4zero10, m4spx, m4xau, m4usdrtb, m4homepx ]
names = ['Infl', 'Zero10', 'SPX', 'XAU', 'USD', 'Homes']
# Download into a dictionary:
msd = {}
for i in ms:
msd[i] = getfred(i)
:: S&P 500 prepend successfully goes back to 1957. :: Case-Shiller prepend successfully goes back to 1987.
After downloading the level series, we compute the YoY percentage change for each series. This will be the a trailing 12-month statistic, thus it's overlapping.
# Compute the YoY percentage change:
msdc = {}
for i in ms:
msdc[i] = pcent( msd[i], 12 )
# Construct the mega YoY dataframe:
mega = paste( [ msdc[i] for i in ms ] )
# Give names to the columns for mega:
mega.columns = names
# Start time given by t0
t0 = '1988'
stats( mega[t0:] )
Infl Zero10 SPX XAU USD Homes count 327.000000 327.000000 327.000000 327.000000 327.000000 327.000000 mean 2.424121 2.229173 8.753083 4.949457 -0.286063 3.882495 std 1.005295 7.463804 16.416248 15.524655 4.982369 8.088091 min -0.180575 -18.521264 -42.349361 -27.752361 -10.577564 -18.906156 25% 1.690927 -3.217100 2.288186 -6.463883 -3.809645 -1.218646 50% 2.366964 2.912582 10.726925 1.898076 -0.357301 4.293769 75% 2.887417 7.752083 19.981864 14.325670 2.682498 10.684985 max 5.242059 20.492399 52.051354 60.357143 14.508997 17.077118 :: Index on min: Infl 2009-07-01 Zero10 1994-10-01 SPX 2009-03-01 XAU 2013-12-01 USD 2008-03-01 Homes 2009-01-01 dtype: datetime64[ns] :: Index on max: Infl 1990-10-01 Zero10 1996-01-01 SPX 2010-03-01 XAU 2006-05-01 USD 2009-03-01 Homes 2004-07-01 dtype: datetime64[ns] :: Head: Infl Zero10 SPX XAU USD Homes T 1988-01-01 3.984315 -12.661625 -6.207571 17.042392 -9.836868 12.139461 1988-02-01 3.876021 -8.068941 -8.186030 9.982617 -8.633477 11.661442 1988-03-01 3.924380 -9.248410 -8.156954 8.841782 -9.393214 11.345646 1988-04-01 3.992870 -5.477528 -8.960111 2.878355 -8.283502 10.974485 1988-05-01 4.017727 -4.487925 -11.871026 -1.578661 -7.507266 10.543908 1988-06-01 4.129092 -4.738070 -10.689462 0.022137 -7.401580 10.559567 1988-07-01 4.276206 -5.671538 -12.487441 -3.115990 -6.469468 10.756853 :: Tail: Infl Zero10 SPX XAU USD Homes T 2014-09-01 1.573155 2.870055 18.259104 -8.035048 1.924209 4.982426 2014-10-01 1.590927 2.873362 13.047620 -6.736243 4.278896 4.557101 2014-11-01 1.397419 3.603244 14.134137 -8.234146 4.984866 4.353347 2014-12-01 1.098285 6.108084 14.380677 -2.298029 6.786695 4.482448 2015-01-01 0.731306 9.213133 10.175566 1.235684 7.608924 4.485425 2015-02-01 0.806330 6.585098 14.399577 -7.207207 8.760392 4.996752 2015-03-01 0.849246 6.019017 11.453936 -11.421092 10.734463 4.990347 :: Correlation matrix: Infl Zero10 SPX XAU USD Homes Infl 1.000000 -0.059018 -0.016182 -0.072354 -0.308788 0.005064 Zero10 -0.059018 1.000000 -0.137220 -0.000802 0.214137 -0.295339 SPX -0.016182 -0.137220 1.000000 -0.212138 -0.049899 0.248055 XAU -0.072354 -0.000802 -0.212138 1.000000 -0.513692 -0.244964 USD -0.308788 0.214137 -0.049899 -0.513692 1.000000 0.039124 Homes 0.005064 -0.295339 0.248055 -0.244964 0.039124 1.000000
There is not much correlation among our assets, except a mild negative between gold XAU and USD. Next, the boxplot gives us an idea of the range of returns, and their persistence. It's a visual aid to the geometric mean returns which is most significant as investment metric.
# Overlapping YoY percentage change, recently:
boxplot(mega[t0:], 'Assets YoYm')
# where the red dot represents the latest point.
:: Finished: boxplot-Assets_YoYm.png
# Geometric mean returns, non-overlapping, annualized:
for i in range(len(ms)):
print names[i], georet(msd[ms[i]][t0:], 12)
Infl [2.33, 2.33, 0.5, 12] Zero10 [2.0, 2.25, 7.19, 12] SPX [7.82, 8.57, 12.23, 12] XAU [3.28, 4.14, 13.09, 12] USD [0.03, 0.12, 4.12, 12] Homes [3.43, 3.46, 2.55, 12]
2014-09-01, georet since 2010
2014-10-11, georet since 2004
2014-10-12, georet since 1988
2015-05-27, georet since 1988
We forecast one-year ahead using the monthly data. Note that current infl is rebased to 1, thus 1.02 would signify 2% increase.
# 12-periods ahead forecasts use default alpha and beta values (robust update):
for i in range(len(ms)):
print names[i]
print holtfred(msd[ ms[i]], h=12 )
# ^we use all available data to forecast
print '------------------------------------'
Infl Forecast 0 1.000000 1 0.998873 2 0.999353 3 0.999834 4 1.000314 5 1.000794 6 1.001274 7 1.001755 8 1.002235 9 1.002715 10 1.003195 11 1.003675 12 1.004156 ------------------------------------ Zero10 Forecast 0 80.929358 1 83.871671 2 84.151155 3 84.430640 4 84.710124 5 84.989608 6 85.269093 7 85.548577 8 85.828062 9 86.107546 10 86.387030 11 86.666515 12 86.945999 ------------------------------------ SPX Forecast 0 2105.200000 1 2146.564284 2 2161.256033 3 2175.947782 4 2190.639532 5 2205.331281 6 2220.023030 7 2234.714780 8 2249.406529 9 2264.098278 10 2278.790028 11 2293.481777 12 2308.173527 ------------------------------------ XAU Forecast 0 1178.500000 1 1178.805087 2 1172.707278 3 1166.609470 4 1160.511661 5 1154.413853 6 1148.316045 7 1142.218236 8 1136.120428 9 1130.022619 10 1123.924811 11 1117.827002 12 1111.729194 ------------------------------------ USD Forecast 0 93.018000 1 95.042219 2 95.923105 3 96.803990 4 97.684876 5 98.565762 6 99.446648 7 100.327534 8 101.208420 9 102.089306 10 102.970192 11 103.851077 12 104.731963 ------------------------------------ Homes Forecast 0 214289.270829 1 212418.051023 2 213348.196411 3 214278.341799 4 215208.487187 5 216138.632575 6 217068.777963 7 217998.923351 8 218929.068739 9 219859.214127 10 220789.359515 11 221719.504904 12 222649.650292 ------------------------------------
Changing Holt-Winters alpha from 0.20 to 0.10 varies the forecast only slightly. The important parameter is beta to capture trend effects. Currently we shall rely on default Holt-Winters settings for robustness.
2014-09-01, Twelve-month Forecasts given data through 2014-07-01:
2014-10-11, Twelve-month Forecasts given ten-year data, robust HW:
2015-05-28, Twelve-month Forecasts given data through 2015-03-01, robust HW:
We examine bonds (zero coupon equivalent of 10-y Treasury), equities (SPX), gold (XAU), EURUSD, and USDJPY at higher frequency (daily) for the most recent developments.
[Inflation, real trade-weighted USD, and US home price data have a slow release schedule (monthly).]
# Specify daily series of interest:
ds = [ d4zero10, d4spx, d4xau, d4eurusd, d4usdjpy ]
names = [ 'Zero10', 'SPX', 'XAU', 'EURUSD', 'USDJPY' ]
# Download into a dictionary:
dsd = {}
for i in ds:
dsd[i] = getfred(i)
:: S&P 500 prepend successfully goes back to 1957.
# Compute the YoY percentage change (overlaping):
dsdc = {}
for i in ds:
dsdc[i] = pcent( dsd[i], 256 )
# Construct the YoY dataframe:
dega = paste( [ dsdc[i] for i in ds ] )
# Give names to the columns for mega:
dega.columns = names
# Start from the recent:
u0 = '2010-01-01'
# Overlapping YoY percentage change, recently:
boxplot( dega[u0:], 'Assets YoYd' )
:: Finished: boxplot-Assets_YoYd.png
# Geometric mean returns, non-overlapping, annualized:
for i in range(len(ds)):
print names[i], georet( dsd[ds[i]][u0:] )
Zero10 [2.33, 2.61, 7.52, 256] SPX [11.36, 12.57, 15.53, 256] XAU [1.36, 2.89, 17.49, 256] EURUSD [-4.21, -3.77, 9.43, 256] USDJPY [4.96, 5.4, 9.33, 256]
2014-10-11, Really near-term picture is too bright for SPX while XAU looks dark. Sell stocks, and start to accumulate gold.
2015-05-28, XAU georet changed from 2.6% to 1.6%. Zero10 monthly forecast is basically unchanged. Real rate is what matters for gold. USD stronger by 4.8% against both the EUR and JPY.
# Show esp. correlations:
stats( dega[u0:] )
Zero10 SPX XAU EURUSD USDJPY count 1426.000000 1426.000000 1426.000000 1426.000000 1426.000000 mean 1.902672 15.245862 5.972715 -2.194030 4.307208 std 6.762567 9.818755 18.978442 8.842339 12.024459 min -13.248728 -5.657641 -29.210332 -23.984762 -14.310589 25% -3.402214 9.723296 -8.516970 -8.651129 -6.838512 50% 2.684079 14.060072 2.285300 -0.706405 1.967362 75% 6.184020 20.287348 24.319358 4.492467 15.174316 max 18.075299 65.300874 52.361809 21.056554 30.357599 :: Index on min: Zero10 2010-01-07 SPX 2011-10-03 XAU 2013-12-26 EURUSD 2015-03-11 USDJPY 2011-03-17 dtype: datetime64[ns] :: Index on max: Zero10 2012-02-01 SPX 2010-03-02 XAU 2011-09-06 EURUSD 2011-06-06 USDJPY 2013-05-28 dtype: datetime64[ns] :: Head: Zero10 SPX XAU EURUSD USDJPY T 2010-01-01 -11.463243 22.574830 27.081507 4.506344 2.117389 2010-01-04 -11.776234 27.252204 32.369431 6.846980 2.548476 2010-01-05 -11.858700 30.595454 35.822249 7.904398 2.878992 2010-01-06 -12.554147 30.437376 36.721113 9.137748 3.212493 2010-01-07 -13.248728 35.492867 37.583688 8.653408 4.513889 2010-01-08 -13.173018 35.702942 39.104938 9.645639 3.471370 2010-01-11 -12.321456 34.919776 38.290855 9.755361 1.783143 :: Tail: Zero10 SPX XAU EURUSD USDJPY T 2015-06-11 1.966382 7.760938 -7.186454 -17.181396 21.006265 2015-06-12 2.237337 6.870700 -8.522815 -17.195301 21.003535 2015-06-15 2.418714 6.192973 -9.988571 -17.076402 20.794987 2015-06-16 2.782262 6.811338 -10.334983 -17.325094 21.089303 2015-06-17 2.419197 7.715977 -10.656049 -17.250515 21.658670 2015-06-18 1.966775 8.252489 -8.726030 -16.380701 20.756757 2015-06-19 2.419923 7.805459 -8.259958 -16.715650 20.696439 :: Correlation matrix: Zero10 SPX XAU EURUSD USDJPY Zero10 1.000000 -0.750870 0.418415 -0.575325 -0.417933 SPX -0.750870 1.000000 -0.152196 0.404478 0.159153 XAU 0.418415 -0.152196 1.000000 0.074339 -0.866292 EURUSD -0.575325 0.404478 0.074339 1.000000 -0.093702 USDJPY -0.417933 0.159153 -0.866292 -0.093702 1.000000