I am trying to create financial data as close as possible to that of asset returns. Using the R code I can collect some stock data and compute the return:
library(quantmod)
library(mgarchBEKK)
start_date = "2015-01-01"
end_date = "2020-01-01"
getSymbols("GOOG", from = start_date, to = end_date)
getSymbols("MSFT", from = start_date, to = end_date)
getSymbols("IBM", from = start_date, to = end_date)
rGOOG <- dailyReturn(GOOG)
rMSFT <- dailyReturn(MSFT)
rIBM <- dailyReturn(IBM)
Plotting the returns data gives me:
plot(rGOOG, type = "l", col = "red")
lines(rMSFT, col = "blue")
lines(rIBM, col = "orange")
I want to be able to create (as similar as possible...) fake returns data. Using a BEKK
process I can run the following:
simulated <- simulateBEKK(
series.count = 3, # number of time series to simulate
T = length(rGOOG), # number of time series observations (i.e. the same number as GOOG/MSFT/IBM)
order = c(1, 1) # parameters p = 1 and q = 1
)
simAsset1 = as.xts(x = simulated$eps[[1]], order.by = time(GOOG)) # collect the daily time series dates from the GOOG xts
simAsset2 = as.xts(x = simulated$eps[[2]], order.by = time(GOOG))
simAsset3 = as.xts(x = simulated$eps[[3]], order.by = time(GOOG))
However, the variation in the returns are too variable for financial data.
I plot the simulated asset returns along with the assets, GOOG, MSFT and IBM.
plot(simAsset1, type = "l", col = "brown")
lines(simAsset2, col = "grey")
lines(rGOOG, col = "red")
lines(rMSFT, col = "blue")
lines(rIBM, col = "orange")
The dark brown and grey lines are the simulated returns and the other lines are the returns for GOOG, MSFT and IBM. Thus the time series data I generate using the BEKK
process is giving too high and too low simulated returns data.
Plotting the histograms also tells me that the data generated is incorrect:
par(mfrow = c(2, 3))
hist(rGOOG, breaks = "FD")
hist(rMSFT, breaks = "FD")
hist(rIBM, breaks = "FD")
hist(simAsset1, breaks = "FD")
hist(simAsset2, breaks = "FD")
hist(simAsset3, breaks = "FD")
The Geometric Brownian Motion seems to do a better job:
library(somebm)
simGBMAsset1 <- gbm(x0 = 1, mu = 0, sigma = 1, t0 = , t = 1, n = length(time(GOOG)))
simGBMAsset1 <- xts(simGBMAsset1[2:length(simGBMAsset1)], order.by = time(GOOG))
simGBMAsset1 <- dailyReturn(simGBMAsset1)
dev.off()
plot(simGBMAsset1, type = "l")
lines(rGOOG, col = "red")
lines(rMSFT, col = "blue")
lines(rIBM, col = "orange")
However the Kurtosis is very different to that of the returns of GOOG, MSFT and IBM.
kurtosis(rGOOG)
kurtosis(rMSFT)
kurtosis(rIBM)
kurtosis(simGBMAsset1)
kurtosis(simAsset1)
kurtosis(simAsset2)
kurtosis(simAsset3)
Which gives:
- GOOG: 14,
- MSFT: 7.1,
- IBM: 6.7,
- simGBMAsset1: -0.074,
- simAsset1: -0.019,
- simAsset2: -0.34,
- simAsset3: 0.65
So since the kurtosis
is less than 3 for the generated time series then the generated data has lighter tails than a normal distribution, which is not representative of the "real" asset prices.
par(mfrow = c(2, 2))
hist(simGBMAsset1, breaks = "FD")
hist(rGOOG, breaks = "FD")
hist(rMSFT, breaks = "FD")
hist(rIBM, breaks = "FD")
My question is, what should I be doing in order to correctly construct simulated financial returns? I have read some papers in which authors are using generative adversarial networks (GANS) to generate financial time series, however, something more simple would be more than sufficient for my problem. The GBM and BEKK models I have currently do not generate the excess kurtosis on stock returns and thus I a thinking that I have gone wrong somewhere or missing something.