1

I am testing how to receive real time data through interactive brokers' API and reqMktData. The algorithm is run through an infinite while loop, which allows for real-time live streaming data until I stop the script. When I run it, it is supposed to continuously print data to the console as specified in the code below. However, nothing is printed until I hit "stop the current command". Then I get a huge data dump consisting of all the data received since the execution of the script.

I have tried the following solution, where I import sys in the beginning of the script and flush the output after each print. However, this doesn't work either:

import sys
sys.stdout.flush()

I'm using python 2.7 and spyder - and am quite new to python.

Hope someone can help! Any inputs are greatly appreciated.

The script I'm testing:

from ib.ext.Contract import Contract
from ib.ext.Order import Order
from ib.opt import Connection, message
import pandas as pd
import datetime as dt


class AlgoSystem:
    def __init__(self, symbol, qty, resample_interval,
                 averaging_period=5, port=7496):
        self.client_id = 1
        self.order_id = 1
        self.qty = qty
        self.symbol_id, self.symbol = 0, symbol
        self.resample_interval = resample_interval
        self.averaging_period = averaging_period
        self.port = port
        self.tws_conn = None
        self.bid_price, self.ask_price = 0, 0
        self.last_prices = pd.DataFrame(columns=[self.symbol_id])
        self.average_price = 0
        self.account_code = None

    def error_handler(self, msg):
        if msg.typeName == "error" and msg.id != -1:
            print "Server Error:", msg


    def tick_event(self, msg):
        if msg.field == 1:
            self.bid_price = msg.price
        elif msg.field == 2:
            self.ask_price = msg.price
        elif msg.field == 4:
            self.last_prices.loc[dt.datetime.now()] = msg.price
            resampled_prices = \
                self.last_prices.resample(self.resample_interval,
                                          how='last',
                                          fill_method="ffill")
            self.average_price = resampled_prices.tail(
                self.averaging_period).mean()[0]

        print dt.datetime.now(), "average:", self.average_price, \
            "bid:", self.bid_price, "ask:", self.ask_price



    def create_contract(self, symbol, sec_type, exch, prim_exch, curr):
        contract = Contract()
        contract.m_symbol = symbol
        contract.m_secType = sec_type
        contract.m_exchange = exch
        contract.m_primaryExch = prim_exch
        contract.m_currency = curr
        return contract


    def request_market_data(self, symbol_id, symbol):
        contract = self.create_contract(symbol,
                                        'STK',
                                        'SMART',
                                        'SMART',
                                        'USD')
        self.tws_conn.reqMktData(symbol_id, contract, '', False)
        time.sleep(1)

    def cancel_market_data(self, symbol):
        self.tws_conn.cancelMktData(symbol)
        time.sleep(1)


    def connect_to_tws(self):
        self.tws_conn = Connection.create(port=self.port,
                                          clientId=self.client_id)
        self.tws_conn.connect()

    def disconnect_from_tws(self):
        if self.tws_conn is not None:
            self.tws_conn.disconnect()

    def register_callback_functions(self):
        # Assign error handling function.
        self.tws_conn.register(self.error_handler, 'Error')

        # Register market data events.
        self.tws_conn.register(self.tick_event,
                               message.tickPrice,
                               message.tickSize)

    def start(self):
        try:
            self.connect_to_tws()
            self.register_callback_functions()
            self.request_market_data(self.symbol_id, self.symbol)

            while True:
                time.sleep(1)

        except Exception, e:
            print "Error:", e
            self.cancel_market_data(self.symbol)

        finally:
            print "disconnected"
            self.disconnect_from_tws()

if __name__ == "__main__":
    system = AlgoSystem("FB", 100, "30s", 5)
    system.start()
Emjora
  • 379
  • 2
  • 11

1 Answers1

2

I don't know anything about the interactive brokers API, but my guess is that your start method needs to be changed to something along the lines of :

def start(self):

    try:
        self.connect_to_tws()
        self.register_callback_functions()
        while True:
            self.request_market_data(self.symbol_id, self.symbol)
            time.sleep(1)

    except Exception, e:
        print "Error:", e
        self.cancel_market_data(self.symbol)

    finally:
        print "disconnected"
        self.disconnect_from_tws()

currently your infinite loop just repeatedly sleeps. I think you want the request_market_data to be inside the while loop.

Alex Lang
  • 160
  • 1
  • 6
  • Hi and thanks for the suggestion. However, this modification will just cause the program to continuously connect, get some data and disconnect. Before the code only connected once, where reqMktData turned "on" the switch for real time data and tick_event was created to handle every incoming message which included tick information. – Emjora Mar 23 '17 at 07:36
  • The only thing in your while loop is a `time.sleep(1)` command. thats why it blocks until you ctrl-C. you need to put something inside the loop that collects data. If you don't want to continuously connect and disconnect, then put the connect and disconnect methods outside the loop, and put the `request_market_data` method inside the loop, if that is possible – Alex Lang Mar 23 '17 at 19:07
  • Alex is most likely right, you can't just sleep your program. Look at http://stackoverflow.com/a/43005947/2855515 where I explained some asynchronous stuff. – brian Mar 24 '17 at 17:52