简体   繁体   中英

IB/IbPy-Understanding how to access and store a variable from API response

My understanding of Interactive Brokers API is of an async nature where if I call reqMktData() after connecting, it calls tickPrice() among other methods, sends parameters to tickPrice(), then tickPrice() passes it's own results to a message object. To read the incoming message objects, I need to implement a message handler from EWrapper.

I am trying to extract the price variable inside the message object, but I have been unsuccessful in extracting the tickPrice() price field or extracting the price inside the message object either from calling tickPrice() directly or from something like msg.price.

Here is my code:

from ib.opt import ibConnection, Connection, message
import time
import ib_data_types as datatype
from ib.ext.Contract import Contract


#price_field = ''

def reply_handler(msg):
print("Reply:", msg)

#def my_callback_handler(msg):
#if msg.field == 4:
    #price_field = msg.price

def request_streaming_data(ib_conn):
    # Stream market data
    ib_conn.reqMktData(1,
                    contract,
                    datatype.GENERIC_TICKS_NONE,
                    datatype.SNAPSHOT_NONE)
    time.sleep(1)


if __name__ == "__main__":
tws_conn = ibConnection(host='localhost', port=7497, clientId=100)
tws_conn.connect()

tws_conn.registerAll(reply_handler)
#tws_conn.register(my_callback_handler, "TickPrice")

contract = Contract()
contract.m_symbol = 'GE'
contract.m_exchange = 'SMART'
contract.m_currency = 'USD'
contract.m_secType = 'STK'

request_streaming_data(tws_conn)
#print(price_field)

The above code works perfectly fine for printing to screen the responses from API in the form such as: Reply: tickString tickerId=1, tickType=45, value=1446324128

Reply: tickPrice tickerId=1, field=4, price=29.15, canAutoExecute=0

Reply: tickSize tickerId=1, field=5, size=23

But when I try to isolate the price field using this modified code below, I get no response or errors of the following:

from ib.opt import ibConnection, Connection, message
import time
import ib_data_types as datatype
from ib.ext.Contract import Contract

price_field = ''
def reply_handler(msg):
print("Reply:", msg)

def my_callback_handler(msg):
if msg.field == 4:
    price_field = msg.price
else:
    print(msg)

def request_streaming_data(ib_conn):
    # Stream market data
    ib_conn.reqMktData(1,
                    contract,
                    datatype.GENERIC_TICKS_NONE,
                    datatype.SNAPSHOT_NONE)
    time.sleep(1)


if __name__ == "__main__":
tws_conn = ibConnection(host='localhost', port=7497, clientId=100)
tws_conn.connect()

#tws_conn.registerAll(reply_handler)
tws_conn.register(my_callback_handler)

contract = Contract()
contract.m_symbol = 'GE'
contract.m_exchange = 'SMART'
contract.m_currency = 'USD'
contract.m_secType = 'STK'

request_streaming_data(tws_conn)
print(price_field)

Output to screen if tws_conn.register(my_callback_handler):

Server Version: 76

TWS Time at connection:20151031 13:50:06 PST

Process finished with exit code 0

Output to screen if tws_conn.registerAll(my_callback_handler):

31-Oct-15 13:56:33 ERROR Exception in message dispatch.

Handler 'my_callback_handler' for 'tickString'

Traceback (most recent call last): File "C:\\Python34\\lib\\site-packages\\ib\\opt\\dispatcher.py", line 44, in call results.append(listener(message)) File "C:/Users/Admin/PycharmProjects/TestStrat/4.py", line 11, in my_callback_handler if msg.field == 4:

AttributeError: 'TickString' object has no attribute 'field'

Lastly I have tested the code from this question here:

IbPy: How to extract API response into a variable

Output:

Server Version: 76

TWS Time at connection:20151031 13:53:51 PST

Price - field 4: 29.31

Process finished with exit code 0

And I get the price field correctly. But as far I can tell, my implementations are similar. Why am I not getting the response? Thanks!

You're trying to parse all messages in your reply handler and making the wrong assumption that they all have a field called field . If you look at your earlier response, TickString doesn't have field .

You need to either send only TickPrice messages or check in your handler if it's really a TickPrice message.

In the example you linked to, notice the code self.tws.register(self.tickPriceHandler, 'TickPrice') . That's making a special handler for just the TickPrice messages.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM