Advertisement
binkleym

Analyzing the yield curve for seasonality

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