Black–Scholes
rl.SwitchingBlackScholesProcess(chain, S0, r, q, sigma) is QuantLib’s BlackScholesMertonProcess with the
volatility sigma allowed to switch.
The model
Write \(S_T = F\,e^{X_T}\) with \(F = S_0e^{(r - q)T}\) the forward, so that \(e^{X}\) is a martingale.
Reduction
Over an interval \(dt\) spent in regime \(i\), \(X\) moves by a normal amount with mean \(-\tfrac12\sigma_i^2\,dt\) and variance \(\sigma_i^2\,dt\), which multiplies \(e^{iuX}\) on average by \(e^{g_i\,dt}\). Meanwhile the regime jumps at the rates in \(Q\). There is no state to factor out:
Closed form
The forcing is constant, so the two-regime characteristic function is exact:
Expanding in \(\varepsilon = 1/\lambda\) gives Black–Scholes at the averaged variance, times the Green–Kubo factor \(e^{\varepsilon\tilde g^2T/2}\) and the memory of the starting regime. A call is Lewis’s formula,
Python
S0, r, q, sigma, lam, T = 100.0, 0.03, 0.0, [0.30, 0.15], 25.0, 1.0
def phi(u):
g = [-0.5 * s * s * (u * u + 1j * u) for s in sigma]
return exact_two_state(g[0], g[1], lam, T)
model = rl.SwitchingBlackScholesProcess(rl.RegimeChain.twoState(lam, lam), S0, r, q, sigma)
for K in (90.0, 110.0):
print(f"K = {K:5.0f} closed form, exact {lewis_call(phi, S0, K, r, q, T):.6f}"
f" library {library_call(model, K, T):.6f}")
K = 90 closed form, exact 16.600838 library 16.600838
K = 110 closed form, exact 6.790125 library 6.790125
regimelib.symbolic.TwoStateConstantForcing holds the same characteristic function as a sympy expression, for
unequal switching rates as well (Symbolic).
Instruments
Vanilla and digital options by the characteristic function; the continuous geometric Asian option, whose forcing in time to maturity \(\tau\) is \(iu(r - q - \tfrac12\sigma_i^2)\tau/T - \tfrac12u^2\sigma_i^2\tau^2/T^2\); barrier and American options on the coupled grid.