Use case · Construct

Build a bull call debit from one chain

The simplest construction path: a typed ChainSnapshot in, a vector of SpreadCandidate out. Configure target delta, DTE band, and wing width via SpreadBuilder; the engine enumerates strike pairs, prunes infeasible combinations, and prices each candidate on the FerroRisk surface.

When to use it

  • You want a directional, defined-risk long position and need the feasible strike pairs enumerated and priced for you.
  • You want construction-time constraints (target delta, DTE band, wing width) rather than filtering a giant candidate set afterward.
  • You want each candidate priced on the FerroRisk surface with a PricingTrace back to the fit.

Example

use ferro_spread::{ChainSnapshot, SpreadBuilder, SpreadStrategy};

let chain = ChainSnapshot::from_enriched(quote_snapshot)?;

let policy = SpreadBuilder::default()
    .strategy(SpreadStrategy::BullCallDebit)
    .dte_range(21..=45)
    .target_delta(0.30)
    .min_wing_pts(5.0)
    .max_wing_pts(20.0);

let candidates: Vec<SpreadCandidate> = policy.construct(&chain)?;

// Each candidate carries legs, debit, max profit,
// max loss, breakeven, and a typed PricingTrace
// pointing back at the FerroRisk surface fit.

Notes

  • The candidate set is everything feasible under the policy; impose priorities with a Ranker.
  • Units and the meaning of debit / max loss / breakeven follow the conventions.
Pricing

Construction does not invent prices — each leg is priced on the same FerroRisk parametric surface that ships as a standalone engine, so the spread P&L and per-leg Greeks are consistent by construction.