Close Navigation
Learn more about IBKR accounts

Essential components of TWS API programs

Lesson 4 of 10
Duration 8:58
Level Intermediate
Close Navigation

This lesson will explore the essential components of a TWS API Python program. This includes the API classes EClient and EWrapper, a function call to create a connection to TWS, and a run loop for processing returned messages in the queue. We’ll walk through a simple “Hello World” example which implements each of these components in order to send a query for details about a financial instrument and then print received details to the console. We’ll then discuss the more comprehensive sample program “Program.py” which is included with the API download and shows the syntax of all API functions.

Study Notes:

In this lesson, we will be discussing the TWS API Python essential components, and discussing them using the Contract Details request as an example. To begin, in any TWS API program you’ll always see two main classes, which would be EClient and EWrapper.  EClient is used for outgoing messages which are sent from the API program to TWS or the IB Gateway.  EWrapper is used to handle incoming messages from the Interactive Brokers server through TWS or IB Gateway.

For this lesson, I will be using Visual Studio Code. However, you can use any development environment of your choice, or even just the command lines and a text editor.  I have installed the API and then opened the python source directory, IBAPI, as well as the python sample code directory, Testbed.

To begin, I will start by importing the necessary modules. I will start by importing EClient, using “from ibapi.client import *” and EWrapper, using “from ibapi.wrapper import *”.  I will also be importing the time module, which I will discuss more later.

After importing my modules, I will now create a class to combine the two modules. I will simply type “class TestApp(EClient, EWrapper):”. Next, I will instantiate the class, as we will be using object-oriented programming going forward.

Now, I will create the EWrapper object for Contract Details, to receive my financial instrument data. I will type “def contractDetails” and include self, request ID, and contract Details as my arguments. And just for this sample, I will only be printing the contract details object, so I will type “print(f’contract details: {contractDetails}’)”. While it is not necessary, I will also include the contractDetailsEnd method, so that I have a safe place to disconnect my socket and acknowledge when I have received all of my data.

With our TestApp class created, I will start working on my Main method. After defining the method, I will add a variable to reference the TestApp class. Next, I will make a call to TestApp’s connect method. Here, I will title this as app.connect. Then I will reference our localhost as the host, then the port we set in TWS, 7497, and then a client ID – I have chosen to use 1000.

We can now begin building our contract. I want to request details for AAPL stock. To do so, I will first create my Contract object, or mycontract. Next, I will assign the symbol, AAPL, and set the security type, to STK. I am choosing to use Interactive Broker’s Smart Routing option as my exchange, and so I will set this to “Smart”. Because I am trading this on a U.S. exchange, I will use the United States Dollar as my currency. In the case of some contracts, they may be ambiguous from the symbol alone. And so, I will specify my primary exchange as NASDAQ, this is also sometimes known as ISLAND.

Now that I have my contract, I’m going to request my financial instrument details. However, I have found in my experience that my computer can typically run my request faster than a socket connection can be built. And so, I will be referencing Python’s “Time” module from earlier, to have my code sleep for 3 seconds. Now I am ready to request my contract details. The only arguments we need to provide are the request ID and our contract.

With everything set, I will create the EWrapper Run loop to receive all of my requested data. To do so, I only need to type “app.run()”. And then, outside of the main loop, I will make a call to the NAME-MAIN idiom.

Once I run my code, we can see our full contract details were returned, such as the contract object, as well as the long name, Apple Inc.  Now the full contract details for an AAPL stock are rather verbose, so maybe I will want to request just the long name for some reason. To do so, I can edit my contractDetails object, to specifically return contractDetails.longName. And as you can see, we are now only returning the contract’s full name. There are many other attributes which you may uniquely request, which can be found in the contract.py file.

If I move over to my ibapi folder, and open the contract.py file, I can scroll down and see a variety of different attributes. For example, I may want to know the liquid trading hours for my contract, or if I traded options, I may want to see the expiration date.

There are a variety of other attributes that are useful, and I would advise reviewing this list to explore what else might be beneficial for you.

Option Contract

With that in mind, lets go ahead and create an options contract for Apple. I’ll start by removing the long name so we can receive the full contract. Then, I’ll change my security type to OPT for Option, and I’ll remove the primary exchange. I’ll also include a “Right”, which I will set to ‘C’ for a Call. If we were to make the options request now, we would receive all Call options for Apple. So it would be best to trim this list down. I would like to get a bit more granular by adding a lastTradeDateorContractMonth.  Here, I will add a contract month for November 2022.

