Asset Classes

Free investment financial education

Language

Multilingual content from IBKR

Close Navigation
Learn more about IBKR accounts

Defining Contracts in the TWS API

Lesson 5 of 11
Duration 12:02
Level Intermediate
Close Navigation

Hello, and welcome to this lesson discussing contract discovery and how to define a contract using the TWS API. Please note that our starting file content will mirror the previous video on essential API components. As a result, I would encourage viewers to review the last lesson before going further in this lesson. To explore contract definitions, we can utilize the EClient.reqContractDetails and EWrapper.contractDetails, as this provides the baseline of contract discovery before moving into other functionality like market data or order placement.

Starting out with last lesson’s template, without the currentTime references, we can start by writing out the EWrapper.contractDetails function. All we need to do is define the function, contractDetails, inside of our TestApp class. This function takes three arguments, self, reqId, and contractDetails. The first two we are familiar with, but contractDetails is a unique class, ContractDetails, which contains all of the contract’s information in a dictionary structure. Including things like the underlying contract details, the supported exchanges, and trading hours.

Users are welcome to print this value directly; however, since we’ll be printing and reading the value, we can utilize some of Python’s dictionary handling. With that in mind, I will create a variable, attrs, and set it equal to the vars() method, taking our contractDetails as an argument. This will produce the key-value pair of our contractDetails object. Then, I’ll look to print a string-joined lambda set. This will appear as print(“\n”.join(f”{name}: {value}” for name, value in attrs.items())). 

I will also add another EWrapper function, contractDetailsEnd. This function simply indicates when there is no data remaining for a request that may return several responses to a single request. The method only takes self and reqId as an argument to help with request tracking. I will use this method to announce contract details has ended, and also disconnect our API session, similar to how we did for the currentTime method before.

Stock Contracts

Now we can move on to the request side of things. Let’s keep things simple to start with and focus on requesting stock contract details, then we can build out futures or options contracts later, since those are a bit more complex. We can create a variable, such as mycontract and set it equal to a Contract object. Now, I can start establishing my contract. As a test case, maybe all I know about my trading is that I want to trade AAPL stock. Therefore, I can set mycontract.symbol to “AAPL” and then mycontract.secType = “STK”.  Please be aware that nearly all secType values are 3 or 4 character representations of a given security type. For example, we might see STK for Stocks, OPT for Options, or FUT for Futures.

We can then send out our EClient.reqContractDetails request to find information on this contract. This request only takes the arguments for a request ID, which we’ll use our app.nextId() function for, and then a Contract object, which we’ll use mycontract for. With these simple additions set, we can run our code, and we should see a large amount of data returned. That is because the contractDetails method can be used to receive any contract that approximately matches our Contract object. The best way to distinguish between your conracts is to look at the actual “contract” value returned. This will return essential values like the conid, symbol, security type, trading exchange, and listing exchange.

Before moving on, let’s take a moment to look at the overall response of the contractDetails object. I can see the extended detail of our contract object, but also values like orderTypes, which show the supported order types with the instrument,  liquidHours, time zone ID, and even market rule information. But this was not exactly what I intended to receive, so let’s further truncate this request.

I can set my contract’s currency value to USD, since I only care to trade in my own base currency. Then, I can also set my exchange value to SMART, because I want to trade using the Interactive Brokers SmartRouting feature. If we request data now, we’ll see that adding two additional parameters returns a single contract for our use and is just the contract I wanted. These four values, symbol, sectype, exchange, and currency; are the basis of any contract we’d like to use.

Users should look to include the primaryExchange value where possible. This is the item just after our trading exchange in the contract object and can be used to distinguish between multiple companies that have otherwise matching symbols and require more distinction. Adding the primary exchange can help resolve most ambiguous contracts.

Futures Contracts

With our baseline stocks settled, we can move on to Futures contracts. Before requesting our contract, I’ll adjust my EWrapper.contractDetails method to just print the contractDetails.contract value, to help conserve space, at least while we are exploring. contractDetails.contract is identical to the Contract object we are creating in our request. As a result, the parameters we send can be mirrored in the parameters we receive. We can uncomment the lambda print value once we have narrowed down our contract.

