彷佛突如其來,彷佛合情合理,咱們和巴菲特老先生一塊兒親見了一次,又一次,雙一次,叒一次的美股熔斷。身處歷史的洪流,眇小的咱們會不由發問:那之後呢?還會有叕一次嗎?因而就有了這篇記錄:利用ARIMA模型來預測美股的走勢。測試
library(quantmod) stock <- getSymbols("^DJI", from="2020-01-01", from="2020-03-31", auto.assign=FALSE) names(stock) <- c("Open", "High", "Low", "Close", "Volume", "Adjusted") stock <- stock$Close stock <- na.omit(stock) train.id <- 1: (0.95*length(stock)) train <- stock[train.id] test <- stock[-train.id]
其實對於屢次熔斷向下再向下的道指來講,撇開各類觀察和檢驗的方法,咱們都知道他必定是非平穩時間序列了。下面兩種方法就是打個版:當咱們遇到不太明顯的時間序列時能夠怎麼作?code
下圖斷崖式降低的曲線代表訓練集爲非平穩時間序列。orm
library(ggplot2) library(scales) plot<-ggplot(data=train) + geom_line(aes(x=as.Date(Index), y=Close), size=1, color="#0072B2")+ scale_x_date(labels=date_format("%m/%d/%Y"), breaks=date_breaks("2 weeks"))+ ggtitle("Dow Jones Industrial Average") + xlab("")+ theme_light() print(plot)
利用 Ljung–Box test 獲得 p-value = 2.2e-16 < 0.05, 由此拒絕時間序列爲白噪聲的假設。blog
Box.test(train, lag=1, type = "Ljung-Box")
因此咱們將利用其二階差分序列進行ARIMA預測。ci
library("tseries") train.diff1 <- diff(train, lag = 1, differences = 1) train.diff2 <- diff(train, lag = 1, differences = 2) adf.test(train) adf.test(na.exclude(train.diff1)) adf.test(na.exclude(train.diff2))
當咱們肯定用二階差分序列進行預測後,則須要對模型進行定階。以下圖所示,對於ACF,滯後1-2階在2倍標準差外,因此q=2;對於PACF,一樣也是滯後1-2階都在2倍標準差外,因此p=2,因此將會選擇模型ARIMA(2,2,2)。get
acf <- acf(na.omit(train.data.diff2$Close), plot=TRUE) pacf <- pacf(na.omit(train.data.diff2$Close), plot=TRUE)
爲了保證選擇的模型是最優的,建議能夠多選擇接近的模型,而後根據AIC準則或者BIC準則選取最優的模型。好比利用自動定階的方法,得出一個模型ARIMA(1,1,0)it
library(forecast) auto.arima(train.data,trace=TRUE) #Best model is ARIMA(1,1,0)
通過比較發現仍是模型ARIMA(2,2,2)較優:io
data.autofit<-arima(train.data,order=c(1,1,0)) AIC(data.autofit) BIC(data.autofit) data.fit<-arima(train.data,order=c(2,2,2)) AIC(data.fit) BIC(data.fit)
Model | AIC | BIC |
---|---|---|
ARIMA(1,1,0) | 930.5894 | 934.6755 |
ARIMA(2,2,2) | 919.8881 | 930.0149 |
對擬合殘差進行白噪聲檢驗,獲得p-value = 0.8221 > 0.05,並且acf在lag=1後迅速減少,可得殘差爲白噪聲。table
forecast <-forecast(data.fit, h=4, level=c(99.5)) forecast.data <- data.frame("Date"=index(train), "Input"=forecast$x, "Fitted"=forecast$fitted, "Residuals"=forecast$residuals) acf(forecast.data$Residuals) Box.test(forecast.data$Residuals, lag=sqrt(length(forecast.data$Residuals)), type = "Ljung-Box")
咱們將訓練集數據和擬合數據同時畫在圖上,能夠看到二者的差異是在可接受範圍的。
ast
將預測結果與測試集對比,二者的最大相對偏差爲 0.056,可見模型是表達充分的,預測結果良好。
data.forecast<-arima(stock,order=c(2,2,2)) newforecast<-forecast(data.forecast, h=5, level=c(99.5))