Asset Classes

Free investment financial education

Language

Multilingual content from IBKR

Close Navigation
Learn more about IBKR accounts

Essential components of TWS API programs

Lesson 4 of 11
Duration 9:02
Level Intermediate
Close Navigation

Welcome to this lesson on 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. This lesson will also include a brief discussion of the nextValidId method, and we can implement threading. Finally, we’ll walk through our reqCurrentTime method to create a basic “Hello World” style script.

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. 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 and threading modules, which we will touch on later.

After importing my modules, I will create a class to combine the EClient and EWrapper modules. I will type “class TestApp(EClient, EWrapper):”. Next, we instantiate the class by defining our init method with def __init__(self): followed by a newline EClient init request using EClient.__init__(self,self).

After our init, let’s create the EWrapper object for NextValidId(self, orderId): to receive order Ids. This will receive the EWrapper return of next valid order id, and retain valid session throughout the trading day to prevent duplicate values. Here, I can create an object for the order id, self.orderId = orderId. Now it may be confusing, but we can now make a new function, nextId, only retaining the object. Within the function, I will increment our newly made self.orderId value by 1, and then return the self.order variable. This way we can maintain the order Id throughout future requests and return the order id to our request.

We will circle back to some of the more elaborate EWrapper functionality in a moment. However, for now, we can just print out this id by creating our TestApp reference. All this takes is setting a variable, let’s use “app”, equal to the TestApp() class. Now, we’ll connect our app to Trader Workstation, by calling app.connect(“127.0.0.1”, 7497, 0). The values in this method are the host, port, and clientId.

Assuming your TWS is on the same machine where your API code is running, this will always be “127.0.0.1” or “localhost”. We have included a description of the standard port values in the transcript of this video. You can also review your TWS socket port setting in our prior video on setting up the Trader Workstation for API use. And then our client ID can be any value, as long as another client ID connection is not using the same value.

Platform

Port

TWS Live

7496

TWS Paper

7497

IBG Live

4001

IBG Paper

4002

With our connect methodology in place, we can implement a little bit of threading to get started. The simple implementation would be to call threading.Thread(target=app.run).start().

Please be aware that we reference the object of app.run, without including the parenthesis. Next, we’ll add a quick time.sleep(1) reference, to allow our object to instantiate before we start sending requests. This value will largely depend on your internal machine speed, so you increase or decrease this value as you see fit.

Then, as a quick test to show off our nextId method, we can use a for loop as the example.  I will write the loop as for I in range(0,5): and then printing the app.nextId() method each time. If we run this script as is, we should see some notifications indicating our connection is OK, followed by our printed ids. These request IDs are used throughout our programming and need to be uniquely assigned on each request. As a result, creating this reliable incrementation tool will be essential. 

We will explore this further through future videos.

But as a simple implementation of the EClient – EWrapper duality, we can move on to a call for the current time in Trader Workstation. Within our for loop, after our call for the nextId value, I will add a new request for app.reqCurrentTime(). This begins the initial request through EWrapper, but to capture the response, we should define the currentTime function within our class.

Calling def currentTime(self,time): we can receive our time value. Within the function, we can print our time value. This function will return the current epoch time observed in Trader Workstation. Epoch time is a single integer time representing the current timestamp in milliseconds. The connection between EClient.reqCurrentTime and EWrapper.currentTime will be an ongoing theme observed through nearly all endpoints used within the API. One external request will be met with one or more asynchronous responses.

One final method to create that will be used throughout the TWS API programming will be our EWrapper.error function. Error will automatically return any error generated by the Trader Workstation while processing your request. This will include values like invalid order formats, market data issues, and more. This will not reflect code issues or similar programming logic failures.

To define this, add the new definition for error within our TestApp class, containing the arguments for self, reqId, errorCode, errorString, and advancedOrderReject. While you are welcome to simply print all of these values directly, I will be adding context to each message through an f-string so we can quickly distinguish which value refers to which argument. If we run our script now, you’ll see various “error” messages. If we read the errorString value of these messages, we’ll realize these are just notifications mentioning that various market data connections are OK. While this method will largely capture error messages, we will receive system notifications such as the market data connectivity through EWrapper.error as well.

