I need to simulate a price series based on a GARCH(1,1) specification for the returns (price changes). I currently have this:

    d_price = diff(price) #the price changes
    garch.model = garch(d_price) #a GARCH(1,1) model
    specs = garchSpec(model = list(omega = garch.model$coef[1], 
        alpha = garch.model$coef[2], beta = garch.model$coef[3]))

    sim = garchSim(spec = specs, n = t) #simulated GARCH returns
    mu = mean(price) #the starting value is the mean of the series
    sim.series = rep(mu, t) 

    #create the simulated price series
    for(i in 2:t){ 
      sim.series[i] = sim.series[i-1] + sim[i-1]

My problem is that this series often becomes negative. I can't have negative prices in my model.

I thought about using percentage price changes instead, but I experience a similar problem - the price series sometimes decreases to arbitrarily small values that are completely unrealistic.

So, my question is this: Is there a best option for simulating a series so that the price never becomes negative or unrealistically small? That is, without putting artificial barriers on the price process (P must be greater than 20, for example).



4 Answers 4


Your problem is that the GARCH model assumes the error terms have normal distributions with zero mean and variance that changes over time. If you want to restrict prices to be positive you have to create a model that has error terms compatible with that assumption. Percentage doesn't help because you still have the nonnegativity assumption and the model you choose still assume normal error distributions.

There is no easy solution. If you could construct a model with an error distribution that is non-negative you will always get positive values but the error term would have a non-zero mean.

  • $\begingroup$ Thanks for your response. I do want my error term to have a mean of zero. I had the same problem when simulating multiple AR(1) price series. I simulated the Ornstein-Uhlenbeck process instead - the continuous time version of an AR(1) process that is guaranteed to be positive. I'll see if I can convert the O-U process into a GARCH process and hopefully I'll be able to post an answer. $\endgroup$
    – wcampbell
    Commented Sep 20, 2012 at 13:31

You can try and simulate logReturns as Garch process i.e. rather than difference in the prices, you can use difference in the log prices. Even if error is very negative, prices would always be positive.


Depending on the use case it might be sufficient to calculate the returns for the series and then convert the returns back to prices. In the end add the minimum value + a small delta (e.g. 1).

r = diff(log(priceSeries))
... do your model estimation
priceSeries = diffinv(aramSim)
priceSeries = priceSeries + min(priceSeries) + 1

This just shifts up the whole price series. Don't do it if absolute prices for some reasons are critical. But you preserve imho the structure and I don't see big issues with doing this. Please correct me if I am wrong. But this is an easy solution.


My solution: I added GARCH volatility to an Ornstein-Uhlenbeck process. Prices are never negative and price volatility is non-constant. Hope this helps someone!!!

    #process parameters
    eta = 0.2 #eta = 0 is equivalent to Geometric Brownian Motion
    mu = 100 #the mean of the process

    #GARCH volatility model
    specs = garchSpec(model = list(omega = 0.000001, alpha = 0.5, beta = 0.4)) 
    sigma = garchSim(spec = specs, n = T)

    P_0 = mu #starting price, known
    P = rep(P_0,T)

    for(i in 2:T){
      P[i] = P[i-1] + eta * (mu - P[i-1]) + sigma[i] * P[i-1]

    #prices and returns
    plot(P,type="l",xlab="Time", main="", ylab = "Price")
    plot(diff(P), type = 'l', ylab = 'Price Changes', xlab = 'Time')

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.