历史日期格式
历史行情最容易让新手困惑的地方之一是时间。reqHistoricalData()、reqHeadTimeStamp() 这类接口既要你传入请求结束时间,也会在回调里返回 K 线时间。如果请求时间和返回时间没有统一时区,回测结果很容易差一小时、差一天,或者在夏令时切换附近错位。
官方参考:
| 字段 | 出现位置 | 中文解释 |
|---|---|---|
endDateTime | reqHistoricalData() | 历史行情请求的结束时间;传空字符串通常表示“截至 TWS 可用的最新时间” |
formatDate | reqHistoricalData() / reqHeadTimeStamp() | 控制返回日期格式,常用 1 返回可读日期字符串,2 返回 Unix 秒级时间戳 |
bar.date | historicalData() 回调 | 每根历史 K 线的时间标签 |
headTimestamp | headTimestamp() 回调 | 某个合约、数据类型最早可用历史数据时间 |
三种常见写法
Section titled “三种常见写法”| 写法 | 示例 | 适合场景 |
|---|---|---|
| 操作者时区 | 20260612 15:59:00 | 只在同一台 TWS、同一时区手工测试 |
| 交易所时区 | 20260612 15:59:00 US/Eastern | 股票、期权、期货等按交易所日历分析 |
| UTC | 20260612-19:59:00 | 后端服务、跨市场系统、数据库统一存储 |
对新手来说,推荐先用交易所时区写清楚,例如美股 AAPL 使用 US/Eastern。这样时间字符串一眼能看出是在美股交易时段,而不是电脑所在时区或服务器时区。
Python 示例
Section titled “Python 示例”app.reqHistoricalData( 97001, # reqId:请求编号 contract, # contract:合约对象 "20260612 15:59:00 US/Eastern", # endDateTime:明确写交易所时区 "2 D", # durationStr:向前取 2 天 "1 hour", # barSizeSetting:每根 K 线 1 小时 "TRADES", # whatToShow:成交数据 1, # useRTH:只使用常规交易时段 1, # formatDate:返回可读日期字符串 False, # keepUpToDate:只要历史数据,不持续更新 [], # chartOptions:普通请求为空)使用 AAPL 请求 1 天、1 小时 K 线时,formatDate=1 回调里返回的日期包含交易所时区:
CONNECTED=TrueFORMAT_DATE_1_ROWS=20260612 09:30:00 US/Eastern|20260612 10:00:00 US/Eastern|20260612 11:00:00 US/Eastern同一个请求把 formatDate 改成 2,返回的是 Unix 秒级时间戳:
FORMAT_DATE_2_ROWS=1781271000|1781272800|1781276400DONE_FLAGS=97101,97102NON_INFO_ERROR_COUNT=0这个结果说明:当请求和返回都带 US/Eastern 时,读者可以直接把它理解成美股交易所时间,而不需要猜测电脑所在时区。使用 Unix 秒级时间戳时,程序应在入库或展示层明确转换时区。
| 建议 | 原因 |
|---|---|
| 请求时间尽量写完整 | 避免 TWS 按默认时区解释 |
| 数据库存 UTC | 方便跨市场、跨服务器、跨夏令时处理 |
| 页面展示再转交易所时区 | 用户看盘通常按交易所时间理解 |
| 不要混用多种格式 | 同一套脚本里混用容易产生隐性偏移 |