Pricing engines
Every engine takes the model and the starting regime. The characteristic-function engines price bonds, European
options, digitals, geometric Asians, bond options, swaptions, caps and credit default swaps; the grid engines price
early exercise and barriers; Monte Carlo is a referee.
The expansion
- rl.FastSwitchingEngine(model, order=4, regime=0, nodes=96, tol=1e-10, maxOrder=12, rtol=1e-12)
The fast-switching expansion of the reduced system a' = (Q + diag g) a in the mean holding time of the chain,
n / -trace Q, through order terms with the initial layer that carries the starting regime. order=None
adds terms until successive orders agree to tol or the series stops improving — the best truncation of an
asymptotic series — and records orderUsed and lastIncrement after NPV(). At Fourier nodes where the
series diverges (large forcing at high frequency) the reduced system is solved numerically instead and the count is
reported; see rl.ExpansionWarning.
engine = rl.FastSwitchingEngine(model, order=None, regime=0)
option.setPricingEngine(engine)
option.NPV()
engine.orderUsed, engine.lastIncrement
option._result("diagnostics")
The numerical solution
- rl.NumericalSwitchingEngine(model, regime=0, nodes=96, rtol=1e-12)
The reduced system solved without expansion: the matrix exponential when the forcing is constant in time (Black–Scholes, Merton, variance gamma), an ODE solver (DOP853) otherwise. The terminal vectors are memoised across strikes at each maturity, which is what makes calibration fast. This is the referee for the expansion with switching on, and it is exact up to quadrature for every model in the all-orders tier.
option.setPricingEngine(rl.NumericalSwitchingEngine(model, regime=1))
Monte Carlo
- rl.MonteCarloSwitchingEngine(model, regime=0, paths=100000, seed=0)
A grid-free referee: regime paths are sampled exactly and each path is priced in closed form (Vasicek bonds,
Black–Scholes options). standardError is set after NPV().
mc = rl.MonteCarloSwitchingEngine(model, regime=0, paths=200000, seed=1)
bond.setPricingEngine(mc)
bond.NPV(), mc.standardError
Finite differences
- rl.SwitchingFDEngine(model, regime=0, n=1001, steps=400, width=None, stretch=None)
Time-stepping on the coupled system u_i' = L_i u_i + sum_j Q_ij u_j, Rannacher’s implicit half-steps followed by
Crank–Nicolson. American exercise projects onto the payoff after every step; a knock-out barrier truncates the grid
at the barrier node; Bermudan swaptions and coupon-bond options compare with the exercise value, per regime, at
each exercise date on a short-rate grid (Vasicek, CIR, Hull–White in its zero-mean factor, G2 on a two-factor grid
with n = (nx, ny)); American options under the hybrid model on a (log S, r) grid. stretch concentrates the
nodes of a two-dimensional grid around the strike and the starting factor by a sinh map (the width of the dense
region as a fraction of the interval; 0.15 halves the Heston vol-of-vol grid error at a given node count); uniform
when None, which suits swaptions, whose exercise region is broad. delta, gamma and theta come from the grid for equity options.
american = rl.VanillaOption(("put", 105.0), exercise="american", maturity=1.0)
american.setPricingEngine(rl.SwitchingFDEngine(model, regime=0, n=1601, steps=800))
american.NPV(), american.delta(), american.gamma()
The first-order tier
- rl.FirstOrderFDEngine(model, regime=0, n=801, width=None, warnAbove=0.03, stretch=None)
For models whose reduction is not exact (SwitchingCEVProcess, SwitchingHestonVolOfVol): the averaged
operator, the Green–Kubo correction sum K_jk A_j A_k carried by an augmented linear system, and the memory term
of the starting regime, all at first order in the holding time. After NPV() the engine exposes averaged,
correction and memory and diagnostics with the relative size of the correction and estimatedError,
about its square; it warns above warnAbove.
cev = rl.SwitchingCEVProcess(chain, 100.0, 0.03, 0.0, sigma=[0.35, 0.15], beta=0.7)
engine = rl.FirstOrderFDEngine(cev, regime=0, n=801)
option.setPricingEngine(engine)
option.NPV()
engine.averaged, engine.correction, engine.memory, engine.diagnostics
- rl.SwitchingFDReferee(model, regime=0, n=801, width=None)
The switching model solved without expansion on the same grid, the referee for the first-order tier.