Interactive Brokers TWS, Python API

236 Views Asked by At

I have a question. See my question in upper case below in the middle of my program. Somehow the two lists are empty. The function position in the class TestApp seems not be called. Any help is appreciated. I am stuck here and could not find a solution without some help.

class TestApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)
        self.position_symbols=[]
        self.position_shares=[]

    def error(self, reqId, errorCode, errorString):
        print('Error: ', reqId, " ", errorCode, " ", errorString)
        
    def position(self, account, contract, position, avgCost):
        super().position(account, contract, position, avgCost)
        print("Position", contract.symbol, position, avgCost)
        self.position_symbols.append(contract.symbol)
        self.position_shares.append(str(position)) 
      
    def nextValidId(self, orderId):
        self.nextOrderId = orderId
        self.start()

    def start(self):
        self.reqPositions()
         
    def stop(self):
        self.done = True
        self.cancelScannerSubscription(1)
        self.disconnect()

class MyThread(Thread, EWrapper, EClient): 
    ib=None
    def __init__(self):
        self.ib=TestApp()
        Thread.__init__(self)
      
        self.start()
      
        self.ib.connect('127.0.0.1', 7497, 0)
        app = TestApp()
        app.nextOrderId = 0
        
    def run(self):
        
        for i in range (332, 345, 2):

            time.sleep(4)
            loopindex = i % numsymbol

            # THOSE TWO LINES OF CODES ARE NOT WORKING. 
            # PROBABLY DUE TO THREADING ISSUES. 
            # THE TWO LISTS ARE EMPTY

            print(self.ib.position_symbols)
            print(self.ib.position_shares)

my = None
while True:
    user_input = input("What do I do?")
    if user_input == "start thread":
        if my == None: 
            my = MyThread()

    elif user_input.upper() in ["REMOVE", "ADD"]:
        do something....
        

1

There are 1 best solutions below

0
On

You should use the new thread for the EClient.run() method. Then do everything else in the main thread.

This now works:

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from threading import Thread
import time


class TestApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)
        self.position_symbols = []
        self.position_shares = []

    def error(self, reqId, errorCode, errorString):
        print('Error: ', reqId, " ", errorCode, " ", errorString)

    def position(self, account, contract, position, avgCost):
        super().position(account, contract, position, avgCost)
        print("Position", contract.symbol, position, avgCost)
        self.position_symbols.append(contract.symbol)
        self.position_shares.append(str(position))

    def nextValidId(self, orderId):
        self.nextOrderId = orderId
        self.start()

    def start(self):
        self.reqPositions()

    def stop(self):
        self.done = True
        self.cancelScannerSubscription(1)
        self.disconnect()


# class MyThread(Thread, EWrapper, EClient):
#     ib = None
#
#     def __init__(self):
#         self.ib = TestApp()
#         Thread.__init__(self)
#
#         self.start()
#
#         self.ib.connect('127.0.0.1', 7497, 0)
#         app = TestApp()
#         app.nextOrderId = 0
#
#     def run(self):
#         for i in range(332, 345, 2):
#             time.sleep(4)
#             # loopindex = i % numsymbol
#
#             # THOSE TWO LINES OF CODES ARE NOT WORKING.
#             # PROBABLY DUE TO THREADING ISSUES.
#             # THE TWO LISTS ARE EMPTY
#
#             print(self.ib.position_symbols)
#             print(self.ib.position_shares)


app = TestApp()
app.connect('127.0.0.1', 7497, 0)

my = None
while True:
    app.nextOrderId = 0
    user_input = input("What do I do?")
    if user_input == "start thread":
        if my == None:
            my = Thread(target=app.run)
            my.start()

    elif user_input.upper() in ["REMOVE", "ADD"]:
        # do
        # something....
        pass

    for i in range(332, 345, 2):
        time.sleep(4)
        # loopindex = i % numsymbol

        # NOW WORKING

        print(app.position_symbols)
        print(app.position_shares)