# Replication file for RDP 2021-04

### Monetary Policy Surprises

    library(lubridate)
    library(tidyverse)
    purrr::walk(list.files(here::here("R"), full.names = T), source)

This file will show how the monetary policy surprises were constructed using a synthetic data series.

The output from using the actual data can be found in ./data/mp-surprises/mp-surprises.csv and ./data/mp-surprises/mp-surprises_all.csv

# 1 Import (fake) OIS data

First import all (fake) OIS data. This contains OIS data for all available time points.

    ois_all <- readr::read_csv(here::here("data", "fake-data", "ois-all.csv"))
    ois_all

    ## # A tibble: 475,314 x 13
    ##    date_time           ois_9m ois_2m ois_3m ois_1y ois_5m ois_1m ois_6m ois_4m
    ##    <dttm>               <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
    ##  1 2001-03-19 10:30:00   4.38  9.65   0.759  6.96   5.48    7.69   6.47 8.70
    ##  2 2001-03-19 11:00:00   5.94  7.46   8.18   1.32   7.11    1.10   7.73 7.24
    ##  3 2001-03-19 11:30:00   1.48  8.72   3.39   3.11   9.42    2.70   9.15 6.57
    ##  4 2001-03-19 12:00:00   1.86  5.37   8.01   5.32   0.841   5.28   7.18 0.0108
    ##  5 2001-03-19 12:30:00   7.95  8.02   1.91   6.21   6.00    1.56   8.85 0.134
    ##  6 2001-03-19 13:00:00   8.55  2.01   9.09   0.157  5.04    6.69   3.47 1.72
    ##  7 2001-03-19 13:30:00   4.45  0.116  3.46   0.534  1.20    4.19   9.86 2.91
    ##  8 2001-03-19 14:00:00   7.37  3.23   7.72   3.92   0.494   2.62   6.30 7.43
    ##  9 2001-03-19 14:30:00   3.39  2.21   0.839  4.94   1.23    3.20   1.73 9.24
    ## 10 2001-03-19 15:00:00   1.39  9.12   7.36   4.32   6.25    7.12   2.12 1.89
    ## # ... with 475,304 more rows, and 4 more variables: ois_1w <dbl>, ois_2y <dbl>,
    ## #   ois_3y <dbl>, ois_18m <dbl>

From this object we need to extract the data around monetary policy events/announcements. To do this we must first import a series of monetary policy events/announcements.

    mp_dates <- readr::read_csv(here::here("data", "mp-surprises", "mp-dates.csv" ))

    mp_board_dates <- mp_dates %>% filter(type == "board_meeting")
    mp_board_dates

    ## # A tibble: 222 x 2
    ##    date_time           type
    ##    <dttm>              <chr>
    ##  1 2001-04-04 09:30:00 board_meeting
    ##  2 2001-05-02 09:30:00 board_meeting
    ##  3 2001-06-06 09:30:00 board_meeting
    ##  4 2001-07-04 09:30:00 board_meeting
    ##  5 2001-08-08 09:30:00 board_meeting
    ##  6 2001-09-05 09:30:00 board_meeting
    ##  7 2001-10-03 09:30:00 board_meeting
    ##  8 2001-11-07 09:30:00 board_meeting
    ##  9 2001-12-05 09:30:00 board_meeting
    ## 10 2002-02-06 09:30:00 board_meeting
    ## # ... with 212 more rows

# 2 Extract relevant data

Using the user defined function `data_window_extract` I feed through the `ois_all` object and ask it to extract the data around the `mp_board_dates$date_time`. The window is given through the arguments `pre` (minutes before), `post` (minutes after) and `open_window` (minutes after open if the monetary policy event falls between close and open)

    ois_mp <- data_window_extract(ois_all, mp_board_dates$date_time, pre = 30, post = 90, open_window = 60)

    ois_mp

    ## # A tibble: 424 x 15
    ##    date_time           name  value               ois_9m ois_2m ois_3m ois_1y
    ##    <dttm>              <chr> <dttm>               <dbl>  <dbl>  <dbl>  <dbl>
    ##  1 2001-04-04 09:30:00 pre   2001-04-04 09:00:00  0.836   9.43   9.03  8.17
    ##  2 2001-04-04 09:30:00 post  2001-04-04 11:00:00  5.33    6.59   6.49  7.98
    ##  3 2001-05-02 09:30:00 pre   2001-05-02 09:00:00  3.68    9.69   3.72  8.34
    ##  4 2001-05-02 09:30:00 post  2001-05-02 11:00:00  3.05    3.35   6.00  0.452
    ##  5 2001-06-06 09:30:00 pre   2001-06-06 09:00:00  0.688   4.88   4.80  8.13
    ##  6 2001-06-06 09:30:00 post  2001-06-06 11:00:00  5.45    3.86   7.39  9.49
    ##  7 2001-07-04 09:30:00 pre   2001-07-04 09:00:00  8.51    8.79   5.08  1.42
    ##  8 2001-07-04 09:30:00 post  2001-07-04 11:00:00  4.05    7.37   1.38  0.187
    ##  9 2001-08-08 09:30:00 pre   2001-08-08 09:00:00  3.32    9.71   1.51  7.11
    ## 10 2001-08-08 09:30:00 post  2001-08-08 11:00:00  5.43    7.49   1.00  0.449
    ## # ... with 414 more rows, and 8 more variables: ois_5m <dbl>, ois_1m <dbl>,
    ## #   ois_6m <dbl>, ois_4m <dbl>, ois_1w <dbl>, ois_2y <dbl>, ois_3y <dbl>,
    ## #   ois_18m <dbl>

