Contract details

In [1]:
from ib_insync import *
util.startLoop()

import logging
# util.logToConsole(logging.DEBUG)

ib = IB()
ib.connect('127.0.0.1', 7497, clientId=11)
Out[1]:
<IB connected to 127.0.0.1:7497 clientId=11>

Suppose we want to find the contract details for AMD stock. Let's create a stock object and request the details for it:

In [2]:
amd = Stock('AMD')

cds = ib.reqContractDetails(amd)

len(cds)
Out[2]:
35

We get a long list of contract details. Lets print the first one:

In [3]:
cds[0]
Out[3]:
ContractDetails(contract=Contract(secType='STK', conId=4391, symbol='AMD', exchange='SMART', primaryExchange='NASDAQ', currency='USD', localSymbol='AMD', tradingClass='NMS', comboLegs=[]), marketName='NMS', minTick=0.01, orderTypes='ACTIVETIM,ADJUST,ALERT,ALGO,ALLOC,AON,AVGCOST,BASKET,BENCHPX,COND,CONDORDER,DARKONLY,DARKPOLL,DAY,DEACT,DEACTDIS,DEACTEOD,DIS,GAT,GTC,GTD,GTT,HID,IBKRATS,ICE,IMB,IOC,LIT,LMT,LOC,MIDPX,MIT,MKT,MOC,MTL,NGCOMB,NODARK,NONALGO,OCA,OPG,OPGREROUT,PEGBENCH,POSTONLY,PREOPGRTH,REL,RPI,RTH,SCALE,SCALEODD,SCALERST,SNAPMID,SNAPMKT,SNAPREL,STP,STPLMT,SWEEP,TRAIL,TRAILLIT,TRAILLMT,TRAILMIT,WHATIF', validExchanges='SMART,AMEX,NYSE,CBOE,PHLX,ISE,CHX,ARCA,ISLAND,DRCTEDGE,BEX,BATS,EDGEA,CSFBALGO,JEFFALGO,BYX,IEX,EDGX,FOXRIVER,NYSENAT,PSX', priceMagnifier=1, underConId=0, longName='ADVANCED MICRO DEVICES', contractMonth='', industry='Technology', category='Semiconductors', subcategory='Electronic Compo-Semicon', timeZoneId='EST (Eastern Standard Time)', tradingHours='20191231:0400-20191231:2000;20200101:CLOSED;20200102:0400-20200102:2000;20200103:0400-20200103:2000;20200104:CLOSED;20200105:CLOSED;20200106:0400-20200106:2000;20200107:0400-20200107:2000;20200108:0400-20200108:2000;20200109:0400-20200109:2000;20200110:0400-20200110:2000;20200111:CLOSED;20200112:CLOSED;20200113:0400-20200113:2000;20200114:0400-20200114:2000;20200115:0400-20200115:2000;20200116:0400-20200116:2000;20200117:0400-20200117:2000;20200118:CLOSED;20200119:CLOSED;20200120:0400-20200120:2000;20200121:0400-20200121:2000;20200122:0400-20200122:2000;20200123:0400-20200123:2000;20200124:0400-20200124:2000;20200125:CLOSED;20200126:CLOSED;20200127:0400-20200127:2000;20200128:0400-20200128:2000;20200129:0400-20200129:2000;20200130:0400-20200130:2000;20200131:0400-20200131:2000;20200201:CLOSED;20200202:CLOSED;20200203:0400-20200203:2000', liquidHours='20191231:0930-20191231:1600;20200101:CLOSED;20200102:0930-20200102:1600;20200103:0930-20200103:1600;20200104:CLOSED;20200105:CLOSED;20200106:0930-20200106:1600;20200107:0930-20200107:1600;20200108:0930-20200108:1600;20200109:0930-20200109:1600;20200110:0930-20200110:1600;20200111:CLOSED;20200112:CLOSED;20200113:0930-20200113:1600;20200114:0930-20200114:1600;20200115:0930-20200115:1600;20200116:0930-20200116:1600;20200117:0930-20200117:1600;20200118:CLOSED;20200119:CLOSED;20200120:0930-20200120:1600;20200121:0930-20200121:1600;20200122:0930-20200122:1600;20200123:0930-20200123:1600;20200124:0930-20200124:1600;20200125:CLOSED;20200126:CLOSED;20200127:0930-20200127:1600;20200128:0930-20200128:1600;20200129:0930-20200129:1600;20200130:0930-20200130:1600;20200131:0930-20200131:1600;20200201:CLOSED;20200202:CLOSED;20200203:0930-20200203:1600', evRule='', evMultiplier=0, mdSizeMultiplier=100, aggGroup=1, underSymbol='', underSecType='', marketRuleIds='26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26', secIdList=[], realExpirationDate='', lastTradeTime='', stockType='COMMON', cusip='', ratings='', descAppend='', bondType='', couponType='', callable=False, putable=False, coupon=0, convertible=False, maturity='', issueDate='', nextOptionDate='', nextOptionType='', nextOptionPartial=False, notes='')

