Menu Home

Lazy GARCH

John wrote a great post a few months back on the virtues of lazy evaluation and using this to generate infinite length geometric Brownian motion prices series.

Lazy evaluation is popular in functional programming, whereby the evaluation of expressions is deferred until when they are actually needed. The purely functional language Haskell defaults to lazy evaluation for all function evaluations. It is one of the core building blocks in functional programming underpinning the notion of functional composition which is very powerful (or lazy - sorry...) once you get used to treating functions as first class types.

But, I digress, a simple use case is in generating infinite streams of values, whereby each value is only generated when needed. This enables you to create sequences of values such as Fibonacci numbers, or even replicate stochastic processes.

Python supports lazy evaluation via generators. You define your function as a generator by creating an iterator which contains a yield expression, generating a value.

For instance, we can use a GARCH(1,1) model to generate a volatility forecast, where our volatility \sigma at time t is given by the following variance equation.

\sigma^2_t = \omega + \alpha\epsilon_{t-1}^2 + \beta\sigma^2_{t-1}

The value of parameters \omega, \alpha and \beta should be found using an optimisation algorithm which I'll talk more about in another post.

The following function defines a GARCH(1,1) annualised volatility generator:

from math import sqrt

import numpy as np


def lazy_garch(omega, alpha, beta, var):

    last_var = var
    epsilon = np.random.randn() * sqrt(var)

    while True:
        var = omega + (alpha * epsilon**2) + (beta * last_var)
        yield sqrt(var) * sqrt(252.0)
        last_var = var
        epsilon = np.random.randn() * sqrt(last_var)

The parameters configure the generator, and the yield expression provides our next value which we access via the iterator next() function.

garch = lazy_garch(omega, alpha, beta, var)  # define our generator
garch.next()  # generate a value

We now have a generator we can use in our GARCH models.

Thanks again to John for the inspiration for this post, he's taken all of this way further then me and created a lazy backtester. Head over to his fantastic blog for more.

Categories: Development Functional Programming Python Volatility

Tagged as:

conor

2 replies

  1. One of the nicest thing about Lazy is the way it separates control from data structure, apart from anything else, the code can feel nicer...

    Thx for the nice words too! : )

Leave a Reply

Your email address will not be published. Required fields are marked *