# 3 Transform data

Now we have the necessary data to create the measure of monetary policy surprises. First, for each tenor, I’ll calculate the change in the OIS contract around a monetary policy announcement.

    ois_surprise <- ois_mp %>%
        select(-value) %>% # remove `value` column which contains actual date-time of extracted data point
        pivot_longer( starts_with("ois") ,  names_to = "tenor") %>%
        pivot_wider( names_from = name, values_from = value) %>%
        mutate(mp_change = post - pre) %>%  # calculate change in OIS around monetary policy announcement
        select(-pre, - post) %>%
        pivot_wider(names_from = tenor, values_from = mp_change)
    ois_surprise

    ## # A tibble: 212 x 13
    ##    date_time            ois_9m ois_2m ois_3m ois_1y ois_5m ois_1m ois_6m ois_4m
    ##    <dttm>                <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
    ##  1 2001-04-04 09:30:00  4.49   -2.84  -2.54  -0.189  3.38  -6.28   3.77   -9.39
    ##  2 2001-05-02 09:30:00 -0.632  -6.35   2.29  -7.89  -2.62   0.766  8.47    8.18
    ##  3 2001-06-06 09:30:00  4.77   -1.02   2.59   1.36   0.578  1.82  -1.49    2.80
    ##  4 2001-07-04 09:30:00 -4.46   -1.43  -3.69  -1.23  -1.28   1.71   0.394   9.03
    ##  5 2001-08-08 09:30:00  2.11   -2.21  -0.510 -6.67  -0.452 -0.284 -2.74   -3.98
    ##  6 2001-09-05 09:30:00 -0.460   0.132 -5.47  -1.27  -3.62  -1.68   1.10    6.32
    ##  7 2001-10-03 09:30:00 -3.28   -7.55   2.19   7.65  -0.340  6.33  -4.68    1.53
    ##  8 2001-11-07 09:30:00 -0.0488  4.59  -4.36  -1.74  -2.35  -0.262  1.00   -7.92
    ##  9 2001-12-05 09:30:00 -1.61   -9.09  -0.213 -6.74  -3.96   4.94  -1.78    2.00
    ## 10 2002-02-06 09:30:00  2.28    8.10   1.28  -1.64  -1.61  -5.89   8.05   -2.09
    ## # ... with 202 more rows, and 4 more variables: ois_1w <dbl>, ois_2y <dbl>,
    ## #   ois_3y <dbl>, ois_18m <dbl>

# 4 Create monetary policy surprises

To create the measure of monetary policy surprises first take the `ois_surprise` data and perform the principal component analysis.

    pca_data <- ois_surprise %>%
      select(-ois_1w, -ois_18m, -ois_2y, -ois_3y) # remove tenors not used in the analysis.

    pca_data <- pca_data[ rowSums(is.na(pca_data)) == 0 , ] # remove row if it contains an NA

    pca <- prcomp(pca_data %>% select(-date_time), center = T, scale. = T ) # perform pca

    pca_surprise <-  bind_cols( decision_date_time = pca_data$date_time,
                                decision_date = lubridate::date(pca_data$date_time),
                                as_tibble(pca$x)  ) # put in nice dataframe

As the factors from PCA are scaleless, I scale the PCA surprises to the change in the 1-month OIS. This allows the surprises to be interpreted as a 100 basis point change in the 1-month OIS.

    mp_surprises_all <- left_join(pca_surprise, ois_surprise, by = c("decision_date_time" = "date_time" )) %>%
                         mp_surprise_scale(., pc = "PC1", scale = "ois_1m") %>%  # scale PC1 by ois_1m
                          relocate(decision_date_time, decision_date, pc1_scaled)
    mp_surprises_all

    ## # A tibble: 212 x 23
    ##    decision_date_time  decision_date pc1_scaled    PC1    PC2     PC3     PC4
    ##    <dttm>              <date>             <dbl>  <dbl>  <dbl>   <dbl>   <dbl>
    ##  1 2001-04-04 09:30:00 2001-04-04        -1.05  -1.60   1.41  -1.62    1.14
    ##  2 2001-05-02 09:30:00 2001-05-02        -1.06  -1.62  -2.20   0.400  -1.96
    ##  3 2001-06-06 09:30:00 2001-06-06         0.183  0.279  0.233  0.713  -0.502
    ##  4 2001-07-04 09:30:00 2001-07-04         0.752  1.14  -1.94   0.0117 -0.759
    ##  5 2001-08-08 09:30:00 2001-08-08        -0.438 -0.667 -0.584 -0.207   0.148
    ##  6 2001-09-05 09:30:00 2001-09-05         0.176  0.267 -1.42  -0.952  -0.453
    ##  7 2001-10-03 09:30:00 2001-10-03         0.904  1.38  -0.595  2.44    1.52
    ##  8 2001-11-07 09:30:00 2001-11-07        -0.422 -0.642  0.706 -0.715   0.530
    ##  9 2001-12-05 09:30:00 2001-12-05        -0.388 -0.590 -2.67   1.32    0.0605
    ## 10 2002-02-06 09:30:00 2002-02-06        -0.975 -1.48   1.65  -1.37   -1.16
    ## # ... with 202 more rows, and 16 more variables: PC5 <dbl>, PC6 <dbl>,
    ## #   PC7 <dbl>, PC8 <dbl>, ois_9m <dbl>, ois_2m <dbl>, ois_3m <dbl>,
    ## #   ois_1y <dbl>, ois_5m <dbl>, ois_1m <dbl>, ois_6m <dbl>, ois_4m <dbl>,
    ## #   ois_1w <dbl>, ois_2y <dbl>, ois_3y <dbl>, ois_18m <dbl>

