Pricing, IV, Greeks,
Volatility.

Institutional-grade options pricing and volatility analytics, in pure Rust — one shared evaluation path from a single contract to a live option chain.

7 models
BSM · Black-76 · Bachelier · Heston · Jumps · Local-Vol · Bjerksund
3 surfaces
SVI · SSVI · SABR — calibration + diagnostics
10 Greeks
First + Second Order
1,800+ tests
Reference + MPFR oracles
262 theorems
Machine-checked in Lean — no sorry
~107 ns
European price / contract
~347 ns
All 10 Greeks / contract

Four pillars on one evaluation path

Pricing with full Greeks coverage, surface calibration, local-vol extraction, live chain analytics, and volatility & microstructure analytics — built so consumers get the same numerical answer whether they call a single contract, fit a surface, stream a venue's option chain, or measure the premium between implied and realized vol.

7M

Seven pricing models

European to American, lognormal to normal, deterministic to stochastic vol, with jumps. Each model named explicitly at the call site; intrinsic at expiry is model-independent.

  • BlackScholesMerton · Black-76 · Bachelier
  • DisplacedBlack — shifted-lognormal forwards
  • Heston — stochastic-vol via Fang-Oosterlee COS
  • JumpDiffusion — Merton (1976) lognormal jumps
  • Bjerksund-Stensland 2002 — American
  • Discrete cash dividends — escrowed-spot American with full-map Greeks
  • De-Americanization — European-equivalent price + IV with early-exercise-premium telemetry
  • Plus opt-in CRR reference + Dupire local-vol kernels
  • Full 10-Greek coverage on every model
σ²

Surfaces, calibrated and diagnosed

SVI, SSVI, and SABR surface calibration with fit-quality diagnostics, pluggable losses, prior regularization, and static-arbitrage repair workflows. Jaeckel IV for per-contract inversion.

  • SVI / SSVI / SABR — public calibration entry points
  • Joint cross-tenor SSVI — Gatheral-Jacquier globals shared across the surface
  • Four-tier fit quality — Healthy / Acceptable / Degenerate / Failed
  • Pluggable loss + prior — Huber, Trimmed-MSE, Bayesian smoothing
  • Quality-filtered prep + bid-ask feasibility filter
  • Vega · bid-ask precision weighting axes for liquidity-aware SVI prep
  • Model-free put-call-parity forward recovery + consistency diagnostic
  • Cross-tenor parity forward curve — market-implied borrow / financing rate
  • Provenance-aware firewall — Live anomaly gates skip Modeled / Theoretical rows
  • Static-arbitrage diagnostics + repair workflows
  • Smile-panel readouts — 25Δ / 10Δ RR + fly + ATM IV with bracket diagnostics
  • σ-standardized log-moneyness wing anchors — stationary across vol and DTE
  • Non-parametric short-DTE fallback for degenerate parametric smiles
  • Dupire local-vol extraction with PDE / forward-PDE / MC
CH

Live chain analytics

Deterministic ChainState snapshots with incremental refresh, derived market metrics, exposure analytics, and typed ferro-wave scenario attribution across baseline and shocked flow.

  • ChainState snapshots + incremental updates
  • ATM term structure · implied move · RR · butterfly
  • DEX / GEX / VEX / vanna / charm exposures
  • Call / put OI concentration · strike + expiry walls
  • Spot ladders · flip levels
  • ferro-wave scenario attribution — spot · vol · rate · time · interaction
  • Smile-aware delta selection · risk reversal · butterfly
σφ

Volatility & microstructure analytics

Realized volatility from OHLC bars, the variance risk premium split into diffusive and jump legs, option-implied correlation, and per-quote and multi-leg execution cost — typed reads on the same fail-loud numerical path.

  • Realized vol — close-to-close · Parkinson · Garman-Klass · Yang-Zhang · bipower
  • Realized jump split — jump-robust diffusive vs jump variance
  • Directional semivariance — downside / upside legs summing exactly to RV
  • Variance risk premium — VrpRead in vol-point + variance units
  • VRP decomposition — diffusive vs jump/tail legs via a Merton fit
  • Merton jump calibration — quote-anchored Q-side fit from a physical-measure prior (Esscher tilt)
  • VRP z-score — normalize the premium against a rolling baseline
  • Implied correlation + dispersion — index vs weighted constituents
  • Effective spread — quoted / half / round-trip cost, typed outcomes
  • Multi-leg round-trip cost — quantity-aware spread aggregation