The contract itself is in the 'contract' property of the contract details. Lets make a list of contracts and look at the first:

In [4]:
contracts = [cd.contract for cd in cds]

contracts[0]
Out[4]:
Contract(secType='STK', conId=4391, symbol='AMD', exchange='SMART', primaryExchange='NASDAQ', currency='USD', localSymbol='AMD', tradingClass='NMS', comboLegs=[])

To better spot the difference between all the contracts it's handy to convert to a DataFrame. There is a utility function to do that:

In [5]:
util.df(contracts)
Out[5]:
secType conId symbol lastTradeDateOrContractMonth strike right multiplier exchange primaryExchange currency localSymbol tradingClass includeExpired secIdType secId comboLegsDescrip comboLegs deltaNeutralContract
0 STK 4391 AMD 0.0 SMART NASDAQ USD AMD NMS False [] None
1 STK 32596680 AMD 0.0 SMART IBIS EUR AMD XETRA False [] None
2 STK 172603743 AMD 0.0 SMART EBS CHF AMD AMD False [] None
3 STK 298633607 AMD 0.0 SMART ASX AUD AMD AMD False [] None
4 STK 4391 AMD 0.0 AMEX NASDAQ USD AMD NMS False [] None
5 STK 4391 AMD 0.0 NYSE NASDAQ USD AMD NMS False [] None
6 STK 4391 AMD 0.0 CBOE NASDAQ USD AMD NMS False [] None
7 STK 4391 AMD 0.0 PHLX NASDAQ USD AMD NMS False [] None
8 STK 4391 AMD 0.0 ISE NASDAQ USD AMD NMS False [] None
9 STK 4391 AMD 0.0 CHX NASDAQ USD AMD NMS False [] None
10 STK 4391 AMD 0.0 ARCA NASDAQ USD AMD NMS False [] None
11 STK 4391 AMD 0.0 ISLAND NASDAQ USD AMD NMS False [] None
12 STK 4391 AMD 0.0 DRCTEDGE NASDAQ USD AMD NMS False [] None
13 STK 4391 AMD 0.0 BEX NASDAQ USD AMD NMS False [] None
14 STK 4391 AMD 0.0 BATS NASDAQ USD AMD NMS False [] None
15 STK 4391 AMD 0.0 EDGEA NASDAQ USD AMD NMS False [] None
16 STK 4391 AMD 0.0 CSFBALGO NASDAQ USD AMD NMS False [] None
17 STK 4391 AMD 0.0 JEFFALGO NASDAQ USD AMD NMS False [] None
18 STK 4391 AMD 0.0 BYX NASDAQ USD AMD NMS False [] None
19 STK 4391 AMD 0.0 IEX NASDAQ USD AMD NMS False [] None
20 STK 4391 AMD 0.0 EDGX NASDAQ USD AMD NMS False [] None
21 STK 4391 AMD 0.0 FOXRIVER NASDAQ USD AMD NMS False [] None
22 STK 4391 AMD 0.0 NYSENAT NASDAQ USD AMD NMS False [] None
23 STK 4391 AMD 0.0 PSX NASDAQ USD AMD NMS False [] None
24 STK 32596680 AMD 0.0 FWB IBIS EUR AMD USSTARS False [] None
25 STK 32596680 AMD 0.0 IBIS IBIS EUR AMD XETRA False [] None
26 STK 32596680 AMD 0.0 BVME IBIS EUR AMD AMD False [] None
27 STK 32596680 AMD 0.0 VSE IBIS EUR AMD AMD False [] None
28 STK 32596680 AMD 0.0 SWB IBIS EUR AMD XETRA False [] None
29 STK 32596680 AMD 0.0 TGATE IBIS EUR AMD AMD False [] None
30 STK 32596680 AMD 0.0 GETTEX IBIS EUR AMD USSTARS False [] None
31 STK 48818298 AMD 0.0 MEXI MEXI MXN AMD AMD False [] None
32 STK 172603743 AMD 0.0 EBS EBS CHF AMD AMD False [] None
33 STK 298633607 AMD 0.0 ASX ASX AUD AMD AMD False [] None
34 STK 298633607 AMD 0.0 ASXCEN ASX AUD AMD AMD False [] None

We can see from this that AMD trades in different currencies on different exchanges. Suppose we want the one in USD on the SMART exchange. The AMD contract is adjusted to reflect that and becomes unique:

In [6]:
amd = Stock('AMD', 'SMART', 'USD')

assert len(ib.reqContractDetails(amd)) == 1

Lets try the same for Intel:

In [7]:
intc = Stock('INTC', 'SMART', 'USD')

