requesting portfolio information on ibpy not "updating it"

466 views Asked by At

I am using ibpy to get my porfolio information every 10 seconds (i need this information in a very frequent manner), specifically the unrealized pnl information for each contract. The way i do it is :

def updatePortfolio(self):
    self._portfolio=[]
    if self._updated_accounts==False:
        print("requesting account updates")
        self._tws.reqAccountUpdates(True,'')
        sleep(3)
        print("requesting account value updates")
        self._tws.updateAccountValue()
        sleep(3)
        print("requesting portfolio updates")
        self._tws.updatePortfolio()
        sleep(3)

However, since I do this pretty frequently (every 10 second). It seems portfolio information is not sent back and it usually leads to empty portfolio. How do i ensure that I could request and refresh the portfolio information and not its update (meaning that i should get the complete portfolio information each time i request)? Thank you.

2

There are 2 answers

2
brian On BEST ANSWER

You don't keep calling it. True means keep sending updates as needed. When a position changes you'll get an update. I'm assuming you left the account blank for privacy, but you need to specify it.

If you need the pnl in an ongoing manner, you should subscribe to market data and calculate based on the contract price and your entry price. You will have received your entry price in the execDetails message;

I'm assuming you want real time updates of your pnl. Your answer seems like it's still using the update portfolio callback. What you need is to track it on your own and then you can see the pnl whenever the price changes.

First save the execution price

def execDetails(msg):
    global posn_val
    print('My entry price',msg.execution.m_price)
    #keep track of what your buying, I just did -1 ES
    posn_val = msg.execution.m_avgPrice * msg.execution.m_cumQty * 50

Then on every price tick you can see the pnl

def price(msg):
    global posn_val, prof #you'll need these accesible
    prof = msg.price * 1 * 50 - posn_val #assuming 1 ES with mult = 50

Register these for messages

tws = Connection.create(port = 7497, clientId=123)
tws.register(execDetails, message.execDetails)
tws.register(price, message.tickPrice)

To request data

es = Contract()
es.m_secType = "FUT" 
es.m_symbol = "ES"
es.m_expiry = "201703"
es.m_currency = "USD"
es.m_exchange = "GLOBEX"
tws.reqMktData(1,es,"",False)

This isn't a complete program, just an idea of how it's done. Most people I know don't use the account information except as a check to make sure nothing has gone wrong. You should keep track of your positions and if IB disagrees, then you figure out what's wrong. It's a more real time way of monitoring.

0
WEQA HUDSA On

I have done something like this to resolve it:

IB_FUTURE_INFO_TABLE = {
    'AUD': [100000],
    'GBP': [62500],
    'CAD': [100000],
    'CHF': [125000],
    'EUR': [125000],
    'JPY': [12500000],
    'NZD': [100000]
}


def request_unrlzd_pnl_report(self):
    self.request_positions()
    unrlzd_pnl_report=[]
    for position_msg in self._positions:
        position_contract_now = position_msg.contract
        symbol=position_contract_now.m_symbol
        if symbol in settings.IB_FUTURE_INFO_TABLE.keys():
            position_pos_now = position_msg.pos
            position_avgCost = position_msg.avgCost
            self.printContract(position_contract_now)
            self.requestData(position_contract_now)
            total_initial_market_value = position_avgCost * (position_pos_now)
            if position_pos_now>0:
               total_final_market_value = self._bid_price * position_pos_now * settings.IB_FUTURE_INFO_TABLE[symbol][0]
            elif position_pos_now<0:
               total_final_market_value = self._ask_price * position_pos_now * settings.IB_FUTURE_INFO_TABLE[symbol][0]

            # total_final_market_value = self._mid_price * position_pos_now * settings.IB_FUTURE_INFO_TABLE[symbol][0]
            total_unrlzd_pnl = total_final_market_value - total_initial_market_value
            total_unrlzd_pnl_ratio = total_unrlzd_pnl / abs(total_initial_market_value)
            unrlzd_pnl_report.append((symbol,position_contract_now,position_pos_now,position_avgCost,total_unrlzd_pnl,total_unrlzd_pnl_ratio))
    # print(unrlzd_pnl_report)
    return  unrlzd_pnl_report