-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy path4-Change Point Detection.R
More file actions
192 lines (157 loc) · 7.24 KB
/
4-Change Point Detection.R
File metadata and controls
192 lines (157 loc) · 7.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# CHANGE POINT DETECTION
################################################################################
## This task is an attempt to check “whether the pattern of the Wells Fargo
## stock follows a Geometric Brownian Motion or not” due to detecting changes.
## Answering this question needs to check for either independency or
## normality of the log returns in the presence of Black & Scholes assumption.
################################################################################
## install.packages("pacman")
## Load required packages at once
library(pacman)
pacman::p_load(quantmod,yuima,sde,fOptions)
## Check (in)dependency of the log returns through correlation analysis
## Load Data from Yahoo Finance and make data preparation
getSymbols("WFC", from="2014-01-01")
s<-WFC$WFC.Adjusted
x<-diff(log(s))
x<-na.omit(x)
## Plot autocorrelation of log returns
acf(x,main="ACF plot for Log Returns", col="red")
## Check Normality by p-value through Shapiro-Test
shapiro.test(as.numeric(x))
## Assess abnormality for the log returns with Graphical Q-Q plot
par(mfrow=c(2,1))
y<-rnorm(10000)
qqnorm(y)
qqline(y, col="red")
qqnorm(x)
qqline(x, col="red")
## Show the discrepancy between the theoretical Gaussian distribution and
## the distribution followed by the log returns of the Wells Fargo stock
hist(x, breaks=30, freq=FALSE, xlab = "log return", main="DENSITY vs. NORMAL DISTRIBUTION")
f<-function(y) dnorm(y, mean=mean(x), sd=sd(x))
curve(f, min(x),max(x), col="blue", lwd=3, add=TRUE)
lines( density(x), col="red",lwd=3 )
## Estimate the percentage drift and the percentage volatility
## with assumption of Geometric Brownian motion (GBM)
Dt <- 1/252 # Data Frequency
alpha.hat <- mean(x)/Dt
variance.hat <- var(x)/Dt
variance.hat
sigma.hat <- sqrt(variance.hat)
sigma.hat
mu.hat<-alpha.hat+0.5* variance.hat
mu.hat
## Depict possible pattern of whatever stock following a GBM behavior
mod <- setModel(drift="0.105*x", diff="0.15629 *x", solve.variable = c("x"))
samp <- setSampling(T=10, n=100000)
x <- simulate(mod, sampling=samp,xinit=5)
plot(x,col="blue",main="GBM PATTERN SIMUlATION", xlab="Time", ylab="Values")
## Perform model selection process when stock price does not follow
## a Geometric Brownian Motion,:
## To do this, use continuous models using
## Akaike Information Criterion (AIC) statistics
## e.g. Merton Model; Vasicek Model;
## Cox, Ingersoll & Ross Models; Dothan Model; Geometric Brownian Motion Model;
## Brennan & Schwartz Model; Constant Elasticity Variance Model; and CKLS Model.
## Load and Prepare Data
getSymbols("WFC", from="2014-01-01")
s<-WFC$WFC.Adjusted
X<-diff(log(s))
X<-na.omit(X)
m <- mean(s)
sigma<- as.numeric(sqrt(var(X)*252)) # n=252, the number of working days in a year
M <- mean(X)*252
# Create facilitator matrices containing the parameters of the models
drift <- c("mu*x", "alpha", "alpha*(mu-x)", "0", "alpha*(mu-x)",
"alpha*(mu-x)", "0", "alpha*x", "alpha*(mu-x)")
diffusion <- c("sigma*x", "sigma", "sigma*sqrt(x)", "sigma*x", "sigma",
"sigma*x", "sigma*x^(3/2)", "sigma*x^gamma", "sigma*x^gamma")
AIC <- c(NA, NA, NA, NA, NA, NA, NA, NA, NA)
MyMat <- rbind(drift,diffusion,AIC)
colnames(MyMat) <- c("GBM", "Merton", "CIR", "Dothan", "Vasicek", "BrenSch", "CIR2", "CEV", "CKLS")
row.names(MyMat) <- c("drift", "diffusion", "AIC")
qlme_GBM <- c(NA, M, sigma,NA); qlme_Merton <- c(1, NA, sigma, NA); qlme_CIR <- c(1, m, sigma, NA)
qlme_Dothan <- c(NA, NA, sigma, NA); qlme_Vasicek <- c(1, m, sigma, NA); qlme_BrenSch <- c(1, m, sigma, NA)
qlme_CIR2 <- c(NA, NA, sigma, NA); qlme_CEV <- c(1, NA, sigma, 0.5); qlme_CKLS <- c(1, m, sigma, 0.5)
qlme_matrix <- rbind(qlme_GBM, qlme_Merton, qlme_CIR, qlme_Dothan, qlme_Vasicek, qlme_BrenSch, qlme_CIR2, qlme_CEV, qlme_CKLS)
colnames(qlme_matrix) <- c("alpha", "mu", "sigma", "gamma")
row.names(qlme_matrix) <- c("GBM", "Merton", "CIR", "Dothan", "Vasicek", "BrenSch", "CIR2", "CEV", "CKLS")
# Find the preferred model with the lowest AIC value.
for (i in 1:dim(MyMat)[2]) {
SMoD <- setModel(drift=MyMat[1,i], diff=MyMat[2,i], solve.variable = c("x"))
yuima.SMoD <- setYuima(model=SMoD, data=setData(s, delta=1/252))
if (i == 1){
fit.SMoD <- qmle(yuima.SMoD, start=list(mu=qlme_matrix[i,2], sigma=qlme_matrix[i,3]))
} else if(i==2){
fit.SMoD <- qmle(yuima.SMoD, start=list(alpha=qlme_matrix[i,1], sigma=qlme_matrix[i,3]))
} else if(i==3){
fit.SMoD <- qmle(yuima.SMoD, start=list(alpha=qlme_matrix[i,1], mu=qlme_matrix[i,2], sigma=qlme_matrix[i,3]))
} else if(i==4){
fit.SMoD <- qmle(yuima.SMoD, start=list(sigma=qlme_matrix[i,3]))
}else if(i==5 || i==6){
fit.SMoD <- qmle(yuima.SMoD, start=list(alpha=qlme_matrix[i,1], mu=qlme_matrix[i,2], sigma=qlme_matrix[i,3]))
}else if(i==7){
fit.SMoD <- qmle(yuima.SMoD, start=list(sigma=qlme_matrix[i,3]))
}else if(i==8){
fit.SMoD <- qmle(yuima.SMoD, start=list(alpha=qlme_matrix[i,1], sigma=qlme_matrix[i,3], gamma=qlme_matrix[i,4]))
}else {
fit.SMoD <- qmle(yuima.SMoD, start=list(alpha=qlme_matrix[i,1], mu=qlme_matrix[i,2], sigma=qlme_matrix[i,3], gamma=qlme_matrix[i,4]))
}
MyMat[3,i] <- AIC(fit.SMoD)
}
which.min(MyMat[3,])
MyMat[3,which.min(MyMat[3,])]
## Utilizing Change Point Analysis try to detect
## volatility clustering in stock market
## Load and order data
getSymbols("WFC", from="2014-01-01", to="2015-08-25")
S <- zoo(WFC$WFC.Close)
## Find and show the volatility change-point
cpoint(S)
plot(S, xlab="TIME", ylab="PRICE", main="STOCK PRICE PLOT AND CHANGE POINT ANALYSIS")
abline(v=cpoint(S), col="red",lwd=2)
## Compute the differences among estimated values
## by using the selected model with respect to the speed of
## mean reversion, long range mean and volatility.
## Load and Prepare data
getSymbols("WFC", from="2014-01-01", to="2015-08-25")
s<-zoo(WFC$WFC.Adjusted)
X<-diff(log(s))
X<-na.omit(X)
m <- mean(s)
sigma<- as.numeric(sqrt(var(X)*252))
getSymbols("WFC", from="2014-01-01", to="2014-10-05")
s1<-zoo(WFC$WFC.Adjusted)
getSymbols("WFC", from="2014-10-06", to="2015-08-25")
s2<-zoo(WFC$WFC.Adjusted)
## Calculate the quasi-likelihood and estimate of the parameters of
## the stochastic differential equation by
## the maximum likelihood method or
## least squares estimator of the drift parameter.
## Build the stochastic differential equations
brensch <- setModel(drift="alpha*(mu-x)", diffusion="sigma*x", solve.variable = c("x"))
## Construct an object of by combining "model", "data",
## "sampling", "characteristic" and "functional"slots.
yuima <- setYuima(model=brensch, data=setData(s, delta=1/252))
yuima1 <- setYuima(model=brensch, data=setData(s1, delta=1/252))
yuima2 <- setYuima(model=brensch, data=setData(s2, delta=1/252))
start <- list(alpha=1, mu=m, sigma=sigma)
## Calculate the quasi-likelihood and ML estimator
fit <- qmle(yuima, start=start)
summary(fit)
fit1 <- qmle(yuima1, start=start)
summary(fit1)
fit2 <- qmle(yuima2, start=start)
summary(fit2)
## Display multiple change point analysis graph
plot(s, xlab="TIME", ylab="PRICE", main="CHANGE POINT ANALYSIS")
cpoint(s1) # 2014-04-15
cpoint(s2) # 2015-08-19
abline(v=cpoint(s1), col="green",lwd=2)
abline(v=cpoint(s2), col="red",lwd=2)
abline(v=cpoint(s), col="blue",lwd=2)
getSymbols("WFC", from="2014-10-06", to="2015-08-18")
s3<-zoo(WFC$WFC.Adjusted)
cpoint(s3) # 2015-03-12
abline(v=cpoint(s3), col="blue",lwd=2)