0
$\begingroup$

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")

enter image description here

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") 

enter image description here

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")

enter image description here

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.

enter image description here

par(mfrow = c(2, 2))
hist(simGBMAsset1, breaks = "FD")
hist(rGOOG, breaks = "FD")
hist(rMSFT, breaks = "FD")
hist(rIBM, breaks = "FD")

enter image description here

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.

$\endgroup$
2
  • 2
    $\begingroup$ Have you considered historical simulation? $\endgroup$
    – Bob Jansen
    Commented Jun 18, 2020 at 14:12
  • $\begingroup$ You could also try using fitting the model using a students-t distribution instead of the normal distribution this would account for fat tails. Maybe something like a DCC-GARCH model would model the series better as you could also take correlations among the assets into account. $\endgroup$ Commented Jun 20, 2020 at 23:42

1 Answer 1

1
$\begingroup$

You haven't provided any parameters to the simulateBEKK method. If you want to simulate fake returns data that are realistic you will need to provide parameters that provide realistic results. In the following code I randomly generated some parameters which seem to simulate a more realistic process than you were doing in the question. By running some analysis you could parameterize the simulateBEKK method with more appropriate parameters.

start_date = "2015-01-01"
end_date = "2020-01-15" 

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)

simulated <- simulateBEKK(
  series.count = 3,
  T = length(rGOOG),
  order = c(1, 1),
  params = c(3.621376e-06,
             -2.441600e-03,
             9.880184e-03,
             -9.592000e-08,
             2.675009e-01,
             -1.634400e-07,
             2.021376e-05,
             -1.241600e-03,
             5.880184e-02,
             -5.592000e-08,
             2.275009e-01,
             -1.634400e-07,
             2.021376e-05,
             -1.241600e-03,
             5.880184e-03,
             -5.592000e-08,
             2.275009e-01,
             -1.634400e-07,
             2.021376e-05,
             -1.241600e-03,
             5.880184e-02,
             5.592000e-08,
             2.275009e-01,
             -1.634400e-07)
)

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))

plot(simAsset1, col = "blue")
lines(rGOOG, col = "red")

hist(rGOOG, breaks = "FD")
hist(simAsset1, breaks = "FD")

The outputted figures don't seem to absurd for this random example: enter image description here enter image description here enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.