Skip to navigation

Combos & Spreads

View as MarkdownOpen in Claude
From a programmatic perspective, terms like “BAG”, “Combo”, and “Spread” are synonymous and may be used interchangeably.

Combos and Spreads

As with standard contracts, you will continue to define the standard values such as symbol, secType, exchange, and currency. However, with combo orders, the “ComboLegs” field must be added and the ComboLeg objects should be attached. The example provided will showcase more detail of behavior; however, these require a conid, exchange, ratio, and an action for every ComboLeg on the order.

Spread contracts combine two or more instruments. To define a combination contract it is required to know the conId of the contract in question.

The conId of an instrument can easily be obtained via the EClientSocket.reqContractDetails request or the /iserver/secdef/search endpoint.

Even though a contract can be created with any pair of instruments, not all instruments are as actively traded as others. If you are unsure why data may not be retrieved, or why an order may not be executed, it is considered best practice to confirm data against the Trader Workstation or Client Portal market data.
ComboLeg()

ConId: int. The conId, or contract Identifier, should be used to specify the exact contract. Symbols or local symbols can not be used for ComboLegs.

Ratio: int. Specify the ratio for the specific leg. The ratio will be multiplied by the totalQuantity field for of the order object.

Action: String. Specify what to do with the order. Users may choose Buy or Sell for these orders.

Exchange: String. Specify the routing exchange for the contract. SMART may be used.

contract = Contract()
contract.symbol = "IBKR,MCD"
contract.secType = "BAG"
contract.currency = "USD"
contract.exchange = "SMART"
leg1 = ComboLeg()
leg1.conId = 43645865#IBKR STK
leg1.ratio = 1
leg1.action = "BUY"
leg1.exchange = "SMART"
leg2 = ComboLeg()
leg2.conId = 9408#MCD STK
leg2.ratio = 1
leg2.action = "SELL"
leg2.exchange = "SMART"
contract.comboLegs = []
contract.comboLegs.append(leg1)
contract.comboLegs.append(leg2)

Smart-Routed Futures Spreads

Futures spreads can also be defined as Smart-routed (non-guaranteed) combos. When placing an order for a non-guaranteed combo from the API, the non-guaranteed flag must be set to 1. Historical data for smart-routed futures spreads is generally available from the API with the requisite market data subscriptions.

contract = Contract()
contract.symbol = "WTI" # WTI,COIL spread. Symbol can be defined as first leg symbol ("WTI") or currency ("USD")
contract.secType = "BAG"
contract.currency = "USD"
contract.exchange = "SMART"
leg1 = ComboLeg()
leg1.conId = 55928698 # WTI future June 2017
leg1.ratio = 1
leg1.action = "BUY"
leg1.exchange = "IPE"
leg2 = ComboLeg()
leg2.conId = 55850663 # COIL future June 2017
leg2.ratio = 1
leg2.action = "SELL"
leg2.exchange = "IPE"
contract.comboLegs = []
contract.comboLegs.append(leg1)
contract.comboLegs.append(leg2)

Inter-commoddity Futures Spread

For Inter-Commodity futures, the ‘Local Symbol’ field in TWS is used for the ‘Symbol’ field in the API contract definition, e.g. “CL.BZ”. They are always guaranteed combos, which is the default in the API.

In some instances, a generic symbol must be provided instead. For example, a inter-commodity future containing ZF and ZN will require that the symbol be set to “FYT”.

Please be mindful that inter-commodity spreads are offered by the exchange directly, and so they are direct-routed though the legs have different underlyings. Only real time, and not historical, data is offered for inter-commodity spread contracts through the API.

It is also possible in many cases to create a spread of the same future contracts in a inter-commodity spread which is smart-routed and non-guaranteed. Historical data for this spread would generally be available from the API. Also, historical data for expired spread contracts is not available in TWS or the API.

contract = Contract()
contract.symbol = "COL.WTI" #symbol is 'local symbol' of intercommodity spread.
contract.secType = "BAG"
contract.currency = "USD"
contract.exchange = "IPE"
leg1 = ComboLeg()
leg1.conId = 183405603 #WTI�Dec'23�@IPE
leg1.ratio = 1
leg1.action = "BUY"
leg1.exchange = "IPE"
leg2 = ComboLeg()
leg2.conId = 254011009 #COIL�Dec'23�@IPE
leg2.ratio = 1
leg2.action = "SELL"
leg2.exchange = "IPE"
contract.comboLegs = []
contract.comboLegs.append(leg1)
contract.comboLegs.append(leg2)