The FED has a mandate to maximize employment, stabilize prices and moderate long-term interest rates. In other words, the FED seeks to keep the unemployment rate close to the natural unemployment rate, seeks to keep inflation near 2% and will increase its balance sheet (print money) to buy government bonds and keep long term interest rates down when the economy faces bad times. In the process of achieving its objectives the FED causes artificial distortions in the marketplace - triggering or amplifying business cycles.
Now that we gave a brief overview of the business cycle dynamics and its causes, we'll look for signs that are characteristic of the late stages of an expanding economy. The 8 signposts chosen will serve to detect anomalies and will be triggered if the values are deemed to be significantly different from what they should be in "normal" market conditions. The particular parameters that cause the signposts to trigger are chosen based on research conducted by the Federal Reserve, Guggenheim Partners, Bank of America and personal research. A brief explanation is provided for each signpost. Some signposts are single data series and others are the result of multiple data series (see Feature Transformation section).
#Gathering macro economic data from the FED to understand the current state of the economy and the likelihood of encountering a recession within the next 12 months. The more "signposts" that are triggered, the higher the likelihood of a recession.
library(quantmod)
library(PerformanceAnalytics)
library(Hmisc)
start <- as.Date("1950-01-03")
end <- Sys.Date()
#For FRED data, from/to does not work. Only works for Yahoo data.
getSymbols('NFCICREDIT', src = 'FRED')
getSymbols('BAMLC0A4CBBBEY', src = 'FRED')
getSymbols('DGS10', src = 'FRED')
getSymbols('UNRATE', src = 'FRED')
getSymbols('NROU', src = 'FRED')
getSymbols('FEDFUNDS', src = 'FRED')
getSymbols('GDPPOT', src = 'FRED')
getSymbols('T5YIFR', src = 'FRED')
getSymbols('T10Y3M', src = 'FRED')
getSymbols('GDPC1', src = 'FRED')
getSymbols('USSLIND', src = 'FRED')
getSymbols('PRS85006021', src = 'FRED')
getSymbols('TOTBUSSMSA', src = 'FRED')
getSymbols('ACDGNO', src = 'FRED')
getSymbols('HOUST', src = 'FRED')
getSymbols('MSPNHSUS', src = 'FRED')
getSymbols('GPDI', src = 'FRED')
getSymbols('LNU03023706', src = 'FRED')
getSymbols('UMCSENT', src = 'FRED')
getSymbols('DTWEXM', src = 'FRED')
getSymbols('CP', src = 'FRED')
getSymbols('^GSPC', src = 'yahoo', from = start, to = end)
#Create function to merge
multi.xts.merge <- function(listOguys) {
dat <- Reduce(function(x, y) {merge.xts(x, y, join = 'outer')}, listOguys)
names(dat) <- as.character(substitute(listOguys))[-1]
return(dat)
}
#Save merged results
data <- multi.xts.merge(list(NFCICREDIT,BAMLC0A4CBBBEY,DGS10,UNRATE,NROU,FEDFUNDS,GDPPOT,T5YIFR,T10Y3M,GDPC1,USSLIND,PRS85006021,TOTBUSSMSA,ACDGNO,HOUST,MSPNHSUS,GPDI,LNU03023706,UMCSENT,DTWEXM,CP,GSPC$GSPC.Close))
data <- data["19490101/20180303"]
data <- na.locf(data) #Fill NA values with most recent value
na_count <- sapply(data, function(y) sum(length(which(is.na(y))))) #Ensure no NA values are present.
#Feature transformations
#Is the economy operating below or above capacity: Real GDP vs Potential GDP.
data$GDP.Gap <- ((data$GDPC1 - data$GDPPOT)/data$GDPPOT)
#What is the corporate (BBB rated) bond spread from 10yr Treasury Yield.
data$CorpBBB.Spread <- (data$BAMLC0A4CBBBEY - data$DGS10)
#Is the actual unemployment rate above or below the "natural/efficient" rate of unemployment?
data$Unemp.Gap <- (data$UNRATE - data$NROU)
#Are interest rates above or below the equilibrium/natural interest rate? In other words, is the FED Funds rate stimulating or slowing economic activity? To calculate the natural interest rate many assumptions are made and the result is a best guess value.
GDPGAP_Rate <- (data$GDPPOT-lag(data$GDPPOT,k=252))/(lag(data$GDPPOT,k=252)) #GDPGAP_Rate transforms nominal Potential GDP to a growth rate from 1 year ago.
data$Rate.Gap <- (data$FEDFUNDS - data$T5YIFR - GDPGAP_Rate + data$T5YIFR - data$T10Y3M)
#How is the "real" economy performing, what is its proportion to the GDP? Real economy includes durable goods orders, housing expenditures and investment spending.
data$Real.Econ <- (data$ACDGNO*1000000 + data$HOUST*1000*data$MSPNHSUS + data$GPDI*1000000000) / (data$GDPC1*1000000000)
# 1. Check if the rate of unemployment is below the natural level of unemployment. It typically reaches near -1% about 12-16 months ahead of a recession and 6 months before recession it starts to climb back up.
x1 <- ifelse(data$Unemp.Gap < -0.85, 1, 0)
# 2. Check if the [artificial] interest rate set by FED is above the natural interest rate. Approx 12 Mo. before recession it crosses above 0%.
x2 <- ifelse(data$Rate.Gap > 0, 1, 0)
(reference: http://www.frbsf.org/economic-research/economists/LW_replication.zip)
# 3. Check if the GDP is in excess of Potential GDP. Before recession it goes above 0 and then starts falling. https://fred.stlouisfed.org/graph/?g=f1cZ
x3 <- ifelse(data$GDP.Gap > 0, 1, 0)
# 4. Check if yield curve flattens. T-bill yields rise faster than 10-year yields. (10 Yr Treasury - 3 Mo Yield). About 12 months before recession it falls below 1% and is usually within 0.5% of the flat curve.
x4 <- ifelse(data$T10Y3M < 1, 1, 0)
# 5. Check if Leading index falls below 1%
x5 <- ifelse(data$USSLIND < 1, 1, 0)
# 6. Check if hours worked growth (% annual change) falls below 0.5%
x6 <- ifelse(data$PRS85006021 < -0.5, 1, 0)
# 7. Check if the "real economy" increases as a proportion of GDP. The higher the proportion the higher the risk.
quantile(data$Real.Econ, na.rm = TRUE) # Check what the 75% quantile is and use that for trigger
x7 <- ifelse(data$Real.Econ > 0.2, 1, 0)
# 8. Check if consumer sentiment is above 90.
x8 <- ifelse(data$UMCSENT > 90, 1, 0)
signposts <- multi.xts.merge(list(x1,x2,x3,x4,x5,x6,x7,x8))
> tail(signposts)
x1 x2 x3 x4 x5 x6 x7 x8
2018-02-23 0 1 1 0 0 0 1 1
2018-02-26 0 1 1 0 0 0 1 1
2018-02-27 0 1 1 0 0 0 1 1
2018-02-28 0 1 1 0 0 0 1 1
2018-03-01 0 1 1 0 0 0 1 1
2018-03-02 0 1 1 0 0 0 1 1
Conclusion: 4 of 8 signposts are currently triggered. Recession is likely at least 1 year away from today.
In addition to the above mentioned signposts the following data sources are also worthy of consideration for predicting recessions:
No comments:
Post a Comment