Close Navigation
Learn more about IBKR accounts

Requesting Market Data

Lesson 4 of 11
Duration 7:29
Level Intermediate
Close Navigation

We will be discussing how to market data in the Client Portal API. Here, we will be specifically focusing on retrieving live market data snapshots, as well as historical market data using Python and the requests library.

Study Notes:

Hello, and welcome to this lesson on requesting market data in the Interactive Brokers Client Portal API. In this lesson, we will be discussing how to find the snapshot fields, how to request live market data snapshots, and how to request historical market data.

Finding Market Data Fields

Let’s begin by first looking at the Interactive Brokers endpoints documentation page. If we scroll down, we will eventually find our iserver/marketdata/snapshot endpoint that we will be working with today. If we click on the banner, we will expand the snapshot section to reveal more information on the endpoint. The reason to point out this section is that we can find what data values we want to work with. Under the ‘Responses’ portion, I can see here where it shows ‘Model’. If we click that, we should find a new grey box.

I can click that right-pointed arrow to expand things, I will see a massive list of all available field values to use with the snapshot endpoint. Some of the most popular values are 31, 55, 84, and 86. As we can see by looking through this page, I will retrieve my last price, symbol, bid, and ask values respectively. There are many more values here that we encourage you to explore, but this will give us a great example to get started. With our fields found, we can start taking a closer look at the actual request.

Requesting Market Data

Jumping back to VS Code, I will create a new program with my typical framework, and a method named marketSnapshot(). I will create my endpoint for my market data request and set to “iserver/marketdata/snapshot”. The snapshot endpoint utilizes a GET request, so now we can start building the parameters list.

We can first create a conid variable, and set it equal to “conids=265598”. Some viewers may have picked up the fact that we stated “conids” instead of just “conid”. That is because this endpoint allows for multiple contract requests at once. You will just need to use a comma to separate each contract ID. Let’s do that by including IBM, or 8314.

            With our contracts set, I will move on to our fields variable. I will set this variable equal to “fields=31,55,84,86” based on what we found before. That is all we need in order to get started with our requests. I will create a params variable, and concatenate my parameters. After that I can create my full url with the request_url set to “”.join([base_url, endpoint, “?”, params]).

Again, I can create a market_req variable and create a new GET request. I can use my json.dumps() method from before to help with readability. And finally, we will print both variables to see our response status and body. So if we make a few requests, we should see all of our fields returned.

Discussing the return

I would like to take a moment to discuss how data is requested and returned. The first request will typically only display the coindex, and the conid. This is just to signify that you have requested data for the given contract. You can think of it as instantiating the market data stream. Often times for stocks, you can make another follow up request right away, and receive data. However, it’s important to note that fields like 7310, or the Option’s Greek Theta, can take a few requests, or even a few moments to begin. That is because some values may not be readily available and must be calculated by Interactive Brokers before returning. Especially on less active strikes, this can take up to a minute before returning these fields.

Requesting Historical Data

            With our live market data returning as intended, we can now move on to a historical market data request. In addition to our standard framework, I will add an endpoint variable, and set this equal to “hmds/history” for my historical data request. This is yet another GET request, so this will be built with a set of parameters: conid, period, bar and optionally, outsideRth and barType.

            As opposed to live data, the historical data request will only allow a single conid at a time. As such, I will make a conid variable and set it equal to 265598 for AAPL. Now, I can make a period variable. This will determine the total range of data returned. It can scale from minutes, hours, days, weeks, months, or even years. But given our example today, I will set it equal to ‘1w’ for 1 week. Then I can create my bar variable and set it equal to ‘1d’, so I can see each day’s bar for the whole week.

            If I wanted to, I could make a request now and receive data without issue. However, I would like to move on to our optional parameters. I will start by setting outsideRth to ‘true’. By default, outsideRth is set to ‘false’ so we only see regular trading hours; however, we can choose to disable this. Next, I will create a barType variable and, in my case, set it equal to ‘midpoint’.

Available values:

  • Period: {Xmin, Xh, Xd, Xw, Xm, Xy}
  • Bar: {Xmin, Xh, Xd, Xw, Xm}
  • outsideRth: {true (for times outside the 9:30 – 16:00 trading hours), false (for those during regular trading hours only)}
  • barType:   {last, midprice, bid, ask, inventory}

Again, I will create a few join variables followed by my request, json, and print values. And so if I request this data, we will see 7 bars returned, for our requested 7 days, along with their OHLC values. It’s important to note that some values, such as the default ‘last’ value for the barType parameter will return Volume for the bar as well, notated by the ‘v’ field returned. Please feel free to explore our available values for both of these endpoints to find the best data for you.

Thank you for watching this lesson on requesting market data 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 – liveData.py

import requests
import json

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

def marketSnapshot():
    base_url = "https://localhost:5000/v1/api/"
    endpoint = "iserver/marketdata/snapshot"

    conid="conids=265598,8314"
    fields="fields=31,55,84,86"


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

    md_req = requests.get(url=request_url, verify=False)
    md_json = json.dumps(md_req.json(), indent=2)

    print(md_req)
    print(md_json)

