Binomial Option Pricing in Actionscript

Sep 09
2009

The binomial option pricing model is one of the simplest pricing models to understand and code. I’m not going to go into an explanation of the model itself, as that would take more time than I’m willing to expend, however I think it’s always useful to have example code lying around and I’m quite happy for some of it to lie around on my website.

private function getPrice(  N:Number, //Number of steps
                            T:Number, //Time to expiry (in years)
                            S:Number, //Spot price of underlying
                            K:Number, //Option strike
                            v:Number, //Volatility of underlying
                            r:Number //risk-free rate 
                         ):Number
{
 
    var dt:Number = T/N; //one time step
 
    var u:Number = 1 + v*Math.sqrt(dt); //up-tick
    var d:Number = 1 - v*Math.sqrt(dt); //down-tick
    var p:Number = 0.5 + r*Math.sqrt(dt)/(2*v); //risk-neutral prob. of up-tick
    var df:Number = 1/(1+r*dt); //discount factor over 1 time step, dt
 
    var optionValues:Array = new Array(N+1);
 
    //populate the tree (for N-steps there will be N+1 values)
    var i:int, j:int, ST:Number;
    for (i=0; i < N+1; i++) 
    {
        ST = spot.value * Math.pow(u, i) * Math.pow(d, N-i);
        optionValues[i] = (ST > K)? ST - K : 0;
    }
 
    //now work backwards to get expected option value at each previous stage
    for (i=N; i >= 0; i--)
    {
        for(j=0; j<i; j++)
        {
            optionValues[j] = (p*optionValues[j+1] + (1-p)*optionValues[j])*df;
        }
    }
 
    return optionValues[0]; 
}

What I’ve written is slightly different from some of the examples you might see (though exactly what Wikipedia suggests) – I don’t bother building up an array of stock prices since each value in the final array can be calculated with a simple formula. This means that I’ve removed a couple of loops from the calculation and (roughly) halved the execution time. I’m also assuming that we’re pricing a vanilla call option and that the risk-free rate is discretely compounded, though it would be fairly trivial to replace the call payoff function ((ST > K)? ST – K : 0) with any kind of external payoff function and to replace the discrete discount factor with a continuous one (1+rt becomes erT, essentially). In the end, with enough time steps, these kinds of changes make only a little difference though.

Have a play :

And for comparison, here’s a Black-Scholes pricer :

VAR, COVAR and COREL in Actionscript

Aug 28
2009

Someone was asking whether or not it’s possible to call Excel functions from a Flex project because they needed to use VAR, COVAR and COREL. The short answer is, of course, no (at least not to my knowledge, and, even if it were possible, I don’t think it’s something you really want to encourage). A better answer would explain that these functions aren’t especially complex and that an Actionscript implementation is fairly straightforward. The wikipedia page on covariance is a little daunting if you’ve never really thought about what these functions entail (or have forgotten), but essentially it boils down to this :

private function corel(X:Array, Y:Array):Number
{
    //correlation coeff between two random variables X and Y is defined as :
    //correlation(X,Y) = covar(X,Y)/(sqrt(Var(X)) * sqrt(Var(Y)))
    //
    //var(X) = covar(X,X);
    //covar(X,Y) = E((X-xm)(Y-ym)); where xm, ym are the population means.
    return covar(X, Y)/Math.sqrt(covar(X, X) * covar(Y, Y));
}
 
private function covar(X:Array, Y:Array):Number
{
    //Sample covariance is Sum((X-xm)(Y-ym))/n-1
    //where n is the sample size and xm & ym are sample means.
    //I'll assume that X and Y are the same size...
    var total:Number = 0;
    var xm:Number = average(X);
    var ym:Number = (X == Y)? xm : average(Y);
    for (var i:int=0; i<X.length; i++)
        total += (X[i]-xm)*(Y[i]-ym);
    return total/(X.length - 1); 
}
 
private function average(X:Array):Number
{
    //Sample mean or average = Sum(X)/(sample size)
    var total:Number = 0;
    for each(var x:Number in X)
        total += x;
    return total/X.length;
}

Of course, it’s not quite that simple – my covar won’t return the same value as COVAR in Excel, because Excel uses the biased estimator (i.e. it divides by n rather than (n-1)), but this cancels out when calculating the correlation coefficient, and correcting covar to the biased estimator is trivial (multply by (n-1)/n). Personally, I think Excel is wrong for defaulting to the biased estimator for COVAR, especially since VAR uses the unbiased one (and, as I’ve written in the comments, VAR(X)=COVAR(X,X)).

Visit Our Friends!

A few highly recommended friends...

Pages List

General info about this blog...