Margrabe's Formula for Exchange Option Pricing: Implementation in OptionStratLib
Margrabe's formula calculates the closed-form price of an exchange option, giving the holder the right to swap one asset for another at maturity without a strike price.
Margrabe's formula for exchange option pricing provides an analytical solution for valuing options to exchange one risky asset for another. The Rust library OptionStratLib implements this model in src/pricing/exchange.rs, offering precise calculations for correlation-dependent derivatives.
Understanding Margrabe's Formula for Exchange Options
An exchange option (or Margrabe option) grants the right to exchange asset (S_2) for asset (S_1) at maturity (T). Unlike standard options, there is no strike price—the payoff is (\max(S_1 - S_2, 0)).
The formula requires five key inputs:
- Spot prices: (S_1) and (S_2) for the two assets
- Volatilities: (\sigma_1) and (\sigma_2) for each asset
- Correlation coefficient: (\rho) between the two assets
- Dividend yields: (q_1) and (q_2) for continuous dividends
- Time to maturity: (T) in years
Implementation in the OptionStratLib Codebase
Core Pricing Logic in src/pricing/exchange.rs
The public entry point is exchange_black_scholes (lines 34-50), which validates the option type and delegates to the internal margrabe_formula function. The implementation handles both long and short positions through the apply_side helper.
// From src/pricing/exchange.rs
pub fn exchange_black_scholes(option: &Options) -> Result<Decimal, PricingError> {
// Validation: ensures OptionType::Exchange
// Extracts exotic parameters: σ₂, q₂, and ρ
// Calls margrabe_formula with computed parameters
}
Combined Volatility Calculation
The model first computes the combined volatility (\sigma) accounting for correlation between assets (lines 31-34):
[ \sigma = \sqrt{\sigma_1^2 + \sigma_2^2 - 2\rho\sigma_1\sigma_2} ]
This represents the volatility of the spread (S_1/S_2), which is the effective underlying for the exchange option.
Drift and d1/d2 Parameters
The implementation calculates the time-scaled drift (\tilde q = q_2 - q_1) (line 45), representing the net cost of carry for holding the spread position.
The d1 and d2 parameters follow the Black-Scholes structure but applied to the ratio (S_1/S_2) (lines 45-46):
[ d_1 = \frac{\ln(S_1/S_2) + (\tilde q + \frac{\sigma^2}{2})T}{\sigma\sqrt{T}} ]
[ d_2 = d_1 - \sigma\sqrt{T} ]
Final Price Computation
The option price combines present values of both assets with their respective risk-neutral probabilities (line 51):
[ C = S_1 e^{-q_1T} N(d_1) - S_2 e^{-q_2T} N(d_2) ]
Where (N(\cdot)) is the standard normal cumulative distribution function. For short positions, the apply_side function (lines 56-60) negates the price.
Practical Code Examples
Pricing an Exchange Option with Margrabe's Formula
This example demonstrates creating an exchange option and calculating its price using the implementation in src/pricing/exchange.rs:
use optionstratlib::{Options, OptionType, Side, ExpirationDate, OptionStyle};
use optionstratlib::pricing::exchange::exchange_black_scholes;
use positive::{pos_or_panic, Positive};
use rust_decimal_macros::dec;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create exchange option: right to exchange S2 (price 100) for S1 (price 150)
let option = Options::new(
OptionType::Exchange { second_asset: 100.0 },
Side::Long,
"ASSET1".to_string(),
Positive::HUNDRED, // placeholder strike (unused)
ExpirationDate::Days(pos_or_panic!(90.0)),
pos_or_panic!(0.25), // σ₁: volatility of S1
Positive::ONE, // quantity
pos_or_panic!(150.0), // S₁: price of asset 1
dec!(0.05), // risk-free rate
OptionStyle::Call, // style irrelevant for exchange
pos_or_panic!(0.02), // q₁: dividend yield of S1
Some(optionstratlib::model::ExoticParams {
exchange_second_asset_volatility: Some(pos_or_panic!(0.20)), // σ₂
exchange_second_asset_dividend: Some(pos_or_panic!(0.01)), // q₂
exchange_correlation: Some(dec!(0.5)), // ρ
..Default::default()
}),
);
let price = exchange_black_scholes(&option)?;
println!("Exchange option price = ${:.4}", price);
Ok(())
}
Using the High-Level API
For existing Options instances, the library provides a generic pricing method that automatically dispatches to Margrabe's formula:
let price = option.calculate_price_black_scholes()?; // Automatically uses exchange_black_scholes for Exchange type
Verifying Correlation Effects
The test suite in src/pricing/exchange.rs (lines 63-79) demonstrates how correlation impacts pricing:
// Low correlation increases option value (diversification benefit)
let mut low_corr = option.clone();
low_corr.exotic_params.as_mut().unwrap().exchange_correlation = Some(dec!(0.0));
let low_price = exchange_black_scholes(&low_corr)?;
// High correlation decreases option value
let mut high_corr = option;
high_corr.exotic_params.as_mut().unwrap().exchange_correlation = Some(dec!(0.9));
let high_price = exchange_black_scholes(&high_corr)?;
assert!(low_price > high_price);
Key Files and Architecture
src/pricing/exchange.rs– Core implementation of Margrabe's formula withexchange_black_scholesandmargrabe_formulafunctions.src/model/types.rs– DefinesOptionType::Exchange { second_asset: f64 }variant.src/pricing/mod.rs– Public re-exports for pricing functions (line 193).src/model/option.rs–Optionsstruct and high-levelcalculate_price_black_scholesmethod.src/model/exotic_params.rs– Holds exchange-specific parameters including volatility, dividend yield, and correlation for the second asset.
Summary
- Margrabe's formula provides a closed-form solution for pricing exchange options where one asset is swapped for another without a strike price.
- The OptionStratLib implementation in
src/pricing/exchange.rscomputes combined volatility accounting for correlation, then applies the standard Black-Scholes structure to the asset ratio. - Key inputs include both assets' prices, volatilities, dividend yields, correlation coefficient, and time to maturity.
- The library handles long and short positions through automatic sign adjustment and validates all exotic parameters before computation.
Frequently Asked Questions
What is Margrabe's formula used for?
Margrabe's formula is used to price exchange options, which give the holder the right to exchange one risky asset for another at maturity. Unlike standard options, there is no cash strike price—the "strike" is the second asset itself. The formula is commonly applied in mergers and acquisitions, spread trading, and currency swap valuations.
How does correlation affect exchange option pricing?
Correlation has an inverse relationship with exchange option value. When correlation (\rho) between the two assets is low (near 0), the combined volatility (\sigma = \sqrt{\sigma_1^2 + \sigma_2^2 - 2\rho\sigma_1\sigma_2}) increases, raising the option price. High correlation (near 1) reduces the effective volatility of the spread, decreasing the option value because the assets tend to move together, reducing the chance of a favorable exchange.
What parameters are required for Margrabe's formula?
The formula requires two sets of asset parameters: spot prices ((S_1), (S_2)), volatilities ((\sigma_1), (\sigma_2)), and continuous dividend yields ((q_1), (q_2)). Additionally, you need the correlation coefficient (\rho) between the assets and the time to maturity (T). In OptionStratLib, these are passed via the ExoticParams struct with fields exchange_second_asset_volatility, exchange_second_asset_dividend, and exchange_correlation.
Where is Margrabe's formula implemented in OptionStratLib?
Margrabe's formula is implemented in src/pricing/exchange.rs within the margrabe_formula function, which is called by the public API function exchange_black_scholes. The implementation handles the combined volatility calculation, d1/d2 computations, and final price derivation using the standard normal CDF. The option type definition resides in src/model/types.rs as OptionType::Exchange, while additional parameters are stored in the ExoticParams struct.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →