Multilingual content from IBKR

Close Navigation
Learn more about IBKR accounts
Implementing Market Scanners using TWS API – Part II

Implementing Market Scanners using TWS API – Part II

Posted January 11, 2021 at 9:00 am
Mayank Rasu

Get started with Part I of this series and learn more about IBKR API and review sample Python code.

Market Scanners using TWS API

Please note that at this time, we are unable to replicate every advanced scanner available in the TWS using the API. However, the good news is that the scope is getting expanded with subsequent new releases of the API and hopefully soon we will be able to implement all advanced scanners using API. Nevertheless, the existing scope is sufficiently large and you should be able to implement reasonably advanced scanners using the API.

Before, we start implementing the market scanner, it may be a good idea to get a list of all the parameters available in API. This can be done using EClient’s reqScannerParameters function and the corresponding EWrapper’s scannerParameters function. Refer the code below.

If you have been able to follow this article so far, interpreting the above code should be quite easy. All that we are doing in this trading app is preparing it to handle scanning parameters data dump once we request this data from the TWS using the reqScannerParameters EClient function. The scannerParameters function exports the parameters data into an XML file. Below is partial snapshot of the XML data dump

The above snapshot shows the list of available filters for scanning US Stocks. Please note that the XML document is quite detailed and it provides the available filters and parameters by asset class. 

Now that we have been able to get the exhaustive list of filters and parameters available with us, let us try implementing a market scanner 

Scanning Top Gainers 

We will now create a trading application which will scan a given universe of stocks continuously and identify stocks which witnessed the largest gain since markets opened. However, rather than casting a very wide net, we will define some market data based filters which will refine our scanning criteria. Below is the code. 

To implement the scanner, we first need to import the ScannerSubscription class from the scanner module of the TWS API. The ScannerSubscription class allows us to create an object which defines the filters and parameters of our scanner. You can see that within the usStkScan function we have created an object scanSub of ScannerSubscription class. Within the function, we define the required filters and parameters of this object by referring to the XML document and using the relevant codes before returning the scanner object. In this example, we have defined our scanner object using the following parameters 

numberOfRows – We want to limit our output to top 50 rows 

abovePrice – Exclude stocks whose stock price is less than $10 

belowPrice – Exclude stocks whose stock price is more than $200 

aboveVolume – Exclude stocks whose daily volume is less than 1 million 

instrument – Scan only stocks 

locationCode – Scan stocks on all major US exchanges 

scanCode – This is the scanning parameter. In this case we have chosen TOP_PERC_GAIN which as per the XML document scans for top percentage gainers 

The relevant EClient function to scan stocks is reqScannerSubscription. The arguments that this function takes are: 

reqID – An integer value which is used to identify one API request from another. 

ScannerSubscription– We need to pass the object of ScannerSubscription class that is returned by the usStkScan function in the above code. 

reqScannerSubscription takes in two more list arguments corresponding to filter options. However, you can pass them as blank lists since we will not be needing those.  

The scannerData function within the TradeApp class is the corresponding EWrapper function which is required to output the data when calling the reqScannerSubscription function 

In the above code, you can see that we have used python threading module as well. This is required because we want to execute the scanner and the websocket connection on different threads (this is a topic for a later discussion) 

Below is the output when I run the above code. 

Not very promising, is it? IB is complaining that I do not have the required permissions to execute this scan. This would be the appropriate time to discuss about the market data subscription requirement for implementing scanners. Since, the output from scanner, does not contain any market data, theoretically we do not need market data subscription to run scanners. However, if we want to use filters based on market data in our scanner then we will need to purchase the relevant subscriptions. For example, in the code above, if we remove the filters pertaining to stock price and volume (abovePrice, belowPrice and aboveVolume) we should be able to get an output. However, this would beat the purpose of our scanning since we will now have to exclude some key filters. Therefore in this case, we will have to purchase market data from relevant US exchanges. Thankfully, the subscription fee tends to be quite reasonable and you can subscribe to whichever market data you want from your IB account settings>>User Settings>>Market Data Subscription 

If we don’t want to scan all the major US stock exchanges and only the ones that we are subscribed to, this can also be done by tweaking the locationCode attribute of the ScannerSubscription object. In the below example, I have updated the locationCode from US.STK.MAJOR to STK.NASDAQ as I am subscribed to receive data from the NASDAQ exchange. 

You can get the list of relevant location codes from the XML file that we have generated. 

Below is the output of the scanner after updating the location code to the exchange for which I am subscribed. The output continues to get refreshed every 30 seconds. 

As you can see, the output lists out the top percentage gainers on the NASDAQ exchange by their rank. This list will keep getting updated as stocks move in an out of the top percentage gainer list. 

Please note that the scanner outputs only lists the contract information. However, the contract information can easily be combined with other TWS API modules, to implement a trading strategy based on scanner outputs. 

The author can be reached at

If you found this article interesting, you may consider enrolling in the author’s TWS API course ( The course starts from the basics of TWS API and some key programming concepts such as OOPs basics and threading and then gradually delves into more advanced concepts to help you build fully automated trading applications on Interactive Brokers’ platform.  

Disclosure: Interactive Brokers

Information posted on IBKR Campus that is provided by third-parties does NOT constitute a recommendation that you should contract for the services of that third party. Third-party participants who contribute to IBKR Campus are independent of Interactive Brokers and Interactive Brokers does not make any representations or warranties concerning the services offered, their past or future performance, or the accuracy of the information provided by the third party. Past performance is no guarantee of future results.

This material is from Rasuquant and is being posted with its permission. The views expressed in this material are solely those of the author and/or Rasuquant and Interactive Brokers is not endorsing or recommending any investment or trading discussed in the material. This material is not and should not be construed as an offer to buy or sell any security. It should not be construed as research or investment advice or a recommendation to buy, sell or hold any security or commodity. 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.

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.