Skip to contents
library(fChange)
#> 
#> Attaching package: 'fChange'
#> The following objects are masked from 'package:stats':
#> 
#>     acf, pacf, qqplot, sd, var

Overview

In this article, we examine several applications for fChange.

Electricity

This section examines the hourly Spanish electricity spot price from 2014. This data is loaded into ${\tt fChange}$, and can be retrieved by calling electricity. The goal is to detect any changes in the data.

This data may be viewed using the following:

plot(electricity,
  val_axis_title = "", res_axis_title = "", FD_axis_title = "",
  plot_title = ""
)

This data seems to exhibit some trends over time (perhaps due to season). We wish to model these trends first, and then search the data for any remaining changes. We’ll use principal component analysis to convert the functional data to finite dimensions, fit a model, and return the model to functional data. In , the functions , , , and are functions that can be used to project the data, e.g.

epca <- pca_examination(X = electricity, TVE = 0.99)
set.seed(654321)
res1 <- fchange(
  X = epca$residuals,
  statistic = "Tn",
  critical = "simulation", method = "characteristic",
  type = "segmentation"
)

The previous approach is similar to the following, except without smoothing incorporated. We show the details more precisely below where binary segmentation is used to investigate the residuals.

set.seed(123456)
elec_mod <- projection_model(electricity, TVE = 0.95, forecast.model = "ets", check.cp = TRUE)

plot(elec_mod$errors, changes = elec_mod$changes)

S&P 500

This section is focused on an application in finance, specifically the S&P500 index. includes this data as , which is pre-loaded. The aim is to detect changes in the stock prices.

The data is collected at minutely resolution. We convert it into the overnight cumulative intraday returns below, and plot it.

compute_ocidr <- function(dat) {
  dat_cidr <- dat
  dat_cidr[, 1] <- 100 * (log(dat[, 1]) - log(dat[1, 1]))
  # Obs
  for (j in 2:ncol(dat_cidr)) {
    dat_cidr[, j] <- 100 *
      (log(dat[, j]) - log(dat[nrow(dat_cidr), j - 1]))
  }

  dat_cidr
}

SPYUS_ocidr <- compute_ocidr(SPYUS500)

plot_ocidr <- plot(dfts(SPYUS_ocidr),
  val_axis_title = "", res_axis_title = "", FD_axis_title = "",
  plot_title = ""
)

The changes can be detected using binary segmentation as follows.

set.seed(25641)
spy_min_changes <- fchange(dfts(SPYUS_ocidr),
  type = "segmentation",
  statistic = "Tn",
  critical = "simulation",
  method = "characteristic"
)
plot_ocidr <- plot(dfts(SPYUS_ocidr),
  changes = spy_min_changes[[1]],
  val_axis_title = "", res_axis_title = "", FD_axis_title = "",
  plot_title = "", type = "fast"
)