[Python quantification] Monte Carlo simulation method for option pricing

This article was first published on the WeChat public account: Python for Finance

Link: https://mp.weixin.qq.com/s/fgN3uRLurcWt-9RHJDGy7Q

How can Monte Carlo simulation methods be used for option pricing?

theoretical derivation

The basic idea of ​​the Monte Carlo method is: in a risk-neutral world, randomly generate the possible path of the underlying asset price, thereby obtaining the expected value of the option return, and then discounting it at the risk-free interest rate to obtain the option price.

Detailed derivation can be viewed at:

Reference article: https://mp.weixin.qq.com/s/qTBuCSAmCc39G2nDfUDgmQ

Monte Carlo simulation method to simulate stock price trend

First of all, we need to simulate the stock price trend through Monte Carlo simulation.

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import pandas as pd
import math
'''
s:股票现价
t:期限(年)
r:无风险利率(年)
sigma:股票年化波动率
N:每年的期数
M:模拟次数
'''
def generate_simulated_stock_returns(t,r,sigma,N):      
    a1=[]
    dt=1/N
    term = int(t*N)
    for i in range (1, term+1):
        z=np.random.normal()
        simulated_return = (r-(sigma**2/2))*dt + z*sigma*(dt**(1/2))
        a1.append(simulated_return)
    array_return=np.array(a1)
    return array_return

def generate_simulated_stock_values(s,t,r,sigma,N):
    rate=generate_simulated_stock_returns(t,r,sigma,N)
    stock_price = [s]
    term = int(t*N)
    for i in range(1, term+1):
        values = stock_price[i-1]*math.e**(rate[i-1])
        stock_price.append(values)
    array_price = np.array(stock_price)
    return array_price

European options

European call option

Pricing of European call options:
C = Max(S t − X , 0 ) e − rt C = Max(S_t-X,0)e^{-rt}C=Max(StX,0)ert

def MCEuroCallOptionValue(s,x,t,r,sigma,N,M):
    call_prices = []
    for i in range(M):
        stock_price = generate_simulated_stock_values(s,t,r,sigma,N)[-1]
        call_price = max(stock_price-x,0)*np.exp(-r*t)
        call_prices.append(call_price)
    price_mean = np.mean(call_prices)  
    return price_mean      
def BSEuroCallOptionValue(s,x,t,r,sigma):
    d1 = (math.log(s/x)+(r+sigma**2/2)*t)/(sigma*math.sqrt(t))
    d2 = d1-sigma*math.sqrt(t)
    c = s*stats.norm.cdf(d1)-x*math.exp(-r*t)*stats.norm.cdf(d2)
    return c
mc_price = MCEuroCallOptionValue(90, 100, 1, 0.1, 0.3, 100, 1000)
print(mc_price)
bs_price = BSEuroCallOptionValue(90, 100, 1, 0.1, 0.3)
print(bs_price)
9.84671058110504
10.51985812604488

European put option

Pricing of European put options:
P = M ax ( X − S t , 0 ) e − rt P = Max(X-S_t,0)e^{-rt}P=Max(XSt,0)ert

def MCEuroPutOptionValue(s,x,t,r,sigma,N,M):
    put_prices = []
    for i in range(M):
        stock_price = generate_simulated_stock_values(s,t,r,sigma,N)[-1]
        put_price = max(x-stock_price,0)*np.exp(-r*t)
        put_prices.append(put_price)
    price_mean = np.mean(put_prices)  
    return price_mean  
def BSEuroPutOptionValue(s,x,t,r,sigma):  
    d1 = (math.log(s/x)+(r+sigma**2/2)*t)/(sigma*math.sqrt(t))
    d2 = d1-sigma*math.sqrt(t)
    p = x*math.exp(-r*t)*stats.norm.cdf(-d2)-s*stats.norm.cdf(-d1)
    return p  
mc_price = MCEuroPutOptionValue(100, 100, 1.0, 0.1, 0.3, 100, 10000)
print(mc_price)
bs_price = BSEuroPutOptionValue(100, 100, 1.0, 0.1, 0.3)
print(bs_price)
7.217875385982609

Asian options

The income of Asian options depends on the average price of the standard asset validity period at least for a period of time. Asian options can be divided into average price options and average strike price options.