From inputs to portfolio risk

Four layers. Inputs typed at the boundary, pricing dispatched explicitly across seven models, surfaces calibrated with fit-quality contracts, and analytics composed over ordered containers and live chain state — never hidden mutable state.

1

Inputs

PricingInputs, IvSolveInputs, and ChainState typed at the boundary. Time in years, rates and dividend yields continuously compounded — no implicit conversions.

2

Price

Seven models dispatch through PricingModel — BSM, Black-76, Bachelier, DisplacedBlack, Heston, JumpDiffusion, Bjerksund-Stensland — plus opt-in CRR reference and Dupire local-vol kernels.

3

Calibrate

SVI / SSVI / SABR surface calibration — per-slice or a joint cross-tenor Gatheral-Jacquier SSVI fit — with pluggable loss, prior regularization, and fit-quality classification. Dupire extracts local-vol from any calibrated surface. Smile-aware delta selectors snap to listed strikes.

4

Aggregate

Position / Strategy / Book / Portfolio containers feed aggregate Greek and bucket reports. ChainExposureState derives DEX / GEX / VEX with ferro-wave scenario attribution.

Ten workflows on one evaluation path

Entry points across the four pillars. Each one is a 10–20 line snippet that takes the workflow from typed input shape to typed output. The deeper guides live in the docs.

01 · Pricing

Price a contract, read all ten Greeks

The single-contract path. One typed PricingInputs, one named model, one call returns the full first- and second-order Greek surface on a shared internal evaluation path — no per-Greek bumping pattern, no inconsistency between sensitivities computed on different paths.

use ferro_risk::{ExerciseStyle, OptionType, PricingInputs,
             PricingModel, greeks_all};

let inputs = PricingInputs {
    option_type: OptionType::Call,
    exercise_style: ExerciseStyle::European,
    spot: 4_850.0,
    strike: 4_900.0,
    time_to_expiry: 0.25,
    rate: 0.045,
    dividend_yield: 0.0,
    volatility: 0.22,
};

let greeks = greeks_all(&inputs, PricingModel::Black76)?;
// greeks.delta, .gamma, .theta, .vega, .rho,
// .vanna, .volga, .charm, .veta, .color
Read the full guide →
Long ATM call · payoff + 10-Greek readout
02 · Pricing

Solve IV, forward, and Greeks in one call

When a workload needs solved IV, explicit forward, AND Greeks on the same contract, contract_analyticsfuses them on a shared internal evaluation path. Jaeckel's Let's-Be-Rational drives the IV solve to machine precision in a handful of iterations.

use ferro_risk::{ExerciseStyle, IvSolveInputs, OptionType,
             PricingModel, contract_analytics};

let inputs = IvSolveInputs {
    option_type: OptionType::Call,
    exercise_style: ExerciseStyle::European,
    spot: 100.0,
    strike: 100.0,
    time_to_expiry: 0.5,
    rate: 0.03,
    dividend_yield: 0.01,
};

let analytics = contract_analytics(
    &inputs,
    8.50,  // observed market price
    PricingModel::BlackScholesMerton,
)?;

// analytics.iv, .forward, .greeks (all 10)
Read the full guide →
Jaeckel solver · |residual| vs iteration
03 · Surfaces

Calibrate a vol surface with fit-quality contract

From normalized chain quotes to a typed SviSmile / SsviSlice / SabrSmile and a SurfaceCalibrationReport that grades the fit Healthy / Acceptable / Degenerate / Failed — on the residual, not just the optimizer. Model-free put-call-parity forward recovery, a joint Gatheral-Jacquier SSVI fit, and a non-parametric short-DTE fallback keep thin near-dated chains honest.

use ferro_risk::{calibrate_svi_surface, FitQuality,
             SviCalibrationPolicy, SurfaceCalibrationSearchPolicy};

let policy = SviCalibrationPolicy::default()
    .with_search(SurfaceCalibrationSearchPolicy::default());

let report = calibrate_svi_surface(&input, &policy)?;

match report.fit_quality() {
    FitQuality::Healthy => use_parametric(&report),
    FitQuality::Acceptable { reason } => // RR25 / ATM IV /
        readouts_only(&report),       // term-structure
    FitQuality::Degenerate { reason } => // shape-model breakdown
        surface_raw_interpolated_skew(/* … */)?,
    FitQuality::Failed { reason } => bail_or_retry(reason),
    _ => unreachable!(),
}
Read the full guide →
SVI fit · SPY 30D · 2026-05-07 · 11 OTM quotes
04 · Surfaces

