Some scans in the TWS Advanced Market Scanner can be accessed via the TWS API through the IBApi.EClient.reqScannerSubscription.
-
client.reqScannerSubscription(7001, ScannerSubscriptionSamples.HighOptVolumePCRatioUSIndexes(), "", null);
TagValue t1 = new TagValue("usdMarketCapAbove", "10000");
TagValue t2 = new TagValue("optVolumeAbove", "1000");
TagValue t3 = new TagValue("avgVolumeAbove", "100000000");
List<TagValue> TagValues = new List<TagValue>{t1, t2, t3};
client.reqScannerSubscription(7002, ScannerSubscriptionSamples.HotUSStkByVolume(), null, TagValues);
-
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);
-
client.reqScannerSubscription(7001, ScannerSubscriptionSamples.HighOptVolumePCRatioUSIndexes(), "", Nothing)
Dim TagValues As List(Of IBApi.TagValue) = New List(Of TagValue)
TagValues.Add(New TagValue("usdMarketCapAbove", "10000"))
TagValues.Add(New TagValue("optVolumeAbove", "1000"))
TagValues.Add(New TagValue("avgVolumeAbove", "100000000"))
client.reqScannerSubscription(7002, ScannerSubscriptionSamples.HotUSStkByVolume(), Nothing, TagValues) ' requires TWS v973+
-
m_pClient->reqScannerSubscription(7001, ScannerSubscriptionSamples::HotUSStkByVolume(), TagValueListSPtr(), TagValueListSPtr());
TagValueSPtr t1(new TagValue("usdMarketCapAbove", "10000"));
TagValueSPtr t2(new TagValue("optVolumeAbove", "1000"));
TagValueSPtr t3(new TagValue("usdMarketCapAbove", "100000000"));
TagValueListSPtr TagValues(new TagValueList());
TagValues->push_back(t1);
TagValues->push_back(t2);
TagValues->push_back(t3);
m_pClient->reqScannerSubscription(7002, ScannerSubscriptionSamples::HotUSStkByVolume(), TagValueListSPtr(), TagValues);
-
1 self.reqScannerSubscription(7001, ScannerSubscriptionSamples.HighOptVolumePCRatioUSIndexes(), [], [])
5 tagvalues.append(TagValue(
"usdMarketCapAbove",
"10000"))
6 tagvalues.append(TagValue(
"optVolumeAbove",
"1000"))
7 tagvalues.append(TagValue(
"avgVolumeAbove",
"10000"))
9 self.reqScannerSubscription(7002, ScannerSubscriptionSamples.HotUSStkByVolume(), [], tagvalues)
Available API filters and and parameters until TWS v973 and API v973.07 are defined in the IBApi.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 IBApi.EWrapper.scannerData and the IBApi.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.
-
public class EWrapperImpl : EWrapper
{
... public virtual void scannerData(int reqId, int rank, ContractDetails contractDetails, string distance, string benchmark, string projection, string legsStr)
{
Console.WriteLine("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);
}
... public virtual void scannerDataEnd(int reqId)
{
Console.WriteLine("ScannerDataEnd. "+reqId);
}
-
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: " + EWrapperMsgGenerator.scannerData(reqId, rank, contractDetails, distance, benchmark, projection, legsStr));
}
... @Override
public void scannerDataEnd(int reqId) {
System.out.println("ScannerDataEnd: " + EWrapperMsgGenerator.scannerDataEnd(reqId));
}
-
Public Class EWrapperImpl
Implements EWrapper
... Public Sub scannerData(reqId As Integer, rank As Integer, contractDetails As IBApi.ContractDetails, distance As String, benchmark As String, projection As String, legsStr As String) Implements IBApi.EWrapper.scannerData
Console.WriteLine("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)
End Sub
... Public Sub scannerDataEnd(reqId As Integer) Implements IBApi.EWrapper.scannerDataEnd
Console.WriteLine("ScannerDataEnd. " & reqId & "\n")
End Sub
-
class TestCppClient : public EWrapper
{
... void TestCppClient::scannerData(int reqId, int rank, const ContractDetails& contractDetails,
const std::string& distance, const std::string& benchmark, const std::string& projection,
const std::string& legsStr) {
printf( "ScannerData. %d - Rank: %d, Symbol: %s, SecType: %s, Currency: %s, Distance: %s, Benchmark: %s, Projection: %s, Legs String: %s\n", reqId, rank, contractDetails.contract.symbol.c_str(), contractDetails.contract.secType.c_str(), contractDetails.contract.currency.c_str(), distance.c_str(), benchmark.c_str(), projection.c_str(), legsStr.c_str());
}
... void TestCppClient::scannerDataEnd(int reqId) {
printf( "ScannerDataEnd. %d\n", reqId);
}
-
1 class TestWrapper(wrapper.EWrapper):
... 1 def scannerData(self, reqId: int, rank: int, contractDetails: ContractDetails,
2 distance: str, benchmark: str, projection: str, legsStr: str):
3 super().scannerData(reqId, rank, contractDetails, distance, benchmark,
10 print(
"ScannerData. ReqId:", reqId, ScanData(contractDetails.contract, rank, distance, benchmark, projection, legsStr))
... 1 def scannerDataEnd(self, reqId: int):
2 super().scannerDataEnd(reqId)
3 print(
"ScannerDataEnd. ReqId:", reqId)
Since the IBApi.EClient.reqScannerSubscription request keeps a subscription open you will keep receiving periodic updates until the request is cancelled via IBApi.EClient.cancelScannerSubscription :
-
client.cancelScannerSubscription(7001);
client.cancelScannerSubscription(7002);
client.cancelScannerSubscription(7003);
-
client.cancelScannerSubscription(7001);
client.cancelScannerSubscription(7002);
client.cancelScannerSubscription(7003);
-
client.cancelScannerSubscription(7001)
client.cancelScannerSubscription(7002)
client.cancelScannerSubscription(7003)
-
m_pClient->cancelScannerSubscription(7001);
m_pClient->cancelScannerSubscription(7002);
-
1 self.cancelScannerSubscription(7001)
2 self.cancelScannerSubscription(7002)
3 self.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 IBApi.EClient.reqScannerParameters function.
-
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.Instrument = "STK";
scanSub.LocationCode = "STK.US.MAJOR";
scanSub.ScanCode = "HOT_BY_VOLUME";
...
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.Instrument = "STOCK.EU";
scanSub.LocationCode = "STK.EU.IBIS";
scanSub.ScanCode = "TOP_PERC_GAIN";
...
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.Instrument = "FUT.EU";
scanSub.LocationCode = "FUT.EU.EUREX";
scanSub.ScanCode = "MOST_ACTIVE";
...
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.Instrument = "IND.US";
scanSub.LocationCode = "IND.US";
scanSub.ScanCode = "HIGH_OPT_VOLUME_PUT_CALL_RATIO";
-
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.instrument("STK");
scanSub.locationCode("STK.US.MAJOR");
scanSub.scanCode("HOT_BY_VOLUME");
...
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.instrument("STOCK.EU");
scanSub.locationCode("STK.EU.IBIS");
scanSub.scanCode("TOP_PERC_GAIN");
...
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.instrument("FUT.EU");
scanSub.locationCode("FUT.EU.EUREX");
scanSub.scanCode("MOST_ACTIVE");
...
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.instrument("IND.US");
scanSub.locationCode("IND.US");
scanSub.scanCode("HIGH_OPT_VOLUME_PUT_CALL_RATIO");
-
'Hot US stocks by volume
Dim scanSub As ScannerSubscription = New ScannerSubscription()
scanSub.Instrument = "STK"
scanSub.LocationCode = "STK.US.MAJOR"
scanSub.ScanCode = "HOT_BY_VOLUME"
... 'Top % gainers at IBIS
Dim scanSub As ScannerSubscription = New ScannerSubscription()
scanSub.Instrument = "STOCK.EU"
scanSub.LocationCode = "STK.EU.IBIS"
scanSub.ScanCode = "TOP_PERC_GAIN"
... 'Most active futures at EUREX
Dim scanSub As ScannerSubscription = New ScannerSubscription()
scanSub.Instrument = "FUT.EU"
scanSub.LocationCode = "FUT.EU.EUREX"
scanSub.ScanCode = "MOST_ACTIVE"
... 'High option volume P/C ratio US indexes
Dim scanSub As ScannerSubscription = New ScannerSubscription()
scanSub.Instrument = "IND.US"
scanSub.LocationCode = "IND.US"
scanSub.ScanCode = "HIGH_OPT_VOLUME_PUT_CALL_RATIO"
-
ScannerSubscription scanSub;
scanSub.instrument = "STK";
scanSub.locationCode = "STK.US.MAJOR";
scanSub.scanCode = "HOT_BY_VOLUME";
...
ScannerSubscription scanSub;
scanSub.instrument = "STOCK.EU";
scanSub.locationCode = "STK.EU.IBIS";
scanSub.scanCode = "TOP_PERC_GAIN";
...
ScannerSubscription scanSub;
scanSub.instrument = "FUT.EU";
scanSub.locationCode = "FUT.EU.EUREX";
scanSub.scanCode = "MOST_ACTIVE";
...
ScannerSubscription scanSub;
scanSub.instrument = "IND.US";
scanSub.locationCode = "IND.US";
scanSub.scanCode = "HIGH_OPT_VOLUME_PUT_CALL_RATIO";
-
2 scanSub = ScannerSubscription()
3 scanSub.instrument =
"STK"
4 scanSub.locationCode =
"STK.US.MAJOR"
5 scanSub.scanCode =
"HOT_BY_VOLUME"
...
2 scanSub = ScannerSubscription()
3 scanSub.instrument =
"STOCK.EU"
4 scanSub.locationCode =
"STK.EU.IBIS"
5 scanSub.scanCode =
"TOP_PERC_GAIN"
...
2 scanSub = ScannerSubscription()
3 scanSub.instrument =
"FUT.EU"
4 scanSub.locationCode =
"FUT.EU.EUREX"
5 scanSub.scanCode =
"MOST_ACTIVE"
...
2 scanSub = ScannerSubscription()
3 scanSub.instrument =
"IND.US"
4 scanSub.locationCode =
"IND.US"
5 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.
-
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.Instrument = "NATCOMB";
scanSub.LocationCode = "NATCOMB.OPT.US";
scanSub.ScanCode = "COMBO_LATEST_TRADE";
-
ScannerSubscription scanSub = new ScannerSubscription();
scanSub.instrument("NATCOMB");
scanSub.locationCode("NATCOMB.OPT.US");
scanSub.scanCode("COMBO_LATEST_TRADE");
-
'Complex orders and trades scan, latest trades
Dim scanSub As ScannerSubscription = New ScannerSubscription()
scanSub.Instrument = "NATCOMB"
scanSub.LocationCode = "NATCOMB.OPT.US"
scanSub.ScanCode = "COMBO_LATEST_TRADE"
-
ScannerSubscription scanSub;
scanSub.instrument = "NATCOMB";
scanSub.locationCode = "NATCOMB.OPT.US";
scanSub.scanCode = "COMBO_LATEST_TRADE";
-
2 scanSub = ScannerSubscription()
3 scanSub.instrument =
"NATCOMB"
4 scanSub.locationCode =
"NATCOMB.OPT.US"
5 scanSub.scanCode =
"COMBO_LATEST_TRADE"
-
TagValue t = new TagValue("underConID", "265598");
List<TagValue> AAPLConIDTag = new List<TagValue>{t};
client.reqScannerSubscription(7003, ScannerSubscriptionSamples.ComplexOrdersAndTrades(), null, AAPLConIDTag);
-
List<TagValue> AAPLConIDTag = Collections.singletonList(new TagValue("underConID", "265598"));
client.reqScannerSubscription(7003, ScannerSubscriptionSamples.ComplexOrdersAndTrades(), null, AAPLConIDTag);
-
Dim AAPLConIDTag As List(Of IBApi.TagValue) = New List(Of TagValue)
AAPLConIDTag.Add(New TagValue("underConID", "265598"))
client.reqScannerSubscription(7003, ScannerSubscriptionSamples.ComplexOrdersAndTrades(), Nothing, AAPLConIDTag) ' requires TWS v975+
-
TagValueSPtr t(new TagValue("underConID", "265598"));
TagValueListSPtr AAPLConIDTag(new TagValueList());
AAPLConIDTag->push_back(t);
m_pClient->reqScannerSubscription(7003, ScannerSubscriptionSamples::ComplexOrdersAndTrades(), TagValueListSPtr(), AAPLConIDTag);
-
1 AAPLConIDTag = [TagValue(
"underConID",
"265598")]
2 self.reqScannerSubscription(7003, ScannerSubscriptionSamples.ComplexOrdersAndTrades(), [], AAPLConIDTag)
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