Class MultiCurrencyExposureSimulator

java.lang.Object
com.quantfinlib.credit.MultiCurrencyExposureSimulator

public final class MultiCurrencyExposureSimulator extends Object
Monte Carlo exposure generator for a netting set of multi-curve swaps and FX forwards on several currency pairs, each foreign currency with its own stochastic short rate. The output 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.