Now if I run this code, you will see a huge list of options. That is because I am not specifying a strike, nor am I specifying the exact expiration day. Because of this, we will want to get even more granular. And so, I will add a strike price of 125. And even with this specificity, I will still get 4 contracts returned. That means I would need to get even more granular than using the month of November and specify an exact expiration date.

Futures Contract

Now that we have an options contract, let’s now try to create a Futures contract. To do so, I’ll start by removing my Right, as well as my strike price. I’m also going to use DAX for my symbol, and set my security type to FUT. I’ll change my exchange to EUREX, and my currency to EUR. We will also want to edit our contract so that our expiration is set for December.

If we run this request, we will still receive 3 different contracts, and that’s because of their multiplier. We have essentially received DAX, DAX Mini, and DAX Micro futures. So to get more granular, I will add a multiplier to my contract. And so I will set mycontract.multipler equal to ‘1’. If we run this request again, we will only receive 1 contract for our DAX future.

You may be thinking that this is a lot of information you need to specify any time you would like to place a trade, particularly for Options or Futures. However, this information can be bundled into a single field, known as the Contract ID, or conId. We can see this as a series of numbers inside of our contract object. If instead of my other fields, I simple specify ‘mycontract.conId’ to this value, we can see that is the only field I need. Because of this, after you know your full contract details, Interactive Brokers strongly advises that you use this field for your other requests, like requesting market data or placing orders.

However, that concludes our video on the TWS API Essentials and the ContractDetails Requests. Thank you for watching, and we look forward to having you join us for mor TWS Python API lessons.

Connectivity

Financial Instruments (Contracts)

Streaming Market Data

Class LIst

EClient

EWrapper

Code Snippets

Stock Contract

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

class TestApp(EClient, EWrapper):
    def __init__(self):
        EClient.__init__(self, self)

    def contractDetails(self, reqId, contractDetails):
        print(f"contract details: {contractDetails}")

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

def main():
    app = TestApp()

    app.connect("127.0.0.1", 7497, 1000)

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

    time.sleep(3)

    app.reqContractDetails(1, mycontract)

    app.run()

if __name__ == "__main__":
    main()

Futures Contract

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

class TestApp(EClient, EWrapper):
    def __init__(self):
        EClient.__init__(self, self)

    def contractDetails(self, reqId, contractDetails):
        print(f"contract details: {contractDetails}")

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

def main():
    app = TestApp()

    app.connect("127.0.0.1", 7497, 1000)

    mycontract = Contract()
    mycontract.symbol = "DAX"
    mycontract.secType = "FUT"
    mycontract.exchange = "EUREX"
    mycontract.currency = "EUR"
    mycontract.lastTradeDateOrContractMonth = "202212"
    mycontract.multiplier = 1

    # Or you can use just the Contract ID
    # mycontract.conId = 552142063


    time.sleep(3)

    app.reqContractDetails(1, mycontract)

    app.run()

if __name__ == "__main__":
    main()

Option Contract

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

class TestApp(EClient, EWrapper):
    def __init__(self):
        EClient.__init__(self, self)

    def contractDetails(self, reqId, contractDetails):
        print(f"contract details: {contractDetails}")

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

def main():
    app = TestApp()

    app.connect("127.0.0.1", 7497, 1000)

    mycontract = Contract()
    mycontract.symbol = "AAPL"
    mycontract.secType = "OPT"
    mycontract.exchange = "SMART"
    mycontract.currency = "USD"
    mycontract.right = "C"
    mycontract.lastTradeDateOrContractMonth = "202211"
    mycontract.strike = 125

    time.sleep(3)

    app.reqContractDetails(1, mycontract)

    app.run()

if __name__ == "__main__":
    main()

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.