Run the canonical smile-panel in one call

ATM IV at the smile's effective forward, 25Δ and 10Δ risk reversals, 25Δ and 10Δ butterfly flies — the canonical morning smile-panel readout — bundled into SurfaceSmileRiskMetrics for a single-call workflow that replaces 3-5 hand-rolled lookups. Each RR wing carries bracket diagnostics — bracket_delta_distance (snap to target) and bracket_spread (interpolation lever-arm) — so consumers can degrade loose-bracket wings instead of trusting the binary Interpolated flag.

use ferro_risk::{surface_smile_risk_metrics, PricingModel,
             SurfaceDeltaConvention,
             SurfaceSmileDeltaSelectionPolicy};

let metrics = surface_smile_risk_metrics(
    &smile,
    &market,
    SurfaceDeltaConvention::Forward,
    PricingModel::BlackScholesMerton,
    SurfaceSmileDeltaSelectionPolicy::default(),
    &listed_strikes,
)?;

// metrics.atm_iv()
// metrics.rr_25().risk_reversal()
// metrics.fly_25(), metrics.fly_10()

// bracket diagnostics quantify wing quality
// metrics.rr_25().put_wing().bracket_delta_distance()
// metrics.rr_25().put_wing().bracket_spread()
Read the full guide →
Smile-panel · SPY 30D · 2026-05-07
05 · Chain Analytics

Derive DEX, GEX, and flow walls from a live chain

Live ChainState in, ChainExposureReport out — per-strike and per-expiry DEX / GEX / VEX / vanna / charm, call/put OI concentration, strike walls, spot ladders, and flip-level detection. ChainExposureStatecaches incremental updates so streaming workloads don't recompute the whole chain on each refresh.

use ferro_risk::{ChainExposureInputs, ChainExposureMetric,
             PricingModel, derive_chain_exposures, strike_walls};

// chain_state, market, policy set up upstream
let inputs = ChainExposureInputs::new(
    &chain_state, &market,
    PricingModel::BlackScholesMerton, policy)?;
let report = derive_chain_exposures(&inputs)?;

// per-strike GEX, via the metric projection
for b in &report.strike_buckets {
    let gex = ChainExposureMetric::Gex
        .value(b.net_exposure);
}

// OI-side walls — one per metric
let walls = strike_walls(&report);
let call_wall = walls.iter().find(|w|
    w.metric == ChainExposureMetric::OpenInterestCall);
Read the full guide →
GEX by strike · SPY 30D · 2026-05-07 · call wall at 740
06 · Scenarios

Explain a portfolio scenario with attribution

A ScenarioDefinition composed of typed ScenarioShock variants — spot-relative, parallel vol, skew, rate, time, custom — runs over a Portfolio and returns exact PnL attribution per position, bucket, and ordered strategy group. The FerroWaveScenarioAdapter maps upstream regime / vol / jump signals into the same shock list.

use ferro_risk::{ScenarioDefinition, ScenarioShock,
             explain_portfolio_scenario_pnl};

let scenario = ScenarioDefinition::new(
    "spot_up_vol_up",
    vec![
        ScenarioShock::SpotRelative { relative: 0.05 },
        ScenarioShock::ParallelVol  { shift: 0.02 },
        ScenarioShock::Skew { slope: -0.01 },
    ],
)?;

let report = explain_portfolio_scenario_pnl(
    &portfolio,
    &scenario,
)?;

// report.pnl · report.books[..] · report.expiry_buckets
// report.position_rows() — per-position PnL, reconciles to total
Read the full guide →
PnL attribution · by position → total
07 · Volatility

Split the variance risk premium into diffusive and jump legs

variance_risk_premium takes implied and realized vol on a shared SurfaceTenor and returns a typed VrpRead in both vol-point and variance units. A JumpDiffusionFit — hand-supplied, or calibrated from quotes with a physical-measure anchor (09 below) — then drives vrp_decomposition, which splits the premium into its diffusive carry and its jump/tail compensation — so a raw implied-minus-realized number becomes two legs you can act on.

use ferro_risk::{variance_risk_premium, vrp_decomposition,
             JumpDiffusionFit, JumpDiffusionParameters,
             RvMethod, SurfaceTenor};

let tenor = SurfaceTenor::new(30.0 / 365.0)?;

