Skip to content

Greeks

What it computes

Per-contract Black–Scholes Greeks — delta, gamma, vega, theta, rho — and implied volatility on every option NBBO update. The analytic uses the contract's mid-price as the option market value, the cached per-symbol underlying spot, a user-supplied risk-free rate (engine rate provider), a user-supplied calendar (engine market calendar), and an optional annual dividend yield.

Implied volatility is solved by bisection against the closed-form Black–Scholes implementation. Once IV converges, the analytic re-evaluates Greeks at the solved IV.

Methodology

Black & Scholes (1973), The Pricing of Options and Corporate Liabilities, Journal of Political Economy 81(3): 637–654, with continuous-dividend yield. Hull, Options, Futures, and Other Derivatives, §15 (Black–Scholes–Merton) and §19 (Greek letters).

See /methodology/black-scholes for the formula derivation.

Inputs

  • Option QuoteTick (NBBO mid as market value).
  • Stock TradeTick (writes underlying spot to the shared engine spot-price cache).
  • The per-spec engine rate provider and engine market calendar.
  • Optional annual_dividend.

Output schema (GreekTick)

The field / type / description table below is regenerated from the GreekTick Rust source by docs-site/scripts/inject-doc-tables.ts on every npm run docs:build. Do not hand-edit between the sentinels.

FieldTypeDescription
contractContractResolved option contract metadata (symbol, expiration, side, strike). Subscribers identify the option by these fields — the wire-level contract id is engine-internal and is not surfaced here.
datei32Trading-session date in YYYYMMDD form, sourced from the triggering Trade or Quote event.
ms_of_dayi32Milliseconds since midnight, sourced from the triggering Trade or Quote event.
underlying_pricef64Most-recent underlying spot price used to compute the Greeks. NaN when the per-symbol spot cache has not yet been populated (see [GreekTickFlags::MISSING_SPOT]).
underlying_datei32Trading-session date (YYYYMMDD) of the underlying spot observation. Equal to [Self::date] under normal conditions. 0 when no underlying snapshot has landed yet.
underlying_ms_of_dayi32Milliseconds-since-midnight of the underlying spot observation. Lets consumers detect stale spot relative to the option event (e.g. ms_of_day - underlying_ms_of_day = age in ms). 0 when no underlying snapshot has landed yet.
bidf64Most-recent observed option NBBO bid. For Quote-triggered emissions this is the triggering quote's bid. For Trade- triggered emissions this is the bid of the most recent same-date quote on the contract's analytic instance, or NaN if no same-date quote has been observed.
askf64Most-recent observed option NBBO ask. Same sourcing rules as [Self::bid].
option_pricef64Option price used to solve / recompute the Greeks. For Trade triggers this is the raw upstream price field; for Quote triggers it is the NBBO mid (bid + ask) / 2, collapsing to the live side when the book is one-sided. Engine-internal — the hosted endpoint does not surface this since the consumer already has bid / ask.
implied_volf64Implied volatility solved from (spot, strike, rate, t, option_price, right) via the bisection solver. Field name matches hosted implied_vol.
iv_errorf64Solver residual: pricing error of implied_vol against option_price, divided by option_price. Nonzero on deep ITM / OTM contracts where the solver hits its iteration cap.
d1f64Black-Scholes d1. Surfaced because hosted does and downstream risk consumers occasionally use it directly (e.g. computing risk-neutral exercise probability via Phi(d2)).
d2f64Black-Scholes d2 = d1 - sigma * sqrt(t).
deltaf64∂V/∂S. Per unit of underlying.
gammaf64∂²V/∂S². Per unit of underlying squared.
thetaf64∂V/∂t (per year, calendar-day basis).
vegaf64∂V/∂σ. Per unit volatility (divide by 100 for the per-percentage-point convention — matches hosted output).
rhof64∂V/∂r. Per unit rate (divide by 100 for the per-percentage-point convention — matches hosted output).
epsilonf64∂V/∂q — sensitivity to the dividend yield. Hosted-parity field.
lambdaf64Option leverage Ω = Δ * S/V. Hosted-parity field.
vannaf64∂²V/(∂S ∂σ) = ∂Δ/∂σ = ∂vega/∂S.
charmf64∂Δ/∂t — delta decay.
vommaf64∂²V/∂σ² = ∂vega/∂σ.
vetaf64∂vega/∂t — vega decay.
veraf64∂vega/∂r (DvegaDr) — vega-to-rate sensitivity. Hosted-parity field.
speedf64∂Γ/∂S = ∂³V/∂S³.
zommaf64∂Γ/∂σ.
colorf64∂Γ/∂t — gamma decay.
ultimaf64∂vomma/∂σ.
dual_deltaf64∂V/∂K. Hosted-parity field.
dual_gammaf64∂²V/∂K². Hosted-parity field.
iv_cachedbooltrue if the bisection IV solver was skipped on this tick because the cached (option_mid, spot) deltas both fell under IvCacheConfig's thresholds, in which case the Greeks were recomputed in closed form against the cached IV. false when the solver re-ran (cache miss, cache disabled via IvCacheConfig, or the very first emission for this contract).
flagsGreekTickFlagsPer-tick annotations.