The application of Asian options to stock option compensation has two functions:

1. Avoid man-made stock price speculation.

2. Reduce the insider trading of the company's employees and the behavior that damages the company's interests.

Asian call option

Pricing of Asian call options:
C = Max(A average ( S ) − X , 0 ) e − rt C = Max(Average(S)-X,0)e^{-rt}C=Max(Average(S)X,0)ert

def MCAsianCallOptionValue(s,x,t,r,sigma,N,M):   
    call_prices = []
    for i in range(M):
        stock_price = np.mean(generate_simulated_stock_values(s,t,r,sigma,N))
        call_price = max(stock_price-x,0)*np.exp(-r*t)
        call_prices.append(call_price)
    price_mean = np.mean(call_prices)   
    return price_mean     
acall_price = MCAsianCallOptionValue(100, 100, 1.0, 0.10, 0.30, 100, 1000)
print(acall_price)
9.494626161093787

Asian put option

Pricing of Asian put options:
P = max ( X − A average ( S ) , 0 ) e − rt P = max(X-Average(S),0)e^{-rt}P=max(XAverage(S),0)ert

def MCAsianPutOptionValue(s,x,t,r,sigma,N,M):   
    put_prices = []
    for i in range(M):
        stock_price = np.mean(generate_simulated_stock_values(s,t,r,sigma,N))
        put_price = max(x-stock_price,0)*np.exp(-r*t)
        put_prices.append(put_price)
    price_mean = np.mean(put_prices)   
    return price_mean  
aput_price = MCAsianPutOptionValue(100, 100, 1.0, 0.10, 0.30, 100, 1000)
print(aput_price)
4.462073414456472

lookback option

Lookback options refer to options whose return depends not only on the strike price of the underlying asset, but also on the highest or lowest price of the underlying asset during the duration of the option. When the look-back option expires, it needs to look back at the performance of the underlying asset in the past. Its income payment structure is related to the maximum or minimum value of the underlying asset price during the contract period. Like many exotic options, the look-back option is also a path-dependent kind of options.

**Lookback options can be divided into the following types according to whether the strike price is fixed or floating:** They are lookback call options with fixed strike price, lookback put options with fixed strike price, lookback call options with floating strike price and Lookback put option with floating strike price.

The execution price of call options and put options with fixed execution prices is fixed when the contract expires, which is no different from ordinary options. The highest price and the lowest price reached by the underlying asset during the option holding period are used as the expiration date price;

For look-back call options and put options with floating strike prices, the lowest and highest prices of the underlying asset during the contract period are selected as the strike price of the option, and the price of the underlying asset is still the price on the expiration date.

look back call options

Looking back at the call option pricing:
C = M ax ( M ax ( S ) − X , 0 ) e − rt C = Max(Max(S)-X,0)e^{-rt}C=Max(Max(S)X,0)ert

def MCLookbackCallOptionValue(s,x,t,r,sigma,N,M):    
    call_prices = []
    for i in range(M):
        stock_price = max(generate_simulated_stock_values(s,t,r,sigma,N))
        call_price = max(stock_price-x,0)*np.exp(-r*t)
        call_prices.append(call_price)
    price_mean = np.mean(call_prices)  
    return price_mean      
lcall_price = MCLookbackCallOptionValue(100, 100, 1.0, 0.10, 0.30, 100, 1000)
print(lcall_price)
29.63502178494703

look back puts

Looking back at the pricing of put options:
P = M ax ( X − M in ( S ) , 0 ) e − rt P = Max(X-Min(S),0)e^{-rt}P=Max(XMin(S),0)ert

def MCLookbackPutOptionValue(s,x,t,r,sigma,N,M):
    put_prices = []
    for i in range(M):
        stock_price = min(generate_simulated_stock_values(s,t,r,sigma,N))
        put_price = max(x-stock_price,0)*np.exp(-r*t)
        put_prices.append(put_price)
    price_mean = np.mean(put_prices)  
    return price_mean
lput_price = MCLookbackPutOptionValue(100, 100, 1.0, 0.10, 0.30, 100, 1000)
print(lput_price)
15.536862634356844

Guess you like

Origin blog.csdn.net/mfsdmlove/article/details/127504309