· 6 years ago · Dec 23, 2019, 12:20 AM
1### R script for analyzing the yield curve
2### by <Mathew.Binkley@Vanderbilt.edu>
3
4### Set your FRED API key here. You may request an API key at:
5### https://research.stlouisfed.org/useraccount/apikeys
6api_key_fred <- "WHATEVER_YOUR_FRED_API_KEY_IS"
7
8### Load necessary libraries, installing if necessary
9### installed, they will be installed the first time you run it
10packages <- c("fredr", "forecast", "lubridate", "tidyverse", "tsibble")
11new_packages <- packages[!(packages %in% installed.packages()[, "Package"])]
12if (length(new_packages)) install.packages(new_packages, quiet = TRUE)
13invisible(lapply(packages, "library", quietly = TRUE, character.only = TRUE))
14
15### Now that the "fredr" library is loaded, set the FRED API key
16fredr_set_key(api_key_fred)
17
18### Select the yield curve series to graph.
19### * 10 yr/3 mo [T10Y3M] curve is considered the most accurate
20### * 10 yr/2 y3 [T10Y2Y] curve was used in the original research
21series <- "T10Y3M"
22
23### Pull yield curve data from FRED
24data <- fredr(series_id = series, frequency = "d") %>%
25 select(date, value) %>%
26 na.omit()
27
28### There are 250 trading days per year, so use that for our frequency
29### when constructin the time series
30data_ts <- ts(data$value,
31 frequency = 250,
32 start = c(year(min(data$date)), month(min(data$date))))
33
34### Now break our data down into trend, seasonal, and remainder
35data_decomposed <- mstl(data_ts)
36
37actual <- ts(data$value)
38trend <- trendcycle(data_decomposed)
39seasonal <- seasonal(data_decomposed)
40remainder <- remainder(data_decomposed)
41
42
43################################################################################
44### Graph 1: Yield Curve using raw data
45################################################################################
46plot(data, type = "l", xlab = "year", ylab = "%",
47 main = paste(series, "Yield Curve (Not Seasonally Adjusted)"))
48abline(h = 0) # Draw a line at 0% to highlight the points where it's inverted
49
50readline(prompt = "Press [ENTER] to continue...")
51
52
53################################################################################
54### Graph 2: Decomposed yield curve into trend, seasonal, remainder
55################################################################################
56
57plot(data_decomposed,
58 main = paste(series, "Yield Curve Decomposition"), xlab = "Year")
59
60readline(prompt = "Press [ENTER] to continue...")
61
62
63################################################################################
64### Graph 3: The seasonal component of the yield curve data
65################################################################################
66
67### Find the amplitude over the past 4 years
68subset <- tail(seasonal, n = 4 * 250)
69amplitude <- round(max(subset) - min(subset), digits = 4)
70
71title <- paste(series, " Yield Curve Seasonal Component\n[Amplitude = ",
72 amplitude, "%]", sep = "")
73
74plot(decimal_date(data$date), seasonal, type = "l", lty = 1,
75 main = title, xlab = "Year", ylab = "%",
76 xlim = c(2018.0, 2019.0), ylim = c(-0.15, 0.15))
77
78readline(prompt = "Press [ENTER] to continue...")
79
80################################################################################
81### Graph 4: Deseasonalized yield curve in our region of interest (2019-2020)
82################################################################################
83### Near yield curve inversions, the yield curve value is always near 0%. So
84### the Seasonal component can dominate the data and distort our view as to
85### what's actually going on. So let's remove it and plot trend + remainder
86
87t1 <- "Yield Curve [Original in dotted blue, Deseasonalized in black]\n"
88title <- paste(series, t1)
89
90plot(decimal_date(data$date), trend + remainder, type = "l",
91 main = title, xlab = "Year", ylab = "%",
92 xlim = c(2019.0, 2020.0), ylim = c(-0.5, 0.5))
93
94abline(h = 0, col = "red") # Draw a line at 0% to highlight inversions
95
96lines(decimal_date(data$date), actual, type = "l", col = "blue", lty = 3)
97
98readline(prompt = "Press [ENTER] to continue...")
99
100
101################################################################################
102### Graph 5: 3 month forecast of yield curve based on its history
103################################################################################
104forecast <- data_ts %>%
105 mstl() %>%
106 forecast(h = 63, level = c(68.27, 95.45))
107
108plot(forecast,
109 main = paste(series, "Yield Curve Three Month Forecast"),
110 xlab = "Year", ylab = "Percent",