Duration: 10:34
Level: Intermediate

This lesson will discuss market scanners in the client portal API. We will go into detail on requesting scanner parameters, how to review those parameter details, and then how to create a final market scanner request.

Study Notes:

Hello, and welcome to this lesson on the Interactive Brokers Client Portal API. In this lesson, we will be discussing how to retrieve the various scanner parameters, how to read the parameters list, and how to make a request using those parameters.

Requesting the Scanner Parameters

 To begin, I can build out my initial framework as I have done before and prepare a scanParams method.  In this case, I will build out an ‘endpoint’ variable, and set it equal to “iserver/scanner/params”. This will return a list of parameters that we would have to reference for our market scanner. Then, we can make a simple get request, and build out our json.dumps method as we have done throughout the series.

As an exception to the standard, we will actually be displaying our details a bit differently than normal. Let’s create a variable, paramFile, and set it equal to ‘open(“./scannerParams.xml”, “w”)’. What this means is that we will create a file using python, I will be calling it ‘scannerParams.xml’, and I will be writing to it, based on the mode, “w”. Now, I want to start iterating through my json inside my file.

To do this, I will write “for I in params_json:”, and then on an indented new line simply write “paramFile.write(i)”. Finally, I can move to an unindented new line, I will write paramFile.close(). What this all means is that I will open a designated file, and for each new content in the json response, I will write it into this file.

You are welcome to print this directly; however, given the amount of information returned, and how frequently we may need to reference this information, it is often best to do so by writing it out to a file.  

If you would like to have peace of mind that the request was successful without referencing the directory, you may also opt to print the params_req.status_code value after closing our file. After running this code, while I won’t have anything in my console, I can see in my folder that there is a new file. With our new file downloaded, we can make a new python file to start our framework. We will come back to the new XML file in just a moment.

Building our Scanner Request

I will jump into a new file, such as “marketScanner.py”. I can then build out my typical framework along with my method, ‘scannerRequest()’. With the framework of our file set, I will go ahead and set my endpoint variable to iserver/scanner/run.

Now for this request, we will need to use a JSON body, so I will go ahead with constructing that. I will call it ‘scan_body’ and set it equal to a set of curly brackets for the array value. Inside these brackets, we need to create a few fields, including “instrument”, “location”, “type”, and “filter”.

With the body set for now, I will create a variable, ‘scan_req’ to make a POST request. Then I can set the URL to ‘base_url+endpoint’, verify to False, and then I will make ‘json’ set it to our ‘scan_body’ variable. Then I will print the json.dumps variable when all is said and done.

Understanding the Parameters XML File

Jumping back to our XML file, we know what fields we need to look for. Let’s start with “instrument” and “location” to see what we’d like to work with. I know I want to work with Stocks and I do not trade outside of the US. To find this, let’s look under the ‘location_tree’ section.

With how we exported the XML, we can see a range of display names discussing what we want, such as “US Stocks”, “US Equity”, and many more. The typical structure for the ‘instrument’ field will be just the security type, so in our case it is just “STK”.

Looking right next to this, I can see the available ‘locations’ that correspond with this. I trade the major exchanges like NYSE and NASDAQ, so I will use “STK.US.MAJOR”. However, if I traded Pinks or on the OTC market, I could use ‘STK.US.MINOR’. And as always, we would encourage you to explore this document as much as possible to find what suits your needs.

With ‘instrument’ and ‘location’ done, we now need the ‘type’ field. This will be the system Interactive Brokers will use to sort your scanner with. All of these scanner types are conveniently located under the ‘scan_type’ list section. This section is broken up to display a human readable tag, ‘display_name’, followed by the ‘code’, which is equivalent to what we’d enter into our scan body’s “type” field, and then a list of instruments the scanner type works with. I think I will sort my list using the ‘Top % Gainers’ type or ‘TOP_PERC_GAIN’, though I would strongly encourage reading through the available offerings.

With this built out, I would like to take another look at our ‘market_scanner.py’ file again. With our new values, I can make a very basic request. So in my case, I will set “instrument”:”STK”, “locations”:”STK.US.MAJOR”, and “type”:”TOP_PERC_GAIN”, and then leave “filter” as an empty list, []. If I run this code, we will see a variety of returned values that we can work with, and in a neat order from 0 all the way to 49 including their contract information.

Understanding how to use Filters

We can finalize our lesson by discussing potential filters you will want to add to your request, as you may not want the minimally sorted values. To find available filters, we will need to jump back to our XML file and go to the ‘instrument_list’ section. Here, we can see each set of filters unique to a given security type. We can see these dictionaries are divided into ’display_name’, ‘type’, and ‘filters’ like before. I am still working with US Stocks, and so I will investigate the first return here. Looking at our ‘filters’ section, we can see a wide range of values for US Stocks alone.

In addition to this section, we can also jump to the ‘filter_list’ section of the XML file as well. There will be a wide range that will include many common filter requests. In my case, I know I want to filter out my instrument price to an exact range, so I will go ahead and jump down several lines until I see the “priceAbove” filter. As you may have noticed, many of these filters are very similar to those available on Interactive Brokers’ other platforms, like Client Portal or Trader Workstation. I want to filter my price range, so I will be using the priceAbove and priceBelow filters. Having chosen my filters, I will go back to my scanner file, and add these to my ‘filters’ list.

The way to add filters is rather straightforward. Within the list, each filter will be in its own array made by two curly brackets. Within there, we will include fields “code” and “value”. As an example, we will use {“code”: “priceAbove”, “value”: 101}. This means that we only want our filter to show contracts with a price above $101. Next, I will mirror this filter with {“code”: “priceBelow”, “value”: 110}. This should now only return contracts that have a price between $101 and $110.

It is important to note that with the inclusion of filtering in the mix, I may receive a reduced number of contracts, or potentially none at all. This is typically a sign of aggressive filtering which does not leave any contracts to match your parameters. This is not necessarily a problem, it means you might need to relax your scanner focus, or potentially remove a few filters.

But with that said, once we run this code, we should see a strong selection of contracts that match our filtered range, that we can now use for requesting market data or placing orders.

Thank you for watching this lesson on Market Scanners 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 SnippetsscannerParams.py

import requests
import json

# Disable SSL Warnings
import urllib3

def scanParams():
    base_url = "https://localhost:5000/v1/api/"
    endpoint = "iserver/scanner/params"

    params_req = requests.get(url=base_url+endpoint, verify=False)
    params_json = json.dumps(params_req.json(), indent=2)

    paramFiles = open("./scannerParams.xml", "w")
    for i in params_json:



if __name__ == "__main__":

Code Snippets – marketScanner.py

# Library Imports
import requests
import urllib3
import json

# Ignore insecure error messages

def reqIserverScanner():
    base_url = "https://localhost:5000/v1/api/"
    endpoint = "iserver/scanner/run"

    scan_body = {
        "instrument": "STK",
        "location": "STK.US.MAJOR",
        "type": "TOP_PERC_GAIN",
        "filter": [

    scan_req = requests.post(url=base_url+endpoint, verify=False, json=scan_body)
    scan_json = json.dumps(scan_req.json(), indent=2)

if __name__ == "__main__":

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.