【问题标题】:Stacked data using python IB API使用 python IB API 堆叠数据
【发布时间】:2020-12-06 20:01:04
【问题描述】:

我正在下载 5 只股票('A'、'AAP'、'AAPL'、'ABBV'、'ABC')的 15 年数据(每日收盘价)。问题是我有一些重复。第一个“A”没有问题,我得到了适量的数据。对于第二个“AAP”,我的行数是正确的两倍,似乎数据被下载了两次。最后 3 只股票的相同问题,我的行数是正确的三倍。我附上了显示 csv 文件大小的屏幕截图,如果一切正常,这些文件应该具有相同的大小。
我怀疑问题来自调用 reqHistoricalData 后的 10 秒暂停;可能太长了。如何避免重复行以及如何暂停适当的时间(不要太长也不要太短)?

import pandas as pd
import datetime as dt
import time
import collections
import threading
import os

from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.contract import Contract
from ibapi.common import BarData

path = r"D:\trading\data\debug\\" 

class IBapi(EWrapper, EClient):
    def __init__(self):
        EClient.__init__(self, self)
        self.data=collections.defaultdict(list)

    def nextValidId(self, orderId: int):
        super().nextValidId(orderId)
        self.nextorderId = orderId
        print('The next valid order id is: ', self.nextorderId)

    def error(self, reqId, errorCode, errorString):
        super().error(reqId, errorCode, errorString)
        print("Error. Id:", reqId, "Code:", errorCode, "Msg:", errorString)
        
    def historicalData(self, reqId:int, bar:BarData):
        self.data["date"].append(bar.date)
        self.data["close"].append(bar.close)
        self.df = pd.DataFrame.from_dict(self.data)

tickers = ["A","AAP","AAPL","ABBV","ABC"]

def run_loop():
    app.run()


app = IBapi()
app.connect("127.0.0.1", 7496, 5)
app.nextorderId = None

# Start the socket in a thread
api_thread = threading.Thread(target=run_loop, daemon=True)
api_thread.start()

# Check if the API is connected via orderid
while True:
    if isinstance(app.nextorderId, int):
        print('connected')
        break
    else:
        print('waiting for connection')
        time.sleep(1)
        
n_id = app.nextorderId

for ticker in tickers:    
    contract = Contract()
    contract.symbol = ticker
    contract.secType = "STK"
    contract.exchange = "SMART"
    contract.currency = "USD" 

    app.reqHistoricalData(n_id, contract, "","15 Y", "1 day", "TRADES", 1, 1, False, [])
    time.sleep(10)
    app.df.to_csv(path + ticker + ".csv")
        
    n_id = n_id + 1
    

app.disconnect()

【问题讨论】:

    标签: python interactive-brokers tws ib-api


    【解决方案1】:

    您没有在请求之间清除列表。

    def historicalData(self, reqId:int, bar:BarData):
            # just keeps adding data to list
            self.data["date"].append(bar.date)
            self.data["close"].append(bar.close)
            # makes a new dataframe on every single bar
            self.df = pd.DataFrame.from_dict(self.data)
    

    historicalDataEnd 方法中,您可以创建一个数据框并将其保存到文件中。制作一个代码和 reqId 的字典,这样你就知道哪个代码完成了。

    在调步调用之间仍然应该有 10 秒的延迟,但不要指望在 10 秒内返回数据。如果它没有到达,您将获得一个空文件(或者在您的情况下,所有以前的代码数据,这似乎发生在 ABC 中)。

    【讨论】:

    • 有没有办法将 n_id 连同日期/价格一起放入 csv 文件或数据框中?我正在做类似的事情并设置了字典,但每个股票代码的唯一值 id 用于 api 的 IBKR 输出
    • @John 提出另一个问题并显示您正在使用的代码。没有理由你不能在 historyData 回调中只执行 `self.data["id"].append(reqId)' ,然后你会在每个柱上获得 id。它实际上只是一个使用号码,可能无论如何都不应该保存。解释你想要做什么。
    • 非常感谢您的帮助,我已将我的问题发布到。是的,ReqId 可能是票,但我仍然无法弄清楚如何在传递到输出的 reqid 变量中应用唯一 ID。您可以提供的任何其他帮助都很棒! :stackoverflow.com/questions/65533454/…
    【解决方案2】:

    您的副本每周五来。您提出一个请求,比如说星期五(第一次迭代),然后在接下来的 2 次迭代(星期六和星期日)中,API 从第一个可能的交易日(上星期五)返回数据。否则 5 秒就足够等待了。

    【讨论】:

      猜你喜欢
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 2021-05-28
      • 2017-08-09
      • 2021-11-26
      • 2014-08-26
      相关资源
      最近更新 更多