Установка переменных для ответов API Interactive Brokers в Python

У меня есть некоторый код, где я запрашиваю рыночные данные в реальном времени для фьючерсного контракта, используя API Interactive Brokers и Python, в данном случае VIX-контракт. Я получаю обратно поток данных, который печатается через исправленные обертки. Это использует настоящий API Python от IB, а не стороннюю библиотеку.

То, что я хотел бы сделать, это в два раза: во-первых, установить переменную на последнюю цену, которая является tickType 4 в ответе (13.0). Во-вторых, я хотел бы затем прекратить потоковую передачу данных для текущего контракта и запросить данные для другого контракта (например, следующую дату истечения срока действия, 20170816.) В противном случае, если бы я мог запросить оба набора данных одновременно и установить их каждый в переменную, то прекратить потоковую передачу, что также было бы удивительно. Это код, который у меня есть, который делает успешный запрос от IB. Предполагая, что API включен, и у вас есть доступ к данным рынка фьючерсов VIX (обмен CFE), ответ таков:

from ibapi.wrapper import EWrapper
from ibapi.client import EClient
from ibapi.utils import iswrapper
from ibapi.common import *
from ibapi.contract import *
from ibapi.ticktype import *
# Request IB Data in less than 50 lines of code
class BasicApp(EWrapper, EClient):
  def __init__(self):
    EClient.__init__(self,self)

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

  @iswrapper
  def tickPrice(self, reqId: TickerId, tickType: TickType, price: float, attrib: TickAttrib):
    super().tickPrice(reqId, tickType, price, attrib)
    print("Tick Price. Ticker Id:", reqId, "tickType:", tickType, "Price:", price, "CanAutoExecute:", attrib.canAutoExecute, "PastLimit", attrib.pastLimit)

  @iswrapper
  def tickSize(self, reqId: TickerId, tickType: TickType, size: int):
    super().tickSize(reqId, tickType, size)
    print("Tick Size. Ticker Id:", reqId, "tickType:", tickType, "Size:", size)

  @iswrapper
  def tickString(self, reqId: TickerId, tickType: TickType, value: str):
    super().tickString(reqId, tickType, value)
    print("Tick string. Ticker Id:", reqId, "Type:", tickType, "Value:", value)

  @iswrapper
  def tickGeneric(self, reqId: TickerId, tickType: TickType, value: float):
    super().tickGeneric(reqId, tickType, value)
    print("Tick Generic. Ticker Id:", reqId, "tickType:", tickType, "Value:", value)

def main():
  app = BasicApp()
  app.connect("127.0.0.1", 4001, 0)
  contract = Contract();
  contract.symbol = "VIX";
  contract.secType = "FUT";
  contract.exchange = "CFE";
  contract.currency = "USD";
  contract.lastTradeDateOrContractMonth = "20170719";
  app.reqMktData(1001, contract, "", False, False, [])
  app.run()

if __name__ == '__main__':
  main()

Это обертки над печатью ответа от IB:

Error: -1   2119   Market data farm is connecting:usfuture.us
Error: -1   2104   Market data farm connection is OK:usfuture.us
Tick string. Ticker Id: 1001 Type: 45 Value: 1499398651
Tick Price. Ticker Id: 1001 tickType: 4 Price: 13.0 CanAutoExecute: False PastLimit False
Tick Size. Ticker Id: 1001 tickType: 5 Size: 1
Tick Size. Ticker Id: 1001 tickType: 5 Size: 1
Tick Size. Ticker Id: 1001 tickType: 8 Size: 3072
Tick Price. Ticker Id: 1001 tickType: 6 Price: 13.15 CanAutoExecute: False PastLimit False
Tick Price. Ticker Id: 1001 tickType: 7 Price: 12.95 CanAutoExecute: False PastLimit False
Tick Price. Ticker Id: 1001 tickType: 9 Price: 13.0 CanAutoExecute: False PastLimit False
Tick Price. Ticker Id: 1001 tickType: 14 Price: 12.3 CanAutoExecute: False PastLimit False
Tick Price. Ticker Id: 1001 tickType: 1 Price: 12.95 CanAutoExecute: True PastLimit False
Tick Size. Ticker Id: 1001 tickType: 0 Size: 140
Tick Price. Ticker Id: 1001 tickType: 2 Price: 13.0 CanAutoExecute: True PastLimit False
Tick Size. Ticker Id: 1001 tickType: 3 Size: 138
Tick Size. Ticker Id: 1001 tickType: 0 Size: 140
Tick Size. Ticker Id: 1001 tickType: 3 Size: 138

2 ответа

Решение

Чтобы прекратить потоковую передачу данных для текущего контракта, позвоните

app.cancelMktData(tickerId); 

Для tickerId используйте то же значение, что и в app.reqMktData (1001 в вашем примере).

Сохранение последней цены не должно быть проблемой. Вставить

lastPrice = price;

в методе tickPrice.

Вы можете получать рыночные данные для нескольких инструментов параллельно, вызывая app.reqMktData с другим tickerId. В этом случае lastprice может храниться в коллекции (например, в словаре, который использует tickerId в качестве ключа).

Цель 1: может быть достигнута с помощью приведенного ниже кода:

      class BasicApp(EWrapper, EClient):
  def __init__(self):
    EClient.__init__(self,self)
    self.reqId_last_price_dict = {}  # This dictionary uses reqId as key, last price as value

  @iswrapper
  def tickPrice(self, reqId: TickerId, tickType: TickType, price: float, attrib: TickAttrib):
    super().tickPrice(reqId, tickType, price, attrib)
    print("Tick Price. Ticker Id:", reqId, "tickType:", tickType, "Price:", price, "CanAutoExecute:", attrib.canAutoExecute, "PastLimit", attrib.pastLimit)
    self.reqId_last_price_dict[reqId] = price  # This line updates the dictionary value with the same reqId whenever a new price returned.

Цель 2:
IB разрешает 3 одновременных запроса данных о рыночных тиках, если вы подписались на одну из их прямых трансляций, как в их документах ниже:

Ограничения Учитывая потенциально большой объем отправляемых данных, запросы на анализ рынка гораздо более ограничены. Как и в случае с запросами исторических данных, количество активных запросов глубины связано с количеством строк рыночных данных, минимум три и максимум 60:

Технических сложностей нет, достаточно запросить тиковые данные по 3-м контрактам одновременно с 3-мя разными reqIds. Мне также нравится инициализировать словарь для хранения информации о контракте для удобства записи данных в базу данных, но не забудьте добавить reqId и контракт в словарь перед запросом данных.

      class BasicApp(EWrapper, EClient):
  def __init__(self):
    EClient.__init__(self,self)
    self.reqId_last_price_dict = {}  # This dictionary uses reqId as key, last price as value
    self.reqId_contract_dict = {}  # This dictionary uses reqId as key, contract as value

  @iswrapper
  def tickPrice(self, reqId: TickerId, tickType: TickType, price: float, attrib: TickAttrib):
    super().tickPrice(reqId, tickType, price, attrib)
    print("Tick Price. Ticker Id:", reqId, "tickType:", tickType, "Price:", price, "CanAutoExecute:", attrib.canAutoExecute, "PastLimit", attrib.pastLimit)
    self.reqId_last_price_dict[reqId] = price  # This line updates the dictionary value with the same reqId whenever a new price returned.
    print('last price for {} is {}.'.format(self.reqId_contract_dict[reqId].symbol, price))
Другие вопросы по тегам