Contracts and qualification
Every market-data request and order identifies an instrument with a Contract. A partially specified contract is a search key; a qualified contract has IBKR's canonical conId, localSymbol, tradingClass, exchange, and other resolved fields.
Convenience constructors
from ib_async import (
Stock, Option, Future, ContFuture, Forex, Index, CFD,
Commodity, Bond, MutualFund, Warrant, Crypto, FuturesOption, Bag,
)
Stock("AAPL", "SMART", "USD", primaryExchange="NASDAQ")
Option("AAPL", "20261218", 250, "C", "SMART", multiplier="100", currency="USD")
Future("ES", "20261218", "CME", multiplier="50", currency="USD")
Forex("EURUSD")
Crypto("BTC", "PAXOS", "USD")
The contract API reference lists every constructor and field.
Qualification
contracts = await ib.qualifyContractsAsync(
Stock("AAPL", "SMART", "USD"),
Future("ES", "202612", "CME", currency="USD"),
)
Qualification calls reqContractDetails and mutates successful input objects. An ambiguous search may return multiple details and cannot be safely qualified. Disambiguate stocks with primaryExchange; futures may require an exact expiry, exchange, currency, trading class, or multiplier. Error 200 means no unique security definition matched.
conId is the strongest identifier while valid, but routing fields still matter. A contract with only conId should normally specify exchange; orders often use SMART while market-depth or exchange-specific features require a direct route.
Security-type notes
| Type | Critical fields and edge cases |
|---|---|
STK | symbol, exchange, currency; use primaryExchange to resolve duplicate symbols. |
OPT | underlying symbol, exact lastTradeDateOrContractMonth, strike, right (C/P), multiplier, exchange/currency. Use reqSecDefOptParams for chains. |
FUT | exact expiry is safer than a month; multiplier may disambiguate variants. Set includeExpired=True only for historical queries. |
CONTFUT | data/analysis instrument; continuous futures cannot be traded. |
FOP | futures-option expiry, strike, right, multiplier, and exchange must match the venue definition. |
CASH | pair base in symbol, quote in currency; Forex("EURUSD") splits the pair. Quantity conventions differ from stocks. |
BAG | combo shell plus comboLegs; each leg needs conId, ratio, action, exchange, and optional open/close/short-sale fields. |
BOND | secIdType/secId or contract ID is usually more reliable than symbol-like fields. |
CRYPTO | venue, account eligibility, quantity/cash quantity, and trading hours are product-specific. |
Contract details
reqContractDetailsAsync returns zero, one, or many ContractDetails. It is the authoritative API source for trading hours, liquid hours, minimum tick, valid exchanges, market-rule IDs, order types, and product metadata.
Do not interpret tradingHours without its timezone (timeZoneId). Sessions can cross midnight and contain closed-date markers. Exchange calendars, holidays, and daylight-saving changes make hard-coded schedules unsafe. For a schedule-shaped response, reqHistoricalSchedule with whatToShow="SCHEDULE" is often easier.
Option chains
Use reqSecDefOptParamsAsync(underlyingSymbol, futFopExchange, underlyingSecType, underlyingConId). It returns OptionChain records split by exchange/trading class/multiplier, each with expirations and strikes. The Cartesian product is not proof every contract exists; qualify intended candidates. Avoid using an intentionally ambiguous reqContractDetails call to enumerate a large chain because it is throttled and returns much heavier schedule metadata.
Official references: basic contracts and options.