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.
The node protocol
How the desktop app and the CLI talk to a running daemon — length-prefixed JSON frames, an HMAC nonce-challenge handshake with capability bound into the signature, and a wire vocabulary that mirrors the core without depending on it.
Alerting
A persisted rule set, a pure evaluator and a delivery seam that run strictly off the hot fold — with a default build that links no trading crate at all, because the watchdog it exists for must be able to page without the core.