It looks like I found culprit: thread locking. I pasted full code below. I implemented thread locking in order to make sure that list of tick data gets fully update before it is analyzed for any trade opportunity. Without this lock I have seen cases where price is update, but size is not, so I was getting two lists of different length. Now, however, this thread locking prevents list from fully updating. I ran the code for 5 minutes and Python script accumulated only 3622 rows, while log file collected 3631. I repeated the exercise. but with thread locking commented and got the same number of lines in both Python script and log. I am a bit new to writing threaded code, anybody have any suggestion how to fix it?
from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.ticktype import TickTypeEnum
import time
import datetime
from pytz import timezone
import threading
import pandas as pd
EST_TZ = timezone('US/Eastern')
GMT_TZ = timezone('GMT')
class TestApp(EWrapper, EClient):
def __init__(self):
EClient.__init__(self, self)
self.last_ticker = []
self.last_exchange = []
self.last_market_time = []
self.last_server_time = []
self.last_price = []
self.last_size = []
self.last_tick_type = []
self.last_past_limit = []
self.last_unreported = []
self.last_special_cond = []
self.lock_last = threading.Lock()
def error(self, reqId, errorCode, errorString):
print("Error: ", reqId, " ", errorCode, " ", errorString)
def tickByTickAllLast(self, reqId, tickType, time, price, size, tickAtrribLast,
exchange, specialConditions):
super().tickByTickAllLast(reqId, tickType, time, price, size, tickAtrribLast,
exchange, specialConditions)
self.update_last_list( reqId, tickType, time, price, size, tickAtrribLast,
exchange, specialConditions)
def update_last_list(self, reqId, tickType, time, price, size, tickAtrribLast,
exchange, specialConditions):
self.lock_last.acquire()
self.last_ticker = self.last_ticker + [reqId]
self.last_exchange = self.last_exchange + [exchange]
self.last_server_time = self.last_server_time + [datetime.datetime.now(EST_TZ)]
self.last_market_time = self.last_market_time + [GMT_TZ.localize(datetime.datetime.fromtimestamp(time)).astimezone(EST_TZ)]
self.last_price = self.last_price + [price]
self.last_size = self.last_size + [size]
self.last_tick_type =self.last_tick_type + [tickType]
self.last_past_limit = self.last_past_limit + [tickAtrribLast.pastLimit]
self.last_unreported = self.last_unreported + [tickAtrribLast.unreported]
self.last_special_cond = self.last_special_cond + [specialConditions]
self.lock_last.release()
app = TestApp()
contract = Contract()
contract.symbol = "SPY"
contract.secType = "STK"
contract.exchange = "SMART"
contract.currency = "USD"
contract.primaryExchange = "ARCA"
app.connect("127.0.0.1", 7497, 0)
time.sleep(1)
app.reqTickByTickData(1 ,contract, "Last", 0, False)
api_thread = threading.Thread(target=app.run)
api_thread.start()
time.sleep(300)
app.cancelTickByTickData(1)
app.disconnect()