Preamble

library("forecast")

Hedge Fund Index

CISDM Equal Weighted Hedge Fund Index NAV, Monthly, 1990 - Present

# Remove earlier time points
data <- read.csv("http://ptrckprry.com/course/forecasting/data/hedge.csv")
data$date <- as.Date(data$date)
data <- subset(data, date >= "1990-01-01")

# Extract returns
hedge <- data$return
n <- length(hedge)
time <- 1:n
plot(time, hedge, type="l", col=2)

ACF, PACF

Original Series

par(mfrow=c(1,2))
Acf(hedge)
Pacf(hedge)

First Difference

par(mfrow=c(1,2))
Acf(diff(hedge))
Pacf(diff(hedge))

AICC

d <- 0
for (p in 0:2) {
    for (q in 0:2) {
        fit <- Arima(hedge, c(p, d, q), include.constant=TRUE)
        cat("ARIMA(", p, ",", d, ",", q, ") : ", fit$aicc, "\n", sep="")
    }
}
ARIMA(0,0,0) : 1373.814
ARIMA(0,0,1) : 1350.627
ARIMA(0,0,2) : 1347.826
ARIMA(1,0,0) : 1345.869
ARIMA(1,0,1) : 1346.968
ARIMA(1,0,2) : 1349.031
ARIMA(2,0,0) : 1346.976
ARIMA(2,0,1) : 1349.035
ARIMA(2,0,2) : 1351.105

Estimation

(fit <- Arima(hedge, c(1, 0, 0), include.constant=TRUE))
Series: hedge 
ARIMA(1,0,0) with non-zero mean 

Coefficients:
         ar1    mean
      0.2975  0.8830
s.e.  0.0530  0.1511

sigma^2 estimated as 3.681:  log likelihood=-669.9
AIC=1345.79   AICc=1345.87   BIC=1357.14

Diagnostic Checking

resid <- residuals(fit)
par(mfrow=c(1,2))
Acf(resid)
Pacf(resid)

Ljung-Box Tests

Box.test(resid, lag=12, type="Ljung-Box", fitdf=2)

    Box-Ljung test

data:  resid
X-squared = 5.3602, df = 10, p-value = 0.8659
Box.test(resid, lag=24, type="Ljung-Box", fitdf=2)

    Box-Ljung test

data:  resid
X-squared = 12.787, df = 22, p-value = 0.9389
Box.test(resid, lag=36, type="Ljung-Box", fitdf=2)

    Box-Ljung test

data:  resid
X-squared = 22.058, df = 34, p-value = 0.943
Box.test(resid, lag=48, type="Ljung-Box", fitdf=2)

    Box-Ljung test

data:  resid
X-squared = 34.988, df = 46, p-value = 0.8818

Histogram of Residuals

hist(resid)

Normal Probability Plot of Residuals

qqnorm(resid)

Simulating from The Fitted Model

nsim <- 5
for (i in 1:nsim) {
    par(mfrow=c(1,2))
    plot(time, hedge, col=2, type="l")
    plot(time, simulate(fit), col=1, type="l", ylim=range(hedge))
}

Bootstrap Simulations

nsim <- 5
for (i in 1:nsim) {
    par(mfrow=c(1,2))
    plot(time, hedge, col=2, type="l")
    plot(time, simulate(fit, bootstrap=TRUE), col=1, type="l", ylim=range(hedge))
}

Gaussian Forecasts

plot(forecast(fit, level=c(95, 99)))

Bootstrap Forecasts

plot(forecast(fit, level=c(95, 99), bootstrap=TRUE, npaths=10000))

Comparison

forecast(fit, h=2, level=c(80, 95, 99, 99.9))
    Point Forecast     Lo 80   Hi 80     Lo 95    Hi 95     Lo 99    Hi 99
325      0.9088513 -1.549937 3.36764 -2.851541 4.669244 -4.033142 5.850844
326      0.8906605 -1.674619 3.45594 -3.032596 4.813917 -4.265372 6.046693
      Lo 99.9  Hi 99.9
325 -5.404362 7.222065
326 -5.695981 7.477302
forecast(fit, h=2, level=c(80, 95, 99, 99.9), bootstrap=TRUE, npaths=10000)
    Point Forecast     Lo 80    Hi 80     Lo 95    Hi 95     Lo 99    Hi 99
325      0.9088513 -1.433458 3.257939 -2.655361 4.409424 -5.854281 6.963332
326      0.8906605 -1.527492 3.230579 -2.944908 4.506494 -6.071943 6.391220
      Lo 99.9  Hi 99.9
325 -8.361445 7.884481
326 -9.107400 8.309420

Is This Useful?

hedge.forecast <- fitted.values(fit)

summary(hedge)                     # 324 observations
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-8.8200 -0.2725  0.9950  0.8860  2.0000  8.3700 
summary(hedge[hedge.forecast > 0]) # 304 observations
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-8.8200 -0.1725  1.0200  0.9671  2.0020  8.3700 
summary(hedge[hedge.forecast > 1]) # 141 observations
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 -2.650   0.400   1.440   1.427   2.290   8.370 
summary(hedge[hedge.forecast > 2]) # only 7 observations
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  0.420   0.950   1.300   2.800   3.805   8.370