You can plot the synthetic monetary policy surprises as in Figure 2 in the RDP as follows:

    p <- ggplot(mp_surprises_all, aes(x = decision_date, y = pc1_scaled)) +
      geom_col() +
      rba_theme() +
      rba_syc() +
      ylab("%") +
      rba_ylim(-3, 3) +
      labs(title = "Figure 2: Monetary Policy Surprises", subtitle = "Factor 1, scaled to one-month OIS",
           caption = "Sources: RBA")  +
      rba_panel_text_size(title = 2, subtitle = 1.2) +
      scale_fill_rba()

    rba_xticks_date(p) # add more x-ticks

# 5 All monetary policy events

The same process can be done for to create the monetary policy surprises using all monetary policy communication dates. Simply expand the object `mp_board_dates` to include other dates outside the monetary policy announcement.

# 6 Equity and earnings changes around monetary policy events

The construction of the files in ./data/equities/ and ./data/earnings/ are constructed in a similar manner to how the object `ois_mp` is constructed. I will therefore not replicate this process.

# 7 Session Information

    sessionInfo()

    ## R version 4.0.3 (2020-10-10)
    ## Platform: x86_64-w64-mingw32/x64 (64-bit)
    ## Running under: Windows 10 x64 (build 14393)
    ##
    ## Matrix products: default
    ##
    ## locale:
    ## [1] LC_COLLATE=English_Australia.1252  LC_CTYPE=English_Australia.1252
    ## [3] LC_MONETARY=English_Australia.1252 LC_NUMERIC=C
    ## [5] LC_TIME=English_Australia.1252
    ##
    ## attached base packages:
    ## [1] stats     graphics  grDevices utils     datasets  methods   base
    ##
    ## other attached packages:
    ##  [1] forcats_0.5.1    stringr_1.4.0    dplyr_1.0.5      purrr_0.3.4
    ##  [5] readr_1.4.0      tidyr_1.1.3      tibble_3.1.0     ggplot2_3.3.3
    ##  [9] tidyverse_1.3.0  lubridate_1.7.10
    ##
    ## loaded via a namespace (and not attached):
    ##  [1] tidyselect_1.1.0  xfun_0.20         bslib_0.2.4       haven_2.3.1
    ##  [5] colorspace_2.0-0  vctrs_0.3.7       generics_0.1.0    htmltools_0.5.1.1
    ##  [9] yaml_2.2.1        utf8_1.2.1        rlang_0.4.10      jquerylib_0.1.3
    ## [13] pillar_1.5.1      withr_2.4.1       glue_1.4.2        DBI_1.1.1
    ## [17] dbplyr_2.1.0      modelr_0.1.8      readxl_1.3.1      lifecycle_1.0.0
    ## [21] munsell_0.5.0     gtable_0.3.0      cellranger_1.1.0  rvest_1.0.0
    ## [25] evaluate_0.14     labeling_0.4.2    knitr_1.31        fansi_0.4.2
    ## [29] highr_0.8         broom_0.7.5       Rcpp_1.0.6        backports_1.2.1
    ## [33] scales_1.1.1      jsonlite_1.7.2    farver_2.1.0      fs_1.5.0
    ## [37] hms_1.0.0         digest_0.6.27     stringi_1.5.3     rprojroot_2.0.2
    ## [41] grid_4.0.3        here_1.0.1        cli_2.4.0         tools_4.0.3
    ## [45] magrittr_2.0.1    sass_0.3.1        crayon_1.4.1      pkgconfig_2.0.3
    ## [49] ellipsis_0.3.1    xml2_1.3.2        reprex_1.0.0      rstudioapi_0.13
    ## [53] assertthat_0.2.1  rmarkdown_2.7     httr_1.4.2        R6_2.5.0
    ## [57] compiler_4.0.3