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.

Duration: 8:58

Level: Intermediate

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.

Read More

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()


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.

Supporting documentation for any claims and statistical information will be provided upon request.

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

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.

trading top
Translate »