@huskly/ibkr-client 0.27.0 → 0.29.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
@@ -65,13 +65,16 @@ routing, and caching. Public request types are the caller contract: this package
65
65
  use TypeScript and pass values accepted by those types. Provider responses remain untrusted and are
66
66
  validated at runtime. Its broker-neutral account API includes:
67
67
 
68
- - `getAccountBalances()` and `getPositions()` for account state. Account balances include typed
68
+ - `getAccountBalances()` and `getPositions()` for account state. Each position carries its current
69
+ session's broker contract ID for exact follow-up reads. Account balances include typed
69
70
  `margin.total`, `margin.securities`, and `margin.commodities` snapshots with IBKR's available
70
71
  funds, buying power, excess liquidity, cushion, SMA, equity-with-loan, Reg-T, initial- and
71
72
  maintenance-margin, full, look-ahead, and leverage values. Margin values are `null` when IBKR
72
73
  omits or returns an invalid value; numeric zero remains `0`.
73
- - `getQuotes()` and `searchInstruments()` for equity/ETF discovery and quotes. `getQuotes()` also
74
- resolves a complete OSI option symbol without loading its option chain.
74
+ - `getQuotes()` and `searchInstruments()` for equity/ETF discovery and quotes. Quote requests accept
75
+ a symbol and an optional broker ID. A broker ID reads that exact contract without symbol
76
+ discovery. A request without one can also resolve a complete OSI option symbol without loading
77
+ its option chain.
75
78
  - `fetchTransactionHistory()` for normalized portfolio transactions.
76
79
  - `fetchOrders()` for normalized live orders, including aggregate `WORKING`
77
80
  matching across IBKR's active order states.
@@ -86,7 +89,9 @@ The reusable `IbkrClient` also exposes typed, read-only strategy data:
86
89
  bid/ask/mid prices, delta, session volume, and open interest.
87
90
  - `getOptionQuote(...)` resolves and prices one exact contract with the same market-data shape.
88
91
  It uses one security-definition request after the per-underlying session search. It does not load
89
- the complete option chain.
92
+ the complete option chain. When an exact ticker has listings in more than one market, option
93
+ discovery selects the one listing with `SMART` option routing. It rejects the result if `SMART`
94
+ does not identify one listing.
90
95
  - `getOptionContract(conid)` maps a broker conid back to durable OSI identity.
91
96
 
92
97
  ### Broker-neutral derivative discovery
@@ -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, BrokerTransactionHistory, 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, PriceHistoryBar, PriceHistoryRequest, TradingDiagnostics } from "../types.js";
2
+ import type { AccountBalances, ActiveDerivativeOrder, AuthStatus, BrokerAccountOrders, BrokerClient, BrokerInstrument, BrokerInstrumentSearchProjection, BrokerOrdersOptions, BrokerPosition, BrokerQuote, BrokerQuoteRequest, BrokerTransactionHistory, 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, PriceHistoryBar, PriceHistoryRequest, TradingDiagnostics } from "../types.js";
3
3
  import { type IbkrRequestSchedulerOptions, type IbkrRequestTelemetry } from "./requestScheduler.js";
