Class MultiCurrencyExposureSimulator
ExposureProfile feeds
the profile overloads of CvaApproximator.
In 3.0 this class absorbed the single-currency ExposureSimulator
of 2.1 to 2.4 (decision D4). A single-currency market is the special case
with zero pairs, or one pair whose foreign rate vol is 0; on that case this
engine reproduces the 2.4 single-currency results path for path from the
same seed, to the tolerance pinned in ExposureSimulatorFoldTest
(own test against values printed by the 2.4.0 code). The trade terms
MultiCurrencyExposureSimulator.SwapTerms, MultiCurrencyExposureSimulator.FxForwardTerms and MultiCurrencyExposureSimulator.Csa are the 2.x
ExposureSimulator.Swap, FxForward and Csa with the
same components.
Plain idea. Every currency has a Hull-White short rate fitted to its own discount curve, every pair has a lognormal spot, and all the Brownian motions are joined by one correlation matrix. Everything is simulated under the domestic risk-neutral measure, so a foreign rate picks up the quanto drift: if the foreign rate tends to rise when the foreign currency strengthens, the domestic investor sees the foreign rate drift down.
Formal statement. Factors are ordered
[W_d, W_1, W_S1, W_2, W_S2, ...] (domestic rate, then per pair
the foreign rate and the spot). Under the domestic measure Q_d
(Brigo and Mercurio, Interest Rate Models, 2nd ed., 2006, section 12.1,
the two-currency Hull-White model):
r_d = x_d + phi_d, dx_d = -a_d x_d dt + sigma_d dW_d
r_c = x_c + phi_c, dx_c = (-a_c x_c - rho_{c,Sc} sigma_c sigma_Sc) dt + sigma_c dW_c
dS_c / S_c = (r_d - r_c) dt + sigma_Sc dW_Sc
The quanto term -rho sigma_c sigma_S is the Girsanov shift
from the foreign to the domestic bank-account measure. Bond prices in
each currency use the Hull-White closed form (Brigo and Mercurio, eq. 3.39)
with that currency's (a, sigma, curve) and the state x_c:
P(t,T) = P(0,T)/P(0,t) * exp( (V(t,T) - V(0,T) + V(0,t)) / 2 - B(t,T) x(t) )
B(t,T) = (1 - e^{-a (T-t)}) / a
V(t,T) = sigma^2/a^2 [ tau - 2 B(tau) + (1 - e^{-2 a tau}) / (2a) ], tau = T - t
The zero-mean Gaussian
part of every state (x, its integral, and the Brownian levels) is drawn
exactly per grid step from its joint covariance, built from integrals
of products of the kernels c0 + c1 e^{-a s}; the quanto drift
enters as the deterministic mean -rho sigma_c sigma_S B_c(t) of
x_c and -rho sigma_c sigma_S (t - B_c(t)) / a_c of its integral.
The spot is then exact:
S_c(t) = S_c(0) * exp(-int r_c) / D_d(0,t) * exp(-sigma_S^2 t / 2 + sigma_S W_S(t)) exp(-int_0^t r_c) = P_c(0,t) exp(-V_c(0,t)/2 - int_0^t x_c)
so D_d(0,t) S_c(t) exp(int r_c) is an exact martingale and
E[D_d(0,t) S_c(t) P_c(t,T)] = S_c(0) P_c(0,T) with no
discretisation bias (tested).
Multi-curve swaps: each swap may carry its own projection curve.
The basis to the discount curve is held deterministic: for a period
(S, T) the simulated projection ratio is
P^f(t,S)/P^f(t,T) = k(S,T) P_d(t,S)/P_d(t,T) with
k = [P^f(0,S)/P^f(0,T)] / [P_d(0,S)/P_d(0,T)], the usual
deterministic-spread multi-curve extension (Mercurio, Interest rate
and the credit crunch: new formulas and market models, 2009, section 3,
with zero spread volatility). The floating coupon pays
k / P_d(S,T) - 1 per unit notional at T, fixed at S. With the
projection equal to the discount curve, k = 1 and the 2.1 single-curve
swap is recovered. Since 2.3 the basis may instead be stochastic
(MultiCurrencyExposureSimulator.BasisFactor), and swaps may be written in a foreign currency
(MultiCurrencyExposureSimulator.ForeignSwap); both are opt-in through the ten-argument
simulate.
Worked example. A 5y EUR/USD forward (domestic USD) with
sigma_S = 12 %, sigma_EUR = 1 %, rho(EUR rate, spot) = -0.5: the
forward FX rate is lognormal under the 5y USD forward measure with
variance int |sigma_S e_S - sigma_c B_c e_c + sigma_d B_d e_d|^2,
so the discounted expected exposure at every date is a Black call; the
test fxForwardEeMatchesBlackWithStochasticRates checks the
simulation against that integral (own test, independent quadrature).
Wrong-way risk stays path-consistent: the rates driver of the
profile is the domestic Brownian W_d and the FX driver is W_S of the
pair chosen by wrongWayFxPair, read on the same paths that
produce the exposure. Swaps are domestic only.
Trades and collateral: a vanilla swap (fixed against a floating leg on
the same schedule, accrual = time between dates) is valued at t from the
simulated curves, with the floating coupon in progress fixed at its reset;
reset dates are added to the internal grid. An FX forward to buy N
foreign at strike K is worth N (S P_f(t,T) - K P_d(t,T)). A cash
flow paid at t is not part of the value at t. Under a two-way CSA the
target at a margin call on value V is V - H if V > H,
V + H if V < -H, else 0, with threshold H; the balance moves to
the target only when the change is at least the minimum transfer amount.
The call for exposure date t is made on the value at t - MPR, so
the collateralised exposure at t is max(V(t) - C(t - MPR), 0)
(Gregory, The xVA Challenge, 3rd ed., 2015, ch. 7). Research lane.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordStochastic projection-discount basis for domestic swaps that carry a projection curve (added in 2.3).static final recordCollateral agreement terms (two-way, symmetric).static interfaceA discount functiont -> P(0,t), t in years, P(0,0) = 1.static final recordDomestic Hull-White short rate.static final recordOne foreign currency: its Hull-White short rate and the spot against the domestic currency (domestic per foreign).static final recordA swap in a foreign currency (added in 2.3).static final recordAn FX forward on one pair.static final recordFX forward: buyforeignNotionalunits of foreign currency atstrikedomestic per foreign atmaturityYears; a negative notional sells.static final recordThe market: domestic rate, foreign currencies, and the correlation of the factors[W_d, W_1, W_S1, W_2, W_S2, ...].static final recordA domestic swap with an optional projection curve for its floating leg.static final recordVanilla fixed-for-floating swap. -
Method Summary
Modifier and TypeMethodDescriptionstatic ExposureProfilesimulate(MultiCurrencyExposureSimulator.Market market, List<MultiCurrencyExposureSimulator.Swap> swaps, List<MultiCurrencyExposureSimulator.ForeignSwap> foreignSwaps, List<MultiCurrencyExposureSimulator.FxForward> forwards, MultiCurrencyExposureSimulator.BasisFactor basis, MultiCurrencyExposureSimulator.Csa csa, double[] times, int paths, long seed, int wrongWayFxPair) Simulates a netting set with foreign-currency swaps and an optional stochastic basis (added in 2.3).static ExposureProfilesimulate(MultiCurrencyExposureSimulator.Market market, List<MultiCurrencyExposureSimulator.Swap> swaps, List<MultiCurrencyExposureSimulator.FxForward> forwards, MultiCurrencyExposureSimulator.Csa csa, double[] times, int paths, long seed) Simulates the netting set with the FX wrong-way driver taken from pair 0.static ExposureProfilesimulate(MultiCurrencyExposureSimulator.Market market, List<MultiCurrencyExposureSimulator.Swap> swaps, List<MultiCurrencyExposureSimulator.FxForward> forwards, MultiCurrencyExposureSimulator.Csa csa, double[] times, int paths, long seed, int wrongWayFxPair) Simulates the netting set.
-
Method Details
-
simulate
public static ExposureProfile simulate(MultiCurrencyExposureSimulator.Market market, List<MultiCurrencyExposureSimulator.Swap> swaps, List<MultiCurrencyExposureSimulator.ForeignSwap> foreignSwaps, List<MultiCurrencyExposureSimulator.FxForward> forwards, MultiCurrencyExposureSimulator.BasisFactor basis, MultiCurrencyExposureSimulator.Csa csa, double[] times, int paths, long seed, int wrongWayFxPair) Simulates a netting set with foreign-currency swaps and an optional stochastic basis (added in 2.3). With no foreign swaps and a null basis it equalssimulate(Market, List, List, Csa, double[], int, long, int)path for path.- Parameters:
market- marketswaps- domestic swaps (may be empty)foreignSwaps- foreign-currency swaps (may be empty)forwards- FX forwards (may be empty)basis- stochastic basis factor, or null for the deterministic basiscsa- collateral terms, or nulltimes- exposure dates, strictly ascending, > 0paths- paths, ≥ 2seed- seedwrongWayFxPair- pair whose spot Brownian is the profile's FX driver- Returns:
- the exposure profile
-
simulate
public static ExposureProfile simulate(MultiCurrencyExposureSimulator.Market market, List<MultiCurrencyExposureSimulator.Swap> swaps, List<MultiCurrencyExposureSimulator.FxForward> forwards, MultiCurrencyExposureSimulator.Csa csa, double[] times, int paths, long seed) Simulates the netting set with the FX wrong-way driver taken from pair 0.- Parameters:
market- marketswaps- swaps (may be empty)forwards- FX forwards (may be empty)csa- collateral terms, or nulltimes- exposure dates, strictly ascending, > 0paths- paths, ≥ 2seed- seed- Returns:
- the exposure profile
-
simulate
public static ExposureProfile simulate(MultiCurrencyExposureSimulator.Market market, List<MultiCurrencyExposureSimulator.Swap> swaps, List<MultiCurrencyExposureSimulator.FxForward> forwards, MultiCurrencyExposureSimulator.Csa csa, double[] times, int paths, long seed, int wrongWayFxPair) Simulates the netting set.- Parameters:
market- marketswaps- swaps (may be empty)forwards- FX forwards (may be empty)csa- collateral terms, or nulltimes- exposure dates, strictly ascending, > 0paths- paths, ≥ 2seed- seedwrongWayFxPair- pair whose spot Brownian is the profile's FX driver (zero driver if no forward trades that pair)- Returns:
- the exposure profile
-