vike
Concepts

Options

The venue-free options core — a normalized chain model, Black–Scholes price and greeks with every transcendental from one portable library, implied vol by bisection, second-order greeks, realized-vol estimators and multi-leg basket analytics.

vike-options is the pure core under the options chain window: egui-free, I/O-free, and dependent on no other crate in the workspace. Three of its modules are a faithful f64 port of the Python oracle's options package and are gated by the parity fixtures; three more are additive, with no Python twin, and are verified by finite differences and self-consistency instead. The crate's contract draws one line firmly: venue-specific fetching and parsing lives in the deribit bridge's chain.rs, order entry stays on the execution client seam, and an option's identity stays in its instrument-name string — no strike, expiry or kind fields on the order request.

The chain model

model.rs holds the normalized types a provider translates into and the UI consumes without knowing which feed produced them: OptionChain for one expiry's snapshot, Expiry with its ISO date, days to expiry and label, StrikeRow as a call and a put at one strike, and OptionQuote. Quote fields are Option<f64> — absent stays absent, never 0.0 — and rows are ascending by strike. Expiries settle at 08:00 UTC through expiry_ms. make_expiry computes days to expiry as a calendar-day difference of UTC dates rather than a floored elapsed-millisecond count: late in the UTC day the floor rounded both today and tomorrow to zero and the expiry strip rendered two 0DTE pills. limit_strikes windows a chain to n strikes below the spot and n at or above it, so a ±3 view shows exactly three rows on each side of the spot band.

Price, greeks and implied vol

greeks.rs derives Δ, Γ, Θ and V uniformly from a feed's implied vol, because feeds give IV but not full greeks. The conventions are European exercise, continuous compounding, no dividends, theta per calendar day, vega per one vol-point, and a 365-day year. The risk-free rate r is a plain parameter — the Python twin read it from the environment at import with a default of zero, and here the read stays in the consuming binary; pass 0.0 to match. black_scholes_price and black_scholes_greeks share one d1_d2 site, and every transcendental — erf, exp and log — comes from the libm crate rather than the platform: IEEE 754 requires + - * / and sqrt correctly rounded and requires nothing of exp and ln, so the MSVC runtime and glibc are each entitled to a different last bit. sqrt deliberately stays on f64. The module records that it was half-converted for a while — libm::erf two lines above an x.ln() — and states the lesson: a half-converted file is worse than an unconverted one, because a nearby libm:: spelling is exactly the evidence a reader uses to decide not to look.

implied_vol inverts the price by bisection over sigma in [1e-4, 5.0]: 64 fixed steps with a 1e-6 absolute early exit, ported verbatim because the iteration shape is part of the oracle contract, and None when the price sits outside the no-arbitrage band. enrich_quote fills a quote's greeks from its IV and returns it unchanged when they are not computable.

The parity tiers, and what may never be re-recorded

Pure-arithmetic sites — days to expiry, windowing, scaling, the non-theoretical columns, format strings — gate exact, as hex bits. Outputs derived through erf, exp or log gate at ≤1e-12 relative against CPython-pinned bits. Neither tolerance is ever widened, and a pure-arithmetic site is never reclassified to the relative tier. The constants are the frozen oracle, and if one ever moves out of tier that is a stop to be argued, not a number to repaste.

Second-order greeks

second_order.rs adds vanna, vomma, charm, veta and color on the same d1/d2 and density internals. It is not an oracle port — the Python twin stops at first order — so it is verified by finite differences against the crate's own first-order greeks, ≤1e-6 relative for every greek, calls and puts. Charm, veta and color are reported per calendar day as passage-of-time derivatives, negative when the quantity decays as the clock runs, so veta reads negative for an at-the-money option at r = 0; published tables mix that sign convention row by row, and the finite-difference gate pins this one. Vanna and vomma are raw annualized sensitivities per 1.0 of sigma — divide by 100 for the per-point scale of the first-order vega. With no dividends the only kind-dependent terms vanish, so every greek here is identical for calls and puts, and the equality is asserted in tests.

Baskets

basket.rs is the multi-leg analytics: expiry payoff, break-evens, maximum profit and loss, net greeks across both orders, and probability of profit and expected value under a lognormal terminal law. A Leg carries a signed quantity — positive long, negative short — and a non-negative per-unit premium, so net_premium is Σ qty·premium with positive meaning a debit paid. payoff_at is P&L at expiry per 1.0 of underlying; contract multipliers are the caller's business. The domain is S_T ∈ [0, ∞): a price cannot go below zero, so the downside is always bounded and only the upward ray can be PayoffBound::Unbounded, decided by the slope beyond the highest strike. Summation is a naive left fold in leg order, so net_greeks is bit-identical to summing the per-leg calls in the same order; the expected-value integral is a fixed-grid composite Simpson, and the whole module is deterministic — no RNG, no I/O, no clock.

Realized vol and the IV–RV read

vol.rs has no Python twin. EwmaVol is the RiskMetrics recursion with λ = 0.94 for daily data, seeding the variance at the first squared return rather than at zero; RollingVol is the sample standard deviation over a window. Both stream update(price) / value() over log returns computed with libm::log, ignore non-finite or non-positive prices so a bad tick cannot poison the fold, and report per-period vol — annualize with DAYS_PER_YEAR (365, matching the greeks' basis; an equities caller passes 252). atm_iv picks the strike nearest the forward F = S·e^{rT}, averaging call and put IV where both are present; iv_rv_spread is the plain difference, positive when implied trades rich. The module says its own materiality is low: nothing outside the file calls these yet, and they were made portable before a consumer arrived because that is the cheap moment.

On this page