I am trying to construct a method in python that evaluates the value of an Arithmetic Asian Option using standard Monte Carlo simulation (without control variates). However, I am not getting the correct option values. The code is adapted from MATLAB source provided here: http://personal.strath.ac.uk/d.j.higham/ch22.m

Here is my implementation: (Key => S0 = stock value, K = strike price, v = volatility, r = risk-free interest rate, T = time to maturity, N = # of observations, M = # of paths in MonteCarlo simulation)

def arithmeticAsianCallValue (S0, K, v, r, T, N, M):

    dt = T*1.0/N
    drift = exp((r-0.5*v*v)*dt)

    Spath = numpy.empty(M, dtype=float)
    arithPayOff = numpy.empty(M, dtype=float)


    for i in range(0,M,1):
        growthFactor = drift * exp(v*sqrt(dt)*scipy.random.randn(1))
        Spath[i] = S0 * growthFactor
        for j in range(i+1,N,1):
            growthFactor = drift * exp(v*sqrt(dt)*scipy.random.randn(1))
            Spath[j] = Spath[j-1] * growthFactor

        arithMean = numpy.mean(Spath)
        arithPayOff[i] = exp(-r*T)* math.max(arithMean-K, 0)

    # Standard Monte Carlo
    Pmean = numpy.mean(arithPayOff)
    Pstd = numpy.std(arithPayOff)

    confmc = [Pmean-1.96*Pstd/sqrt(M), Pmean+1.96*Pstd/sqrt(M)]

    return confmc
  • $\begingroup$ Would you mind tell us the expected option value and what the code gives you? $\endgroup$ – HelloWorld Apr 12 '17 at 10:13
  • $\begingroup$ @SmallChess For values of S=100,K=100,v=0.30,r=0.05,T=3(years),N=50,M=100000 My code gives -ve option values i.e. [-41.56, -41.24] while expected should be 14.77 $\endgroup$ – stud91 Apr 12 '17 at 10:17
  • 1
    $\begingroup$ I am voting to close this question for being too basic. Here are some things that look off to me: 1) I suppose Spath is supposed to hold a single path of your simulation? If yes, it should have dimension N and not M. 2) Spath[i] should probably be Spath[0], range(i+1,N,1) should be range(1,N,1). Making these changes I get an estimate of 14.6557. $\endgroup$ – LocalVolatility Apr 12 '17 at 14:26
  1. numpy.max wouldn't work in this case. Try Math.max. If you don't believe me, try this:

print(numpy.max(-100, 0))



  1. You're supposed to draw from random Gaussian, not uniform.


Create an array of the given shape and populate it with random samples from a uniform distribution.

Adivice for programming: you're not using the vectorized implementation offered by numpy. If you aren't, forget about it. Mixing looping code with numpy like in this case would just introduce unnecessary bugs.


Spath is a single dimensional numpy array for a single path. You should have initialized it with N not M. Making it M means you'd average the uninitialised elements (0 by default in Python), and thus very low option value.

@Bob_Jansen and other mods: I'm tempted to close the question off-topic. This is is clearly homework. The finance concepts is fine, it's the actual implementation (e.g. python loops) that's creating incorrect outputs. When I wrote my response, I thought the error was just like misunderstanding in Gaussian. We're here to answer about finance, not python looping.

| improve this answer | |
  • $\begingroup$ Thanks. I changed rand to randn() and Math.max but option values are still wrong. Now the are [0.00031477403247266164, 0.00041123058778192275] $\endgroup$ – stud91 Apr 12 '17 at 11:06
  • $\begingroup$ @stud91 Post your new code. Let's keep trying. There're still other bugs. $\endgroup$ – HelloWorld Apr 12 '17 at 11:07
  • $\begingroup$ It'd be helpful if you mentioned why numpy.max(-100,0) returns 100 - because it's casting the first arg to an array and then taking the minimum along the zeroth axis. $\endgroup$ – will Apr 12 '17 at 11:08
  • $\begingroup$ @will You're right. But in this scenario, there is no need to do numpy.max(). The simple Math.max is enough. $\endgroup$ – HelloWorld Apr 12 '17 at 11:09
  • $\begingroup$ @SmallChess updated $\endgroup$ – stud91 Apr 12 '17 at 11:09

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