let vrp = variance_risk_premium(
    0.22, 0.18,  // implied, realized vol
    tenor, RvMethod::YangZhang,
)?;

let params =
    JumpDiffusionParameters::new(0.9, -0.02, 0.08);
let fit = JumpDiffusionFit::new(0.18, params)?;
let split = vrp_decomposition(fit, vrp);

// split.diffusive_vrp(), .jump_vrp(),
// split.jump_variance_share()
Read the full guide →
VRP decomposition · premium = diffusive + jump
08 · Volatility

Read option-implied correlation from an index and its constituents

implied_correlationtakes the index's implied vol and a slice of typed BasketConstituent weights and IVs on a shared tenor, and returns a DispersionRead: the average pairwise correlation the market is pricing, plus the dispersion premium between the weighted-average constituent vol and the index vol — the read a dispersion book is built on. rho_implied is reported raw, so an out-of-range implied correlation is surfaced, not hidden.

use ferro_risk::{implied_correlation, BasketConstituent,
             SurfaceTenor};

let tenor = SurfaceTenor::new(30.0 / 365.0)?;

let constituents = vec![
    BasketConstituent::new(0.28, 0.35)?,
    BasketConstituent::new(0.24, 0.40)?,
    BasketConstituent::new(0.31, 0.25)?,
];

// index_iv on the same tenor
let read =
    implied_correlation(0.19, &constituents, tenor)?;

// read.rho_implied(), .dispersion_vol_pts(),
// read.weighted_avg_vol()
Read the full guide →
Implied correlation · index vs constituents
09 · Volatility

Calibrate the jump triple from quotes, anchored in the physical measure

calibrate_jump_diffusion fits the risk-neutral Merton triple against option quotes, identified by a JumpAssumptioncarrying the physical measure — the wire payload of ferro-wave's parametric wavelet jump detector maps into it field-for-field. The calibrator owns the P → Q Esscher tilt (the jump risk premium θ), jump_prior_cross_check holds the prior against the bipower realized jump split, and is_confident() folds tilt identifiability and the cross-check into one gate — a fit that cannot be identified says so instead of converging anyway.

use ferro_risk::{calibrate_jump_diffusion, jump_prior_cross_check,
             realized_jump_split, JumpAssumption, JumpEstimateUncertainty,
             JumpMeasure, JumpPriorCrossCheckPolicy};

// physical-measure anchor — e.g. ferro-wave's jump detector
let unc = JumpEstimateUncertainty::new(32, 0.68, 0.005, 0.004)?;
let prior = JumpAssumption::new(
    JumpMeasure::Physical, 3.66, -0.082, 0.025, unc)?;

let realized = realized_jump_split(&bars, 252.0)?;
let check = jump_prior_cross_check(&prior, &realized,
    JumpPriorCrossCheckPolicy::new(0.35)?)?;

let outcome = calibrate_jump_diffusion(
    &input, &policy, &prior, Some(check))?;

// outcome.is_confident() · outcome.tilted_assumption()
// outcome.per_expiry()[i].fit() → vrp_decomposition(..)
Read the full guide →
Jump calibration · P anchor → Q fit
10 · Pricing

De-Americanize an equity quote across its dividend schedule

Listed equity options are American and their underlyings pay discrete cash dividends — so the quotes a surface fitter wants are the wrong shape twice over. A DividendSchedule on IvSolveInputs prices the escrowed spot S − Σ Dᵢ·e^(−r·tᵢ) through the unchanged Bjerksund-Stensland kernel, and de_americanize_quote strips the early-exercise premium to a European-equivalent price and IV that SSVI can actually fit. The premium is reported, never thresholded — the bias is yours to gate on.

use ferro_risk::{de_americanize_quote, DividendEvent,
             DividendSchedule, ExerciseStyle, IvSolveInputs,
             OptionType};

// one $0.96 ex-div 38 days out, 110-day expiry
let schedule = DividendSchedule::new(vec![
    DividendEvent::new(38.0 / 365.0, 0.96)?,
])?;

let inputs = 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(&inputs, 12.9220)?;

// quote.european_equivalent_iv()    → 0.26000
// quote.european_equivalent_price() → 12.6626
// quote.eep_fraction()              → 0.02008
Read the full guide →
De-Am · schedule-aware vs schedule-blind IV on the same quote

Performance as a first-class feature

Speed is designed in, not bolted on. These are wall-clock measurements on an Apple M1 Pro (10-core), release build — single-contract latency for streaming, and 100,000-contract batch throughput — with the hot paths held to a Criterion budget in CI so a regression fails the build before it ships.

