@huskly/ibkr-client 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -129,9 +129,16 @@ interval. Authentication, entitlement, invalid contract, and ambiguous contract
129
129
  recovery.
130
130
 
131
131
  - `getOptionExpiries(...)` discovers weekly and monthly maturities across month buckets.
132
- - `getOptionChain(...)` returns an exact-expiry chain with canonical OSI symbols, conids,
133
- bid/ask/mid prices, delta, session volume, and open interest.
134
- - `getOptionQuote(...)` resolves and prices one exact contract with the same market-data shape.
132
+ - `getOptionChain(symbol, expiry, right?)` is the strict strategy-ready path. It returns only
133
+ exact-expiry contracts that have bid, ask, and delta values. It fails if no contract has all three
134
+ values. Set `right` to `C` or `P` to skip definition and quote requests for the unused side.
135
+ - `getOptionChainSnapshot(symbol, expiry, right)` returns every qualified contract for one exact
136
+ expiry and option side. It preserves canonical OSI symbols and conids. Missing bid, ask, mid,
137
+ delta, volume, open interest, availability, and timestamp values are `null`. The result includes
138
+ qualified, returned, malformed-definition, and missing-field counts. These diagnostics contain no
139
+ account IDs or credentials. If a warmed snapshot stays sparse, the method returns the fields that
140
+ IBKR supplied and keeps the other fields as `null`.
141
+ - `getOptionQuote(...)` resolves and prices one exact contract with the strict market-data shape.
135
142
  It serializes the session search with one exact security-definition request. It caches an
136
143
  identical exact request and does not load the complete option chain. When an exact ticker has listings in more than one market, option
137
144
  discovery selects the one listing with `SMART` option routing. It rejects the result if `SMART`
@@ -306,12 +313,14 @@ structured response in `BrokerErrorDetail.details`; transport exceptions are ret
306
313
  ### Request pacing and temporary blocks
307
314
 
308
315
  Every authenticated request runs through one priority scheduler per `IbkrClient`. The default
309
- limits allow at most ten requests globally and one exploratory security-definition request at a
310
- time. Order preview, status, warning, cancellation, and immediate-trade requests take priority
311
- over queued discovery. Multi-month derivative discovery also primes each month serially. A
312
- session-level transaction guard keeps each stateful security-definition search with its dependent
313
- strike or definition request. An exact expiry/strike/right request expands only that requested
314
- contract.
316
+ limits allow at most ten requests globally. Stateful security-definition discovery stays at one
317
+ request at a time. Read-only `iserver/secdef/info` expansion uses a separate conservative limit of
318
+ four concurrent requests. Configure it with `maxSecdefInfoConcurrent`; it cannot exceed the global
319
+ limit. Order preview, status, warning, cancellation, and immediate-trade requests take priority over
320
+ queued discovery. Multi-month derivative discovery also primes each month serially. A session-level
321
+ transaction guard keeps each stateful security-definition search with its dependent strike request.
322
+ For option-chain discovery, independent definition reads run outside this guard after search and
323
+ strikes finish. An exact expiry/strike/right request expands only the requested contracts.
315
324
 
316
325
  A 429 pauses the shared queue behind one `Retry-After`-aware exponential backoff with jitter.
317
326
  Individual queued reads do not start independent retry loops. Exhausted throttling throws
@@ -330,7 +339,9 @@ safe `Retry-After` value when it is available. Callers do not have to parse the
330
339
 
331
340
  `IbkrClient` accepts optional scheduler limits and an `onRequestTelemetry` callback. Scheduler
332
341
  options also accept `now`, `sleep`, and `random` functions for controlled runtimes and tests.
333
- Telemetry for each retry contains only a sanitized endpoint category, event, attempt, and delay. It
342
+ Telemetry for each retry contains only a sanitized endpoint category, event, attempt, and delay.
343
+ `onOptionDiscoveryTelemetry` reports search, strikes, definitions, and snapshot phases. It includes
344
+ the symbol, month, optional right, duration, definition request count, and snapshot batch count. It
334
345
  does not contain account IDs, order IDs, credentials, request payloads, or full URLs. A telemetry
