from ib_insync import *
util.startLoop()
import logging
# util.logToConsole(logging.DEBUG)
ib = IB()
ib.connect('127.0.0.1', 7497, clientId=11)
<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:
amd = Stock('AMD')
cds = ib.reqContractDetails(amd)
len(cds)
35
We get a long list of contract details. Lets print the first one:
cds[0]
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:
contracts = [cd.contract for cd in cds]
contracts[0]
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:
util.df(contracts)
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:
amd = Stock('AMD', 'SMART', 'USD')
assert len(ib.reqContractDetails(amd)) == 1
Lets try the same for Intel:
intc = Stock('INTC', 'SMART', 'USD')
assert len(ib.reqContractDetails(intc)) == 1
Let's try a non-existing contract:
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
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:
amd
Stock(symbol='AMD', exchange='SMART', currency='USD', comboLegs=[])
ib.qualifyContracts(amd)
amd
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:
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:
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:
matches = ib.reqMatchingSymbols('intc')
matchContracts = [m.contract for m in matches]
matches
[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=[])]
assert intc in matchContracts
ib.disconnect()