~107 ns
9.4M / sec · 1 core
European price, per contract

Black-Scholes-Merton — the per-tick latency of pricing a streaming quote.

~347 ns
2.9M sets / sec · 1 core
All 10 Greeks, per contract

First- and second-order, on one shared evaluation path — no per-Greek bumping.

~459 ns
2.2M solves / sec · 1 core
Implied-vol solve, per contract

Jaeckel's rational Let's-Be-Rational solver, to machine precision in a handful of iterations.

5.8 ms
17M sets / sec · 10 cores
100K full Greek sets

All ten Greeks for 100,000 contracts, parallelized across cores with deterministic Rayon.

8.2 ms
12M / sec · 10 cores
100K fused analytics

Solved IV, explicit forward, and all ten Greeks per contract — for 100,000 contracts at once.

~4.9 µs
Bjerksund-Stensland 2002
American price, per contract

A two-stage exercise boundary — higher-fidelity than a single-boundary approximation (see below).

Head to head vs QuantLib

Same Apple M1 Pro · same models and inputs · single-threaded · QuantLib 1.41 called from Python

PathFerroRiskQuantLib (Python)Result
European · price~107 ns~1,990 ns~19× faster
European · implied vol~459 ns~14,020 ns~30× faster
European · Greeks~347 ns (10)~3,480 ns (5)~10× faster
American · price~4.9 µs~2.6 µs~0.5× · +3× accuracy
American · Greeks~26.7 µs (10)not exposedFerroRisk only

Medians of repeated runs, release build. QuantLib is driven from Python the way desks use it — option and engine built once, spot re-quoted per tick — so the figures reflect the realistic from-Python cost, single-threaded. Batched across 10 cores, FerroRisk prices 100K full Greek sets in 5.8 ms — roughly 60× a single-threaded QuantLib-from-Python loop over the same chain. American pricing is the one path where QuantLib is faster per call (~1.9×), because it solves the cheaper single-boundary approximation. FerroRisk runs the Bjerksund-Stensland 2002 two-stage boundary: against a 16,384-step CRR oracle on the same contract it prices to 0.016 error versus QuantLib's 0.048 — roughly 3× more accurate for about 2× the work — and it exposes full analytical Greeks on the American path, which QuantLib's analytic engine does not.

Built from first principles

FerroRisk is not a port of someone else's library. Every model starts with the source research, is implemented in-tree in pure Rust, is validated against the canonical reference and an independent oracle, and has its core pricing laws machine-checked in Lean before it ships.

01

Start from the research

Each model comes from its source paper, not a second-hand transcription — Bjerksund-Stensland (2002) for American, Merton (1976) jump-diffusion, Heston via Fang-Oosterlee COS, Gatheral-Jacquier (2014) SSVI, Hagan SABR, Dupire local-vol, and Jaeckel's Let's-Be-Rational IV solver.

02

Implement in-tree

The numerics live in the crate — closed-form wherever the math allows, with no hidden BLAS and no math DSL. The Cody normal CDF, the rational-branch IV solver, and the dual-number analytical Greeks are written and owned here.

03

Validate against canon and oracles

European IV round-trips match Jäckel's reference C++ to 4 ULPs — fixtures stored as exact bit patterns, never a paper's rounded tables. The fast American path is held against a 16,384-step CRR tree, second-order Greeks against a Richardson high-precision reference, and the SIMD transcendentals against MPFR grids.

04

Reproducible by construction

The same inputs always produce the same numbers. Parallel batch APIs use deterministic Rayon for byte-identical reports across thread counts, and every SIMD kernel is bit-tracked against the scalar twin it replaces.

05

Proven, not just tested

The pricing mathematics is machine-checked in Lean — 262 theorems with no sorry, kernel-verified against a minimal axiom base: put-call parity, every first-order Greek and the higher-order surface, the Black-Scholes PDE, and implied-vol existence & uniqueness. The standard normal CDF is the genuine Gaussian, not an assumption — and these laws can't drift from the code.

06

Verified down to the floating point

Beyond the reals: the Cody normal-CDF and normalised-Black kernels carry rigorous rounding bounds (Gappa) and an approximation bound against the true erf (Sollya), and the proved identities are checked holding in the shipping f64 code to ~1e-15. The Let's-Be-Rational IV solver converges to machine precision in ≤2 iterations across the moneyness wings.

