跳转到内容

历史行情

历史行情用于一次性查询某个合约过去一段时间的数据。它和实时行情不同:实时行情是持续推送,历史行情是发出请求后返回一批结果,结束后通过回调通知本次请求完成。

历史行情最常见的用途包括:

  • 拉取 K 线,用于图表、回测和策略信号计算。
  • 查询某个合约最早可用历史数据时间。
  • 获取历史逐笔成交或历史 bid/ask。
  • 检查不同 whatToShow 数据类型的返回差异。
  • 理解时间格式、交易所时区和 UTC 存储口径。
目标方法主要回调
历史 K 线reqHistoricalData()historicalData()historicalDataEnd()
取消历史 K 线cancelHistoricalData()无固定结束回调,通常由程序清理状态
最早可用数据点reqHeadTimeStamp()headTimestamp()
取消最早时间请求cancelHeadTimeStamp()无固定结束回调
历史逐笔数据reqHistoricalTicks()historicalTicks()historicalTicksBidAsk()historicalTicksLast()
直方图数据reqHistogramData()histogramData()

大多数开发者会先从 reqHistoricalData() 开始,因为它最容易理解,也最常用于图表和回测。

reqHistoricalData() 的核心参数是:

参数中文含义示例
contract要查询的合约AAPL 股票 Contract
endDateTime结束时间"" 表示使用 TWS 可用的最新时间
durationStr向前查询多长时间1 D1 W1 M
barSizeSetting每根 bar 的周期5 mins1 hour1 day
whatToShow数据口径TRADESMIDPOINTBIDASK
useRTH是否只要常规交易时段1 常规时段,0 包含盘前盘后
formatDate返回时间格式1 可读字符串,2 Unix 时间戳
keepUpToDate是否持续更新最后一根 bar历史回填用 False

新手最容易错的是把 durationStrbarSizeSetting 组合得过大。例如请求很长时间范围的 1 秒线,容易触发历史数据限制或等待很久。应先用小范围确认字段,再扩大请求范围。

历史行情不等于完全绕过行情权限。不同产品、交易所、数据类型和账户订阅状态都会影响返回结果。

现象常见原因
返回 200合约定义不准确,或 TWS 找不到该证券定义。
返回 162历史数据服务拒绝请求,常见于权限、范围、限频或无数据。
返回 10089API 行情需要额外订阅。
返回空数组该时间范围、数据类型或产品没有可用数据。
只返回部分数据请求范围过大、数据被过滤,或产品历史数据不完整。

如果普通模拟账户遇到权限不足,不要把示例改成假成功。文档和程序都应说明:合约能识别、连接正常,但账户缺少对应数据权限。

历史行情一定要重视时区。TWS 可能返回交易所时区、操作员时区或 UTC 相关格式。正式系统建议:

  • 展示给用户时,使用交易所时区或用户选择的时区。
  • 写入数据库时,保存 UTC 或明确带时区的时间。
  • 回测时固定 useRTHformatDatewhatToShow,避免不同数据口径混用。
  1. 先用 reqContractDetails() 确认合约。
  2. reqHistoricalData() 请求 AAPL 这类高流动性股票的 1 D + 5 mins + TRADES
  3. historicalDataEnd() 后再处理结果。
  4. 对比 useRTH=1useRTH=0
  5. 再学习 whatToShow、历史逐笔、最早可用数据点和限频规则。