That concludes our lesson on the Essential Components of 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 Snippet – essentials.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 currentTime(self, time):
    print(time)

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

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

# for i in range(0,5):
#   print(app.nextId())
app.reqCurrentTime()

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.

20 thoughts on “Essential components of TWS API programs”

  • Ankit

    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 %

    • Interactive Brokers

      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!

  • Paul

    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

    • Interactive Brokers

      Hello Paul, thank you for reaching out. This error message is triggered to indicate the contract definition provided in your RTD formula cannot be found by TWS. Please view this User Guide for more information: https://interactivebrokers.github.io/tws-api/rtd_fqa_errors.html

      Please reach back out if you have any more questions. We are here to help!

  • nathan

    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?

    • Interactive Brokers

      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!

  • Adam

    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

  • Andrea

    Hello, how can the forex contract be viewed?

    • Interactive Brokers

      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://www.ibkrcampusdev.wpengine.com/campus/ibkr-api-page/contracts/#forex. We hope this helps!

  • Osaso man

    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.

  • A Davies.

    @5.44 in the video i get the following errors: Traceback (most recent call last): File “”, line 2, in File “”, line 7, in nextId AttributeError: ‘TestApp’ object has no attribute ‘orderId’ Seems like this code and tutorial is no longer working.

    • Keshav Reddy

      your client(Ib gateway or TW) is not running. login to the client to fix this issue.

    • Andrew C.

      I got the same exact error.

      • Interactive Brokers

        Hello, thank you for reaching out. This is most likely a result of a typo in the code. If you directly copy the ‘Code Snippet – essentials.py’ does not replicate this behavior. That being said, if you were to interchangeably use lowercase and uppercase characters throughout the ‘nextValidId()’ and ‘nextId()’ functions, your described issue can be replicated. Please be sure to review your variable naming convention to make sure they are matched accordingly. If you have any additional questions, please create a web ticket for this inquiry; we have a category specifically for “API.” One of our API experts will be happy to guide you! http://spr.ly/IBKR_ClientServicesCampus

    • Interactive Brokers

      Hello, thank you for reaching out. This is most likely a result of a typo in the code. If you directly copy the ‘Code Snippet – essentials.py’ does not replicate this behavior. That being said, if you were to interchangeably use lowercase and uppercase characters throughout the ‘nextValidId()’ and ‘nextId()’ functions, your described issue can be replicated. Please be sure to review your variable naming convention to make sure they are matched accordingly. If you have any additional questions, please create a web ticket for this inquiry; we have a category specifically for “API.” One of our API experts will be happy to guide you! http://spr.ly/IBKR_ClientServicesCampus

  • david

    there is error”TestApp.error() missing 1 required positional argument: ‘advancedOrderReject'”,how to fix it and why it is happened?

    • Interactive Brokers

      Hello, thank you for reaching out. It sounds like TWS may be providing 4 error arguments, while we accept 5. This is most common when using mismatched versions of TWS and the API. However, a simple fix for this issue is to create a default value for the AdvancedOrderRejectParams variable. This is done by modifying our error method definition to the following:
      def error(self, reqId, errorCode, errorString, advancedOrderReject=””):

      If you have any additional questions, please create a web ticket for this inquiry; we have a category specifically for “API.” One of our API experts will be happy to guide you! http://spr.ly/IBKR_ClientServicesCampus

  • Troy

    my orderId’s are not being printed with the following error message:
    AttributeError: ‘TestApp’ object has no attribute ‘orderId’

    • Interactive Brokers

      Hi Troy, thank you for reaching out. This is most likely a result of a typo in the code. If you directly copy the ‘Code Snippet – essentials.py’ does not replicate this behavior. That being said, if you were to interchangeably use lowercase and uppercase characters throuhgought the ‘nextValidId()’ and ‘nextId()’ functions, your described issue can be replicated. Please be sure to review your variable naming convention to make sure they are matched accordingly. If you have any additional questions, please create a web ticket for this inquiry; we have a category specifically for “API.” One of our API experts will be happy to guide you! http://spr.ly/IBKR_ClientServicesCampus

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.

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.