Mathematical correctness as a gate

Pricing libraries are easy to write and hard to verify. FerroRisk treats numerical correctness, calibrated performance, regression coverage, and formal proof obligations over stable pricing and risk laws as release gates — not aspirations.

Mathematical Correctness

Numerical equality round-trips, property tests, and known-answer suites against reference implementations — CRR for American, closed-form analytics for European. 1,800+ tests, 600+ property assertions, and 17 fuzz targets cover the pricing, surface, and chain-analytics paths. Every release passes the gate.

FM

Formal Proof Gates

262 machine-checked Lean theorems over the pricing mathematics — kernel-verified with no sorry on the three standard axioms — plus Gappa/Sollya floating-point rounding and approximation bounds on the numeric kernels, and an f64 conformance harness that holds the proved identities to ~1e-15. The claim stays scoped to those laws, not every market model or trading outcome.

PT

Calibrated Performance Gates

scripts/check_perf_thresholds.sh rejects regressions against testing/perf_thresholds.json with RAYON_NUM_THREADS=4fixed; stale Criterion output is rejected before thresholds are checked, so a regression can't merge. The measured throughput figures are in the benchmarks above — hot kernels run through pulp's runtime-dispatched SIMD, bit-identical to scalar on the same FP unit.

Rs

Pure Rust. Lean by design.

Zero unsafe in the core — the SIMD intrinsics are encapsulated by pulp. Three runtime dependencies — rayon for parallel batch APIs, thiserror for typed errors, and pulp for portable runtime-dispatched SIMD (on by default; --no-default-features drops it for the always-present scalar path) — plus serde behind a feature flag. The numerics live in-tree: no hidden BLAS, no math DSL, no surprise transitive graph. High performance follows from the absence of surprises.

No surprises in the API contract

Pricing-library bugs hide in unit conventions. FerroRisk names them on the surface so a reader of the call site can reproduce the math without reading the source.

yr

Time in years

time_to_expiry is expressed in years. A 30-day expiry is 30.0 / 365.0. There is no implicit calendar conversion at any pricing entry point.

e

Continuously-compounded rates

Both rate and dividend_yield are continuously compounded. For Black-76, set dividend_yield = 0.0 — the model uses the risk-free rate as the effective carry term.

/d

Per-calendar-day decay

theta, charm, veta, and colorare reported per calendar day, not per year. This matches how risk desks read time-decay on a daily P&L.

∂σ

Vega and rho on raw scale

vega is reported as dV/dσ, not per one volatility point. rho is reported as dV/dr, not per basis point. Convert at the surface, not inside the engine.

One typed API, every pillar

A taste below — the guides walk each workflow end to end, and the complete API reference documents every public type, function, and trait.

Compute the full first- and second-order Greeks surface in one call, on a shared internal evaluation path

greeks_all takes a typed PricingInputs and a named PricingModel and returns the 10-Greek surface for the contract — no per-Greek bumping pattern, no inconsistency between sensitivities computed on different internal paths.

For larger workloads, greeks_batch and contract_analytics_batch parallelize via Rayon with per-contract error isolation. Use contract_analytics when a workload needs solved IV, explicit forward, and Greeks for the same contract in one fused step.

use ferro_risk::{ExerciseStyle, OptionType, PricingInputs,
             PricingModel, greeks_all};

let inputs = PricingInputs {
    option_type: OptionType::Call,
    exercise_style: ExerciseStyle::European,
    spot: 4_850.0,
    strike: 4_900.0,
    time_to_expiry: 0.25,
    rate: 0.045,
    dividend_yield: 0.0,
    volatility: 0.22,
};

let greeks = greeks_all(&inputs, PricingModel::Black76).unwrap();
// greeks.delta, .gamma, .theta, .vega, .rho,
// .vanna, .volga, .charm, .veta, .color
10 Greeks per callShared eval pathRayon batchPer-call error isolation

Talk to us

Reach out for design-partner support, integration guidance on the surface-calibration and chain-analytics surfaces, or term-structure / calibration optimizer planning. The pricing core is formally verified — the math is proven, not just tested.

hello@morphiqlabs.com

Tell us about your use case

  • Asset class and model — equity, futures, American / European, stochastic-vol, jumps
  • Workload — single contracts, surface calibration, streaming chain analytics
  • Surface needs — SVI / SSVI / SABR, fit-quality tolerances, Dupire local-vol
  • Integration timeline and existing infrastructure