11 thoughts on “Essential components of TWS API programs”

  • there are errors in output –should we ignore it ?

    akotak@Ankitkumars-MacBook-Pro IBJts % /usr/bin/python3 /Users/akotak/Downloads/AlgoTrading/IBJ
    ts/source/pythonclient/tests/lesson_3.py
    ERROR -1 2104 Market data farm connection is OK:usfarm.nj
    ERROR -1 2104 Market data farm connection is OK:cashfarm
    ERROR -1 2104 Market data farm connection is OK:usfarm
    ERROR -1 2106 HMDS data farm connection is OK:ushmds
    ERROR -1 2158 Sec-def data farm connection is OK:secdefil
    contract details: 265598,AAPL,STK,,0,,,SMART,NASDAQ,USD,AAPL,NMS,False,,,,combo:,NMS,0.01,ACTIVETIM,AD,ADJUST,ALERT,ALGO,ALLOC,AON,AVGCOST,BASKET,BENCHPX,CASHQTY,COND,CONDORDER,DARKONLY,DARKPOLL,DAY,DEACT,DEACTDIS,DEACTEOD,DIS,DUR,GAT,GTC,GTD,GTT,HID,IBKRATS,ICE,IMB,IOC,LIT,LMT,LOC,MIDPX,MIT,MKT,MOC,MTL,NGCOMB,NODARK,NONALGO,OCA,OPG,OPGREROUT,PEGBENCH,PEGMID,POSTATS,POSTONLY,PREOPGRTH,PRICECHK,REL,REL2MID,RELPCTOFS,RPI,RTH,SCALE,SCALEODD,SCALERST,SIZECHK,SMARTSTG,SNAPMID,SNAPMKT,SNAPREL,STP,STPLMT,SWEEP,TRAIL,TRAILLIT,TRAILLMT,TRAILMIT,WHATIF,SMART,AMEX,NYSE,CBOE,PHLX,ISE,CHX,ARCA,ISLAND,DRCTEDGE,BEX,BATS,EDGEA,CSFBALGO,JEFFALGO,BYX,IEX,EDGX,FOXRIVER,PEARL,NYSENAT,LTSE,MEMX,IBEOS,OVERNIGHT,PSX,1,0,APPLE INC,,Technology,Computers,Computers,US/Eastern,20230819:CLOSED;20230820:CLOSED;20230821:0400-20230821:2000;20230822:0400-20230822:2000;20230823:0400-20230823:2000;20230824:0400-20230824:2000,20230819:CLOSED;20230820:CLOSED;20230821:0930-20230821:1600;20230822:0930-20230822:1600;20230823:0930-20230823:1600;20230824:0930-20230824:1600,,0,,,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,1,[4311536688: ISIN=US0378331005;],,COMMON,,,,,,False,False,0,False,,,,,False,,0.0001,0.0001,100
    End of contractDetails
    akotak@Ankitkumars-MacBook-Pro IBJts %

    • Hello Ankit, thank you for reaching out. All supported API programming languages offer call back functions to receive error messages sent from the TWS for troubleshooting purposes. Socket-based APIs (e.g., C#, Java, VB.Net, C++, Python and ActiveX) handle error messages within the error() call back function in the EWrapper interface. For additional information, including a list of message codes, please review our API documentation. We hope this helps!
      If your query is still not answered after reviewing the documentation, please create a web ticket in Client Portal with the category “API.” Our experts will be glad to help you out!

  • I directly copied the futures contract and received the error:
    ERROR 1 200 No security definition has been found for the request

    Im not sure where this is coming from or what it means

  • how to restrict the option contract for a particular date, not the all valid dates in the whole month? E.g. if on 1/Jan/2024, I only want to request data from the IB server for the SPY option contract expiry on that date?

    • Hello Nathan, thank you for reaching out. The contract specifications can be as precise or vague as needed in the TWS API. Our example assumed you have no knowledge of the expiration, so we look at the whole month of November. If you know an expiration is taking place on January 1st, 2024, you could set mycontract.lastTradeDateOrContractMonth = “20240101” to include the year, month, and day of the expiration. Please reach back out if you have more questions. We are here to help!

  • I have the same issue as Paul, which I understand, however one I get the “ERROR 1 200 No security definition has been found for the request”, the code continues to run in this infinite loop and I have to restart the kernel to stop it. I am using a Jupyter Notebook. Is there a way to stop it if this error occurs? Thanks

    • Hello, thank you for reaching out. Forex contracts are constructed by setting the symbol to the target currency, while the ‘currency’ value is equal to the base. In an example of EUR.USD pairs, we would set the symbol, or target currency, to ‘EUR’ while our base currency value would be ‘USD’. You can find more details on contracts in our documentation here: https://ibkrcampus.com/ibkr-api-page/contracts/#forex. We hope this helps!

  • Fyi if you directly copy paste the futures example and run it, you will get an error. This is because you are trying to pull contract details for the DAX future with expiry 2022 which is too far in the past. Try updating the year to the current or next year and it should work.

Leave a Reply

Your email address will not be published. Required fields are marked *

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.

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.