Search code examples
interactive-brokerstws

Using TWS API to get unrealised PnL of all subaccounts


I am trying to find the unrealised PnL of all the subaccounts in Interactive Brokers. As this is my first time using the TWS API, I am not sure what I am doing wrong.

After reading through the API documentation, the reqPnL method on the EClient seemed like the ideal way to get what I want. Below is the code I tried:

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from threading import Timer


class TestApp(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)

        self.reqPnL(17001, 'All', '')

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

    def pnl(self, reqId: int, dailyPnL: float, unrealizedPnL: float, realizedPnL: float):
        print("Daily PnL Single. ReqId:", reqId, "Position:", decimalMaxString(pos),
        "DailyPnL:", floatMaxString(dailyPnL), "UnrealizedPnL:", floatMaxString(unrealizedPnL),
        "RealizedPnL:", floatMaxString(realizedPnL), "Value:", floatMaxString(value))

        self.cancelPnL(17001)


def main():
    app = TestApp()
    app.connect("127.0.0.1", 7496, 0)
    app.run()


if __name__ == "__main__":
    main()

The results I am getting is:

Error:  -1   504   Not connected
Error:  -1   2104   Market data farm connection is OK:hfarm
Error:  -1   2104   Market data farm connection is OK:eufarmnj
Error:  -1   2104   Market data farm connection is OK:cashfarm
Error:  -1   2104   Market data farm connection is OK:usfuture
Error:  -1   2104   Market data farm connection is OK:afarm
Error:  -1   2104   Market data farm connection is OK:jfarm
Error:  -1   2104   Market data farm connection is OK:usfarm.nj
Error:  -1   2104   Market data farm connection is OK:eufarm
Error:  -1   2104   Market data farm connection is OK:usopt
Error:  -1   2104   Market data farm connection is OK:usfarm
Error:  -1   2106   HMDS data farm connection is OK:euhmds
Error:  -1   2106   HMDS data farm connection is OK:hkhmds
Error:  -1   2106   HMDS data farm connection is OK:fundfarm
Error:  -1   2106   HMDS data farm connection is OK:ushmds
Error:  -1   2158   Sec-def data farm connection is OK:secdefhk

I am not sure what am I doing wrong. I feel like either I am forgetting an Ewrapper function or I am not suppose to be using 17001 for the ReqId. Please help.


Solution

  • You cannot make a request in initialisation as connect has not yet been called. Try calling it after the nextValidId callback:

    from ibapi.client import EClient
    from ibapi.wrapper import EWrapper
    from ibapi.contract import Contract
    from threading import Timer
    
    class TestApp(EWrapper, EClient):
        def __init__(self):
            EClient.__init__(self, self)
    
        def nextValidId(self, orderId: int):
            self.orderId = orderId
            self.reqPnL(17001, 'All', '')
    
        def error(self, reqId, errorCode, errorString):
            print("Error: ", reqId, " ", errorCode, " ", errorString)
    
        def pnl(self, reqId: int, dailyPnL: float, unrealizedPnL: float, realizedPnL: float):
            print("Daily PnL Single. ReqId:", reqId, "Position:", decimalMaxString(pos),
            "DailyPnL:", floatMaxString(dailyPnL), "UnrealizedPnL:", floatMaxString(unrealizedPnL),
            "RealizedPnL:", floatMaxString(realizedPnL), "Value:", floatMaxString(value))
    
            self.cancelPnL(17001)
    
    def main():
        app = TestApp()
        app.connect("127.0.0.1", 7496, 0)
        app.run()
    
    if __name__ == "__main__":
        main()