code: def handleTickPrice(self, msg):
          
          # self.log.debug("[TICK PRICE]: %s - %s", dataTypes["PRICE_TICKS"][msg.field], msg)
          # return
  
          if msg.price < 0:
              return
  
          df2use = self.marketData
          canAutoExecute = msg.canAutoExecute == 1
          if self.contracts[msg.tickerId].m_secType in ("OPT", "FOP"):
              df2use = self.optionsData
              canAutoExecute = True
  
          # create tick holder for ticker
          if msg.tickerId not in df2use.keys():
              df2use[msg.tickerId] = df2use[0].copy()
  
          # bid price
          if canAutoExecute and msg.field == dataTypes["FIELD_BID_PRICE"]:
              df2use[msg.tickerId]['bid'] = float(msg.price)
          # ask price
          elif canAutoExecute and msg.field == dataTypes["FIELD_ASK_PRICE"]:
              df2use[msg.tickerId]['ask'] = float(msg.price)
          # last price
          elif msg.field == dataTypes["FIELD_LAST_PRICE"]:
              df2use[msg.tickerId]['last'] = float(msg.price)
  
          # fire callback
          self.ibCallback(caller="handleTickPrice", msg=msg)
docs: holds latest tick bid/ask/last price