335
346
  observer failure does not change request scheduling or request settlement.
336
347
 
@@ -362,7 +373,7 @@ const [balances, history, expiries] = await Promise.all([
362
373
  ]);
363
374
  const expiry = expiries[0];
364
375
  if (!expiry) throw new Error(`No listed expiries for ${symbol} in ${from}..${to}`);
365
- const chain = await client.getOptionChain(symbol, expiry);
376
+ const chain = await client.getOptionChain(symbol, expiry, "C");
366
377
  console.log({ equityRead: Number.isFinite(balances.netLiquidation), historyBars: history.bars.length,
367
378
  expiry, contracts: chain.length, first: chain[0]?.symbol });
368
379
  NODE
@@ -1,5 +1,5 @@
1
1
  import type { IbkrOauth1Config } from "./oauthConfig.js";
2
- import type { AccountBalances, ActiveDerivativeOrder, AuthStatus, BrokerAccountOrders, BrokerClient, BrokerInstrument, BrokerInstrumentSearchProjection, BrokerOrdersOptions, BrokerPosition, BrokerQuote, BrokerQuoteOptions, BrokerQuoteRequest, BrokerTransactionHistory, BrokerErrorDetail, DerivativeContract, DerivativeContractQuery, DerivativeComboExecutionRequest, DerivativeComboReconciliation, DerivativeComboReconciliationRequest, DerivativeComboPreviewRequest, DerivativeComboPreviewResult, DerivativeContingentChildOrderRequest, DerivativeContingentParentOrderRequest, DerivativeDiscoveryClient, DerivativeExecutionClient, DerivativeExecution, DerivativeExecutionQuery, DerivativeMultiOrderResult, DerivativeOrderGraphLookup, DerivativeOrderGraphRequest, DerivativeOrderGraphResult, DerivativeOrderGraphWarningContinuation, DerivativeOrderCancellationResult, DerivativeOrderCancelRequest, DerivativeOrderLifecycle, DerivativeOrderLookup, DerivativeOrderSubmissionResult, DerivativeSingleOrderRequest, DerivativePreviewClient, DerivativeExpiry, DerivativeExpiryQuery, DerivativeQuote, DerivativeReferenceQuote, OptionContract, OptionMarketQuote, OptionQuoteRequest, OptionRight, PriceHistoryContractCandidate, PriceHistoryRequest, PriceHistoryResult, PriceHistoryTelemetry, TradingDiagnostics } from "../types.js";
2
+ import type { AccountBalances, ActiveDerivativeOrder, AuthStatus, BrokerAccountOrders, BrokerClient, BrokerInstrument, BrokerInstrumentSearchProjection, BrokerOrdersOptions, BrokerPosition, BrokerQuote, BrokerQuoteOptions, BrokerQuoteRequest, BrokerTransactionHistory, BrokerErrorDetail, DerivativeContract, DerivativeContractQuery, DerivativeComboExecutionRequest, DerivativeComboReconciliation, DerivativeComboReconciliationRequest, DerivativeComboPreviewRequest, DerivativeComboPreviewResult, DerivativeContingentChildOrderRequest, DerivativeContingentParentOrderRequest, DerivativeDiscoveryClient, DerivativeExecutionClient, DerivativeExecution, DerivativeExecutionQuery, DerivativeMultiOrderResult, DerivativeOrderGraphLookup, DerivativeOrderGraphRequest, DerivativeOrderGraphResult, DerivativeOrderGraphWarningContinuation, DerivativeOrderCancellationResult, DerivativeOrderCancelRequest, DerivativeOrderLifecycle, DerivativeOrderLookup, DerivativeOrderSubmissionResult, DerivativeSingleOrderRequest, DerivativePreviewClient, DerivativeExpiry, DerivativeExpiryQuery, DerivativeQuote, DerivativeReferenceQuote, OptionChainSnapshot, OptionContract, OptionDiscoveryTelemetry, OptionMarketQuote, OptionQuoteRequest, OptionRight, PriceHistoryContractCandidate, PriceHistoryRequest, PriceHistoryResult, PriceHistoryTelemetry, TradingDiagnostics } from "../types.js";
3
3
  import { type IbkrRequestSchedulerOptions, type IbkrRequestTelemetry } from "./requestScheduler.js";