We can tweak our existing contract to another contract we’re looking for. I want to look into ES Futures trading, so I’ll adjust my contract symbol and security type to ES and FUT accordingly. For those unaware, SMART Routing is only supported for stocks, options, and combinations. As a result, I would not be able to use SMART for my ES future.

So, in this case, I will comment out the exchange field, and send my request. 

This will return numerous contracts, though we’ll notice that a lot of the contracts coming back are either CME or QBALGO. Given I don’t want to trade the algo, and I simply want to trade the CME exchange, I’ll uncomment my exchange value, and set this to “CME”. We can also find the date values, which correlate to the lastTradeDateOrContractMonth value. I will add this to my own contract month for December, and I can receive only the ES contracts traded by CME in December of 2024. If we uncomment our lambda function and run our script, we’ll find all of the relevant information we want.

Options Contract

Before diving into the options contract, I’ll once again comment out the contractDetails lambda function, and simply print the contract object. I will also tweak my existing contract object again, because now I’m thinking about trading SPX options. This will only require a few modifications from the ES contract, and would be an almost identical set of values if we were looking to trade Futures Options. I will adjust my symbol to SPX, secType to OPT, and my exchange back to SMART. If we run the script now, we’ll receive hundreds of results back, as there are several expiries, rights, and strikes traded throughout the month of December, even with our existing filtering.

To filter out our options contract further, I’ll set my right to Put, using mycontract.right = “P”. In the case of rights, you may use P or Put for puts, or C or Call for call options. With our right set, there is still a lot to filter. Near the end of our contract object, we’ll notice these “SPX” and “SPXW” values. These values are known as the TradingClass of the contract and distinguish between multiple matching derivatives. In this scenario, this distinguishes between the monthly SPX contracts and the weekly contracts. This is especially relevant, as these two contracts can overlap their expiration date, and the trading class may be the only distinct value.

If we make the request now, we will still find tons of results. This is because all of the potential strike values are being returned, which is particularly large, especially for an index like SPX. As a result, it’s best to further truncate our request by including a strike in our contract. I will narrow my focus to a strike of 5300, which gives us one last contract. I will uncomment our lambda function before running the script, so we can see all these values that were being requested and returned.

Extended Contract Information

There are several additional security types with their own unique parameters. I’d like to briefly discuss some additional resources users should consult to find these details. With regard to the API specific fields, the TWS API Contract class reference is listed in our documentation on IBKR Campus that provides context to each parameter for review.

Similarly, we also maintain an entire Contracts page, which users should consult to find which parameters are needed for each contract type. This will provide an API-Agnostic structure which displays what values, such as symbol, secType, and exchange, are required for special contract types. This will even include information on building futures spreads or option combos, all of which are built on the foundation discussed throughout this lesson.

Finally, users should look to utilize Trader Workstation’s Description page for more insight on retrieving contract-specific details. To accomplish this, search for any contract you typically consult in your day-to-day trading. After adding the contract to your watchlist, or if it is already in your Portfolio, right click the instrument, click the drop-down arrow, then “Financial Instrument Details” and finally “Description”. This will bring up a window in Trader Workstation which provides nearly all of the contract information discussed here. It is an essential tool while you are learning to search for contracts through the API independently.

This concludes our lesson on defining contracts in the TWS API. Thank you for watching. If you have any questions, please be sure to review our documentation or leave a comment below this video. We look forward to having you in the next lesson of our TWS API series.

Code Snippets – contractDiscovery.py

from ibapi.client import *
from ibapi.wrapper import *
import time
import threading

