I wrote a Monte-Carlo simulation of delta hedging for a european call. R and Sigma are fixed.
I start simulation with zero money and short call option. At each step I borrow money to buy 'delta' of assets. At the end of simulation I look at my debt after option settlement. This is fee I should have been payed for the option.
My question: I've noticed that stddev( my cash after all settlements ) != 0. But, it is still << than stdev of payoff. That means that delta hedging did not hedge me completely. Is it ok? Why?
The following code gives me
required_initial_fee mean = 72.17 stdev = 0.56
discounted_option_payoff mean = 74.34 stdev = 426.68
from numpy import log, sqrt, exp, maximum
from math import erf
import pandas as pd
import numpy as np
@np.vectorize
def N_cdf(x):
'Cumulative distribution function for the standard normal distribution'
return (1.0 + erf(x / sqrt(2.0))) / 2.0
def BS_CALL_DELTA(S, K, T, r, sigma):
d1 = ( log(S/K) + (r + 0.5 * sigma**2) * T ) / (sigma * sqrt(T))
return N_cdf(d1)
S0 = 100 # Initial stock price
K = 100 # Strike price
r = 0.05 # Risk-free interest rate
sigma = 0.5 # Volatility
T = 3000 # Time to expiration
N = 100000 # Number of simulations
days_per_year = 250 # Time steps per year
#simulate price path
np.random.seed(2024)
dt = 1.0/days_per_year
# simulate path
simulated_paths = np.zeros((T, N))
simulated_paths[0] = S0
for i in range(0, T-1):
w = np.random.standard_normal(N)
simulated_paths[i+1] = simulated_paths[i] * (1 + r*dt + sigma * np.sqrt(dt)*w)
previous_delta = np.zeros(N)
# Total amount of borrowings is stored in 'debt' variable. Daily continuous interest rate is accrued on this debt
debt = np.zeros(N)
for t_i in range(0, T - 1):
S_i = simulated_paths[t_i]
year_fraction_left_to_maturity = float(T - t_i) / days_per_year
delta = BS_CALL_DELTA(S_i, K, year_fraction_left_to_maturity, r, sigma)
# As Im doing delta hedging, by the end of the period I must own 'delta' amount of shares on the previous step I had 'previous_delta' amount. So I need to buy 'delta-previous_delta' of shares
settled_cash_out = (delta - previous_delta) * S_i
previous_delta = delta
# I lend money to buy stocks. This is my total due
debt = debt * exp(r / days_per_year) + settled_cash_out
# now I need to handle the last day:
S_final = simulated_paths[-1]
option_payoff = maximum.reduce([S_final - K, np.zeros(N)])
discounted_option_payoff = option_payoff * exp( -r * T / days_per_year)
# at the end of the last step I sell all my stocks (I have previous_delta of stocks) and pay payoff
settled_cash_out = -S_final * previous_delta + option_payoff
debt = debt * exp(r / days_per_year) + settled_cash_out
#how much money should I take as a commission to have 0 pnl by the end of the contract, to compensate my spendings on debt
required_initial_fee = debt * exp( -r * T / days_per_year)
print("required_initial_fee", round(required_initial_fee.mean(), 2), round(required_initial_fee.std(), 2))
print("discounted_option_payoff", round(discounted_option_payoff.mean(), 2), round(discounted_option_payoff.std(), 2))