We are going to look at weekly stock price data of Altaba Inc.from 2005 to 2018. The data is freely available here.
General speaking, there are several goals in this project:
Check if it is possible to fit a stationary model (e.g.ARMA) and get appropriate number of parameters.
Fit appropriate model (e.g.GARCH) to volatility of the returns as benchmark, which may be useful for forecasting.
In order to understand how financial markets work, we need to model financial leaverage by implementing POMP model. Here, we fit the time-varying leverage model.
Let us plot the weekly closing price of Altaba Inc.from 2015 to 2018. In order to get a demeaned stationary data, we use log return of the index and remove the mean.
MA0 | MA1 | MA2 | MA3 | MA4 | MA5 | |
---|---|---|---|---|---|---|
AR0 | -2157.46 | -2158.02 | -2162.68 | -2161.32 | -2159.34 | -2159.40 |
AR1 | -2157.50 | -2158.83 | -2161.36 | -2159.38 | -2157.38 | -2157.52 |
AR2 | -2162.89 | -2160.95 | -2159.37 | -2157.37 | -2156.11 | -2160.60 |
AR3 | -2160.92 | -2158.92 | -2157.42 | -2163.79 | -2164.29 | -2163.75 |
AR4 | -2159.14 | -2157.74 | -2155.40 | -2165.78 | -2162.97 | -2161.80 |
AR5 | -2160.15 | -2158.44 | -2163.43 | -2162.33 | -2160.32 | -2161.17 |
return_arma43 <- arima(demeaned_returns,order=c(4,0,3))
acf(residuals(return_arma43))
##
## Call:
## arima(x = demeaned_returns, order = c(4, 0, 3))
##
## Coefficients:
## ar1 ar2 ar3 ar4 ma1 ma2 ma3
## 0.1717 -0.7154 -0.4648 -0.1109 -0.2371 0.6398 0.4757
## s.e. 0.3016 0.2181 0.3013 0.0389 0.3023 0.2205 0.3047
## intercept
## 0.0000
## s.e. 0.0016
##
## sigma^2 estimated as 0.002344: log likelihood = 1091.89, aic = -2165.78
## [1] 1.00165 1.00165 2.99818 2.99818
## [1] 1.047350 1.416714 1.416714
The ARCH and GARCH models have become widely used for financial time series modeling. We are going to fit a GARCH model. We know that the GARCH(1,1) model is a popular choice, and is appropriate for most of cases.
Before we fit a GARCH(1,1) model to the demeaned returns, we can use ljung box to check the autocorrelations of a time series and McLeod-Li test to examine that if GARCH model is suitable for this data. The null hypothesis of McLeod-Li test is no arch effect in the data.
require(tseries)
fit.garch <- garch(demeaned_returns,grad = "numerical", trace = FALSE)
summary(fit.garch)
##
## Call:
## garch(x = demeaned_returns, grad = "numerical", trace = FALSE)
##
## Model:
## GARCH(1,1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -4.7388162 -0.5064102 0.0009373 0.5582291 4.0863591
##
## Coefficient(s):
## Estimate Std. Error t value Pr(>|t|)
## a0 7.570e-05 2.918e-05 2.594 0.00949 **
## a1 9.783e-02 1.704e-02 5.741 9.39e-09 ***
## b1 8.758e-01 2.271e-02 38.570 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Diagnostic Tests:
## Jarque Bera Test
##
## data: Residuals
## X-squared = 111.37, df = 2, p-value < 2.2e-16
##
##
## Box-Ljung test
##
## data: Squared.Residuals
## X-squared = 0.37536, df = 1, p-value = 0.5401
L.garch <- logLik(fit.garch)
L.garch
## 'log Lik.' 1120.236 (df=3)
Since the parameters of GARCH model are not explanatory. We are going to implement POMP model using stochastic equation to represent leverage. We used the data that were downloaded, detrended and analyzed by Bretó (2014). The notation of model is given below.
\(R_n=\frac{exp{(2G_n)}-1}{exp{(2G_n)}+1}\),
\(Y_n=exp{(H_n/2)}\epsilon_n\),
\(H_n=\mu_h(1-\phi)+\phi H_{n-1}+\beta_{n-1}R_n exp{(-H_{n-1}/2)} +\omega_n\),
\(G_n = G_{n-1} + \upsilon_n\),
where \(\beta_n = Y_n\sigma_\eta\sqrt{1-\phi^2}\),{\(\epsilon_n\)} is an iid \(N(0,1)\) sequence, { \(\upsilon_n\)} is an iid \(N(0,\sigma_\upsilon^2)\) sequence, and {\(\omega_n\)} is an iid \(N(0,\sigma_\omega^2)\) sequence.
Here, \(H_n\) is the log volatility, \(R_n\) is leverage defined as the correlation between index return on day n-1 and the increase in the log volatility from day n-1 to day n.
First, we need to build a pomp model based on notation from Bretó (2014). And then we set some parameter values to simulate from the model for testing the code and investigating the fitted model.
expit<-function(real){1/(1+exp(-real))}
logit<-function(p.arg){log(p.arg/(1-p.arg))}
params_test <- c(
sigma_nu = exp(-4.5),
mu_h = -0.25,
phi = expit(4),
sigma_eta = exp(-0.07),
G_0 = 0,
H_0=0
)
sim1.sim <- pomp(AABA.filt,
statenames=AABA_statenames,
paramnames=AABA_paramnames,
covarnames=AABA_covarnames,
rprocess=discrete.time.sim(step.fun=Csnippet(AABA_rproc.sim),delta.t=1)
)
sim1.sim <- simulate(sim1.sim,seed=10001,params=params_test)
sim1.filt <- pomp(sim1.sim,
covar=data.frame(
covaryt=c(obs(sim1.sim),NA),
time=c(timezero(sim1.sim),time(sim1.sim))),
tcovar="time",
statenames=AABA_statenames,
paramnames=AABA_paramnames,
covarnames=AABA_covarnames,
rprocess=discrete.time.sim(step.fun=Csnippet(AABA_rproc.filt),delta.t=1)
)
plot (sim1.filt,main="simulated filtering object")
Let’s carry out a local search using the IF2 algorithm of Ionides et al.(2015), implemented by mif2. For that, we need to set the rw.sd and cooling.fraction.50 algorithmic parameters:
params_test <- c(
sigma_nu = exp(-4.5),
mu_h = -0.25,
phi = expit(4),
sigma_eta = exp(-0.07),
G_0 = 0,
H_0=0
)
run_level <- 4
AABA_Np <- c(100,1e3,2e3,1e4)
AABA_Nmif <- c(10, 100,200,300)
AABA_Nreps_eval <- c(4, 10, 20,20)
AABA_Nreps_local <- c(10, 20, 20,20)
AABA_Nreps_global <-c(10, 20, 100,100)
AABA_rw.sd_rp <- 0.02
AABA_rw.sd_ivp <- 0.1
AABA_cooling.fraction.50 <- 0.5
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1124 1133 1141 1137 1142 1144
For better estimating parameters, we need to try different start values of parameters. We could set a value box in reasonable parameter space and then randomly choose initial values from this box. Also, we will plot the global geometry of the likelihood surface around diverse parameter estimates.
AABA_box <- rbind(
sigma_nu=c(0.001,0.03),
mu_h =c(-8,-1),
phi = c(0.6,0.99),
sigma_eta = c(0.001,1),
H_0 = c(-1,1),
G_0 = c(-2,-2)
)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1107 1139 1140 1138 1141 1144
plot(if.box[r.global_test$logLik>max(r.global_test$logLik)-10])
run_level <- 4
AABA_Np <- c(100,1e3,2e3,5e3)
AABA_Nmif <- c(10, 100,200,280)
AABA_Nreps_eval <- c(4, 10, 20, 20)
AABA_Nreps_local <- c(10, 20, 20, 20)
AABA_Nreps_global <-c(10, 20, 100, 100)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1081 1127 1139 1133 1140 1142
plot(if.box[r.global_test2$logLik>max(r.global_test2$logLik)-10])
Previous analysis does not clearly show the hypothesis that \(\sigma_\nu>0\). We can compute a likelihood profile of \(\sigma_\nu\) to make a inference. Firstly, we just zoom in on the scatter plot of \(\sigma_\nu\) in global search result:
plot(logLik~sigma_nu,data=subset(r.global_test,logLik>max(r.global_test$logLik)-10),log="x")
## lower upper
## 0.0000100 0.0862152
1.Ionides, E. (n.d.).Stats 531 (Winter 2018) ‘Analysis of Time Series’
2.Bretó, C. 2014. On idiosyncratic stochasticity of financial leverage effects. Statistics & Probability Letters 91:20–26.
3.W.Wang. 2005. Testing and modelling autoregressive conditional heteroskedasticity of streamflow processes. Nonlinear Processes in Geophysics (2005) 12: 55–66.