Skip to content

Conversation

@joaquinbejar
Copy link
Owner

Summary

This PR implements pricing support for Spread options as described in issue #245. Spread options are multi-asset options whose payoff depends on the difference between two underlying asset prices.

What was implemented

ExoticParams Extensions

Added spread-specific fields to ExoticParams:

  • spread_second_asset_volatility: Volatility of the second underlying asset
  • spread_second_asset_dividend: Dividend yield of the second asset
  • spread_correlation: Correlation between the two assets (-1 to 1)

Pricing Implementation

Created src/pricing/spread.rs with two pricing methods:

Kirk's Approximation (K ≠ 0)

  • Treats spread option as a call on S1 with adjusted strike (S2 + K)
  • Adjusted volatility: σ = sqrt(σ1² + (S2/(S2+K))² × σ2² - 2ρ × σ1 × σ2 × S2/(S2+K))
  • Standard Black-Scholes formula with adjusted parameters

Margrabe's Formula (K = 0)

  • Closed-form solution for exchange options
  • Combined volatility: σ = sqrt(σ1² + σ2² - 2ρσ1σ2)
  • Price = S1×e^(-q1×T)×N(d1) - S2×e^(-q2×T)×N(d2)

Payoff Structure

  • Call: max(S1 - S2 - K, 0)
  • Put: max(K - (S1 - S2), 0) = max(K + S2 - S1, 0)

Why These Methods?

  • Kirk's Approximation: Industry-standard method for spread options with non-zero strike. Provides good accuracy for most practical cases while maintaining computational efficiency.
  • Margrabe's Formula: Exact closed-form solution for exchange options (K = 0). No approximation needed when strike is zero.

Technical Decisions

  • Correlation is validated to be within [-1, 1]
  • Uses the existing big_n function for normal CDF calculations
  • Properly handles dividend yields for both assets
  • Supports both long and short positions

Common Applications

  • Energy markets: Crack spreads (crude oil vs. refined products), spark spreads (natural gas vs. electricity)
  • Agricultural markets: Crush spreads (soybeans vs. soybean meal/oil)
  • Interest rate markets: Yield curve spreads

Tests

12 comprehensive unit tests covering:

  • Spread call and put pricing (positive values)
  • Margrabe formula (K = 0 exchange option)
  • Kirk approximation (K ≠ 0)
  • Correlation impact on pricing
  • Invalid correlation rejection
  • Missing parameters handling
  • Short position pricing
  • Put-call parity verification
  • Deep ITM/OTM scenarios
  • Negative correlation handling

Files Changed

  • src/model/option.rs: Added spread fields to ExoticParams
  • src/model/format.rs: Updated Display implementations
  • src/pricing/spread.rs: NEW - Spread option pricing implementation
  • src/pricing/mod.rs: Added spread module export
  • src/pricing/black_scholes_model.rs: Routed Spread to new module
  • src/pricing/rainbow.rs: Updated ExoticParams in tests
  • src/pricing/cliquet.rs: Updated ExoticParams in tests
  • examples/examples_exotics/src/bin/cliquet_example.rs: Updated ExoticParams

Closes #245

- Add spread-specific fields to ExoticParams (volatility, dividend, correlation)
- Implement Kirk's approximation for spread options with non-zero strike
- Implement Margrabe's formula for exchange options (K = 0)
- Support both call and put spread options
- Add comprehensive unit tests (12 tests covering all scenarios)
- Update Display implementations for new ExoticParams fields
- Route Spread options in black_scholes_model.rs to new module
Removed deprecated markdown files for the following issues:
- #237: Asian Option Pricing Model
- #239: Binary Option Pricing Model
- #240: Lookback Option Pricing Model
- #241: Compound Option Pricing Model
- #242: Chooser Option Pricing Model
- #243: Cliquet Option Pricing Model

These files are no longer needed as all corresponding features have been implemented and integrated.
@joaquinbejar joaquinbejar merged commit 518ffc1 into main Jan 13, 2026
11 checks passed
@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

❌ Patch coverage is 84.00000% with 16 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/pricing/spread.rs 90.32% 9 Missing ⚠️
src/model/format.rs 0.00% 6 Missing ⚠️
src/pricing/black_scholes_model.rs 0.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
src/model/option.rs 57.37% <ø> (ø)
src/pricing/cliquet.rs 88.23% <ø> (ø)
src/pricing/rainbow.rs 94.21% <ø> (ø)
src/pricing/black_scholes_model.rs 59.67% <0.00%> (+1.86%) ⬆️
src/model/format.rs 77.12% <0.00%> (-2.55%) ⬇️
src/pricing/spread.rs 90.32% <90.32%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Implement Spread option pricing model

2 participants