4
4
  interface IbkrRequestInput {
5
5
  path: string;
@@ -12,6 +12,8 @@ export interface IbkrClientOptions {
12
12
  onRequestTelemetry?: (event: IbkrRequestTelemetry) => void;
13
13
  /** Receive safe contract and request metadata before each price-history request. */
14
14
  onPriceHistoryTelemetry?: (event: PriceHistoryTelemetry) => void;
15
+ /** Receive safe timing and request counts for option-discovery phases. */
16
+ onOptionDiscoveryTelemetry?: (event: OptionDiscoveryTelemetry) => void;
15
17
  }
16
18
  /** Safe HTTP response evidence retained when the raw transport rejects a request. */
17
19
  export interface IbkrHttpErrorResponse {
@@ -67,6 +69,7 @@ export declare class IbkrClient implements BrokerClient, DerivativeDiscoveryClie
67
69
  private readonly requestNow;
68
70
  private secdefPrimingTail;
69
71
  private readonly onPriceHistoryTelemetry;
72
+ private readonly onOptionDiscoveryTelemetry;
70
73
  private readonly onRequestTelemetry;
71
74
  constructor(config: IbkrOauth1Config, options?: IbkrClientOptions);
72
75
  /** Obtain the live session token (idempotent — safe to await repeatedly). */
@@ -243,7 +246,9 @@ export declare class IbkrClient implements BrokerClient, DerivativeDiscoveryClie
243
246
  /** Discover every listed weekly/monthly expiry in the requested calendar range. */
244
247
  getOptionExpiries(symbol: string, right: OptionRight, fromDate: string, toDate: string): Promise<string[]>;
245
248
  /** Build one exact-expiry chain with canonical OSI symbols and required pricing/greeks. */
246
- getOptionChain(symbol: string, expiry: string): Promise<OptionMarketQuote[]>;
249
+ getOptionChain(symbol: string, expiry: string, right?: OptionRight): Promise<OptionMarketQuote[]>;
250
+ /** Return every qualified contract for one exact expiry and side without hiding sparse data. */
251
+ getOptionChainSnapshot(symbol: string, expiry: string, right: OptionRight): Promise<OptionChainSnapshot>;
247
252
  /** Fetch one exact option quote; null means the contract is not listed. */
248
253
  getOptionQuote(input: OptionQuoteRequest): Promise<OptionMarketQuote | null>;
249
254
  /** Resolve a conid back into the canonical OSI-bearing option contract. */
@@ -259,9 +264,12 @@ export declare class IbkrClient implements BrokerClient, DerivativeDiscoveryClie
259
264
  private discoverOptions;
260
265
  private loadOptionUnderlying;
261
266
  private loadOptionContracts;
262
- private loadOptionContractsPrimed;
267
+ private fetchOptionChainSnapshot;
268
+ private fetchNullableOptionQuotes;
263
269
  private fetchOptionQuotes;
264
270
  private historyInterval;
271
+ private elapsedSince;
272
+ private emitOptionDiscoveryTelemetry;
265
273
  private requestPriceHistory;
266
274
  private recoverDailyHistory;
267
275
  private dailyHistoryWindows;
@@ -1 +1 @@
1
- {"version":3,"file":"ibkrClient.d.ts","sourceRoot":"","sources":["../../src/ibkr/ibkrClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ibkrClient.d.ts","sourceRoot":"","sources":["../../src/ibkr/ibkrClient.ts"],"names":[],"mappings":"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"}
@@ -259,10 +259,12 @@ export class IbkrClient {
259
259
  requestNow;
260
260
  secdefPrimingTail = Promise.resolve();
261
261
  onPriceHistoryTelemetry;
262
+ onOptionDiscoveryTelemetry;
262
263
  onRequestTelemetry;
263
264
  constructor(config, options = {}) {
264
265
  this.raw = new RawIbkrClientCtor(config);
265
266
  this.onPriceHistoryTelemetry = options.onPriceHistoryTelemetry ?? (() => undefined);
267
+ this.onOptionDiscoveryTelemetry = options.onOptionDiscoveryTelemetry ?? (() => undefined);
266
268
  this.onRequestTelemetry = options.onRequestTelemetry ?? (() => undefined);
267
269
  const schedulerOptions = options.requestScheduler;
268
270
  this.requestNow = schedulerOptions?.now ?? (() => this.now());
@@ -3283,8 +3285,8 @@ export class IbkrClient {
3283
3285
  const contracts = [];
3284
3286
  for (let index = 0; index < months.length; index += OPTION_DISCOVERY_MONTH_CONCURRENCY) {
3285
3287
  const batch = months.slice(index, index + OPTION_DISCOVERY_MONTH_CONCURRENCY);
3286
- const batchContracts = (await Promise.all(batch.map((month) => this.discoverOptions(normalized, month)))).flat();
3287
- contracts.push(...batchContracts);
3288
+ const batchContracts = await Promise.all(batch.map((month) => this.discoverOptions(normalized, month, right)));
3289
+ contracts.push(...batchContracts.flatMap((result) => result.contracts));
3288
3290
  }
3289
3291
  return [
3290
3292
  ...new Set(contracts
@@ -3293,17 +3295,38 @@ export class IbkrClient {
3293
3295
  ].sort();
3294
3296
  }
3295
3297
  /** Build one exact-expiry chain with canonical OSI symbols and required pricing/greeks. */
3296
- async getOptionChain(symbol, expiry) {
3297
- const contracts = (await this.discoverOptions(symbol, monthCode(expiry))).filter((contract) => contract.expiry === expiry);
3298
+ async getOptionChain(symbol, expiry, right) {
3299
+ const month = monthCode(expiry);
3300
+ const normalized = symbol.trim().toUpperCase();
3301
+ const discovery = await this.discoverOptions(normalized, month, right);
3302
+ const contracts = discovery.contracts.filter((contract) => contract.expiry === expiry && (right === undefined || contract.right === right));
3298
3303
  if (!contracts.length) {
3299
3304
  throw new Error(`IBKR returned no option contracts for ${symbol} ${expiry}`);
3300
3305
  }
3301
- const quoted = await this.fetchOptionQuotes(contracts, { allowIncomplete: true });
3306
+ const quoted = await this.fetchOptionQuotes(contracts, {
3307
+ allowIncomplete: true,
3308
+ telemetry: { symbol: normalized, month, right: right ?? null },
3309
+ });
3302
3310
  if (!quoted.length) {
3303
3311
  throw new Error(`IBKR returned no usable option quotes for ${symbol} ${expiry}`);
3304
3312
  }
3305
3313
  return quoted;
3306
3314
  }
3315
+ /** Return every qualified contract for one exact expiry and side without hiding sparse data. */
3316
+ async getOptionChainSnapshot(symbol, expiry, right) {
3317
+ const month = monthCode(expiry);
3318
+ const normalized = symbol.trim().toUpperCase();
3319
+ const discovery = await this.discoverOptions(normalized, month, right);
3320
+ const contracts = discovery.contracts.filter((contract) => contract.expiry === expiry);
3321
+ if (!contracts.length) {
3322
+ throw new Error(`IBKR returned no ${right} option contracts for ${symbol} ${expiry}`);
3323
+ }
3324
+ return this.fetchOptionChainSnapshot(contracts, discovery.malformedDefinitionCount, {
3325
+ symbol: normalized,
3326
+ month,
3327
+ right,
3328
+ });
3329
+ }
3307
3330
  /** Fetch one exact option quote; null means the contract is not listed. */
3308
3331
  async getOptionQuote(input) {
3309
3332
  const contract = await this.resolveOptionContract(input);
@@ -3556,14 +3579,21 @@ export class IbkrClient {
3556
3579
  }
3557
3580
  return result;
3558
3581
  }
3559
- discoverOptions(symbol, month) {
3582
+ discoverOptions(symbol, month, right) {
3560
3583
  const normalized = symbol.trim().toUpperCase();
3561
- const key = `${normalized}:${month}`;
3584
+ const key = `${normalized}:${month}:${right ?? "*"}`;
3562
3585
  let pending = this.optionDiscovery.get(key);
3563
- if (!pending) {
3564
- pending = this.loadOptionContracts(normalized, month);
3565
- this.optionDiscovery.set(key, pending);
3586
+ if (!pending && right !== undefined) {
3587
+ const complete = this.optionDiscovery.get(`${normalized}:${month}:*`);
3588
+ if (complete !== undefined) {
3589
+ pending = complete.then((result) => ({
3590
+ contracts: result.contracts.filter((contract) => contract.right === right),
3591
+ malformedDefinitionCount: result.malformedDefinitionCount,
3592
+ }));
3593
+ }
3566
3594
  }
3595
+ pending ??= this.loadOptionContracts(normalized, month, right);
3596
+ this.optionDiscovery.set(key, pending);
3567
3597
  return pending;
3568
3598
  }
3569
3599
  async loadOptionUnderlying(symbol) {
@@ -3611,97 +3641,211 @@ export class IbkrClient {
3611
3641
  throw new Error(`IBKR lost the selected underlying for ${symbol}`);
3612
3642
  return underlying;
3613
3643
  }
3614
- loadOptionContracts(symbol, month) {
3615
- return this.withSecdefPriming(() => this.loadOptionContractsPrimed(symbol, month));
3616
- }
3617
- async loadOptionContractsPrimed(symbol, month) {
3618
- const underlying = await this.loadOptionUnderlying(symbol);
3619
- const strikes = await this.req({
3620
- path: "iserver/secdef/strikes",
3621
- params: { conid: String(underlying.conid), sectype: "OPT", month },
3644
+ async loadOptionContracts(symbol, month, right) {
3645
+ const { underlying, requests } = await this.withSecdefPriming(async () => {
3646
+ const searchStarted = this.requestNow();
3647
+ const selectedUnderlying = await this.loadOptionUnderlying(symbol);
3648
+ this.emitOptionDiscoveryTelemetry({
3649
+ phase: "SEARCH",
3650
+ symbol,
3651
+ month,
3652
+ right: right ?? null,
3653
+ durationMs: this.elapsedSince(searchStarted),
3654
+ definitionRequestCount: 0,
3655
+ snapshotBatchCount: 0,
3656
+ });
3657
+ const strikesStarted = this.requestNow();
3658
+ const strikes = await this.req({
3659
+ path: "iserver/secdef/strikes",
3660
+ params: { conid: String(selectedUnderlying.conid), sectype: "OPT", month },
3661
+ });
3662
+ this.emitOptionDiscoveryTelemetry({
3663
+ phase: "STRIKES",
3664
+ symbol,
3665
+ month,
3666
+ right: right ?? null,
3667
+ durationMs: this.elapsedSince(strikesStarted),
3668
+ definitionRequestCount: 0,
3669
+ snapshotBatchCount: 0,
3670
+ });
3671
+ const callStrikes = strikes.call ?? [];
3672
+ const putStrikes = strikes.put ?? [];
3673
+ if (callStrikes.length === 0 && putStrikes.length === 0) {
3674
+ throw new Error(`IBKR returned empty option strikes for ${symbol} ${month} after secdef/search priming`);
3675
+ }
3676
+ const definitionRequests = [
3677
+ ...(right === undefined || right === "C"
3678
+ ? callStrikes.map((strike) => ({ strike, right: "C" }))
3679
+ : []),
3680
+ ...(right === undefined || right === "P"
3681
+ ? putStrikes.map((strike) => ({ strike, right: "P" }))
3682
+ : []),
3683
+ ];
3684
+ return { underlying: selectedUnderlying, requests: definitionRequests };
3622
3685
  });
3623
- const requests = [
3624
- ...(strikes.call ?? []).map((strike) => ({ strike, right: "C" })),
3625
- ...(strikes.put ?? []).map((strike) => ({ strike, right: "P" })),
3626
- ];
3627
- if (!requests.length) {
3628
- throw new Error(`IBKR returned empty option strikes for ${symbol} ${month} after secdef/search priming`);
3629
- }
3686
+ const definitionsStarted = this.requestNow();
3687
+ const responses = await Promise.all(requests.map(({ strike, right: requestRight }) => this.req({
3688
+ path: "iserver/secdef/info",
3689
+ params: {
3690
+ conid: String(underlying.conid),
3691
+ sectype: "OPT",
3692
+ month,
3693
+ strike,
3694
+ right: requestRight,
3695
+ },
3696
+ })));
3697
+ this.emitOptionDiscoveryTelemetry({
3698
+ phase: "DEFINITIONS",
3699
+ symbol,
3700
+ month,
3701
+ right: right ?? null,
3702
+ durationMs: this.elapsedSince(definitionsStarted),
3703
+ definitionRequestCount: requests.length,
3704
+ snapshotBatchCount: 0,
3705
+ });
3706
+ if (requests.length === 0)
3707
+ return { contracts: [], malformedDefinitionCount: 0 };
3630
3708
  const contracts = [];
3631
- for (const batch of chunks(requests, OPTION_SECDEF_INFO_BATCH_SIZE)) {
3632
- const responses = await Promise.all(batch.map(({ strike, right }) => this.req({
3633
- path: "iserver/secdef/info",
3634
- params: {
3635
- conid: String(underlying.conid),
3636
- sectype: "OPT",
3637
- month,
3638
- strike,
3639
- right,
3640
- },
3641
- })));
3642
- for (const raw of responses.flat()) {
3643
- const contract = normalizeOptionContract({
3644
- conid: raw.conid,
3645
- symbol: raw.symbol ?? underlying.symbol,
3646
- maturityDate: raw.maturityDate,
3647
- right: raw.right,
3648
- strike: raw.strike,
3649
- });
3709
+ let malformedDefinitionCount = 0;
3710
+ for (const response of responses) {
3711
+ if (!Array.isArray(response)) {
3712
+ throw new Error(`IBKR returned malformed option definitions for ${symbol} ${month}`);
3713
+ }
3714
+ for (const raw of response) {
3715
+ if (!isUnknownRecord(raw)) {
3716
+ malformedDefinitionCount += 1;
3717
+ continue;
3718
+ }
3719
+ let contract;
3720
+ try {
3721
+ contract = normalizeOptionContract({
3722
+ conid: typeof raw["conid"] === "number" ? raw["conid"] : undefined,
3723
+ symbol: typeof raw["symbol"] === "string" ? raw["symbol"] : underlying.symbol,
3724
+ maturityDate: typeof raw["maturityDate"] === "string" ? raw["maturityDate"] : undefined,
3725
+ right: typeof raw["right"] === "string" ? raw["right"] : undefined,
3726
+ strike: typeof raw["strike"] === "string" || typeof raw["strike"] === "number"
3727
+ ? raw["strike"]
3728
+ : undefined,
3729
+ });
3730
+ }
3731
+ catch {
3732
+ malformedDefinitionCount += 1;
3733
+ continue;
3734
+ }
3650
3735
  if (contract)
3651
3736
  contracts.push(contract);
3737
+ else
3738
+ malformedDefinitionCount += 1;
3652
3739
  }
3653
3740
  }
3654
3741
  const unique = [...new Map(contracts.map((contract) => [contract.conid, contract])).values()];
3655
3742
  if (!unique.length) {
3656
- throw new Error(`IBKR returned no usable option definitions for ${symbol} ${month}`);
3743
+ throw new Error(`IBKR returned no usable option definitions for ${symbol} ${month} (${String(malformedDefinitionCount)} malformed)`);
3744
+ }
3745
+ return { contracts: unique, malformedDefinitionCount };
3746
+ }
3747
+ async fetchOptionChainSnapshot(contracts, malformedDefinitionCount, telemetry) {
3748
+ const fields = [
3749
+ "bid",
3750
+ "ask",
3751
+ "mid",
3752
+ "delta",
3753
+ "volume",
3754
+ "openInterest",
3755
+ "availability",
3756
+ "timestamp",
3757
+ ];
3758
+ const missingFieldCounts = Object.fromEntries(fields.map((field) => [field, 0]));
3759
+ const quotes = await this.fetchNullableOptionQuotes(contracts, telemetry);
3760
+ for (const quote of quotes) {
3761
+ for (const field of fields) {
3762
+ if (quote[field] === null)
3763
+ missingFieldCounts[field] += 1;
3764
+ }
3657
3765
  }
3658
- return unique;
3766
+ const diagnostics = {
3767
+ qualifiedCount: contracts.length,
3768
+ returnedCount: quotes.length,
3769
+ malformedDefinitionCount,
3770
+ missingFieldCounts,
3771
+ };
3772
+ return { quotes, diagnostics };
3659
3773
  }
3660
- async fetchOptionQuotes(contracts, options = {}) {
3661
- const { allowIncomplete = false } = options;
3662
- const result = [];
3663
- const skipped = [];
3664
- for (const batch of chunks(contracts, OPTION_MARKETDATA_BATCH_SIZE)) {
3774
+ async fetchNullableOptionQuotes(contracts, telemetry) {
3775
+ const quotes = [];
3776
+ const batches = chunks(contracts, OPTION_MARKETDATA_BATCH_SIZE);
3777
+ const snapshotsStarted = this.requestNow();
3778
+ for (const batch of batches) {
3665
3779
  const params = {
3666
3780
  conids: batch.map((contract) => contract.conid).join(","),
3667
3781
  fields: OPTION_QUOTE_FIELDS,
3668
3782
  };
3669
3783
  await this.req({ path: "iserver/marketdata/snapshot", params });
3670
3784
  await this.wait(2000);
3671
- const snapshots = await this.req({
3785
+ const response = await this.req({
3672
3786
  path: "iserver/marketdata/snapshot",
3673
3787
  params,
3674
3788
  });
3675
- const byConid = new Map(snapshots
3676
- .filter((snapshot) => snapshot.conid !== undefined)
3677
- .map((snapshot) => [snapshot.conid, snapshot]));
3789
+ if (!Array.isArray(response)) {
3790
+ throw new Error("IBKR returned malformed option market-data snapshots");
3791
+ }
3792
+ const snapshots = response.filter((snapshot) => isUnknownRecord(snapshot) &&
3793
+ typeof snapshot["conid"] === "number" &&
3794
+ Number.isSafeInteger(snapshot["conid"]) &&
3795
+ snapshot["conid"] > 0);
3796
+ const byConid = new Map(snapshots.map((snapshot) => [snapshot.conid, snapshot]));
3678
3797
  for (const contract of batch) {
3679
3798
  const snapshot = byConid.get(contract.conid);
3680
- const bid = snapshot ? this.snapshotNumber(snapshot, "84") : undefined;
3681
- const ask = snapshot ? this.snapshotNumber(snapshot, "86") : undefined;
3682
- const delta = snapshot ? this.snapshotNumber(snapshot, "7308") : undefined;
3683
- if (bid === undefined || ask === undefined || delta === undefined) {
3684
- if (allowIncomplete) {
3685
- skipped.push(contract.symbol);
3686
- continue;
3687
- }
3688
- throw new Error(`IBKR returned incomplete option market data for ${contract.symbol} (bid/ask/delta required)`);
3689
- }
3690
- const volume = snapshot ? (this.snapshotVolume(snapshot) ?? null) : null;
3691
- const openInterest = snapshot ? (this.snapshotNumber(snapshot, "7638") ?? null) : null;
3692
- result.push({
3799
+ const bid = snapshot ? (this.snapshotNumber(snapshot, "84") ?? null) : null;
3800
+ const ask = snapshot ? (this.snapshotNumber(snapshot, "86") ?? null) : null;
3801
+ const rawAvailability = snapshot?.["6509"];
3802
+ quotes.push({
3693
3803
  ...contract,
3694
3804
  bid,
3695
3805
  ask,
3696
- mid: (bid + ask) / 2,
3697
- delta,
3698
- volume,
3699
- openInterest,
3700
- availability: normalizeDerivativeDataAvailability(snapshot?.["6509"]),
3806
+ mid: bid !== null && ask !== null ? (bid + ask) / 2 : null,
3807
+ delta: snapshot ? (this.snapshotNumber(snapshot, "7308") ?? null) : null,
3808
+ volume: snapshot ? (this.snapshotVolume(snapshot) ?? null) : null,
3809
+ openInterest: snapshot ? (this.snapshotNumber(snapshot, "7638") ?? null) : null,
3810
+ availability: typeof rawAvailability === "string" || typeof rawAvailability === "number"
3811
+ ? normalizeDerivativeDataAvailability(rawAvailability)
3812
+ : null,
3701
3813
  timestamp: snapshot ? this.snapshotTimestamp(snapshot) : null,
3702
3814
  });
3703
3815
  }
3704
3816
  }
3817
+ if (telemetry !== undefined) {
3818
+ this.emitOptionDiscoveryTelemetry({
3819
+ phase: "SNAPSHOTS",
3820
+ ...telemetry,
3821
+ durationMs: this.elapsedSince(snapshotsStarted),
3822
+ definitionRequestCount: 0,
3823
+ snapshotBatchCount: batches.length,
3824
+ });
3825
+ }
3826
+ return quotes;
3827
+ }
3828
+ async fetchOptionQuotes(contracts, options = {}) {
3829
+ const { allowIncomplete = false, telemetry } = options;
3830
+ const result = [];
3831
+ const skipped = [];
3832
+ for (const quote of await this.fetchNullableOptionQuotes(contracts, telemetry)) {
3833
+ if (quote.bid === null || quote.ask === null || quote.delta === null) {
3834
+ if (allowIncomplete) {
3835
+ skipped.push(quote.symbol);
3836
+ continue;
3837
+ }
3838
+ throw new Error(`IBKR returned incomplete option market data for ${quote.symbol} (bid/ask/delta required)`);
3839
+ }
3840
+ result.push({
3841
+ ...quote,
3842
+ bid: quote.bid,
3843
+ ask: quote.ask,
3844
+ mid: (quote.bid + quote.ask) / 2,
3845
+ delta: quote.delta,
3846
+ availability: quote.availability ?? "unavailable",
3847
+ });
3848
+ }
3705
3849
  if (allowIncomplete && skipped.length && skipped.length === contracts.length) {
3706
3850
  const symbol = contracts[0]?.underlying ?? "unknown";
3707
3851
  const expiry = contracts[0]?.expiry ?? "unknown";
@@ -3728,6 +3872,21 @@ export class IbkrClient {
3728
3872
  const endDay = this.utcDayStart(input.endDate);
3729
3873
  return { start, end: endDay + DAY_MS - 1, days: (endDay - start) / DAY_MS + 1 };
3730
3874
  }
3875
+ elapsedSince(startedAt) {
3876
+ return Math.max(0, this.requestNow() - startedAt);
3877
+ }
3878
+ emitOptionDiscoveryTelemetry(event) {
3879
+ try {
3880
+ const result = this.onOptionDiscoveryTelemetry({
3881
+ event: "OPTION_DISCOVERY_PHASE",
3882
+ ...event,
3883
+ });
3884
+ void Promise.resolve(result).catch(() => undefined);
3885
+ }
3886
+ catch {
3887
+ // Telemetry observers cannot change discovery or quote settlement.
3888
+ }
3889
+ }
3731
3890
  async requestPriceHistory(contract, requestedSymbol, request) {
3732
3891
  this.onPriceHistoryTelemetry({
3733
3892
  event: "PRICE_HISTORY_REQUEST",
@@ -4370,6 +4529,7 @@ export class IbkrClient {
4370
4529
  return this.requestScheduler.schedule({
4371
4530
  endpoint: this.requestEndpoint(input.path),
4372
4531
  priority: this.requestPriority(input.path),
4532
+ secdefInfo: input.path === "iserver/secdef/info",
4373
4533
  retryable: retryPolicy !== "SINGLE_ATTEMPT",
4374
4534
  retryServerErrors: retryPolicy === "PRICE_HISTORY",
4375
4535
  }, async () => {