undefined

Market Scanners

Some scans in the TWS Advanced Market Scanner can be accessed via the TWS API through the LYNXApi.EClient.reqScannerSubscription.

** Python **

self.reqScannerSubscription(7001, ScannerSubscriptionSamples.HighOptVolumePCRatioUSIndexes(), [], [])

# Generic Filters
tagvalues = []
tagvalues.append(TagValue("usdMarketCapAbove", "10000"))
tagvalues.append(TagValue("optVolumeAbove", "1000"))
tagvalues.append(TagValue("avgVolumeAbove", "10000"));

self.reqScannerSubscription(7002,ScannerSubscriptionSamples.HotUSStkByVolume(), [], tagvalues) # requires TWS v973+

** Java **

client.reqScannerSubscription(7001, ScannerSubscriptionSamples.HighOptVolumePCRatioUSIndexes(), null, null);

TagValue t1 = new TagValue("usdMarketCapAbove", "10000");
TagValue t2 = new TagValue("optVolumeAbove", "1000");
TagValue t3 = new TagValue("avgVolumeAbove", "100000000");
List<TagValue> TagValues = Arrays.asList(t1, t2, t3);
client.reqScannerSubscription(7002, ScannerSubscriptionSamples.HotUSStkByVolume(), null, TagValues); // requires TWS v973+

Available API filters and and parameters until TWS v973 and API v973.07 are defined in the LYNXApi.ScannerSubscription object, including [AbovePrice, BelowPrice, AboveVolume, ...] . Some Market Scanner Examples are listed at the bottom of this page.

Scans are limited to a maximum result of 50 results per scan code, and only 10 API scans can be active at a time.

Results are delivered via LYNXApi.EWrapper.scannerData and the LYNXApi.EWrapper.scannerDataEnd marker will indicate when all results have been delivered. The returned results to scannerData simply consist of a list of contracts. There are no market data fields (bid, ask, last, volume, ...) returned from the scanner, and so if these are desired they have to be requested separately with the reqMktData function. Since the scanner results do not include any market data fields, it is not necessary to have market data subscriptions to use the API scanner. However to use filters, market data subscriptions are generally required.

** Python **

class TestWrapper(wrapper.EWrapper):

def scannerData(self, reqId: int, rank: int, contractDetails: ContractDetails,distance: str, benchmark: str, projection: str,
                legsStr: str):
    super().scannerData(reqId, rank, contractDetails, distance, benchmark,projection, legsStr)

    print("ScannerData. ReqId:", reqId, "Rank:", rank, "Symbol:", contractDetails.contract.symbol,"SecType:", contractDetails.contract.secType,"Currency:", contractDetails.contract.currency,"Distance:", distance, "Benchmark:", benchmark,"Projection:", projection, "Legs String:", legsStr)

    print("ScannerData. ReqId:", reqId, ScanData(contractDetails.contract, rank, distance, benchmark, projection, legsStr))

def scannerDataEnd(self, reqId: int):
    super().scannerDataEnd(reqId)
    print("ScannerDataEnd. ReqId:", reqId)

** Java **

