Use case · Pricing

Price discrete dividends and de-Americanize an equity quote

A DividendSchedule on IvSolveInputs prices the escrowed spot S − Σ Dᵢ·e^(−r·tᵢ) through the unchanged Bjerksund-Stensland kernel. de_americanize_quote then strips the early-exercise premium off an American quote and hands back a European-equivalent price and implied volatility — the shape a surface fitter can actually consume — with the premium surfaced as bias telemetry rather than thresholded away.

When to use it

  • You are fitting an SVI / SSVI surface on listed equity options. The quotes are American and the underlying pays discrete cash dividends, so neither the exercise style nor the carry assumption matches what the smile model expects.
  • You need an implied vol from a dividend-paying American quote that is not biased by a continuous-yield approximation — a schedule-blind inversion of the same quote can be off by more than a vol point.
  • You want the early-exercise premium as an explicit, per-contract number you can gate on — eep_fraction() tells you how far the de-Americanization moved the quote, so a heavily exercise-loaded contract can be dropped rather than silently fitted.

The escrow

The escrowed-spot model subtracts the present value of the dividends that fall on or before expiry from the observed cum-dividend spot, then diffuses the remainder as ordinary geometric Brownian motion:

S_esc = S − Σ_{tᵢ ≤ T} Dᵢ · e^(−r·tᵢ)

Events beyond the option's expiry are ignored by model definition, not rejected — so one per-underlying schedule can be shared across a whole chain of expiries. The escrow is computed once per solve, outside the root-finder, and the unchanged Bjerksund-Stensland kernel prices the escrowed process. An empty schedule (or one whose events all fall beyond expiry) reproduces the no-dividend path bit-for-bit.

Example

use ferro_risk::{
    american_price_with_dividends, contract_analytics, de_americanize_quote,
    DividendEvent, DividendSchedule, ExerciseStyle, IvSolveInputs, OptionType,
    PricingInputs, PricingModel,
};

// One $0.96 quarterly dividend going ex 38 days out; the option has 110 days.
let schedule = DividendSchedule::new(vec![
    DividendEvent::new(38.0 / 365.0, 0.96)?,
])?;

let pricing = PricingInputs {
    option_type: OptionType::Put,
    exercise_style: ExerciseStyle::American,
    spot: 190.0,          // observed, cum-dividend
    strike: 195.0,
    time_to_expiry: 110.0 / 365.0,
    rate: 0.043,
    dividend_yield: 0.0,  // discrete schedule, not a continuous yield
    volatility: 0.26,
};

// 12.9220 with the schedule; 12.4141 without it.
let premium = american_price_with_dividends(&pricing, &schedule)?;

// Invert an observed quote and strip the early-exercise premium.
let solve = IvSolveInputs {
    option_type: OptionType::Put,
    exercise_style: ExerciseStyle::American,
    spot: 190.0,
    strike: 195.0,
    time_to_expiry: 110.0 / 365.0,
    rate: 0.043,
    dividend_yield: 0.0,
    dividends: Some(schedule),
};

let quote = de_americanize_quote(&solve, premium)?;
// quote.european_equivalent_iv()    → 0.26000  (0.27232 with dividends: None)
// quote.european_equivalent_price() → 12.6626
// quote.early_exercise_premium()    → 0.2594
// quote.eep_fraction()              → 0.02008

// The same schedule flows through the fused analytics path.
let analytics =
    contract_analytics(&solve, premium, PricingModel::BjerksundStensland)?;
# Ok::<(), ferro_risk::FerroRiskError>(())
Why it matters

On that contract the schedule-aware inversion recovers the true 0.26000. Inverting the identical quote with dividends: None returns 0.27232 — a 1.23 vol-point overstatement fed straight into whatever surface, VRP read, or z-score consumes it.

Greeks are full-map

The Greeks follow the institutional convention: they are total derivatives of V(S, t, r, σ) with the dividend present value inside the differentiation, not partials of the escrowed process holding the escrow fixed. Delta, gamma, vega, vanna, and volga pass through unchanged; rho gains +Δ·B where B = Σ tᵢ·Dᵢ·e^(−r·tᵢ); theta, charm, veta, and color gain −(r·PV/365) times the spot-partial of the differentiated quantity. Every correction sign is pinned by finite-difference cross-checks against the actual pricing map.

The types

DividendEventDescription
new(ex_time_years, cash_amount)Validated constructor — both must be finite and strictly positive.
ex_time_years()Ex-dividend time in year fractions from the valuation instant.
cash_amount()Cash paid per share at the ex-time.
DividendScheduleDescription
new(events)Validated constructor — ex-times must be non-decreasing; ties are allowed (a special and a regular dividend can share an ex-date).
empty()The empty schedule: the exact no-discrete-dividend identity.
events()Events in non-decreasing ex-time order.
DeAmericanizedQuoteDescription
european_equivalent_price()European twin price at the de-Americanized volatility (on the escrowed spot when a schedule is present).
european_equivalent_iv()The de-Americanized implied volatility — the Bjerksund-Stensland inversion of the American quote.
early_exercise_premium()American quote minus the European twin, floored at zero.
eep_fraction()The premium as a fraction of the American quote, in [0, 1]. Reported, never thresholded.
Scope

A non-empty schedule is only meaningful on the BS2002 American path; pairing it with another model or exercise style fails loud with UnsupportedModelExerciseCombination rather than silently ignoring the dividends. Surface-level de_americanize_surface_input does not yet take a schedule.

Model bias

The escrow is an approximation and the crate documents it rather than hiding it: with q = 0 an escrowed American call equals its European twin, a known consequence of the model that is pinned as a regression anchor. The reference oracle is a control-variate CRR tree on the same escrowed diffusion with an independently recomputed escrow, frozen as a 10,000-step fixture.

Related

Feed the European-equivalent price and IV into surface calibration, or read the same schedule-aware contract through contract_analytics for solved IV, forward, and all ten Greeks in one call.