1 Check your working directory

getwd()
## [1] "/Volumes/Macintosh HD - Data/Users/Morgane/Documents/Harrisburg University/Analytics Master Classes/ANLY 565 Summer Time Series/Assignment #4"

2 Set your working directory to “ANLY 580/RScript”.

setwd("/Volumes/Macintosh HD - Data/Users/Morgane/Documents/Harrisburg University/Analytics Master Classes/ANLY 565 Summer Time Series/Assignment #4/RScript")
getwd()
## [1] "/Volumes/Macintosh HD - Data/Users/Morgane/Documents/Harrisburg University/Analytics Master Classes/ANLY 565 Summer Time Series/Assignment #4/RScript"

3 Download “ffrategdp.xls” data file and set the “observation_date” variable to the date format and the “FEDFUNDS” and “GDPC1” variables to the numeric format. The “FEDFUNDS” variable represents the effective federal funds rate, which indicates the interest rate at which depository institutions trade federal funds (balances held at Federal Reserve Banks) with each other overnight. The “GDPC1” variable represents real gross domestic product.

library(readxl)
FED_DS<-read_excel("/Volumes/Macintosh HD - Data/Users/Morgane/Documents/Harrisburg University/Analytics Master Classes/ANLY 565 Summer Time Series/Assignment #4/RScript/ffrategdp.xls", col_types = c("date", "numeric","numeric"))

4 By using ts() function create a time series object that contains two variables: “FEDFUNDS” and “GDPC1”. Label it as “ffrategdpts”.

range(FED_DS$observation_date)
## [1] "1954-07-01 UTC" "2019-04-01 UTC"

1st, we identify the min. and max. for the dates of this dataset. The observations are provided on the first of each quarter, starting on July 1st, 1954 and ending on April 1st, 2019.

