How FX products work
Every FX product here comes back to one idea: two currencies, each with its own discount curve, and a spot rate that ties them together today. This page explains how forwards, swaps and options follow from that, how an FX desk quotes volatility, and what changes when one currency can't be delivered offshore. The reference pages list the calls; this page is the why behind them.
What every FX product shares
An FX rate is quoted as units of the quote currency per one unit of the base: EUR/USD at 1.10 means 1.10 dollars per euro. A forward is quoted the same way, either as an outright rate or as forward points, the outright less the spot, usually in pips (units of the fourth decimal).
A market for FX products holds three things: a discount curve for each currency, built from that
currency's own quotes, and the spot that converts between them, set with with_fx_rates. Which
pairs exist, their spot lags and their calendars are market conventions, listed in the
FX conventions catalog.
Covered interest parity
A euro held to a date and exchanged then must cost the same, in dollars, as a euro exchanged now with the dollars held to . Otherwise you could borrow in one currency, lend in the other and lock in a profit. Writing for the spot and , for the two discount factors to , the forward is
When dollar rates are above euro rates, , and the euro trades at a forward premium.
FX forwards
A forward buying euros at contract rate on receives euros and pays dollars. Convert the euros at the forward and discount in dollars, and its value is
Struck at it's worth nothing. Once has passed the currencies have been exchanged, and the contract is worth nothing too. See FX forwards.
FX swaps
An FX swap exchanges two currencies now and exchanges them back later, at rates agreed today. The second exchange undoes the first, so it carries no currency risk: it's a loan in one currency secured by the other. That's why banks use it to fund in a currency they don't hold.
It's two forwards on one pair with opposite notionals: buy base on at , sell base on at . Its value is the sum of the two forwards' values,
The swap points are , the interest rate differential over the swap's life. Because the points carry that differential, FX swaps are also the instruments that mark one currency's discount curve against another's, which cross-currency calibration does. See FX swaps.
FX options
An FX option is the right, not the obligation, to exchange two currencies at a fixed rate on a future date. It expires on one date and, if exercised, delivers on its own delivery date, usually the pair's spot lag after expiry.
How the surface is quoted
An FX desk doesn't quote vols by strike. For each expiry it quotes three numbers:
- the at-the-money vol;
- the 25-delta risk reversal, the call's vol less the put's, which carries the skew;
- the 25-delta butterfly, the wings' average vol over the at-the-money vol, which carries the smile's curvature.
From those three, each expiry's smile is built as three nodes keyed by the option they price:
25P, the put with delta ; ATM, the delta-neutral straddle; and 25C, the call with delta
. An option reads its vol at its strike, with each node placed at the strike its delta names.
Across expiries the surface is linear in total variance. How a pair's deltas are quoted, spot or
forward, premium-adjusted or not, is a market convention you pass when you build the surface; see
FX vol surface.
Garman-Kohlhagen
Under Garman-Kohlhagen the base currency pays a continuous yield, its own interest rate. With the forward to delivery, the vol the smile reads at the strike , the time to expiry and the quote currency's discount factor to delivery, a call on units of base is worth
and a put is .
Put-call parity
A call less a put at one strike pays whatever the rate at expiry: that's a forward bought at . So, whatever the vol,
Strikes named by delta
A strike can be named by its delta instead. Under the spot convention a put's delta is
, so the 25-delta put is the strike where that equals , with
worked out at the vol the smile reads at that strike. The strike and the vol depend on each
other, so the pair is solved together. On a smile that quotes the 25-delta put, the answer is the
25P node: its strike and its vol. See FX options.
Non-deliverable forwards
Some currencies, such as the won, the rupee and the real, can't be delivered offshore. A non-deliverable forward (NDF) never exchanges the local currency. Two business days before its value date, the pair's published rate, the fixing, is compared with the contract rate, and the difference on the notional is paid in a deliverable currency, usually dollars.
Because the local currency can't leave the country, the forward traded offshore isn't the one
onshore rates imply. Capital controls keep the two markets apart, and the gap moves with demand for
offshore hedging. The offshore forward lives on the offshore curve: the local currency's
discount under dollar collateral, KRW-CSA-USD for won, which the offshore recipe marks from NDF
outrights:
An NDF buying dollars against won at contract rate pays dollars at the fixing . Before the fixing, that amount is projected at the offshore forward and discounted in dollars, since dollars are what it pays:
The recipe marks the offshore curve so that reproduces each quoted outright, so an NDF struck at a quoted outright is worth nothing. The onshore forward is a different number, and the NDF doesn't read it. Each market's NDF terms, its fixing source, calendars and lags, are carried as templates, listed in the non-deliverable conventions catalog. See NDF.
Non-deliverable options
A non-deliverable option (NDO) is to an FX option what an NDF is to a forward. It's European, it expires on the fixing date the NDF terms give for its tenor, and its payoff is converted at that fixing and paid in dollars. Converting at the fixing doesn't change the payoff's shape, so it's priced by Garman-Kohlhagen on the pair's surface. What changes is the forward: the won leg is never paid, so the option reads the offshore forward, as the NDF does.
A call less a put at one strike pays won, converted at the fixing to dollars, which is the NDF at that strike:
See NDO.
Non-deliverable swaps
A non-deliverable swap (NDS) is the local market's own interest rate swap, a won swap on the 3M CD rate for example, with each net payment converted at the FX fixing two business days before it and paid in dollars. A non-deliverable cross-currency swap (NDCCS) pays a local fixed leg, settled in dollars at each payment's fixing, against a SOFR leg, and exchanges notionals at the end.
Both read the offshore curve. NDS par rates don't mark it, because all of an NDS's payments convert
by the same factor and say little about the discount. What they do mark is the local index the swap
floats on: the KRW recipe takes KRW-CD-NDS par rates, when the sheet quotes them, and marks the 3M
CD projection from them. Each of those rungs is an NDS solved against the dollar curve and the
offshore won curve, so those two must be on the market before the KRW sheet is added. An NDS's par
rate is the fixed rate at which it's worth nothing; an NDCCS's is the local fixed rate at which its
converted local leg equals its SOFR leg. See NDS and NDCCS.
From formula to API
| Symbol | Meaning | Rust | Python |
|---|---|---|---|
| the spot, quote per base | MarketContext::with_fx_rates |
MarketContext.with_fx_rates |
|
| each currency's discount | with_recipe_quotes per currency |
with_recipe_quotes per currency |
|
| the forward | from the market's curves | from the market's curves | |
| of a forward | its value | FxForward::new, then AnyInstrument::npv |
products.fx_forward, then Instrument.npv |
| an FX swap | two forwards as one trade | FxSwap::new(near, far) |
products.fx_swap(near, far) |
| the pair's surface | FxVolSurface::new, pinned by with_fx_vols |
vols.FxVolSurface, pinned by with_fx_vols |
|
| an option's value | FxOption::new, then AnyInstrument::npv |
products.fx_option, then Instrument.npv |
|
| a strike by delta | the 25-delta put | Strike::AtDelta(0.25) |
products.fx_option(…, delta=0.25) |
| the offshore curve | with_recipe_quotes under KRW-CSA-USD |
with_recipe_quotes("KRW-CSA-USD", …) |
|
| an NDF, an NDO | drafted from a template | AnyTemplate::ndf, AnyTemplate::ndo |
Template.ndf, Template.ndo |
| an NDS, an NDCCS | drafted from a template | AnyTemplate::nds, CrossCurrencySwap::from_template |
Template.nds, Template.cross_currency_swap |
See also
- FX forwards, FX swaps and FX options, the deliverable products.
- NDF, NDO and NDS and NDCCS, the non-deliverable ones.
- Cross-currency calibration, for a curve marked from FX swaps.
- FX conventions and FX vol surface, the conventions catalog and the surface's reference page.
From the 0.0 line at revision bf7f2e2. Every printed number is that revision's own output.