Duration: 10:37
Level: Intermediate

In this lesson, we will be discussing how contract information is requested from only knowing the contract’s symbol. Following this methodology, you will be able to make requests throughout the series for a variety of contracts using the contract ID. This will cover stock, future, options, and futures options discovery.

Study Notes:

Hello, and welcome to this lesson on the Interactive Brokers Client Portal API. In this lesson, we will be discussing how to find a contract id using the contract symbol, how to pull option chain data, and how to pull future data.

Searching for contract by underlying symbol

            To begin, let’s start with searching for a contract by the underlying symbol. We can import the same libraries from the last episode. Now I will create a method for our request, contractSearch() method.

With the framework set, we can go back to the contractSearch() method and add some variables. I will create our base_url variable once again, and an endpoint variable set to “iserver/secdef/search”. This endpoint allows us to search for an underlying symbol or company name and retrieve a relevant contract ID. The contract ID, or conid, is a unique contract identifier that will correspond to a specific symbol, security type, and currency. Every contract at Interactive Brokers will have a unique ID.

Once we have built our URL, we will need to use a JSON body. I will create the variable, ‘json_body’, and set it equal to a set of curly brackets to create an array value. Inside these brackets we need to create a few fields. In this case, we’ll create “symbol”, “secType”, and “name”. For Symbol I will use “ES”, and for secType, I will use “STK”. For the moment, I will set “name” to “false”. This field can be used to search for a company name instead of just the standard symbol.

With the body set, I will create a reference to our coming request. I’ll create the variable ‘contract_req’ and set it equal to requests.post. Here we can set the URL to our base_url+endpoint and verify to False. Then the ‘json’ tag to the variable, json_body.

We can show the response status code in the console by printing our contract_req variable. Before doing so, I will use the json library to help make this more legible. We will print the json-encoded content of the response using json.dumps. Json.dumps function will convert a string into a json dictionary.  The parameters are the contract_req.json() and indent=2. If indent is a non-negative integer, the json array elements will be pretty-printed with that indent level.

Once we have added these initial parameters we can now run this code and view the returned values. Initially our status Response code [200] indicates that the request has succeeded.

In this case there is a long list of values returned. First, we can see the conid we were initially looking for along with the companyHeader, name, description, as well as further information relating to each security type. As this lists all contracts with symbol ES, we can also see further conids and companyNames returned. For example, Eversource Energy and Esso STE in this case.

How to request contract details for Futures

Next, we will be calling the iserver/secdef/info endpoint for more informative Contract Details based on conid. It is important for derivatives to call the /secdef/search endpoint for the underlying contract before calling any other secdef endpoints. We will use the previously obtained conid for ES, or the E-mini S&P 500, in this case.

When requesting contract details for Futures, we can use the same initial python file while then creating our new contract_info.py file.

In this case, the futures_url variable will point to the iserver/secdef/info endpoint and the parameters will contain the conid, sectype, month and exchange values. These details can all be pulled from our prior request.

Parameters are unique from how a json body is constructed. Instead of a comma separated array, we will be appending a question mark, followed by the parameter set equal to our value, and then delimited using an ampersand. So, to construct this, I will create four variables.

  • conid=”conid=11004968″
  • secType=”secType=FUT”
  • month=”month=SEP23″
  • exchange=”exchange=CME”

Then I will create the variable “params” and set it equal to ‘“&”.join([conid,sectype,month,exchange])’. This will concatenate all of my strings with an ampersand between them. We can then follow this by defining request_url and setting that equal to ‘“”.join([base_url, endpoint, “?”, params])’. Now, we have a full url that displays our base url, our endpoint, and then a question mark to signify our parameters are starting. Finally, we end the string with our concatenated parameters string.

While this can certainly all be written in a single string for our example, this is a common structure to help with automating the request flow once you have developed a self-sufficient program.

Now, we can wrap up this program by creating another Get request and assigning it to contract_req. We will use our request_url as the destination to create our request. Now if we print the status value and the json.dumps value of our request, we can see a range of details on our futures contract. If we ever need to double check a derivative conid, review the validExchanges of the contract, or otherwise.

We can now run this code and see the futures contract details returned as expected.

How to request contract info for options

Requesting Options or Futures Options are quite similar. In the case of options or futures options, we must request the secdef/search endpoint, followed by the secdef/strikes endpoint before requesting the info or rules endpoint. Regardless of whether you have the contract ID beforehand or not, these endpoints must be called first.

Now can create a new file for the strikes endpoint to represent this. I will use the same framework we have been operating with, and create a new method called strikeSearch(). I will create and endpoint variable referencing the iserver/secdef/strikes string. Just like my secdef/info endpoint, I will create a conid, sectype, month, and exchange variable. I will set the conid to the underlying contract ID field, secType to “FOP”, month to “JUL23” to review the July 23 futures option, and finally in the case of Futures Options, I will define the exchange as CME. It is important to note that for standard options, you may leave out the Exchange value, as SMART is set by default.

Maintaining the other formatting as I had before, when I call this endpoint, I will see a huge range of all potential strikes a contract could use. With my knowledge of my current expiry and strike information, I will make a call to the info endpoint for my futures option. I can maintain all the same parameters as with my prior call to /info, but now include both a strike, which I will set to ‘4800’, and right, which I will set to C for ‘Call’. With my derivative contract IDs found, I can now proceed to request market data, place orders, and more.

Thank you for watching this lesson on Contract Details in the Client Portal API. If you find this lesson helpful, please check out our other lessons in the Client Portal API tutorial series.

Code Snippet – contractDetails.py

import requests
import json

# Disable SSL Warnings
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# reauthenticate
def contractSearch():
    base_url = "https://localhost:5000/v1/api/"
    endpoint = "iserver/secdef/search"

    json_body = {"symbol" : "ES", "secType": "STK", "name": False}

    contract_req = requests.post(url=base_url+endpoint, verify=False, json=json_body)

    contract_json = json.dumps(contract_req.json(), indent=2)
    print(contract_json)

if __name__ == "__main__":
    contractSearch()

Code Snippet – contractInfo.py

import requests
import json

# Disable SSL Warnings
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# reauthenticate
def contractInfo():
    base_url = "https://localhost:5000/v1/api/"
    endpoint = "iserver/secdef/info"

    conid="conid=11004968"
    secType = "secType=FOP"
    month = "month=JUL23"
    exchange = "exchange=CME"
    strike = "strike=4800"
    right = "right=C"

    params = "&".join([conid, secType, month, exchange, strike, right])
    request_url = "".join([base_url, endpoint, "?", params])

    contract_req = requests.get(url=request_url, verify=False)
    contract_json = json.dumps(contract_req.json(), indent=2)

    print(contract_req)
    print(contract_json)

if __name__ == "__main__":
    contractInfo()

contractStrikes.py

import requests
import json

# Disable SSL Warnings
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# reauthenticate
def contractStrikes():
    base_url = "https://localhost:5000/v1/api/"
    endpoint = "iserver/secdef/strikes"

    conid = "conid=11004968"
    secType = "secType=FOP"
    month = "month=JUL23"
    exchange = "exchange=CME"

    params = "&".join([conid, secType, month, exchange])
    request_url = "".join([base_url, endpoint, "?", params])

    strikes_req = requests.get(url=request_url, verify=False)
    strikes_json = json.dumps(strikes_req.json(), indent=2)

    print(strikes_req)
    print(strikes_json)

if __name__ == "__main__":
    contractStrikes()

Leave a Reply

Note that all comments are held for moderation before publishing.

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 LLC, 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.