Get the Top Percentage Gainers using the IBKR API in Python

This example shows how to get a list of the top gainers on the day in US stocks using the Interactive Brokers (IBKR) API for Python.

The API works by connecting to a locally running Trader Workstation (TWS) instance. Make sure TWS is up and running; both live trading a paper trading logins will work.

In TWS, we need to enable EClients in TWS under Global Configuration / API. This will allow clients from localhost to connect to TWS over HTTP.

Install the IBKR API package using:

$ pip install ibapi

We extend both EClient and EWrapper to inherit the functionality of reading the scanner feed.
We call the scannerData() method of the superclass to get the actual data. We can ignore most of the parameters to scannerData(), but need to include them to match the signature.

Note that we need to launch a listener in a thread in parallel to the main script.
We connect to the data feed, read some items and disconnect.

The following script will get the first ten of the top percentage gainers at the time it is run:

import time
import threading

from ibapi.client import EClient
from ibapi.scanner import ScannerSubscription
from ibapi.wrapper import EWrapper

# Class extending IBKR scanner base classes.
class IBapi(EWrapper, EClient):
  def __init__(self):
    EClient.__init__(self, self)

  def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection, legsStr):
    super().scannerData(reqId, rank, contractDetails, distance, benchmark, projection, legsStr)
    position = rank + 1 # Zero based indexing.
    print(f"{position}: {contractDetails.contract.symbol}")

  def scannerDataEnd(self, reqId):
    print("End of scanner data.")
    self.disconnect()

# Function to run continuously.
def ibApiRunLoop(ibApiApp):
  ibApiApp.run()

# Main script.

TWS_HOST = '127.0.0.1'
TWS_PORT = 7497
CLIENT_ID = 12345

ibApi = IBapi()
ibApi.connect(TWS_HOST, TWS_PORT, CLIENT_ID)

thread = threading.Thread(target=ibApiRunLoop, args=(ibApi,), daemon=True)
thread.start()

time.sleep(1) # Allow time for connection.

scannerSub = ScannerSubscription()
scannerSub.numberOfRows = 10
scannerSub.instrument='STK' # Stocks.
scannerSub.locationCode='STK.US.MAJOR' # US major exchanges.
scannerSub.scanCode='TOP_PERC_GAIN' # Top percentage gainers.

requestId = 1000 # An arbitrary request ID.
filters = [] # No special filters needed.

ibApi.reqScannerSubscription(requestId, scannerSub, filters, filters)

time.sleep(5) # Allow time to receive data.

ibApi.disconnect()

Example output:

1: LUCY
2: TNMG
3: DEVS
4: SRXH
5: SMCX
6: SMCL
7: LOBO
8: LGMK
9: HIMZ
10: SMCI
End of scanner data.

Note that to get more details, e.g. the last price of the tickers, we need to query data specific to each ticker.

References

https://www.interactivebrokers.com/campus/ibkr-quant-news/interactive-brokers-python-api-native-a-step-by-step-guide/

https://www.interactivebrokers.com/campus/ibkr-quant-news/implementing-market-scanners-using-tws-api-part-ii/