Duration: 7:29
Level: Intermediate

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

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


    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)


if __name__ == "__main__":

Code Snippet – histData.py

import requests
import json

# Disable SSL Warnings
import urllib3

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


    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)


if __name__ == "__main__":

2 thoughts on “Requesting Market Data”

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

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.