flags is a GreekTickFlags bitset; the currently-defined bits are MISSING_SPOT, EXPIRED, MISSING_CALENDAR, and MISSING_RATE.

Configuration (GreeksRequest)

Regenerated from the GreeksRequest Rust source — see the note above.

FieldTypeDescription
contractsSecurityFilterContracts the subscription tracks. Include the underlying stock contract here so the analytic can populate the shared per-symbol spot price cache from underlying trades.
rateArc<dyn RateService>Risk-free rate provider. Looked up per emission with (event_date, expiry_date); production deployments inject a curvekit-backed provider that auto-refreshes on date rollover.
annual_dividendOption<f64>Optional override of the implied dividend yield (annual decimal). None defers to the engine-wired [Self::dividend_cache] for a per-symbol carry yield, and falls back to the hosted convention of zero dividend yield only when the cache has no entry for the underlying. An explicit value here always wins over the cache.
dividend_cacheArc<crate::reference_data::dividend_yield::DividendYieldCache>Engine-wired per-symbol dividend-yield cache. Seated at subscribe time by DefaultSpec via wire_dividend_yield; the fluent builder seats an empty stub at default_spec time. Consulted on the dispatch path only when [Self::annual_dividend] is None — the per-tick lookup resolves the continuous-dividend carry yield q = D / S from the live underlying spot the analytic already holds (O(1), lock-light, non-blocking).
triggerGreeksTriggerTrigger source: Trade, Quote, or both. Default: [GreeksTrigger::OnTradeAndQuote].
quote_phasesQuotePhaseFilterCycle-phase filter applied to Quote-driven emissions. Default: all three phases admitted.
iv_cacheIvCacheConfigIV-cache reuse thresholds. Default: 1 ¢ option mid, 5 ¢ spot. Pass [IvCacheConfig::off] to disable caching.
emitEmitPolicyWhether the analytic emits one bar per qualifying tick ([EmitPolicy::OnEveryTick]) or accumulates a snapshot over a timer ([EmitPolicy::OnClose] — currently behaves identically to OnEveryTick because the tick path emits unconditionally).
spot_cacheSpotPriceCacheShared spot price cache, populated by the analytic from underlying stock trades and read by every option contract on the same subscription. Build via [new_spot_price_cache] and clone the returned Arc into the spec.
calendarArc<dyn MarketCalendar>Market calendar provider. Looked up per emission with the triggering event's date to derive the option-trading cutoff (close_time on regular sessions, close_time + 15m on early-close days, None on holidays / weekends).

Operational characteristics

  • Per-tick latency. One IV bisection (≈ 30 iterations max) plus closed-form Greeks.
  • Allocation discipline. No allocations on the hot path.
  • Cross-day staleness. A cached spot from yesterday's session never silently prices today's option trades — MISSING_SPOT fires instead.
  • Replay parity. Deterministic given identical input tick order.

Example

rust
// Cargo.toml:
//   kairos = "0.1"

use kairos::{Client, GreeksRow};

let client = Client::connect(("me@example.com", "secret"))?;

let sub = client
    .live()
    .greeks(["QQQ"])
    .on_event(|row: &GreeksRow| {
        // The callback fires once per emission with a typed `GreeksRow`.
        println!("delta={} gamma={}", row.delta, row.gamma);
    })?;
// ... later ...
sub.unsubscribe();

Historical and replay drives swap client.live() for the preview client.historical(start, end) (feature historical-mode) and client.replay() (feature replay-mode) namespaces; the per-analytic builder, the filter accessor, and the .on_event callback are identical.

Proprietary. All rights reserved.