Search code examples
pythoninteractive-brokersibpy

Retrieve ScannerSubscription results using IbPy


I'm struggling with the results of a ScannerSubscription.
For example, if I request:

qqq_id = 0
subscript = ScannerSubscription()
subscript.numberOfRows(15)
subscript.m_scanCode = 'HIGH_OPEN_GAP'
subscript.m_instrument = 'STK'
subscript.m_averageOptionVolumeAbove = ''
subscript.m_couponRateAbove = ''
subscript.m_couponRateBelow = ''
subscript.m_abovePrice = '5'
subscript.m_belowPrice = ''
subscript.m_marketCapAbove = ''
subscript.m_marketCapBelow = ''
subscript.m_aboveVolume = '100000'
subscript.m_stockTypeFilter = 'ALL'
subscript.locationCode('STK.US.MAJOR')
tws_conn.reqScannerSubscription(qqq_id, subscript)
tws_conn.reqScannerParameters()

I received a scannerData response like this:

<scannerData reqId=0, rank=0, contractDetails=<ib.ext.ContractDetails.ContractDetails object at 0x00000000036EFA58>, distance=None, benchmark=None, projection=None, legsStr=None>
etc...

But I cannot retrieve the result values, for example:

reqScannerParameters() xml result specifies <colId>390</colId> as the colId for the Gap value:

<ScanType>
    <displayName>Top Close-to-Open % Gainers</displayName>
    <scanCode>HIGH_OPEN_GAP</scanCode>
    <instruments>STK,STOCK.NA,STOCK.EU,STOCK.HK,FUT.US,FUT.HK,FUT.EU,FUT.NA</instruments>
    <absoluteColumns>false</absoluteColumns>
<Columns varName="columns">
<Column>
    <colId>390</colId>
    <name>Gap</name>
    <display>true</display>
    <section>m</section>
    <displayType>DATA</displayType>
</Column>

How do I retrieve the GAP value?
Is this even possible ?


Solution

  • Now I'm sure you're supposed to request data after getting the contract.

    import pandas as pd
    scans = 15
    res = pd.DataFrame(index = range(scans), columns = ['sym','open','close','calc']).fillna(0)
    msgs = []
    
    from ib.ext.Contract import Contract
    from ib.opt import ibConnection, message
    from ib.ext.TickType import TickType as tt
    
    def tickPrice(msg):
        global scans 
    
        if msg.field in [tt.OPEN, tt.CLOSE]:
            res.loc[msg.tickerId,tt.getField(msg.field)] = msg.price
    
        op = res.loc[msg.tickerId,'open']
        cl = res.loc[msg.tickerId,'close']
    
        if  op > 0 and cl > 0 and res.loc[msg.tickerId,'calc'] == 0:
            res.loc[msg.tickerId,'calc'] = ((op-cl)*100/cl)
            con.cancelMktData(msg.tickerId)
            scans -= 1
            if scans == 0:
                print(res)
                con.disconnect()
    
    def snapshot(msg):
        res.loc[msg.rank,'sym'] = msg.contractDetails.m_summary.m_symbol
        #tt.OPEN (14) isn't coming with snapshot
        con.reqMktData(str(msg.rank), msg.contractDetails.m_summary, "", False)
    
    def watcher(msg):
        #print (msg)
        msgs.append(msg)
    
    def scanData(msg):
        snapshot(msg)
    
    def scanDataEnd(msg):
        con.cancelScannerSubscription(qqq_id)
    
    con = ibConnection(port=7497, clientId=888)
    con.registerAll(watcher)
    con.unregister(watcher, message.scannerData)
    con.register(scanData, message.scannerData)
    con.unregister(watcher, message.scannerDataEnd)
    con.register(scanDataEnd, message.scannerDataEnd)
    con.unregister(watcher, message.tickPrice)
    con.register(tickPrice, message.tickPrice)
    
    con.connect()
    
    from ib.ext.ScannerSubscription import ScannerSubscription
    qqq_id = 0
    subscript = ScannerSubscription()
    subscript.numberOfRows(15)
    subscript.m_scanCode = 'HIGH_OPEN_GAP'
    subscript.m_instrument = 'STK'
    subscript.m_averageOptionVolumeAbove ='0'
    subscript.m_abovePrice = '5'
    subscript.m_aboveVolume = '100000'
    
    con.reqScannerSubscription(qqq_id, subscript)
    

    res at 1 pm est =

            sym   open  close       calc
    0       TAC   4.95   4.25  16.470588
    1      CTRP  44.80  40.99   9.294950
    2      IIIN  39.26  36.58   7.326408
    3       LFC  14.60  13.63   7.116654
    4       ACH  11.59  10.87   6.623735
    5      KALV   9.01   8.38   7.517900
    6      OMER  13.25  12.75   3.921569
    7      DWTI  68.00  66.50   2.255639
    8      WLDN  23.75  23.43   1.365770
    9       BZQ  19.67  18.73   5.018687
    10     JNUG   6.55   6.43   1.866252
    11  GXP PRB  50.78  49.80   1.967871
    12       AU  10.85  10.59   2.455146
    13     USLV  13.07  12.81   2.029664
    14      CBD  16.60  16.03   3.555833
    

    I don't know why they don't come in rank order??