def handlePortfolio(self, msg):
        """ handle portfolio updates """

        # log handler msg
        self.log_msg("portfolio", msg)

        # contract identifier
        contract_tuple = self.contract_to_tuple(msg.contract)
        contractString = self.contractString(contract_tuple)

        # try creating the contract
        self.registerContract(msg.contract)

        # new account?
        if msg.accountName not in self._portfolios.keys():
            self._portfolios[msg.accountName] = {}

        self._portfolios[msg.accountName][contractString] = {
            "symbol":        contractString,
            "position":      int(msg.position),
            "marketPrice":   float(msg.marketPrice),
            "marketValue":   float(msg.marketValue),
            "averageCost":   float(msg.averageCost),
            "unrealizedPNL": float(msg.unrealizedPNL),
            "realizedPNL":   float(msg.realizedPNL),
            "totalPNL":      float(msg.realizedPNL) + float(msg.unrealizedPNL),
            "account":       msg.accountName
        }

        # fire callback
        self.ibCallback(caller="handlePortfolio", msg=msg)