交互式经纪商逐笔数据

问题描述 投票:0回答:2

我正在尝试从 Interactivebrokers/TWS 获取一天的报价数据,这是我编写的函数:

def ticker_data(ticker, start, end='',numberOfTicks=1000, Exchange='SMART', Currency='USD', ip='127.0.0.1', port=7496, clientId=1):
ib = IB()
ib.connect(ip, port, clientId=clientId)

contract = Stock(ticker, Exchange, Currency)

real_end = start
df = pd.DataFrame()

while end != real_end:
    ticks = ib.reqHistoricalTicks(contract,
                                  startDateTime=real_end,
                                  endDateTime=end,
                                  numberOfTicks=numberOfTicks,
                                  whatToShow='TRADES',
                                  useRth=True)

    df = pd.concat([df, util.df(ticks)], ignore_index=True)
    print("Latest time in DataFrame:", df.iloc[-1]['time'])
    print("Updated real_end_1:", real_end)
    print("End time:", end)
    print("length of recived_data:", len(ticks))
    print()


    real_end = datetime.strptime(str(df.iloc[-1]['time']), "%Y-%m-%d %H:%M:%S%z").strftime("%Y%m%d %H:%M:%S")#+' US/Eastern'

ib.disconnect()
return df

这是我的称呼方式:

from functions.simple_ib_data import ticker_data
from datetime import datetime, timedelta

import pandas as pd

start = (datetime.now() - timedelta(days=1)).replace(hour=9, minute=30, second=0, microsecond=0).strftime("%Y%m%d %H:%M:%S")
end = (datetime.now() - timedelta(days=1)).replace(hour=23, minute=59, second=59, microsecond=0).strftime("%Y%m%d %H:%M:%S")

data = ticker_data(ticker="NCLH", start=start, end=end)
print(data)

所以我认为它会像这样工作: 我得到 1000 个刻度数据,然后从收到的最新刻度中获取时间 使其成为新请求的开始并重复直到到达结束

问题: 我认为有一分钟女巫的开始时间与结束时间相同,所以我遇到了这个“cicle”,其中最新滴答的时间与第一次滴答的时间相同,所以输出如下所示:

DataFrame 中的最新时间:2023-12-01 14:33:35+00:00 更新了 real_end_1: 20231201 09:30:00 结束时间:20231201 23:59:59 receive_data 长度:1007

DataFrame 中的最新时间:2023-12-01 14:33:35+00:00 更新了 real_end_1: 20231201 14:33:35 结束时间:20231201 23:59:59 receive_data 长度:1007

DataFrame 中的最新时间:2023-12-01 14:33:35+00:00 更新了 real_end_1: 20231201 14:33:35 结束时间:20231201 23:59:59 receive_data 长度:1007

(并且永远重复)

我正在使用 ib_insync

任何帮助都非常感激。

python stock interactive-brokers ib-insync
2个回答
0
投票

IBAPI 是一个多进程系统。它使用 2 个线程。一种是向IBAPI发送请求,另一种是接收数据。两项操作同时进行。 因此,您必须发送第一个请求并等待接收数据并从接收到的数据中获取最后一个时间戳,然后您可以从最后接收到的数据中获取新的开始时间。 使用 While 循环无法实现此目的。 您将必须采用一种切换机制,在该机制中您将发送请求并使用一些布尔运算结束第一个请求,一旦收到数据,您就可以进行下一个调用。 因此,您必须重新审视您的策略。 While 循环将最终阻塞线程。 您必须拆分程序并执行它。


0
投票

当最新的tick时间与前一个请求的结束时间相同时,就会出现问题,导致无限循环。要解决此问题,您可以修改 real_end 变量以添加较小的时间增量以避免重叠。这是带有虚拟示例的更新代码:

` 从 ib_insync 导入 IB、Stock、util 从日期时间导入日期时间,时间增量 将 pandas 导入为 pd

defticker_data(ticker, start, end='', numberOfTicks=1000, Exchange='SMART', 货币='USD', ip='127.0.0.1', port=7496, clientId=1): ib = IB() ib.connect(ip, 端口, clientId=clientId)

contract = Stock(ticker, Exchange, Currency)

real_end = start
df = pd.DataFrame()

while real_end < end:
    ticks = ib.reqHistoricalTicks(contract,
                                  startDateTime=real_end,
                                  endDateTime=end,
                                  numberOfTicks=numberOfTicks,
                                  whatToShow='TRADES',
                                  useRth=True)

    if len(ticks) > 0:
        df = pd.concat([df, util.df(ticks)], ignore_index=True)
        print("Latest time in DataFrame:", df.iloc[-1]['time'])
        print("Updated real_end:", real_end)
        print("End time:", end)
        print("Length of received_data:", len(ticks))
        print()

        latest_time = datetime.strptime(str(df.iloc[-1]['time']), "%Y-%m-%d %H:%M:%S%z")
        real_end = (latest_time + timedelta(seconds=1)).strftime("%Y%m%d %H:%M:%S")
    else:
        break

ib.disconnect()
return df

虚拟示例

start = (datetime.now() - timedelta(天=1)).replace(小时=9, 分钟=30, 秒=0, 微秒=0).strftime("%Y%m%d %H:%多发性硬化症”) end = (datetime.now() - timedelta(天=1)).replace(小时=23,分钟=59,秒=59,微秒=0).strftime("%Y%m%d %H:%M :%S")

数据=ticker_data(ticker=“AAPL”,开始=开始,结束=结束) 打印(数据) ` 对代码的主要修改是:

添加了条件 real_end < end in the while loop to ensure it stops when real_end reaches or exceeds end. Added a check if len(ticks) > 0 来处理未收到报价的情况。 修改了 real_end 更新,使用 timedelta(seconds=1) 添加 1 秒的小时间增量,以避免重叠问题。

我还提供了一个使用“AAPL”作为股票代码的虚拟示例。请注意,您需要与盈透证券的 TWS 或 IB 网关建立有效连接,并拥有必要的市场数据订阅才能检索报价数据。

代码现在将以 1000 个刻度为单位检索刻度数据,以较小的增量更新 real_end 时间,并继续,直到达到指定的结束时间或没有更多可用的刻度。

© www.soinside.com 2019 - 2024. All rights reserved.