assert len(ib.reqContractDetails(intc)) == 1

Let's try a non-existing contract:

In [8]:
xxx = Stock('XXX', 'SMART', 'USD')

assert len(ib.reqContractDetails(xxx)) == 0
Error 200, reqId 6: No security definition has been found for the request, contract: Stock(symbol='XXX', exchange='SMART', currency='USD', comboLegs=[])

or a Forex contract

In [9]:
eurusd = Forex('EURUSD')

assert len(ib.reqContractDetails(eurusd)) == 1

With the qualifyContracts method the extra information that is send back from the contract details request is used to fill in the original contracts.

Lets do that with amd and compare before and aftwards:

In [10]:
amd
Out[10]:
Stock(symbol='AMD', exchange='SMART', currency='USD', comboLegs=[])
In [11]:
ib.qualifyContracts(amd)
amd
Out[11]:
Stock(conId=4391, symbol='AMD', exchange='SMART', primaryExchange='NASDAQ', currency='USD', localSymbol='AMD', tradingClass='NMS', comboLegs=[])

TIP: When printing a contract, the output can be copy-pasted and it will be valid Python code.

The conId that is returned can by itself be used to uniquely specify a contract:

In [12]:
contract_4391 = Contract(conId=4391)

ib.qualifyContracts(contract_4391)

assert contract_4391 == amd

A whole bunch of contracts can be qualified at the same time. A list of all the successfull ones is returned:

In [13]:
qualContracts = ib.qualifyContracts(amd, intc, xxx, eurusd)

assert intc in qualContracts
assert xxx not in qualContracts
Error 200, reqId 12: No security definition has been found for the request, contract: Stock(symbol='XXX', exchange='SMART', currency='USD', comboLegs=[])
Unknown contract: Stock(symbol='XXX', exchange='SMART', currency='USD', comboLegs=[])

There is also an API function to request stocks (only stocks) that match a pattern:

In [14]:
matches = ib.reqMatchingSymbols('intc')
matchContracts = [m.contract for m in matches]

matches
Out[14]:
[ContractDescription(contract=Contract(secType='STK', conId=38709539, symbol='INTC', primaryExchange='MEXI', currency='MXN', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=270639, symbol='INTC', primaryExchange='NASDAQ.NMS', currency='USD', comboLegs=[]), derivativeSecTypes=['CFD', 'OPT', 'IOPT', 'WAR', 'FUT']),
 ContractDescription(contract=Contract(secType='STK', conId=12178234, symbol='INTC', primaryExchange='EBS', currency='CHF', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=11463493, symbol='INTCUSD', primaryExchange='EBS', currency='USD', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=130861844, symbol='S', primaryExchange='MEXI', currency='MXN', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=130861851, symbol='2S7', primaryExchange='FWB', currency='EUR', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=130651996, symbol='S', primaryExchange='NYSE', currency='USD', comboLegs=[]), derivativeSecTypes=['CFD', 'OPT', 'FUT']),
 ContractDescription(contract=Contract(secType='STK', conId=14015710, symbol='4613', primaryExchange='TSEJ', currency='JPY', comboLegs=[]), derivativeSecTypes=['CFD']),
 ContractDescription(contract=Contract(secType='STK', conId=257765562, symbol='603737', primaryExchange='SEHKNTL', currency='CNH', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=257310905, symbol='002436', primaryExchange='SEHKSZSE', currency='CNH', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=234809383, symbol='FING.B', primaryExchange='SFB', currency='SEK', comboLegs=[]), derivativeSecTypes=['CFD', 'OPT', 'IOPT']),
 ContractDescription(contract=Contract(secType='STK', conId=234809384, symbol='FPQ1', primaryExchange='FWB2', currency='EUR', comboLegs=[]), derivativeSecTypes=['IOPT']),
 ContractDescription(contract=Contract(secType='STK', conId=83364054, symbol='FRP', primaryExchange='VALUE', currency='USD', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=169544707, symbol='ECC', primaryExchange='NYSE', currency='USD', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=96816938, symbol='E16', primaryExchange='SGX', currency='USD', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=90691307, symbol='1151', primaryExchange='SEHK', currency='HKD', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=173148149, symbol='JYNT', primaryExchange='NASDAQ.SCM', currency='USD', comboLegs=[]), derivativeSecTypes=['OPT']),
 ContractDescription(contract=Contract(secType='STK', conId=392988575, symbol='1JO', primaryExchange='FWB2', currency='EUR', comboLegs=[]), derivativeSecTypes=[]),
 ContractDescription(contract=Contract(secType='STK', conId=131085231, symbol='4621', primaryExchange='TSEJ', currency='JPY', comboLegs=[]), derivativeSecTypes=[])]
In [15]:
assert intc in matchContracts
In [16]:
ib.disconnect()