I am currently trying to correctly price European Call Closed Form Spread Options using Python. The main problem I am currently running into is that I have nothing to compare the option price so that I know that my code is working correctly.
Does anyone know if this code is correct ? Am I missing something ? Any help / info is appreciated.
This is my code:
import numpy as np
S1 = 110 # Spot price of first asset
S2 = 100 # Spot price of second asset
K = 25 # Strike price
T = 1 # Time to maturity in years
r = 0.05 # Risk-free interest rate
sigma1 = 0.1 # Volatility of first asset
sigma2 = 0.15 # Volatility of second asset
rho = 0.8 # Correlation between the two assets
num_simulations = 10000000 # Number of Monte Carlo simulations
def monte_carlo_spread_option_price(S1, S2, K, T, r, sigma1, sigma2, rho, num_simulations):
np.random.seed(0) # for reproducible results
# Simulating correlated paths
dt = T
Z1 = np.random.standard_normal(num_simulations)
Z2 = np.random.standard_normal(num_simulations)
Z3 = rho * Z1 + np.sqrt(1 - rho**2) * Z2
# GBM formula
S1_T = S1 * np.exp((r - sigma1**2 / 2) * dt + sigma1 * np.sqrt(dt) * Z1)
S2_T = S2 * np.exp((r - sigma2**2 / 2) * dt + sigma2 * np.sqrt(dt) * Z3)
# Calculate the payoff for each path at maturity (T)
payoff_T = np.maximum(S1_T - S2_T - K, 0)
# Average the payoffs and discount back to present value
option_price = np.exp(-r * T) * np.mean(payoff_T)
return option_price
option_price = monte_carlo_spread_option_price(S1, S2, K, T, r, sigma1, sigma2, rho, num_simulations)
print(f'The price of the spread call option is: {option_price}')
I am also trying to add control variates to reduce the simulation error, something like this:
$$E[e^{-rT} \cdot C(T)] = c + E[e^{-rT}(C(T)-c(T))]$$
where
$C(T) = \max((S_1(T) - S_2(T) - K),0)$,
$\begin{align} c(T) &= C(a,b) \\ & = E_0 e^{-rT} \left((S_1(T) - S_2(T) - K) I \left(S_1(T) \geq \frac{a (S_2(T))^b}{E[(S_2(T))^b]}\right)\right), \end{align}$
$a = F_2 + K$,
$b = \frac{F_2}{F_2+K}$,
and where $F_2$ is the forward price of the asset $S_2$.