兰森的小红书二维码在小红书打开 →跳到正文
兰森 · PA Research
返回

16 年 ES 一分钟数据:我从哪里获得,又是怎么“清洗”的

目录
  1. 总结
  2. 数据从哪里来
  3. 为什么要用“连续合约”
  4. 价格本身是干净的
  5. 真正的问题:哪些日子不能用
  6. 1. 换合约前后(66 次)
  7. 2. 节假日和半日市(128 天)
  8. 3. 数据有问题的日子(14 天)
  9. 清洗结果
  10. 局限
  11. 我怎么用它
  12. 如何复现

总结

数据从哪里来

CME Globex MDP 3.0 数据集介绍页

CME Globex MDP 3.0 是芝加哥商品交易所(CME)的官方行情数据源,Globex 上交易的所有期货、期权都从这里发出。Databento 从 2010 年 6 月 6 日开始收录这份数据,按用量收费,我当时下载 1 分钟 K 线花了大约 20 美元。

我下载的具体内容:

项目选择
数据集CME Globex MDP 3.0(GLBX.MDP3)
品种ES,E-mini S&P 500 期货
合约ES.c.0,连续合约(见下文)
K 线OHLCV-1m,也就是 1 分钟的开高低收和成交量
时间范围2010-06 ~ 2026-09
格式CSV

为什么要用“连续合约”

ES 不是一个合约,而是每个季度一个:ESZ6 是 2026 年 12 月到期,ESH7 是 2027 年 3 月到期,以此类推。每个合约只在到期前的几个月里是主力。

要研究 16 年的走势,就得把这些合约首尾接起来。ES.c.0 就是 Databento 自动接好的“连续合约”:永远取当前最近到期的那一个,到期后自动换到下一个。这个“自动换”正是后面最大的坑。

价格本身是干净的

我检查了全部约 550 万行 1 分钟 K 线:

检查项结果
缺失值 / 重复时间0 / 0
最高价低于开收盘、最低价高于开收盘0
不在 0.25 最小跳动单位上的价格0
极端大 K 线抽查都对得上真实事件,比如 2020 年熔断、2025-04-09 关税暂停
用 SPY 独立核对(2023–2024,约 8000 根 K 线)ES 与 SPY 的价格比值最大偏离 0.23%,没发现错价

真正的问题:哪些日子不能用

1. 换合约前后(66 次)

ES.c.0 是在交割周五之后的那个周日晚上才换到新合约的。可旧合约在交割周五早上 9:30 就停止交易了,所以:

周四 周五 · 交割 周六 周日 周一 周二 ES.c.0 旧合约 新合约 白盘无数据 周末休市 删除区间 周四 16:15 → 周一 16:15 拼成的夜盘 程序当成同一个夜盘 新旧合约差十几到几十点,最多 224 点:拼出来的周一夜盘高低点是假的
换约那一周。灰色是旧合约,蓝色是新合约,时间按 24 小时等比例画。

处理:每次换约,删掉从周四晚上到换约后周一收盘这一段。周一整天删掉,周二完整保留。

特例:2026 年 6 月的交割日碰上六月节(6/19 周五休市),交割提前到周四,当晚就换了合约,处理时单独考虑。

2. 节假日和半日市(128 天)

其中 5 天正好落在换约的删除区间里,已经随换约一起删掉,所以下面漏斗图里这一类只算 123 天。

3. 数据有问题的日子(14 天)

情况天数例子
数据源中间缺一大段32020-02-28 上午 10:58 之后直到周日晚上都没有数据
夜盘被假期拉长,包含好几个晚上8耶稣受难日股市休市但期货开了早盘;飓风桑迪股市停了两天;两次总统国葬
整天缺失之后的第一天3源数据里 2014 年有 6 个正常交易日整天缺失,它们后面那一天的“昨天”会取错

清洗结果

原始数据里有白盘的日子4129 天

  • 保留3924
  • 换合约前后(66 次)−68
  • 节假日和半日市−123
  • 数据有问题−14
按白盘交易日计,条形长度按天数等比例画。和换约重叠的 5 个节假日只算一次。节假日和半日市本来就不是完整交易日,只看完整交易日的话,4001 天里删掉 77 天,约 2%。
结果
可用交易日3924 天,白盘都覆盖 09:30–16:15;其中 3901 天是完整的 405 根 1 分钟 K 线(5 分钟 81 根),另外 23 天少几根(见“局限”)
损失约 2% 的完整交易日
混入两个合约的夜盘0
包含多个晚上的夜盘0

局限

我怎么用它

以后每一篇研究都基于这份清洗后的数据,文章里不再重复说明。清洗规则写成了一个脚本,有新数据时重新跑一遍即可。

如何复现

Prompt:下载数据

请帮我写一段 Python 代码,从 Databento 下载 ES 期货(标普 500 E-mini)的历史 1 分钟 K 线。要求:
1. 使用官方 databento 库;数据集 GLBX.MDP3(CME Globex MDP 3.0),合约代码 ES.c.0,代码类型 continuous(连续合约),数据格式 ohlcv-1m。
2. 时间从 2010-06-06 到今天。
3. 先用 metadata.get_cost 查询并打印这次下载的费用,等我输入 y 确认后才真正下载,避免误扣费。
4. API 密钥运行时用 getpass 让我手动输入,不要写在代码或文件里。
5. 把结果保存为 CSV,保留 ts_event、instrument_id、open、high、low、close、volume 等原始列,时间保持 UTC。
6. 下载完打印总行数、第一行和最后一行的时间,方便我核对。
7. 每一步都加中文注释,告诉我需要先安装什么(pip install databento)。

Prompt:清洗数据

我有一份 ES 期货 1 分钟 K 线 CSV(Databento 的 ES.c.0 连续合约,时间是 UTC,含 instrument_id 列)。请帮我写 Python 代码完成清洗,规则如下:
1. 把时间转成美东时间(US/Eastern),自动处理夏令时。白盘 RTH = 09:30–16:15(1 分钟 K 线从 09:30 到 16:14,共 405 根);夜盘 ETH = 前一个交易日 16:15 到当天 09:29。
2. 先检查数据质量并打印结果:缺失值、重复时间、最高价低于开收盘或最低价高于开收盘、价格不在 0.25 最小跳动单位上的行数。
3. 删除换合约前后的数据:找出 instrument_id 变化的位置(换约),删掉“交割日前最后一个交易日 16:15”到“换约后第一个交易日 16:15”这一段。交割日一般是第三个周五;如果那天放假,交割会提前一天,要单独处理。
4. 删除节假日和半日市:白盘最后一根 K 线早于 13:30 的日子(股市休市只有期货开盘,或 13:00 提前收盘),同样连前一晚的夜盘一起删。
5. 删除夜盘包含两个及以上晚上的日子(比如耶稣受难日、国葬日股市休市但期货照常交易),以及整天缺失数据之后的第一天。
6. 输出清洗后的 1 分钟数据,并按美东时间合成一份 5 分钟数据(开盘取第一根、最高取最大、最低取最小、收盘取最后一根、成交量求和)。
7. 最后验证并打印:剩下多少个交易日、每天白盘是否完整(405 根 1 分钟 K 线)、有没有任何一天的夜盘混入两个合约。
请每一步加中文注释,说明为什么这样做。

(补充说明:2026 年 10 月补充下载了 2026 年 4–9 月的数据,文中的时间范围和数字已按合并后的数据更新。)


分享这篇文章:

上一篇
机构会专门收割散户吗?用苹果开盘两小时算一笔账
下一篇
ES 一天能走多远:16 年日内波幅的中位数是 0.90%