Vasicek
rl.SwitchingVasicek(chain, r0, a, b, sigma) is QuantLib’s Vasicek(r0, a, b, sigma) with the mean level
b and the volatility sigma allowed to switch.
The model
with \(y_t\) the hidden regime. The same equation serves as a default intensity, in which case the bond below is a survival probability.
Reduction
The bond \(u_i(t, r) = \mathbb{E}[e^{-\int_0^t r_s ds} \mid r_0 = r,\ y_0 = i]\) solves
Try \(u_i = e^{-B(t)r}a_i(t)\). The terms proportional to \(r\) cancel when \(B' = 1 - aB\), so \(B(t) = (1 - e^{-at})/a\). The reversion speed does not switch, so one \(B\) serves every regime, and
Closed form
With \(\bar b, \tilde b = \tfrac12(b_1 \pm b_2)\), \(\bar s, \tilde s = \tfrac12(\sigma_1^2 \pm \sigma_2^2)\) and \(I_n = \int_0^T B^n\),
Python
r0, a, b, sigma, lam, T = 0.03, 0.5, [0.06, 0.02], [0.015, 0.008], 8.0, 5.0
E, B, I1, I2, I3, I4 = powers_of_B(a, T)
bbar, bt = half(b)
sbar, st = half([s * s for s in sigma])
closed = np.exp(-B * r0) * second_order(
int_gbar=-a * bbar * I1 + sbar * I2 / 2,
int_gt2=a * a * bt * bt * I2 - a * bt * st * I3 + st * st * I4 / 4,
gt_T=-a * bt * B + st * B * B / 2,
gt_0=0.0,
dgt_T=(-a * bt + st * B) * E,
lam=lam)
model = rl.SwitchingVasicek(rl.RegimeChain.twoState(lam, lam), r0, a, b, sigma)
print(f"closed form, second order {closed:.10f}")
print(f"library, numerical {library_bond(model, T):.10f}")
closed form, second order 0.8335592514
library, numerical 0.8335593214
The same formula is available as a sympy expression, with its derivatives:
from regimelib.symbolic import VasicekTwoStateBond
f = VasicekTwoStateBond(regime=0)
values = dict(r0=r0, kappa=a, theta1=b[0], theta2=b[1], sigma1=sigma[0], sigma2=sigma[1], lam=lam, T=T)
print(f"symbolic price {f.evaluate(f.price, **values):.10f}")
print(f"dP/dr0 {f.evaluate(f.delta(), **values):.10f}")
print(f"dP/dlambda {f.evaluate(f.greek('lam'), **values):.3e}")
symbolic price 0.8335592514
dP/dr0 -1.5302730828
dP/dlambda 1.123e-04
Instruments
Bonds, coupon bonds, options on bonds, swaptions, caps and Bermudan swaptions; as an intensity, survival probabilities and credit default swaps. Options on bonds use the same forcing with a terminal exponent \(c\), which changes \(B\) to \(B_c(t) = c\,e^{-at} + (1 - e^{-at})/a\), and a terminal vector that selects the regime at expiry (Instruments).