reqMktData () - как отправить новый запрос снимка после вызова app.run ()? - PullRequest
1 голос
/ 28 апреля 2020

Как новые reqMktData() запросы могут быть поставлены в очередь после того, как app.run() был вызван, и сообщение l oop вращается?

Небольшая предыстория, запросы рыночных данных моментального снимка от API TWS следуют этому pattern:

  1. Создание объекта контракта
  2. Вызов reqMktData() для запроса очереди, передача объекта контракта,
  3. Вызов app.run() для запуска сообщения l oop
  4. Получение снимка рыночных данных в обратном вызове
  5. Сообщение l oop вращается ... но ничего нового не поступало, поскольку запросы были для снимка.

... есть ли и принятая идиома о том, как новые запросы могут быть поставлены в очередь в вращающемся сообщении l oop? Как это можно сделать? Мои идеи были:

a. Взломайте метод app.runclient.py), добавьте таймер истечения и повторно вызывайте app.run() для каждого нового запроса. Мех.
б. Создайте отдельный поток для очередей новых запросов
c. Очередь новых запросов в функции обратного вызова (здесь tickprice)
d. Вызвать app.run() в отдельном потоке и reqMktData() новые запросы в главном потоке.

Tyvm, Keith: ^)

Пример минимального, проверяемого и полного

import ...

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

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

    @iswrapper
    # ! [tickprice]
    def tickPrice(self, reqId: TickerId, tickType: TickType, price: float,
                  attrib: TickAttrib):
        super().tickPrice(reqId, tickType, price, attrib)
        print(f"~~> {reqId}, {tickType}, {price}")


def main():
    app = Goose()
    app.connect("127.0.0.1", 7496, 0)
    print("serverVersion:%s connectionTime:%s" % (app.serverVersion(), app.twsConnectionTime()))

    a = Contract()
    a.symbol = "AAPL"
    a.secType = "STK"
    a.exchange = "SMART"
    a.currency = "USD"
    a.primaryExchange = "NASDAQ"

    # Queue request. Note "True" setting for MD snapshot (not streaming)
    app.reqMktData(1000, a, "", True, False, [])

    # Enter event loop
    app.run()

    # Sleep 3 seconds, then make a request for MSFT data.
    # NEVER EXECUTES - Main thread with app.run() event loop spinning.
    time.sleep(3)
    m = Contract()
    m.symbol = "AAPL"
    m.secType = "STK"
    m.exchange = "SMART"
    m.currency = "USD"
    m.primaryExchange = "NASDAQ"
    app.reqMktData(1001, m, "", True, False, [])

if __name__ == "__main__":
    main()
...