public class EWrapperImpl implements EWrapper {

@Override
public void scannerData(int reqId, int rank,
    ContractDetails contractDetails, String distance, String benchmark,
    String projection, String legsStr) {
System.out.println("ScannerData. "+reqId+" - Rank: "+rank+", Symbol: "+contractDetails.contract().symbol()+", SecType: "+contractDetails.contract().secType()+", Currency: "+contractDetails.contract().currency()
        +", Distance: "+distance+", Benchmark: "+benchmark+", Projection: "+projection+", Legs String: "+legsStr);
}

@Override
public void scannerDataEnd(int reqId) {
System.out.println("ScannerDataEnd. "+reqId);
}

Since the LYNXApi.EClient.reqScannerSubscription request keeps a subscription open you will keep receiving periodic updates until the request is cancelled via LYNXApi.EClient.cancelScannerSubscription :

** Python **

self.cancelScannerSubscription(7001)
self.cancelScannerSubscription(7002)
self.cancelScannerSubscription(7003)

** Java **

client.cancelScannerSubscription(7001);
client.cancelScannerSubscription(7002);
client.cancelScannerSubscription(7003);

Market Scanner Examples

With API v973.07 and TWS v973 and lower, the available API scans are the fields of the ScannerSubscription object, i.e. abovePrice, aboveVolume, belowPrice, etc. Beginning with the next version of the API (expected to be v973.08) and TWS v974, an extra parameter scannerSubscriptionFilterOptions has been added to the API to allow for generic filters. This field is entered as a list of TagValues which have a tag followed by its value, e.g. TagValue("usdMarketCapAbove", "10000") indicates a market cap above 10000 USD. Available filters can be found using the LYNXApi.EClient.reqScannerParameters function.

** Python **

#Hot US stocks by volume

scanSub = ScannerSubscription()
scanSub.instrument = "STK"
scanSub.locationCode = "STK.US.MAJOR"
scanSub.scanCode = "HOT_BY_VOLUME"

# Top % gainers at LYNXIS

scanSub = ScannerSubscription()
scanSub.instrument = "STOCK.EU"
scanSub.locationCode = "STK.EU.LYNXIS"
scanSub.scanCode = "TOP_PERC_GAIN"


# Most active futures at SOFFEX

scanSub = ScannerSubscription()
scanSub.instrument = "FUT.EU"
scanSub.locationCode = "FUT.EU.SOFFEX"
scanSub.scanCode = "MOST_ACTIVE"


# High option volume P/C ratio US indexes

scanSub = ScannerSubscription()
scanSub.instrument = "IND.US"
scanSub.locationCode = "IND.US"

scanSub.scanCode = "HIGH_OPT_VOLUME_PUT_CALL_RATIO"xxxxxxxxxx def histogramData(self, reqId:int, items:HistogramDataList):    print("HistogramData. ReqId:", reqId, "HistogramDataList:", "[%s]"          % "; ".join(map(#Hot US stocks by volumescanSub = ScannerSubscription()​scanSub.instrument = "STK"​scanSub.locationCode = "STK.US.MAJOR"​scanSub.scanCode = "HOT_BY_VOLUME"​...​# Top % gainers at LYNXIS​scanSub = ScannerSubscription()​scanSub.instrument = "STOCK.EU"​scanSub.locationCode = "STK.EU.LYNXIS"​scanSub.scanCode = "TOP_PERC_GAIN"​...​# Most active futures at SOFFEX​scanSub = ScannerSubscription()​scanSub.instrument = "FUT.EU"​scanSub.locationCode = "FUT.EU.SOFFEX"​scanSub.scanCode = "MOST_ACTIVE"​...​# High option volume P/C ratio US indexes​scanSub = ScannerSubscription()​scanSub.instrument = "IND.US"​scanSub.locationCode = "IND.US"​scanSub.scanCode = "HIGH_OPT_VOLUME_PUT_CALL_RATIO"str, items)))python

** Java **

//Hot US stocks by volume

ScannerSubscription scanSub = new ScannerSubscription();
scanSub.instrument("STK");
scanSub.locationCode("STK.US.MAJOR");
scanSub.scanCode("HOT_BY_VOLUME");

//Top % gainers at LYNXIS

ScannerSubscription scanSub = new ScannerSubscription();
scanSub.instrument("STOCK.EU");
scanSub.locationCode("STK.EU.LYNXIS");
scanSub.scanCode("TOP_PERC_GAIN");

//Most active futures at SOFFEX

ScannerSubscription scanSub = new ScannerSubscription();
scanSub.instrument("FUT.EU");
scanSub.locationCode("FUT.EU.SOFFEX");
scanSub.scanCode("MOST_ACTIVE");

//High option volume P/C ratio US indexes

ScannerSubscription scanSub = new ScannerSubscription();
scanSub.instrument("IND.US");
scanSub.locationCode("IND.US");
scanSub.scanCode("HIGH_OPT_VOLUME_PUT_CALL_RATIO");

See also Scanner Parameters

Complex Orders and Trades Scanner

The TWS Complex and Orders and Trades Scanner is a special scan type available from the API with TWS v975 and API v973.07 or higher.

** Python **

# High option volume P/C ratio US indexes
scanSub = ScannerSubscription()
scanSub.instrument = "NATCOMB"
scanSub.locationCode = "NATCOMB.OPT.US"
scanSub.scanCode = "COMBO_LATEST_TRADE"     

** Java **

//Complex orders and trades scan, latest trades
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.instrument("NATCOMB");
scanSub.locationCode("NATCOMB.OPT.US");
scanSub.scanCode("COMBO_LATEST_TRADE");

** Python **

AAPLConIDTag = [TagValue("underConID", "265598")]

self.reqScannerSubscription(7003, ScannerSubscriptionSamples.ComplexOrdersAndTrades(), [], AAPLConIDTag) # requires TWS v975+ 

** Java **

List<TagValue> AAPLConIDTag = Collections.singletonList(new TagValue("underConID", "265598")); // 265598 is the conID for AAPL stock
client.reqScannerSubscription(7003, ScannerSubscriptionSamples.ComplexOrdersAndTrades(), null, AAPLConIDTag); // requires TWS v975+

Complex Orders and Trades Scanner available scan codes:

  • COMBO_LATEST_TRADE
  • COMBO_QUOTES
  • COMBO_MOST_ACTIVE
  • COMBO_ALL_TRADE_TIME_ASC
  • COMBO_ALL_TRADE_TIME_DESC
  • COMBO_ALL_QUOTE_TIME_ASC
  • COMBO_ALL_QUOTE_TIME_DESC
  • COMBO_ALL_TRADE_QUOTE_TIME_ASC
  • COMBO_ALL_TRADE_QUOTE_TIME_DESC
  • COMBO_ALL_VOLUME_ASC
  • COMBO_ALL_VOLUME_DESC