The venue-agnostic options data surface — the reader seam, chain and contract records,
quotes, snapshots and the OCC symbol helper. Everything here lives in
SabrTrader.Pipeline.Contracts (bundled by the SDK meta-package), namespace
SabrTrader.Pipeline.Options. Narrative:
Options data & trading.
The reader seam
| Type |
Members |
IOptionChainReader |
The read-only, venue-agnostic entry point (obtained from a context, never constructed):
bool IsAvailable; event Action? AvailabilityChanged (any thread —
always unsubscribe on dispose);
Task<IReadOnlyList<OptionUnderlying>> SearchUnderlyingsAsync(string query, ct);
Task<IOptionChainView?> OpenChainAsync(string underlyingSymbol, ct) — null when
no connected venue serves the symbol. |
IOptionChainView |
: IDisposable. An open chain bound to the (hidden) venue that resolved it; all
provider ids are only meaningful within the same view. string UnderlyingSymbol;
OptionChain Chain (full expiry list + the venue's default nearest expiries);
Task<OptionChain> GetContractsAsync(IReadOnlyList<DateOnly> expiries, ct);
Task<OptionChainSnapshot> GetSnapshotAsync(OptionChainSnapshotRequest? request = null, ct);
IDisposable SubscribeQuotes(IReadOnlyList<string> providerInstrumentIds, Action<OptionQuote> onQuote).
Dispose tears down the view's quote subscriptions; a view does not outlive its venue. |
OptionChainSnapshotRequest |
record; bounds for one snapshot capture, every field optional (null = host default, values are
clamped bounds, never guarantees): IReadOnlyList<DateOnly>? Expiries,
int? MaxExpiries, int? MaxContracts (centered on the money; a
~30-contracts-per-expiry near-the-money floor is kept regardless),
double? MinGreekCoverage (0..1), TimeSpan? GreekWaitTimeout. |
Chain & contract data
| Type |
Members |
OptionChain |
record, required init: string UnderlyingSymbol,
string UnderlyingProviderInstrumentId (empty when the venue doesn't report one),
IReadOnlyList<DateOnly> Expiries (always complete, ascending),
IReadOnlyList<OptionContract> Contracts (only the fetched expiries);
void Validate(). |
OptionContract |
record, required init: string ProviderInstrumentId,
string UnderlyingSymbol, DateOnly Expiry, decimal Strike,
OptionRight Right; init: OptionExerciseStyle ExerciseStyle,
decimal Multiplier (default 100), string? Currency,
string NativeInstrumentType (empty when the source didn't classify); computed
string DisplaySymbol ("AAPL 18DEC26 150 C"); void Validate(). |
OptionRight |
enum: Call, Put. |
OptionExerciseStyle |
enum: Unknown, American, European. |
OptionUnderlying |
record (string UnderlyingId, string Symbol, string Description) — one
underlying-search hit. |
Quotes & snapshots
| Type |
Members |
OptionQuote |
record; one PARTIAL quote delta — a null field means "unchanged", never "gone". Required init:
string ProviderInstrumentId; init (all nullable decimal):
Bid, Ask, Mid, Last, Delta,
Gamma, Theta, Vega, ImpliedVol (a fraction:
0.25 = 25%), Volume, OpenInterest, NetChange,
PercentChange; bool? AccessDenied (true only when the venue explicitly
refused market data for the instrument — never inferred from absent fields). |
OptionChainSnapshot |
record, required init: IReadOnlyList<OptionChainSnapshotEntry> Entries,
IReadOnlyList<DateOnly> Expiries, string UnderlyingProviderInstrumentId,
string UnderlyingSymbol; init decimal? UnderlyingPrice (spot at capture
time, when reported). |
OptionChainSnapshotEntry |
record (OptionContract Contract, OptionQuote Quote). |
OCC symbol
| Type |
Members |
OccOptionSymbol |
readonly record struct (string Root, DateOnly Expiry, bool IsCall, decimal Strike) —
the OCC/OSI concatenated form {root}{yyMMdd}{C|P}{strike×1000, 8 digits}
(e.g. AAPL240119C00190000). string ToSymbol();
static OccOptionSymbol Parse(string symbol),
bool TryParse(string? symbol, out OccOptionSymbol result) — strict full-match only,
so a plain equity ticker can never false-positive (safe as an option-vs-equity discriminator). |
Context access
| Member |
Where |
IIndicatorContext.OptionChains |
IOptionChainReader? — null when the host serves no options data. Namespace
SabrTrader.Pipeline.Indicators. |
IStrategyContext.OptionChains / Strategy.OptionChains
|
Same reader from strategy code; plus the strategy-side trading verbs
PlaceMultiLegOrderAsync, PrecheckMultiLegOrderAsync,
ExerciseOptionAsync (all default-implemented — unsupported hosts answer through the
result, never throw). |
OptionChainReaderAmbient |
static (namespace SabrTrader.Pipeline.Indicators): Reader,
SetReader(reader), IDisposable Use(reader) — the host-installed ambient
the context defaults read; plugins normally never touch it directly (tests use
Use to scope a fake). |
Trading types
The multi-leg order model — MultiLegOrderRequest, OptionLeg,
PositionEffect, NetPriceDirection, MultiLegPlacement,
MultiLegPrecheckResult and the MultiLegOrders /
ExerciseOptions capability flags — lives in SabrTrader.Pipeline.Venues.Trading
and is documented in the Trading reference. Narrative
usage: Multi-leg orders & exercise.