# Basket Option pricing of two stocks

I am trying to use Monte Carlo simulation to price arithmetic basket option consisting of two stocks. There seems to be something wrong in my implementation. According to the inputs

S1=100, S2=100, K=100, v1=30%, v2=30%, r=5%, T=3, M=100000, type=call


the value should be 24.345. But for me it's coming out to be 21.913. Here is my implementation:

dt = T
drift1 = exp((r-0.5*v1*v1)*dt)
drift2 = exp((r-0.5*v2*v2)*dt)

S1next = 0.0
S2next = 0.0
arithPayOff = numpy.empty(M, dtype=float)

scipy.random.seed([100])

for i in range(0,M,1):
growthFactor1 = drift1 * exp(v1*sqrt(dt)*scipy.random.randn(1))
S1next = S1 * growthFactor1
growthFactor2 = drift2 * exp(v2*sqrt(dt)*scipy.random.randn(1))
S2next = S2 * growthFactor2

# Arithmetic mean
arithMean = 0.5 * (S1next+S2next)
arithPayOff[i] = exp(-r*T) * max(callOrPut*(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 numpy.mean(confmc)

• Why dt = T? This implies a time interval of 3 years. dt - should be possibly small – cykor21 Apr 15 '17 at 17:35
• @cykor21 we take time step to be 1 as need to simulate stock prices at maturity T only – stud91 Apr 15 '17 at 17:39
• What's the correlation between the two stock returns? – Alex C Apr 15 '17 at 18:57
• @AlexC it is 0.5 – stud91 Apr 15 '17 at 18:58
• This is an inefficient way to calculate the value. Instead do quadrature on the 1-d marginals, with the Black-Scholes formula as the integrand. – Brian B Apr 15 '17 at 23:32

The problem in your code is that the correlation is completely ignored. I would replace the loop by the following piece of code:

for i in range(0,M,1):
Rand1 = scipy.random.randn(1)
Rand2 = scipy.random.randn(1)
growthFactor1 = drift1 * exp(v1 * sqrt(dt) * Rand1)
S1next = S1 * growthFactor1
growthFactor2 = drift2 * exp(v2 * sqrt(dt) * (0.5 * Rand1 + sqrt(0.75) * Rand2))
S2next = S2 * growthFactor2

# Arithmetic mean
arithMean = 0.5 * (S1next+S2next)
arithPayOff[i] = exp(-r * T) * max(callOrPut * (arithMean - K), 0)


Basically, two correlated standard normal random variables $X_1$ and $X_2$ with correlation $\rho$ can be expressed as \begin{align*} X_1 &= \xi,\\ X_2 &= \rho\, \xi + \sqrt{1-\rho^2}\, \eta, \end{align*} where $\xi$ and $\eta$ are two independent standard normal random variables.

• @stud91 - worth looking into the Cholesky Decomposition for generating correlated random number sequences. – FinanceGuyThatCantCode Apr 17 '17 at 19:31
• @FinanceGuyThatCanCode in the case of two random variables this is the cholesky decomposition... – will Apr 18 '17 at 21:15
• @will - Gordon added the equations with $X_1$ and $X_2$ after the suggestion, but stud91 should probably look it up in general given his error in the code he posted. – FinanceGuyThatCantCode Apr 18 '17 at 21:45
• Ah okay. And that is true. – will Apr 18 '17 at 21:47
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 1, "mathjax_display_tex": 0, "mathjax_asciimath": 1, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.6170538067817688, "perplexity": 2921.08012254448}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2019-47/segments/1573496670821.55/warc/CC-MAIN-20191121125509-20191121153509-00160.warc.gz"}