4
4
  interface IbkrRequestInput {
5
5
  path: string;
@@ -97,7 +97,8 @@ export declare class IbkrClient implements BrokerClient, DerivativeDiscoveryClie
97
97
  /** Return { conid: day P&L }. Snapshots need a warm-up call before data lands. */
98
98
  private fetchDayPnl;
99
99
  private normalizePosition;
100
- getQuotes(symbols: string[]): Promise<Record<string, BrokerQuote>>;
100
+ getQuotes(requests: readonly BrokerQuoteRequest[]): Promise<Record<string, BrokerQuote>>;
101
+ private fetchQuotes;
101
102
  /** Resolve equity/ETF symbols to IBKR contracts via `trsrv/stocks`. */
102
103
  searchInstruments(symbol: string, projection?: BrokerInstrumentSearchProjection): Promise<BrokerInstrument[]>;
103
104
  fetchTransactionHistory(startDate: Date, endDate: Date): Promise<BrokerTransactionHistory[]>;
@@ -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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"}
@@ -1262,7 +1262,14 @@ export class IbkrClient {
1262
1262
  async getPositions(symbol) {
1263
1263
  const accountId = await this.getAccountId();
1264
1264
  const rows = await this.fetchAllPositions(accountId);
1265
- const dayPnl = await this.fetchDayPnl(rows.map((p) => String(p.conid)).filter(Boolean));
1265
+ for (const position of rows) {
1266
+ if (position.conid === undefined ||
1267
+ !Number.isSafeInteger(position.conid) ||
1268
+ position.conid <= 0) {
1269
+ throw new Error(`IBKR returned an invalid position contract id for ${position.contractDesc ?? "-"}`);
1270
+ }
1271
+ }
1272
+ const dayPnl = await this.fetchDayPnl(rows.map((position) => String(position.conid)));
1266
1273
  let positions = rows.map((p) => this.normalizePosition(p, dayPnl));
1267
1274
  if (symbol) {
1268
1275
  const upper = symbol.toUpperCase();
@@ -1312,7 +1319,11 @@ export class IbkrClient {
1312
1319
  const symbol = assetClass === "OPT"
1313
1320
  ? (extractOsiPositionSymbol(contractDescription) ?? contractDescription)
1314
1321
  : contractDescription;
1322
+ if (p.conid === undefined || !Number.isSafeInteger(p.conid) || p.conid <= 0) {
1323
+ throw new Error(`IBKR returned an invalid position contract id for ${symbol}`);
1324
+ }
1315
1325
  return {
1326
+ brokerId: String(p.conid),
1316
1327
  symbol,
1317
1328
  assetType: ASSET_CLASS_LABELS[assetClass] ?? (assetClass || "-"),
1318
1329
  longQuantity: qty > 0 ? qty : 0,
@@ -1321,16 +1332,43 @@ export class IbkrClient {
1321
1332
  ...(p.multiplier === undefined ? {} : { multiplier: p.multiplier }),
1322
1333
  marketPrice: toNumber(p.mktPrice),
1323
1334
  marketValue: toNumber(p.mktValue),
1324
- currentDayProfitLoss: p.conid !== undefined ? (dayPnl.get(p.conid) ?? 0) : 0,
1335
+ currentDayProfitLoss: dayPnl.get(p.conid) ?? 0,
1325
1336
  openProfitLoss: toNumber(p.unrealizedPnl),
1326
1337
  };
1327
1338
  }
1328
- async getQuotes(symbols) {
1329
- const contracts = await Promise.all(symbols.map((symbol) => this.resolveQuoteContract(symbol)));
1330
- const resolvedContracts = contracts.filter((contract) => contract !== undefined);
1331
- if (!resolvedContracts.length)
1339
+ async getQuotes(requests) {
1340
+ const unique = new Map();
1341
+ for (const request of requests) {
1342
+ if (!request.symbol.trim())
1343
+ throw new Error("A quote request symbol is required");
1344
+ const existing = unique.get(request.symbol);
1345
+ if (existing !== undefined && existing.brokerId !== request.brokerId) {
1346
+ throw new Error(`Conflicting IBKR broker contract ids for ${request.symbol}`);
1347
+ }
1348
+ unique.set(request.symbol, request);
1349
+ }
1350
+ const contracts = await Promise.all([...unique.values()].map(async (request) => {
1351
+ if (request.brokerId === undefined)
1352
+ return this.resolveQuoteContract(request.symbol);
1353
+ if (!/^[1-9]\d*$/.test(request.brokerId)) {
1354
+ throw new Error(`Invalid IBKR broker contract id: ${request.brokerId}`);
1355
+ }
1356
+ const conid = Number(request.brokerId);
1357
+ if (!Number.isSafeInteger(conid) || conid <= 0) {
1358
+ throw new Error(`Invalid IBKR broker contract id: ${request.brokerId}`);
1359
+ }
1360
+ return {
1361
+ requestedSymbol: request.symbol,
1362
+ symbol: request.symbol,
1363
+ conid,
1364
+ };
1365
+ }));
1366
+ return this.fetchQuotes(contracts.filter((contract) => contract !== undefined));
1367
+ }
1368
+ async fetchQuotes(contracts) {
1369
+ if (!contracts.length)
1332
1370
  return {};
1333
- const conids = resolvedContracts.map((contract) => contract.conid).join(",");
1371
+ const conids = contracts.map((contract) => contract.conid).join(",");
1334
1372
  const params = { conids, fields: QUOTE_FIELDS };
1335
1373
  await this.req({ path: "iserver/marketdata/snapshot", params }); // warm up
1336
1374
  await this.wait(2000);
@@ -1341,16 +1379,15 @@ export class IbkrClient {
1341
1379
  const snapshotByConid = new Map(snapshots
1342
1380
  .filter((snapshot) => snapshot.conid !== undefined)
1343
1381
  .map((snapshot) => [snapshot.conid, snapshot]));
1344
- const histories = await Promise.all(resolvedContracts.map((contract) => this.fetchQuoteHistory(contract.conid)));
1382
+ const histories = await Promise.all(contracts.map((contract) => this.fetchQuoteHistory(contract.conid)));
1345
1383
  const quotes = {};
1346
- for (const [index, contract] of resolvedContracts.entries()) {
1384
+ for (const [index, contract] of contracts.entries()) {
1347
1385
  const snapshot = snapshotByConid.get(contract.conid);
1348
1386
  if (snapshot === undefined)
1349
1387
  continue;
1350
1388
  const history = histories[index];
1351
1389
  const quote = this.normalizeQuote(contract, snapshot, history);
1352
1390
  quotes[contract.requestedSymbol] = quote;
1353
- quotes[contract.symbol] = quote;
1354
1391
  }
1355
1392
  return quotes;
1356
1393
  }
@@ -3335,22 +3372,32 @@ export class IbkrClient {
3335
3372
  return [];
3336
3373
  }
3337
3374
  const sections = item["sections"];
3338
- if (!Array.isArray(sections) ||
3339
- !sections.some((section) => isUnknownRecord(section) &&
3340
- typeof section["secType"] === "string" &&
3341
- section["secType"].trim().toUpperCase() === "OPT")) {
3375
+ if (!Array.isArray(sections))
3342
3376
  return [];
3343
- }
3377
+ const optionSections = sections.flatMap((section) => {
3378
+ if (!isUnknownRecord(section))
3379
+ return [];
3380
+ const secType = section["secType"];
3381
+ if (typeof secType !== "string" || secType.trim().toUpperCase() !== "OPT")
3382
+ return [];
3383
+ const exchange = section["exchange"];
3384
+ return [{ exchange: typeof exchange === "string" ? exchange : null }];
3385
+ });
3386
+ if (!optionSections.length)
3387
+ return [];
3388
+ const supportsSmart = optionSections.some(({ exchange }) => exchange?.split(";").some((name) => name.trim().toUpperCase() === "SMART") ?? false);
3344
3389
  const conid = Number(item["conid"]);
3345
- return Number.isSafeInteger(conid) && conid > 0 ? [{ conid, symbol }] : [];
3390
+ return Number.isSafeInteger(conid) && conid > 0 ? [{ conid, symbol, supportsSmart }] : [];
3346
3391
  });
3347
3392
  const unique = [
3348
3393
  ...new Map(candidates.map((candidate) => [candidate.conid, candidate])).values(),
3349
3394
  ];
3350
- if (unique.length !== 1) {
3351
- throw new Error(`IBKR option underlying identity is ${unique.length ? "ambiguous" : "missing"} for ${symbol}`);
3395
+ const smart = unique.filter((candidate) => candidate.supportsSmart);
3396
+ const eligible = smart.length > 0 ? smart : unique;
3397
+ if (eligible.length !== 1) {
3398
+ throw new Error(`IBKR option underlying identity is ${eligible.length ? "ambiguous" : "missing"} for ${symbol}`);
3352
3399
  }
3353
- const [underlying] = unique;
3400
+ const [underlying] = eligible;
3354
3401
  if (underlying === undefined)
3355
3402
  throw new Error(`IBKR lost the selected underlying for ${symbol}`);
3356
3403
  return underlying;