if __name__ == "__main__":
    marketSnapshot()

Code Snippet – histData.py

import requests
import json

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

def historicalData():
    base_url = "https://localhost:5000/v1/api/"
    endpoint = "hmds/history"

    conid="conid=265598"
    period="period=1w"
    bar="bar=1d"
    outsideRth="outsideRth=true"
    barType="barType=midpoint"

    params = "&".join([conid, period, bar,outsideRth, barType])
    request_url = "".join([base_url, endpoint, "?", params])

    hd_req = requests.get(url=request_url, verify=False)
    hd_json = json.dumps(hd_req.json(), indent=2)

    print(hd_req)
    print(hd_json)

if __name__ == "__main__":
    historicalData()

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 “Requesting Market Data”

  • I see exponential moving averages are available… what about RSI? It’s harder to calculate and would be a bigger help than emas… please?

  • I want to get the historical data of the specified “startTime”. How should this time format be transmitted? Can you give an example? I use java. Thank you.

    • Hello, thank you for reaching out. With the release of TWS 10.17 and TWS API 10.18 clients now can send date/time in different formats:

      API allows UTC format “yyyymmdd-hh:mm:ss” in date/time fields.
      Example: 20220930-15:00:00
      API allows date/time field format with instrument’s exchange timezone (for all non-operator fields) and operator’s time zone (for all fields).
      Example: IBM 20220930 15:00:00 US/Eastern
      We hope this helps!

    • Hi Thomas, yes, it is possible to get real-time market data through Interactive Brokers. You can follow these steps to subscribe to live market data:

      1. Log in to the Client Portal
      2. Click on the User menu (head and shoulders icon) in the top right corner, then select Settings
      3. Under User Settings, go to Trading Platform > Market Data Subscriptions
      We hope this helps!

  • Hi,
    to get “day” historical data with attributes below is OK.
    period=”period=1d”
    bar=”bar=15min”

    to get “hours” historical data with attributes below is NOT OK.
    period=”period=8h”
    bar=”bar=15min”

    Is this correct behavior of system? Thank you.

  • Hi, how do I find out the conids for already expired options ? For example

    https://localhost:5000/v1/api/iserver/secdef/info?conid=756733&secType=OPT&month=JAN24&strike=470

    Will return all the “new” options on SPY for JAN 24.

    But if I try the ones which are already expired (in this example DEC23) it returns “no contracts retrieved”

    https://localhost:5000/v1/api/iserver/secdef/info?conid=756733&secType=OPT&month=DEC23&strike=470

    I would like to find out the conids of expired options so I can fetch the historical intraday data for a specific contract on a specific day (this is for 0DTE trading).

    Thank you

  • How do I get all the securities in a specified index (e.g. Russell3k)? And the conid associated to them?
    Thank you!

  • During the trading day, it is possible to obtain historical candles and the current real-time candle. For example, 5:40 PM here I would like to complete 5 minutes candles in the past so e.g. 5:35, 5:30, 5:25 and so on. And the current candle at 5:40 PM.
    Ist this possible with one api call.
    Programming language is python.

    Thank you

    • Hello, thank you for reaching out. Each query for market data would require it’s own request. The WebAPI does not support updated historical market data through a single request. As a result, the /iserver/marketdata/history or /hmds/history endpoints should be used to request 5 minute bars as needed. I would note that the websocket endpoint does not support regularly streamed historical data either, and so the only method to receive bars through the webapi would be through regular queries.

      If the need for bar data is greater than the need for WebAPI usage, our TWS API does support historical bar data as well as building live bars with the keepUpToDate=True flag. Please see ( https://ibkrcampus.com/ibkr-api-page/twsapi-doc/#hist-keepUp-date) for more information.”

  • Hi there, thanks for the helpful videos. I’m trying to get historical options price for NVDA. First I got conid for NVDA running “iserver/secdef/search”. Then I found conid for 900 options for APR24 and use “hmds/history” to get 2w data with 5m bars. I’m getting the response but in the [‘data’] of the response, I get it with t, o, c, h, l. I don’t see other fields like volume or greeks. How do I get them ?

    • Hello, thank you for reaching out. The data received will be unique between barTypes. As we discussed in the video, “It’s important to note that some values, such as the default ‘last’ value for the barType parameter will return Volume for the bar as well, notated by the ‘v’ field returned.” Other barTypes, like what we saw with MidPoint, will only return the OHLCT values, as Bid and Ask do not maintain a trade volume. Other values, such as historical Greeks, are not available via Interactive Brokers in any of our barType values.

      We hope this answers your question.

  • Hi,

    Re: my previous question on the 30th of March:
    “How do I get all the securities in a specified index (e.g. Russell3k)? And the conid associated to them?”

    Through the app, I can see the breakdown of some ETFs (SPY, for example) into the holdings (stocks & weights). Is this information available via the API too?

    Thanks!

    • Hello, thank you for reaching out. At this time, this is not available via the API. Please reach back out with any more questions. We are here to help!

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.