1
$\begingroup$

I'm trying to detect the breakpoints in Facebook's stock price with strucchange::breakpoints.

library(quantmod)
library(ggplot2)
library(strucchange)
FB <- getSymbols("FB", auto.assign = FALSE)
Y <- FB$FB.Adjusted
bp <- index(Y)[breakpoints(Y ~ 1)$breakpoints]
ggplot(data = Y, aes(x = index(Y), y = Y)) +
  geom_line(color="#3078EA") +
  stat_smooth(color = "#3F5A93", method = "loess") +
  ylab("Facebook's adjusted close price") + xlab("Time") +
  geom_vline(xintercept=bp, linetype=2)

The result is

enter image description here

Major breakpoints such as 2018-03-17 and 2018-07-25 are undetected. Instead, I got four seemingly insignificant breakpoints: 2013-08-22, 2014-09-15, 2015-10-22, and 2017-04-21.

How do I locate the shocks? As a side note, this is for my Bayesian final project, so if you have alternative Bayesian methods for detecting structural breaks in your mind, feel free to share them with me.

$\endgroup$

2 Answers 2

4
$\begingroup$

The first reason for this is due to the default parameter that gives the minimal segment size (a segment is the gap between two breakpoints)

h: minimal segment size either given as fraction relative to the sample size or as an integer giving the minimal number of observations in each segment.

By default h is set to be $0.15$. Since you have $1{,}784$ data points and $15\%$ of this is $267.6$, the breakpoints function will only detect a change if the effect of it is still noticeable $268$ days later. The two breakpoints you mentioned in your question don't satisfy this criterion so they will not be reported. The minimum h value that you can use is $2$ because there must be at least $2$ data points in a segment to fit the linear model.

If I run the following code: (this will take some time to run!)

bp <- index(Y)[breakpoints(Y ~ 1, h = 2, breaks = 35)$breakpoints]

[Here the breaks parameter gives the maximum number of breaks to look for - if you don't set a maximum it will set it to the maximum possible and the code will take an extremely long time to run. I've capped it at $35$ just because it was taking a long time but if you set it higher it will uncover more breakpoints]

I get the following output:

bp

[1] "2012-07-26" "2012-11-20" "2013-07-24" "2013-09-05" "2013-12-12"

[6] "2014-01-30" "2014-03-25" "2014-05-23" "2014-07-22" "2015-02-18"

[11] "2015-06-22" "2015-10-21" "2016-02-24" "2016-04-27" "2016-07-26"

[16] "2016-11-02" "2017-01-10" "2017-02-21" "2017-04-24" "2017-07-17"

[21] "2017-10-26" "2018-03-19" "2018-04-25" "2018-05-30" "2018-07-05"

[26] "2018-07-25" "2018-09-04" "2018-10-09" "2018-11-09" "2019-01-07"

[31] "2019-01-30" "2019-04-01" "2019-04-22" "2019-05-30" "2019-06-13"

So it can detect the changes that you mentioned as well as many others. The plot for these breakpoints is below. many breakpoints

The second reason is that the model you are using with

breakpoints(Y ~ 1)

chooses a set of breakpoints $(\tau_1, \tau_2, \dots, \tau_k)$ assuming that the data are generated according to the following model: $$Y_t = \begin{cases} \mu_1 + \epsilon_t & \text{if } 0 < t \leq \tau_1,\\ \mu_2 + \epsilon_t & \text{if } \tau_1 < t \leq \tau_2,\\ \dots & \dots \\ \mu_{k + 1} + \epsilon_t & \text{if } \tau_k < t \leq n. \end{cases}$$ So the underlying mean of the process should be a step function. Based on the curve that you can fit to the data I'm not sure this is a good model for all of your data - something like a linear model with auto-correlated errors may be a more appropriate model.

The breakpoints method chooses the number and positions of breakpoints that minimise the Bayesian Information Criterion (BIC). If you want a more Bayesian choice of both the number of breakpoints and their positions then you would need to specify a prior distribution on both of these. One way to do the sampling would be using reversible jump MCMC as pioneered in Peter Green's 1995 paper, Reversible jump Markov chain Monte Carlo computation and Bayesian model determination , but this might be too much work for your project. If the number of breakpoints is known then Gibbs sampling can be used to estimate the distribution of the breakpoints, as in Carlin, B. P., A. E. Gelfand, and A. F. M. Smith (1992). Hierarchical Bayesian analysis of changepoint problems. Journal of the Royal Statistical Society, Series C (Applied Statistics) 41(2), 389–405.

$\endgroup$
4
  • $\begingroup$ Thanks for the detailed answer! Do you think detrending the data first (with linear regression or differencing), and then applying strucchange::breakpoints would be a good idea? The Bayesian methods you mentioned are a little too complicated, since breakpoint detection is just the very first step of my project, but I'll take a closer look at them later. $\endgroup$
    – nalzok
    Commented Jun 22, 2019 at 10:29
  • 2
    $\begingroup$ It depends on what you want to detect - if you're just looking to detect shocks then you could work with log-returns, which is a common technique in finance. Apply $y_t \rightarrow \log(y_t)$ to each data point, and then look at $\Delta y_t = y_t - y_{t-1}$. In this case, the series $\Delta y_t$ will be roughly normally distributed with some notable outliers that correspond to shocks. $\endgroup$
    – Alex
    Commented Jun 22, 2019 at 13:00
  • $\begingroup$ One more question: do you think it's necessary to apply a log transformation to the data before doing any further analysis (like forecasting)? It seems that this is a convention when working with financial data, but Facebook's stock price looks really, really linear. $\endgroup$
    – nalzok
    Commented Jun 22, 2019 at 13:04
  • 2
    $\begingroup$ I agree that it doesn't make sense to have a universal rule that you must log-transform the data before you do anything else. In this data set there is a clear trend if you don't log-transform the data so feel free to leave it as it is. $\endgroup$
    – Alex
    Commented Jun 22, 2019 at 13:58
2
$\begingroup$

I don't think of breakpoints as being a natural way to analyze this, but rather would fit a flexible nonlinear function and get Bayesian credible interval bands to represent uncertainty in the function estimate. For example, you could use a regression spline with lots of knots. If you think of a structural change as a change in the first derivative of this function, you could easily differentiate the fit and show a credible interval for the first derivative. Likewise for the second derivative (acceleration) and third derivative (jolt).

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.