class TestApp(EClient, EWrapper):
  def __init__(self):
    EClient.__init__(self, self)
  
  def nextValidId(self, orderId):
    self.orderId = orderId
  
  def nextId(self):
    self.orderId += 1
    return self.orderId

  def error(self, reqId, errorCode, errorString, advancedOrderReject):
    print(f"reqId: {reqId}, errorCode: {errorCode}, errorString: {errorString}, orderReject: {advancedOrderReject}")

  def contractDetails(self, reqId, contractDetails):
    attrs = vars(contractDetails)
    print("\n".join(f"{name}: {value}" for name,value in attrs.items()))
    # print(contractDetails.contract)

  def contractDetailsEnd(self, reqId):
    print("End of contract details")
    self.disconnect()

app = TestApp()
app.connect("127.0.0.1", 7497, 0)
threading.Thread(target=app.run).start()
time.sleep(1)

mycontract = Contract()
# Stock
# mycontract.symbol = "AAPL"
# mycontract.secType = "STK"
# mycontract.currency = "USD"
# mycontract.exchange = "SMART"
# mycontract.primaryExchange = "NASDAQ"

# Future
# mycontract.symbol = "ES"
# mycontract.secType = "FUT"
# mycontract.currency = "USD"
# mycontract.exchange = "CME"
# mycontract.lastTradeDateOrContractMonth = 202412

# Option
mycontract.symbol = "SPX"
mycontract.secType = "OPT"
mycontract.currency = "USD"
mycontract.exchange = "SMART"
mycontract.lastTradeDateOrContractMonth = 202412
mycontract.right = "P"
mycontract.tradingClass = "SPXW"
mycontract.strike = 5300

app.reqContractDetails(app.nextId(), mycontract)

Join The Conversation

If you have a general question, it may already be covered in our FAQs. If you have an account-specific question or concern, please reach out to Client Services.

2 thoughts on “Defining Contracts in the TWS API”

  • YORDANIS COBAS LOBAINA

    contract = Contract()
    contract.symbol = ‘USD.CAD’
    contract.secType = ‘CASH’
    contract.exchange = ‘IDEALPRO’
    contract.currency = ‘CAD’
    what_to_show = ‘ASK’

    I don’t know what I’m doing wrong?
    I get the following error:
    Error 200: No security definition has been found for the request

    • Interactive Brokers

      Hello, thank you for reaching out. “USD.CAD” is the local symbol for the US Dollar – Canadian Dollar forex pair. So to fix this, you can modify your code to use:
      contract.symbol = “USD”
      OR
      contract.localSymbol = “USD.CAD”.

      We hope this answers your question!

Leave a Reply

Disclosure: Interactive Brokers

The analysis in this material is provided for information only and is not and should not be construed as an offer to sell or the solicitation of an offer to buy any security. To the extent that this material discusses general market activity, industry or sector trends or other broad-based economic or political conditions, it should not be construed as research or investment advice. To the extent that it includes references to specific securities, commodities, currencies, or other instruments, those references do not constitute a recommendation by IBKR to buy, sell or hold such investments. This material does not and is not intended to take into account the particular financial conditions, investment objectives or requirements of individual customers. Before acting on this material, you should consider whether it is suitable for your particular circumstances and, as necessary, seek professional advice.

The views and opinions expressed herein are those of the author and do not necessarily reflect the views of Interactive Brokers, its affiliates, or its employees.

Disclosure: API Examples Discussed

Throughout the lesson, please keep in mind that the examples discussed are purely for technical demonstration purposes, and do not constitute trading advice. Also, it is important to remember that placing trades in a paper account is recommended before any live trading.

Disclosure: Options (with multiple legs)

Options involve risk and are not suitable for all investors. For information on the uses and risks of options, you can obtain a copy of the Options Clearing Corporation risk disclosure document titled Characteristics and Risks of Standardized Options by clicking the link below. Multiple leg strategies, including spreads, will incur multiple transaction costs. "Characteristics and Risks of Standardized Options"

Disclosure: Displaying Symbols on Video

Any stock, options or futures symbols displayed are for illustrative purposes only and are not intended to portray recommendations.

IBKR Campus Newsletters

This website uses cookies to collect usage information in order to offer a better browsing experience. By browsing this site or by clicking on the "ACCEPT COOKIES" button you accept our Cookie Policy.