跳转到内容

历史日期格式

历史行情最容易让新手困惑的地方之一是时间。reqHistoricalData()reqHeadTimeStamp() 这类接口既要你传入请求结束时间,也会在回调里返回 K 线时间。如果请求时间和返回时间没有统一时区,回测结果很容易差一小时、差一天,或者在夏令时切换附近错位。

官方参考:

字段出现位置中文解释
endDateTimereqHistoricalData()历史行情请求的结束时间;传空字符串通常表示“截至 TWS 可用的最新时间”
formatDatereqHistoricalData() / reqHeadTimeStamp()控制返回日期格式,常用 1 返回可读日期字符串,2 返回 Unix 秒级时间戳
bar.datehistoricalData() 回调每根历史 K 线的时间标签
headTimestampheadTimestamp() 回调某个合约、数据类型最早可用历史数据时间
写法示例适合场景
操作者时区20260612 15:59:00只在同一台 TWS、同一时区手工测试
交易所时区20260612 15:59:00 US/Eastern股票、期权、期货等按交易所日历分析
UTC20260612-19:59:00后端服务、跨市场系统、数据库统一存储

对新手来说,推荐先用交易所时区写清楚,例如美股 AAPL 使用 US/Eastern。这样时间字符串一眼能看出是在美股交易时段,而不是电脑所在时区或服务器时区。

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=True
FORMAT_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|1781276400
DONE_FLAGS=97101,97102
NON_INFO_ERROR_COUNT=0

这个结果说明:当请求和返回都带 US/Eastern 时,读者可以直接把它理解成美股交易所时间,而不需要猜测电脑所在时区。使用 Unix 秒级时间戳时,程序应在入库或展示层明确转换时区。

建议原因
请求时间尽量写完整避免 TWS 按默认时区解释
数据库存 UTC方便跨市场、跨服务器、跨夏令时处理
页面展示再转交易所时区用户看盘通常按交易所时间理解
不要混用多种格式同一套脚本里混用容易产生隐性偏移