We examine inflation data: CPI and PCE, including the core versions, along with the 10-year BEI rate (break-even inflation). We also examine gold returns and its correlations to inflation. A combined inflation statistic m4infl is defined, and we make a brief forecast.
FRED is a free data service from the Federal Reserve Bank in St. Louis.
Dependencies:
Python 2.7 and modules: matplotlib, pandas, yi_1tools, yi_fred, yi_plot.
CHANGE LOG
2015-02-02 Code review and revision. Include sample forecast.
2014-09-02 Introduce new inflation series m4infl. Use getfred().
2014-08-06 Major revision directly based on refined modules.
2014-07-25 Expand to include inflation statistics including BEI.
Major fix of yi_fred.getdataframe()
2014-07-24 First version includes module yi_fred converted from fred-plot notebook.
# NOTEBOOK settings and system details: [00-tpl v14.09.28]
# 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 will disable autoreload.
# Generate plots inside notebook:
%matplotlib inline
# DISPLAY options
from IPython.display import Image
# e.g. Image(filename='holt-winters-equations.png', embed=True)
from IPython.display import YouTubeVideo
# e.g. YouTubeVideo('1j_HxD4iLn8')
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: Tue Feb 3 13:07:07 PST 2015 :: IPython version: 2.3.0 :: pandas version: 0.15.0 :: Working directory (set as $workd): /home/yaya/Dropbox/ipy/fecon235/nb
Each economic time series has its own "fredcode" which is listed at the FRED site, see module yi_fred for details.
from yi_1tools import *
from yi_fred import *
from yi_plot import *
# Get various inflation and bond statistics:
ts = {}
for i in ml_infl + ml_long:
ts[i] = getfred(i)
:: S&P 500 prepend successfully goes back to 1957.
# Collection of inflation levels
tsinf = [ ts[i] for i in ml_infl ]
# Make a dataframe consists of those inf levels:
inf_levels = paste( tsinf )
# Label the column names:
inf_levels.columns = ['CPI', 'CPIc', 'PCE', 'PCEc']
# We are interested in year-over-year inflation rates, expressed in percent:
inf = pcent( inf_levels, 12 ).dropna()
boxplot( inf, 'Inflation' )
:: Finished: boxplot-Inflation.png
The small appended "c" denotes core version of headline versions of inflation. The red dot represents the most recent data point.
stats(inf)
CPI CPIc PCE PCEc count 660.000000 660.000000 660.000000 660.000000 mean 3.919813 3.857954 3.431895 3.352024 std 2.864429 2.625527 2.465611 2.197169 min -1.958761 0.597276 -1.183584 0.947246 25% 1.953565 2.019125 1.687979 1.640647 50% 3.173076 3.000836 2.640439 2.449200 75% 4.728765 4.890308 4.329166 4.495992 max 14.592275 13.604488 11.577525 10.233897 :: Index on min: CPI 2009-07-01 CPIc 2010-10-01 PCE 2009-07-01 PCEc 2010-12-01 dtype: datetime64[ns] :: Index on max: CPI 1980-03-01 CPIc 1980-06-01 PCE 1974-10-01 PCEc 1975-02-01 dtype: datetime64[ns] :: Head: CPI CPIc PCE PCEc T 1960-01-01 1.240951 2.006689 1.670171 2.028755 1960-02-01 1.413793 2.341137 1.686311 2.140951 1960-03-01 1.518813 2.000000 1.679398 2.047995 1960-04-01 1.932367 2.000000 1.850666 1.986418 1960-05-01 1.825069 1.661130 1.907975 2.040701 1960-06-01 1.717623 1.655629 1.664733 1.815005 1960-07-01 1.372213 1.324503 1.643994 1.760207 :: Tail: CPI CPIc PCE PCEc T 2014-06-01 2.075496 1.927383 1.605614 1.495733 2014-07-01 1.996553 1.854931 1.573990 1.485662 2014-08-01 1.711412 1.729024 1.450057 1.466353 2014-09-01 1.664221 1.736551 1.429209 1.478953 2014-10-01 1.651111 1.817423 1.401492 1.509104 2014-11-01 1.281443 1.711828 1.151644 1.403127 2014-12-01 0.662847 1.612027 0.748578 1.330772 :: Correlation matrix: CPI CPIc PCE PCEc CPI 1.000000 0.929263 0.980531 0.912526 CPIc 0.929263 1.000000 0.924300 0.963566 PCE 0.980531 0.924300 1.000000 0.954342 PCEc 0.912526 0.963566 0.954342 1.000000
inf_av = todf(( inf['CPI'] + inf['CPIc'] + inf['PCE'] + inf['PCEc'] ) / 4 )
stats( inf_av )
Y count 660.000000 mean 3.640421 std 2.484236 min -0.160953 25% 1.807088 50% 2.834695 75% 4.589724 max 12.016273 :: Index on min: Y 2009-07-01 dtype: datetime64[ns] :: Index on max: Y 1980-03-01 dtype: datetime64[ns] :: Head: Y T 1960-01-01 1.736641 1960-02-01 1.895548 1960-03-01 1.811551 1960-04-01 1.942363 1960-05-01 1.858719 1960-06-01 1.713247 1960-07-01 1.525229 :: Tail: Y T 2014-06-01 1.776056 2014-07-01 1.727784 2014-08-01 1.589212 2014-09-01 1.577233 2014-10-01 1.594783 2014-11-01 1.387011 2014-12-01 1.088556 :: Correlation matrix: Y Y 1
# The shortest of our time series under consideration, m4tips10,
# starts at 2003-01-01, so let
start = '2003-01-01'
plotdf( inf_av[start:], 'Inflation mean' )
:: Finished: plotdf-Inflation_mean.png
During the Great Recession, we can see the dramatic drop in inflation rates.
bei = todf( ts[m4bond10] - ts[m4tips10] )
plotdf(bei[start:], 'Inflation BEI')
:: Finished: plotdf-Inflation_BEI.png
Studies of forward-looking BEI vs. realized inflation generally show BEI overestimates inflation.
tail(bei)
Y T 2014-07-01 2.26 2014-08-01 2.20 2014-09-01 2.07 2014-10-01 1.92 2014-11-01 1.88 2014-12-01 1.70 2015-01-01 1.61
bei_inf_av = todf((bei + inf_av) / 2)
plotdf(bei_inf_av[start:], 'Inflation BEI av')
:: Finished: plotdf-Inflation_BEI_av.png
tail(bei_inf_av)
Y T 2014-06-01 2.003028 2014-07-01 1.993892 2014-08-01 1.894606 2014-09-01 1.823617 2014-10-01 1.757391 2014-11-01 1.633505 2014-12-01 1.394278
The gold data from FRED is daily, not monthly, so we resample accordingly.
gold_daily = getfred( d4xau )
gold = monthly(gold_daily)
# Monthly gold data since 1968-04-01
# Compute annualized returns:
gold_ret = pcent(gold, 12)
plotdf( gold_ret[start:] )
However, it is known that real rates somewhat explain gold price. For example, when real rates are negative, gold looks like a better alternative than fixed income. So in another notebook, we look at 10-y TIPS vs. gold price.
# Conversions to dataframe with label before paste:
dfa = todf( inf_av, 'Iav')
dfb = todf( bei, 'BEI' )
dfc = todf( bei_inf_av, 'BEI_Iav')
dfd = todf( gold_ret, 'Gold' )
# Mother of all annualized inflation rates:
infall = paste( [inf, dfa, dfb, dfc, dfd] )
# Correlation matrix going back to 2003-01-01 (start of BEI)
cormatrix(infall)
CPI CPIc PCE PCEc Iav BEI BEI_Iav \ CPI 1.000000 0.474120 0.990622 0.739846 0.971721 0.530389 0.923311 CPIc 0.474120 1.000000 0.460276 0.832302 0.649081 0.254937 0.578081 PCE 0.990622 0.460276 1.000000 0.778708 0.973807 0.539102 0.928241 PCEc 0.739846 0.832302 0.778708 1.000000 0.874817 0.458853 0.823979 Iav 0.971721 0.649081 0.973807 0.874817 1.000000 0.529831 0.943957 BEI 0.530389 0.254937 0.539102 0.458853 0.529831 1.000000 0.780069 BEI_Iav 0.923311 0.578081 0.928241 0.823979 0.943957 0.780069 1.000000 Gold 0.475334 0.119828 0.500489 0.368790 0.457367 0.220171 0.423112 Gold CPI 0.475334 CPIc 0.119828 PCE 0.500489 PCEc 0.368790 Iav 0.457367 BEI 0.220171 BEI_Iav 0.423112 Gold 1.000000
CPI and PCE are tightly correlated, as are CPIc and PCEc. Surprisingly, CPI and CPIc are only moderately correlated, only 47%. The market traded BEI is modestly correlated with economic statistics of inflation. Gold returns seemingly have little to do with inflation (more correlated with headline inflation, as it includes food and energy, than core inflation, which excludes such components).
# Most recent values:
tail(infall)
CPI CPIc PCE PCEc Iav BEI BEI_Iav \ T 2014-06-01 2.075496 1.927383 1.605614 1.495733 1.776056 2.23 2.003028 2014-07-01 1.996553 1.854931 1.573990 1.485662 1.727784 2.26 1.993892 2014-08-01 1.711412 1.729024 1.450057 1.466353 1.589212 2.20 1.894606 2014-09-01 1.664221 1.736551 1.429209 1.478953 1.577233 2.07 1.823617 2014-10-01 1.651111 1.817423 1.401492 1.509104 1.594783 1.92 1.757391 2014-11-01 1.281443 1.711828 1.151644 1.403127 1.387011 1.88 1.633505 2014-12-01 0.662847 1.612027 0.748578 1.330772 1.088556 1.70 1.394278 Gold T 2014-06-01 -7.889010 2014-07-01 1.945525 2014-08-01 -4.215976 2014-09-01 -8.035048 2014-10-01 -6.736243 2014-11-01 -8.234146 2014-12-01 -2.298029
To readily access our findings above, we developed the m4infl series. Each measure of inflation levels is first rescaled such that the most recent point is equal to 1. This eliminates the base year problem and the arbitrarily set level of 100 somewhere in time. Now we can take the simple average among inflation levels which is by construction will be equally weighted.
As a very convenient by-product, the recipricol of m4infl yields multiplicative factors useful for deflating prices, see m4defl.
The average between backward and forward-looking inflation rates is codified as m4inflbei.
# Let's see if our two different methods agree:
infl = getfred(m4infl)
inflrate = pcent(infl, 12)
stat2( dfa['Iav'], inflrate['Y'] )
:: FIRST variable: count 660.000000 mean 3.640421 std 2.484236 min -0.160953 25% 1.807088 50% 2.834695 75% 4.589724 max 12.016273 Name: Iav, dtype: float64 :: SECOND variable: count 660.000000 mean 3.622258 std 2.461081 min -0.176972 25% 1.806515 50% 2.823135 75% 4.592996 max 11.868998 Name: Y, dtype: float64 :: CORRELATION 0.999958175524 -------------------------Summary of Regression Analysis------------------------- Formula: Y ~ <x> + <intercept> Number of Observations: 660 Number of Degrees of Freedom: 2 R-squared: 0.9999 Adj R-squared: 0.9999 Rmse: 0.0227 F-stat (1, 658): 7865713.8149, p-value: 0.0000 Degrees of Freedom: model 1, resid 658 -----------------------Summary of Estimated Coefficients------------------------ Variable Coef Std Err t-stat p-value CI 2.5% CI 97.5% -------------------------------------------------------------------------------- x 1.0094 0.0004 2804.59 0.0000 1.0087 1.0101 intercept -0.0158 0.0016 -10.00 0.0000 -0.0189 -0.0127 ---------------------------------End of Summary---------------------------------
Our results are almost perfectly correlated, which we expected by construction.
For predicting inflation, it is better to use levels, rather than rates, as primary form of time-series. Forecasting will be covered in detail in another notebook. But here we quickly demonstrate the Holt-Winters method.
# Let's forecast 12 periods ahead:
holtfred( infl, 12 )
Forecast 0 1.000000 1 1.004692 2 1.005643 3 1.006594 4 1.007545 5 1.008496 6 1.009447 7 1.010398 8 1.011349 9 1.012300 10 1.013251 11 1.014202 12 1.015153
2015-02-03: The 12-months ahead forecast calls for an annual inflation rate of 1.52% (average of CPI, CPIc, PCE, and PCEc).