Skip to content
All library documents

Simulating Multivariate Returns with BEKK Requires Calibrated Parameters

Article Quant Q&A · Author: user113156

Summary

The document compares simulated returns from a multivariate BEKK process and geometric Brownian motion with observed stock returns. The author finds that default BEKK output appears too volatile and that both approaches fail to reproduce the excess kurtosis seen in the selected equity series. The response identifies a central setup issue: the BEKK simulation was run without supplied parameters, so its output was not calibrated to the return data.

An example then supplies a parameter vector and shows simulated series and a histogram for comparison with observed returns. The parameters are described as randomly generated, and the response says they appear more plausible while suggesting that further analysis could identify more appropriate values. This is illustrative rather than evidence of a reliable fit: visual comparison and kurtosis alone do not establish realistic marginal tails, volatility clustering, or cross-asset dependence. The example does not provide a formal estimation method or validation results, and its code should be treated as a starting point for parameter calibration.

Key ideas

  • BEKK simulations depend on model parameters, so unspecified or unsuitable values can produce unrealistic return variation.
  • The response supplies an example parameter vector for a three-series simulation.
  • It recommends analyzing and calibrating parameters against observed returns.
  • Comparing plots and kurtosis can reveal mismatches but does not validate the full return distribution or dependence structure.
  • No systematic calibration or out-of-sample validation is demonstrated.

Tags

Full text
# Correctly simulating BEKK series to model asset returns


# Correctly simulating BEKK series to model asset returns












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:







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

## Answer by Trevor Hansen (score 1)

https://quant.stackexchange.com/a/55183

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:

Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.