【问题标题】:Getting Interactive Brokers API into Pandas将 Interactive Brokers API 导入 Pandas
【发布时间】:2019-09-05 05:38:12
【问题描述】:

Python 和 IB API 的新手,坚持这个简单的事情。 This application 工作正常并打印 IB 服务器回复。但是,我无法弄清楚如何将这些数据放入熊猫的数据框或任何其他变量中。您如何“获取数据”?谢谢!

在论坛、文档或 youtube 上我找不到任何有用的示例。我认为答案必须是将 accountSummary 返回到 pd.Series,但不知道如何。

预期的输出将是可以在应用程序之外进行操作的数据系列或变量。

from ibapi import wrapper
from ibapi.client import EClient
from ibapi.utils import iswrapper #just for decorator
from ibapi.common import *
import pandas as pd

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

    @iswrapper
    def nextValidId(self, orderId:int):
        print("setting nextValidOrderId: %d", orderId)
        self.nextValidOrderId = orderId
        # here is where you start using api
        self.reqAccountSummary(9002, "All", "$LEDGER")

    @iswrapper
    def error(self, reqId:TickerId, errorCode:int, errorString:str):
        print("Error. Id: " , reqId, " Code: " , errorCode , " Msg: " , errorString)

    @iswrapper
    def accountSummary(self, reqId:int, account:str, tag:str, value:str, currency:str):
        print("Acct Summary. ReqId:" , reqId , "Acct:", account, 
            "Tag: ", tag, "Value:", value, "Currency:", currency)
    #IB API data returns here, how to pass it to a variable or pd.series

    @iswrapper
    def accountSummaryEnd(self, reqId:int):
        print("AccountSummaryEnd. Req Id: ", reqId)
        # now we can disconnect
        self.disconnect()

def main():
    app = TestApp()
    app.connect("127.0.0.1", 4001, clientId=123)
    test = app.accountSummary
    app.run()

if __name__ == "__main__":
    main()

【问题讨论】:

    标签: python-3.x pandas api interactive-brokers


    【解决方案1】:

    嗨,我遇到了同样的问题,而 collections 为我解决了这个问题。这是我的差价合约数据代码。也许它会帮助某人。您将在 app.df 中获得您的数据。任何改进建议都非常受欢迎。

    import collections
    import datetime as dt
    from threading import Timer
    from ibapi.client import EClient
    from ibapi.wrapper import EWrapper
    from ibapi.contract import Contract
    import pandas as pd
    
    # get yesterday and put it to correct format yyyymmdd{space}{space}hh:mm:dd
    yesterday = str(dt.datetime.today() - dt.timedelta(1))
    yesterday = yesterday.replace('-','')
    
    IP = '127.0.0.1'
    PORT = 7497
    
    class App(EClient, EWrapper):
    
        def __init__(self):
            super().__init__(self)
            self.data = collections.defaultdict(list)
        
        def error(self, reqId, errorCode, errorString):
            print(f'Error {reqId}, {errorCode}, {errorString}')
        
        def historicalData(self, reqId, bar):
            self.data['date'].append(bar.date)
            self.data['open'].append(bar.open)
            self.data['high'].append(bar.high)
            self.data['low'].append(bar.low)
            self.data['close'].append(bar.close)
            self.data['volume'].append(bar.volume)
            self.df = pd.DataFrame.from_dict(self.data)
    
        def stop(self):
            self.done = True
            self.disconnect()
    
    # create App object
    app = App()
    print('App created...')
    app.connect(IP, PORT, 0)
    print('App connected...')
    
    # create contract
    contract = Contract()
    contract.symbol = 'IBDE30'
    contract.secType = 'CFD' 
    contract.exchange = 'SMART' 
    contract.currency = 'EUR' 
    print('Contract created...')
    
    # request historical data for contract
    app.reqHistoricalData(reqId=1, 
                        contract=contract, 
                        endDateTime=yesterday,
                        durationStr='1 W',  
                        barSizeSetting='15 mins', 
                        whatToShow='ASK', 
                        useRTH=0, 
                        formatDate=1, 
                        keepUpToDate=False, 
                        chartOptions=[])
    
    Timer(4, app.stop).start()
    app.run()
    

    【讨论】:

      【解决方案2】:

      我会将数据存储到字典中,从字典中创建一个数据帧,然后使用 concat 函数将新数据帧附加到主数据帧。这是一个例子:

      def accountSummary(self, reqId:int, account:str, tag:str, value:str, currency:str):
          acct_dict = {"account": account, "value": value, "currency": currency}
          acct_df = pd.DataFrame([acct_dict], columns=acct_dict.keys())
          main_df = pd.concat([main_df, acct_df], axis=0).reset_index()
      

      更多信息,您可能喜欢Algorithmic Trading with Interactive Brokers

      【讨论】:

      • 马特,你能澄清一下吗?您的解决方案似乎引发了错误,因为我认为 api 是异步的。从那以后,我看到的唯一从线程中获取数据的是 queue.Queue,但我只能取出队列中的最后一项。不过感谢您的回复。我没有在您的书中看到队列,但会记住以供将来参考。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多