In the ts() formula, “start” indicates the time of the first observation. In our case our dataset starts with July, which is period 3 (the start of the 3rd quarter of the year. If it was January we would have used “1”, or “2” for April, and “4” for October. Our “frequency”" is “4”" because this is quarterly data.

ffrategdpts<-ts(FED_DS[-1],start=c(1954,3), end=c(2019,2), freq = 4)
str(ffrategdpts)
##  Time-Series [1:260, 1:2] from 1954 to 2019: 1.027 0.987 1.343 1.5 1.94 ...
##  - attr(*, "dimnames")=List of 2
##   ..$ : NULL
##   ..$ : chr [1:2] "FEDFUNDS" "GDPC1"

5 Create two stand alone variables “fedrate” and “gdp” that take on values of the “FEDFUNDS” and “GDPC1” variables from the “ffrategdpts” data set.

fedrate<-ffrategdpts[,1]
gdp<-ffrategdpts[,2]

6 When the federal funds rate goes down, the commercial loan interest rates go down too. This means that people can borrow cheaply and invest in their businesses, which will result in higher gross domestic product.

Therefore, you suspect that the federal funds rate has a negative correlation with GDP. To test this hypothesis you decide to use lm() function to estimate the coefficients of a linear regression model in which “gdp” is a dependent variable and “fedrate” is an independent variable. Save the estimated model as gdpfr.lm. Based on the results of this model can you make any conclusions about the nature of the relationship between the gdp and the federal funds rate?

gdpfr.lm<-lm(gdp~fedrate)
summary(gdpfr.lm)
## 
## Call:
## lm(formula = gdp ~ fedrate)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -8680.0 -3843.8   526.3  3522.0  8398.7 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 11915.26     467.51  25.487  < 2e-16 ***
## fedrate      -538.30      78.18  -6.885 4.38e-11 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 4504 on 258 degrees of freedom
## Multiple R-squared:  0.1552, Adjusted R-squared:  0.1519 
## F-statistic:  47.4 on 1 and 258 DF,  p-value: 4.382e-11

Based on the linear model, we see that the fed rate is indeed a statistically significant variable when explaining the change in gdp. Given the negative coefficient, it confirms that there is a negative correlation between the two variables. However, we note that the adjusted r-square is quite low (15%), meaning that it is only a small portion of the explaination.

7 You have suspected that the “gdp” variable may contain a unit root. By using Augmented Dickey Fuller method test “gdp” variable for the presence of unit root. Does “gdp” variable contain a unit root? Is “gdp” variable stationary?

library(tseries)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
adf.test(gdp)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  gdp
## Dickey-Fuller = -1.5023, Lag order = 6, p-value = 0.7855
## alternative hypothesis: stationary

The null hypothesis of a unit root can be rejected for the gdp variable, as the p-value is above 0.05. GDP might therefore be a stationary variable.

8 By using Augmented Dickey Fuller method test “fedrate” variable for the presence of unit root.

Does “fedrate” variable contain a unit root? Is “fedrate” variable stationary?

adf.test(fedrate)
## 
##  Augmented Dickey-Fuller Test
## 
## data:  fedrate
## Dickey-Fuller = -2.783, Lag order = 6, p-value = 0.2462
## alternative hypothesis: stationary

The null hypothesis of a unit root can be rejected for the fedrate variable, as the p-value is above 0.05. FEDRATE might therefore be a stationary variable.

9 The Phillips-Ouliaris test shows whether there is evidence that the series are cointegrated, which justifies the use of a regression model. Are “gdp” and “fedrate” variables cointegrated? Is “gdpfr.lm” a suitable model to explore the relationship between “gdp” and “fedrate”?

po.test(cbind(fedrate, gdp))
## Warning in po.test(cbind(fedrate, gdp)): p-value greater than printed p-value
## 
##  Phillips-Ouliaris Cointegration Test
## 
## data:  cbind(fedrate, gdp)
## Phillips-Ouliaris demeaned = -13.028, Truncation lag parameter = 2,
## p-value = 0.15

The P.O. tests for the null hypothesis that our variables are not cointegrated. As the p-value is above 0.05, the null hypothesis can be rejected. The two variables might be cointegrated, which means that there is a long-run relationship between these two variables: the distance between the two variables remains stable over time, even if they are negatively correlated as we indicated previously.

10 Create the following 2 new variables:

  1. “gdpgrowth” - that represents quarterly percentage change in GDP
  2. “fedratediff” - that represents quarterly difference in the federal funds rate (simple difference). To each of the variables add “NA” as the first observation. This will ensure that the new variables are of the same length as the existing variables.
head(gdp)
## [1] 2682.601 2735.091 2813.212 2858.988 2897.598 2914.993
gdpgrowth<-c(NaN,diff(gdp)/lag(gdp, -1)*100)
head(gdpgrowth)
## [1]       NaN 1.9566831 2.8562487 1.6271792 1.3504779 0.6003248
fedratediff<-c(NaN,diff(fedrate))
head(fedratediff)
## [1]        NaN -0.0400000  0.3566667  0.1566667  0.4400000  0.4166667

11 By using ts() and cbind() functions add “gdpgrowth” and “fedratediff” variables to the “ffrategdpts” data set.

ffrategdpts<-(ts(cbind(gdpgrowth,fedratediff),start=c(1954,3), end=c(2019,2), freq = 4))
head(ffrategdpts)
##      gdpgrowth fedratediff
## [1,]       NaN         NaN
## [2,] 1.9566831  -0.0400000
## [3,] 2.8562487   0.3566667
## [4,] 1.6271792   0.1566667
## [5,] 1.3504779   0.4400000
## [6,] 0.6003248   0.4166667

12 Use na.omit() function to get rid of the missing values in the “ffrategdpts” data set. Save the new data set as “ffrategdptscc”.

ffrategdptscc<-(na.omit(ffrategdpts))
head(ffrategdptscc)
##       gdpgrowth fedratediff
## [1,]  1.9566831  -0.0400000
## [2,]  2.8562487   0.3566667
## [3,]  1.6271792   0.1566667
## [4,]  1.3504779   0.4400000
## [5,]  0.6003248   0.4166667
## [6,] -0.3884057   0.1266667
tail(ffrategdptscc)
##        gdpgrowth  fedratediff
## [254,] 0.6319565  0.243333333
## [255,] 0.8671157  0.290000000
## [256,] 0.7236478  0.186666667
## [257,] 0.2713327  0.296666667
## [258,] 0.7652069  0.183333333
## [259,] 0.5100521 -0.006666667

13 Create 2 new variables: (1) “ggdp” - takes on values of the “gdpgrowth” from the “ffrategdptscc”, (2) “dfrate” - takes on values of the “fedratediff” from the “ffrategdptscc”

ggdp<-ffrategdptscc[, 1]
head(ggdp)
## [1]  1.9566831  2.8562487  1.6271792  1.3504779  0.6003248 -0.3884057
plot(ggdp)

dfrate<-ffrategdptscc[,2]
head(dfrate)
## [1] -0.0400000  0.3566667  0.1566667  0.4400000  0.4166667  0.1266667
plot(dfrate)

14 Use to Augmented Dickey-Fuller test to determine whether “ggdp” and “dfrate” are stationary or not. Does “ggdp” contain a unit root? Is “ggdp” stationary? Does “dfrate” contain a unit root? Is “dfrate” stationary?

adf.test(ggdp)
## Warning in adf.test(ggdp): p-value smaller than printed p-value
## 
##  Augmented Dickey-Fuller Test
## 
## data:  ggdp
## Dickey-Fuller = -6.0671, Lag order = 6, p-value = 0.01
## alternative hypothesis: stationary
adf.test(dfrate)
## Warning in adf.test(dfrate): p-value smaller than printed p-value
## 
##  Augmented Dickey-Fuller Test
## 
## data:  dfrate
## Dickey-Fuller = -7.2109, Lag order = 6, p-value = 0.01
## alternative hypothesis: stationary

The p-value of both tests indicates that both variables contain a unique root: they are non-stationary.

15 Use lm() function to estimate the coefficients of a linear regression model in which “ggdp” is a dependent variable and “dfrate” is as an independent variable. Lable these estimates as “ggdp.dfrate.lm”. Based on the findings of the linear regression model what is the nature of the relationship between the growth rate of real gdp and difference in federal funds rate?

ggdp.dfrate.lm<-lm(ggdp~dfrate)
summary(ggdp.dfrate.lm)
## 
## Call:
## lm(formula = ggdp ~ dfrate)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -2.90290 -0.40464 -0.00131  0.42111  2.93096 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.76121    0.05114   14.88  < 2e-16 ***
## dfrate       0.32673    0.05940    5.50 9.14e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.823 on 257 degrees of freedom
## Multiple R-squared:  0.1053, Adjusted R-squared:  0.1018 
## F-statistic: 30.25 on 1 and 257 DF,  p-value: 9.144e-08

The coefficients indicate that there is a positive relationship between the change in gdp and fed rates. The fed rate is a significant variable when explaining the growth in GDP.

16 Create a variable called “ggdp.dfrate.lm.resid” that represents the residual series obtained from the “ggdp.dfrate.lm” regression

ggdp.dfrate.lm.resid<-ggdp.dfrate.lm$residuals

17 Constract acf and pacf functions for “ggdp.dfrate.lm.resid”. What can you say about the goodness of the fit of the model?

acf(ggdp.dfrate.lm.resid)

pacf(ggdp.dfrate.lm.resid)

The fit of the model is not satisfying as the acf and pacf plots for residuals indicate that there is autocorrelation (3 significant legs for the ACF and 2 for the PACF).

18 Maybe vector autoregression model would prove a better fit. Upload “vars” library that contains VAR() function

library(vars)
## Loading required package: MASS
## Loading required package: strucchange
## Loading required package: zoo
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## Loading required package: sandwich
## Loading required package: urca
## Loading required package: lmtest

19 Estimate a VAR model for the “ggdp” and “dfrate” variables. This model includes 3 lags of each variable. Save the estimates of the var model as “ggdp.dfrate.var”

ggdp.dfrate.var <- VAR(cbind(ggdp, dfrate), p = 3, type = "trend") 
coef(ggdp.dfrate.var) 
## $ggdp
##               Estimate   Std. Error     t value     Pr(>|t|)
## ggdp.l1    0.324346779 0.0638048645  5.08341772 7.288016e-07
## dfrate.l1 -0.020511529 0.0630905367 -0.32511261 7.453688e-01
## ggdp.l2    0.295653241 0.0630572221  4.68864995 4.534155e-06
## dfrate.l2 -0.352935097 0.0637934116 -5.53246939 7.980323e-08
## ggdp.l3    0.093258635 0.0633473231  1.47217957 1.422352e-01
## dfrate.l3  0.006540845 0.0656761751  0.09959235 9.207481e-01
## trend      0.001063776 0.0004282042  2.48427286 1.363989e-02
## 
## $dfrate
##               Estimate   Std. Error    t value     Pr(>|t|)
## ggdp.l1    0.243789828 0.0634633835  3.8414250 1.552692e-04
## dfrate.l1  0.243621515 0.0627528787  3.8822365 1.326314e-04
## ggdp.l2    0.052200154 0.0627197424  0.8322763 4.060505e-01
## dfrate.l2 -0.255109914 0.0634519919 -4.0205186 7.701112e-05
## ggdp.l3   -0.052778955 0.0630082909 -0.8376510 4.030301e-01
## dfrate.l3  0.211064262 0.0653246789  3.2310034 1.399820e-03
## trend     -0.001031574 0.0004259125 -2.4220330 1.614880e-02

20 Use plot() and irf() functions to obtain and plot impulse response functions for each variable. IRF illustrates the behavior of a variable in response to one standard deviation shock in its own value and in the value of the other variable. Based on the these graph what conclusions can you draw about the nature of the relationship between the growth rate of gdp and the difference in federal funds rate? Any potential explanations?

plot(irf(ggdp.dfrate.var, response="ggdp", boot=T, nsteps = 4))

plot(irf(ggdp.dfrate.var, response="dfrate", boot=T, nsteps = 4))

From the graph#3 (OIR from dfrate vs. ggdp), we see that the strongest orthogonal response of ggdp after an impulse of dfrate (the difference in fed interest rate) is the highest at lag 3. A 1% increase of the fed interest rate causes a 30% decrease of the gdp growth rate at lag 3. With a 95% confidence, the gdp growth rate for a 1% increase of fed rate is between approx. -15% and -40%. Interestingly, we see that for the first 2 lags, the increase in interest rates could result in a positive impact on the gdp growth rate but for the majority; the increase will have a negative impact on the gdp growth rate. We also see that the negative impact of the increase of fed. rate reduces rapidly after lag 3.

21 Use resid() function to obtain the residuals from the ggdp equation of the “ggdp.dfrate.var” model. Save this residual series as “var.ggdp.resid”.

var.ggdp.resid<-(resid(ggdp.dfrate.var)[, 1])

22 Use resid() function to obtain the residuals from the dfrate equation of the “ggdp.dfrate.var” model.

Save this residual series as “var.dfrate.resid”.

var.dfrate.resid<-(resid(ggdp.dfrate.var)[, 2])

24 Plot acf and pacf functions for the ’var.ggdp.resid“. Does”ggdp.dfrate.var" model provide a good fit to explain growth rate of gdp?

acf(var.ggdp.resid)

pacf(var.ggdp.resid)

No more autocorrelation visible on the acf/pacf plots: the fit of the model is good.

25 Plot acf and pacf functions for the ’var.dfrate.resid“. Does”ggdp.dfrate.var" model provide a good fit to explain the difference in federal funds rate?

acf(var.dfrate.resid)

pacf(var.dfrate.resid)

There is still some autocorrelation that is not captured by the model. The acf/pacf plots: the fit of the model is not good.

26 Use “ggdp.dfrate.var” model and predict() function to forecast growth rate of gdp and change in federal funds rate over the upcoming year. Save the predicted values as “VAR.pred”

VAR.pred <- predict(ggdp.dfrate.var, n.ahead = 4)
VAR.pred
## $ggdp
##           fcst      lower    upper       CI
## [1,] 0.6309280 -0.9292571 2.191113 1.560185
## [2,] 0.7101314 -0.9288717 2.349134 1.639003
## [3,] 0.7821502 -1.0291380 2.593438 1.811288
## [4,] 0.8437790 -1.0187770 2.706335 1.862556
## 
## $dfrate
##             fcst     lower    upper       CI
## [1,] -0.10401903 -1.655854 1.447816 1.551835
## [2,] -0.11413444 -1.769390 1.541121 1.655255
## [3,] -0.09381149 -1.795873 1.608250 1.702061
## [4,] -0.09254682 -1.796220 1.611126 1.703673

27 Use ts() function and VAR.pred forecast to create a new variable “ggdp.pred”. It should contain the forecasted values of the growth rate of gdp over the next 4 quarters.

ggdp.pred <- ts(VAR.pred$fcst$ggdp[, 1], start = c(2019,3), fr = 4)
ggdp.pred
##           Qtr1      Qtr2      Qtr3      Qtr4
## 2019                     0.6309280 0.7101314
## 2020 0.7821502 0.8437790

28 Use ts() function and VAR.pred forecast to create a new variable “dfrate.pred”. It should contain the prediction of the change in the federal funds rate over the next 4 quarters.

dfrate.pred <- ts(VAR.pred$fcst$dfrate[, 1], start = c(2019,3), fr = 4)
dfrate.pred
##             Qtr1        Qtr2        Qtr3        Qtr4
## 2019                         -0.10401903 -0.11413444
## 2020 -0.09381149 -0.09254682

29 Plot the times series graph of the past growth rates of gdp alongside its future forecasted values. Do you expect the gdp to grow over the next 4 quarters? Is a new recession likely to happen in the coming year?

tail(ggdp)
## [1] 0.6319565 0.8671157 0.7236478 0.2713327 0.7652069 0.5100521
ggdp.pred
##           Qtr1      Qtr2      Qtr3      Qtr4
## 2019                     0.6309280 0.7101314
## 2020 0.7821502 0.8437790
ts.plot(cbind(ggdp, ggdp.pred), lty = 1:2,col=c("navy blue","red"))

The GDP is expected to grow over the next 4 quarters.

30 Plot the times series graph of the past changes of the federal funds rate alongside its future forecasted values. Do you expect the federal funds rate to increase over the next 4 quarters? Should one take out a loan now?

dfrate.pred
##             Qtr1        Qtr2        Qtr3        Qtr4
## 2019                         -0.10401903 -0.11413444
## 2020 -0.09381149 -0.09254682
ts.plot(cbind(dfrate, dfrate.pred), lty = 1:2,col=c("navy blue","red"))

Unsurprisingly, the interest rates from the FED are expected to decrease in the next four quarters. As federal funds rate goes down, the commercial loan interest rates would go down too: this is would be a good time to take a loan as it will be cheaper!