The fast-switching engine
One recursion for every model whose state factors out of an exponential-affine formula.
Many expectations of the form $\mathbb{E}\big[e^{-\int_0^t c\cdot x_r\,dr}\,\phi(x_t)\big]$ are exponential-affine in the state $x$, with coefficients that solve ODEs. When a finite Markov chain $y_t$ modulates the model but leaves the state-dependent coefficient unchanged, the state factors out and what remains is a linear system in time only:
$$u_i(t,x) = e^{-B(t)\cdot x}\,a_i(t), \qquad a' = \big(Q + \operatorname{diag} g(t)\big)\,a, \qquad a(0) = \mathbf 1 .$$The model enters only through the functions $g_i(t)$, one per regime. The table lists them for the examples on this site.
| Model | Switching parameters | Time function |
|---|---|---|
| Vasicek, any number of regimes | mean level, volatility | $-\kappa\theta_i B + \tfrac12\sigma_i^2 B^2$ |
| Gaussian factors, two-name credit | means, volatilities, correlations | $-\sum_j \kappa_j\theta_{ji} B_j + \tfrac12\sum_{j,l}\rho_{jl,i}\sigma_{ji}\sigma_{li}B_jB_l$ |
| CIR | mean level | $-\kappa\theta_i B_{\mathrm{CIR}}$ |
| Vasicek with jumps | mean, volatility, jump intensity | $-\kappa\theta_i B + \tfrac12\sigma_i^2B^2 + \ell_i\big(\tfrac{1}{1+mB} - 1\big)$ |
| Poisson counts | arrival rate | $(z-1)\,\ell_i$ |
| Heston | long-run variance | $\kappa\theta_i D(t)$, complex |
| Fast mean-reverting factor | mean level and volatility, continuously | operator in the Hermite basis, with correlation |
The recursion
Write the generator as $Q = Q_0/\varepsilon$ with $\varepsilon$ the mean holding time, let $\pi$ be the stationary distribution, and set $s = \pi\cdot a$ and $w = a/s - \mathbf 1$, so that $\pi\cdot w = 0$. Then
The outer series $w = \sum_{n\ge1}\varepsilon^n w_n$ follows from $w_n = Q_0^{\#}\big(w_{n-1}' - F_{n-1}\big)$, where $Q_0^{\#}$ is the group inverse of $Q_0$ and $F_{n-1}$ collects the terms of $F$ of that order. Each step is solvable because $\pi$ annihilates the right-hand side. When every $g_i$ is a sum of exponentials $e^{-\alpha t}$ the class is closed under products and derivatives, so every $w_n$ is again such a sum and every term of $\log s$ integrates in closed form. Otherwise $g_i$ is held as a Chebyshev series.
The outer series does not satisfy $w(0) = 0$. The initial layer $\eta = w - w_{\mathrm{outer}}$, in the fast time $\tau = t/\varepsilon$, solves $d\eta/d\tau = Q_0\eta + \varepsilon\,[F(w_{\mathrm{outer}}+\eta) - F(w_{\mathrm{outer}})]$ with $\eta(0) = -w_{\mathrm{outer}}(0)$. It is solved order by order in the eigenbasis of $Q_0$, in the span of $\tau^k e^{\mu\tau}$, and it contributes to $\log s$ from order $\varepsilon^2$ or later. The result is $a_i = s\,(1 + w_i + \eta_i)$ with error $O(\varepsilon^{N+1})$ after $N$ orders.
Other inputs
Time-dependent parameters, such as a Hull–White mean level $\theta(t)$ fitted to a yield curve, change only the functions $g_i$, which the engine then holds as Chebyshev series. A terminal exponential payoff $e^{-\beta x_T}$ changes only the starting value of $B$, so transforms of the terminal state, and the option prices that follow from them by Fourier inversion, need no new machinery. A continuous fast factor in place of the chain is treated on its own page.
Code and checks
- fastswitch.py: the engine, for any finite chain, real or complex coefficients.
- models.py: the $g_i$ for each model, with the state-dependent factor.
- verify_engine.py: agreement with the two-state code, and orders 1 to 6 on a three-state chain against a 30-digit numerical solution.
- verify_models.py: each model's reduction against Monte Carlo of the switching model, and each expansion's convergence.