Данные по портфелю, информация об аккаунте

Общие вопросы

Несколько функций в API подписываются на обновления позиции. Каждый из них следует модели «подписаться и опубликовать», когда делается первоначальный запрос на подписку, затем TWS отправляет полный список всех позиций, соответствующих запросу, а затем продолжает отправлять обновления списка по мере их появления в режиме реального времени. пока подписка не будет отменена.
  1. reqAccountUpdates вызывает возврат информации о позиции и учетной записи для указанной учетной записи. Его можно использовать только с одной учетной записью одновременно.
  2. reqPositions подписывается на обновления позиций до 50 учетных записей одновременно.
  3. reqPositionsMulti подписывается на обновления позиций в учетной записи и/или модельном портфеле.
Важно иметь в виду, что из TWS API доступна только информация о текущих позициях аккаунта, поскольку это единственные данные, доступные в TWS по умолчанию. Информацию об исторических позициях счета можно получить с помощью гибких запросов или выписок в «Управлении счетом»(Account Management). Распространенная путаница связана с остатками денежных средств. Виртуальные денежные позиции, которые не представляют собой реальные денежные остатки, а являются лишь закладками, используемыми форекс-трейдерами для отслеживания сделок, возвращаются с информацией о позиции и представлены форекс-парой, например. евро.доллар США. Реальные остатки денежных средств возвращаются вместе с информацией о счете, обсуждаемой далее, в одной валюте, а не в паре.
Информация об учетной записи, такая как чистая ликвидность, остатки денежных средств в разных валютах и данные о необходимой марже, возвращается после вызова нескольких различных функций:
  1. reqAccountUpdates, упомянутый ранее, одновременно запрашивает информацию о позиции и учетной записи для одной учетной записи.
  2. reqAccountSummary можно использовать для подписки на обновления данных учетной записи сразу для нескольких учетных записей.
  3. reqAccountSummaryMulti можно использовать для подписки на обновления стоимости учетной записи для конкретной учетной записи или модели портфеля.
Данные учетной записи, запрашиваемые с помощью этих функций, совпадают с данными, отображаемыми в окне учетной записи TWS. При запросе данных счета из API изначально возвращается полный список всех типов данных (ключей счета), а затем отправляются обновления либо при наличии сделки, либо при изменении значения за три минуты. Это соответствует тому же шаблону обновления в окне учетной записи TWS.

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from threading import Timer

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

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

    def nextValidId(self, orderId):
        self.start()

    def updatePortfolio(self, contract: Contract, position: float, marketPrice: float, marketValue: float,
                        averageCost: float, unrealizedPNL: float, realizedPNL: float, accountName: str):
        print("UpdatePortfolio.", "Symbol:", contract.symbol, "SecType:", contract.secType, "Exchange:", contract.exchange,
              "Position:", position, "MarketPrice:", marketPrice, "MarketValue:", marketValue, "AverageCost:", averageCost,
              "UnrealizedPNL:", unrealizedPNL, "RealizedPNL:", realizedPNL, "AccountName:", accountName)

    def updateAccountValue(self, key: str, val: str, currency: str, accountName: str):
        print("UpdateAccountValue. Key:", key, "Value:", val, "Currency:", currency, "AccountName:", accountName)

    def updateAccountTime(self, timeStamp: str):
        print("UpdateAccountTime. Time:", timeStamp)

    def accountDownloadEnd(self, accountName: str):
        print("AccountDownloadEnd. Account:", accountName)

    def start(self):
        # Account number can be omitted when using reqAccountUpdates with single account structure
        self.reqAccountUpdates(True, "")

    def stop(self):
        self.reqAccountUpdates(False, "")
        self.done = True
        self.disconnect()

def main():
    app = TestApp()
    app.nextOrderId = 0
    app.connect("127.0.0.1", 7497, 0)

    Timer(5, app.stop).start()
    app.run()

if __name__ == "__main__":
    main()

В этом примере показано, как reqAccountUpdates запускает подписку на обновления позиции и значения счета. Существуют обратные вызовы для updateAccountValue с каждым значением учетной записи, за которыми следуют обратные вызовы для updatePortfolio с каждой позицией. После начальных обратных вызовов возвращаются данные для всех ключей учетных записей, есть обратный вызов на accountDownloadEnd. Позже есть отдельные обратные вызовы для элементов, которые изменились.