面向交易机器人的免费财经日历 API
每个自动化策略早晚都要回答同一个问题:接下来半小时有没有新闻?要回答它,得有一份机器能读的财经日历,而这比找日历本身难得多。多数日历只是网页;少数现成的数据源,不是限频,就是收费,要么哪天说没就没了。
这篇指南是那番寻找的精简版,也介绍了我们最后自己做出来、向所有人开放的端点。
🗺️ 机器人现在从哪里拿日历
| 数据源 | 费用 | 能拿到什么 | 问题在哪 |
|---|---|---|---|
Forex Factory 周文件(ff_calendar_thisweek.json,另有 XML 和 CSV) | 免费 | 本周事件、影响级别和预期值 | 每个 IP 地址每五分钟只能下载两次,一台 VPS 上跑很多终端就会超限;文件里没有公布值 |
经纪商的 MT5 日历(MQL5 的 Calendar* 函数) | 免费 | 终端内的完整日历 | 只有 MT5 有;部分经纪商不转发 |
| 抓取日历网站 | 免费,直到哪天不免费 | 页面上有什么就拿什么 | 页面改版、反爬虫、使用条款 |
| 付费行情数据 API | 每月几十美元起 | 历史长、覆盖国家多 | 只为问一句“30 分钟内有没有新闻”,功能太多,价格太贵 |
| 小型个人 API | 免费套餐,需要密钥 | 往往不错 | 背后只有一个人;密钥和限额说变就变 |
这些办法本身都没错,只是各有各的失灵方式。在 VPS 上无人值守的机器人根本察觉不到,直到它在一次利率决议里照常下了单。
🎯 机器人真正需要什么
把问题拆到最简,需求只有几条:
- 只要未来一两天,不是未来一年。过滤器只往前看几个小时。
- 在服务器端过滤:只要机器人交易的货币,只要它关心的影响级别。几 KB 就够,用不着 1 MB。
- UTC 的 Unix 时间戳。任何平台都能比较两个整数;在 MQL 里解析日期,谁都不乐意。
- 一个靠得住的时钟。机器人自己的时钟都靠猜:经纪商时间的时差不明,VPS 的时区不明。日历应该告诉它现在几点,好让它用同一把尺子去比。
- 为轮询而设计。几百个机器人每 15 分钟请求一次,应该算正常流量,而不是滥用。
- 不要密钥,不要账户。多一把密钥,就多一样会泄露、要轮换、要维护的东西。
- 所有平台都能访问,包括那些限制联网的平台。
🔓 端点
GET https://showmytrades.com/api/public/calendar/v1?currency=EUR,USD&impact=high&days=1
| 参数 | 取值 | 默认值 |
|---|---|---|
currency | USD, EUR, GBP, JPY, AUD, NZD, CAD, CHF, CNY 中任选,逗号分隔 | 全部九种 |
impact | high、medium、low、holiday,逗号分隔,或者 all | high |
days | 往后 1 到 30 天;窗口总是从 6 小时前开始 | 1 |
format | json 或 csv | json |
每个事件包含 ts(Unix 秒,UTC)、time(ISO 8601)、currency、impact、title、forecast、previous 和 actual。此外还有:稳定的 id,改期后也不变;status(scheduled;moved,旧时间放在 moved_from;tentative);confidence,表示日期是发布这项数据的机构或央行确认的(official),还是几份相互吻合的日历确认的。另有一个单独的变更列表(changes feed),列出您上次下载之后被改期或取消的事件。每个响应都会用 server_time 给出当前的 UTC 时间:拿 ts 跟它比,而不是跟经纪商或 VPS 的时钟比。只需要时钟的话,GET https://showmytrades.com/api/public/time 会单独返回它,永不缓存。响应缓存 15 分钟,带 ETag;限额是每个 IP 地址每分钟 600 次请求。完整说明见参考页面,其中还有一种专门设计的 CSV 格式,保证 MQL 的 StringSplit() 不会切错。
三种语言,三个调用示例:
curl "https://showmytrades.com/api/public/calendar/v1?currency=USD&impact=high,medium&days=7&format=csv"
import requests
events = requests.get(
"https://showmytrades.com/api/public/calendar/v1",
params={"currency": "EUR,USD", "impact": "high", "days": 2},
timeout=10,
).json()["events"]
next_release = min(events, key=lambda e: e["ts"]) if events else None
const res = await fetch('https://showmytrades.com/api/public/calendar/v1?currency=GBP&impact=high&days=1')
const { events } = await res.json()
const soon = events.filter(e => Math.abs(e.ts * 1000 - Date.now()) < 30 * 60 * 1000)
🔌 各平台的接法
| 平台 | 方式 | 代码 |
|---|---|---|
| MetaTrader 4 | 用 WebRequest(),并把 https://showmytrades.com 加进允许列表 | 只需一个包含文件 SMT_NewsFilter.mqh |
| MetaTrader 5 | 同一个包含文件,或者内置日历 | 内置日历还是 API,两种代码都有 |
| cTrader(桌面版和云端) | 端口 25345 上的 WebSocket,因为 cTrader Cloud 不允许 cBot 发 HTTP 请求 | 一个完整的 C# cBot |
| Python、Node,任何能发 HTTP 的环境 | 上面的端点 | 本页的代码示例 |
| AI 助手(Claude、ChatGPT) | MCP 服务器的 get_economic_calendar 工具,不用密钥 | 直接问:“本周有哪些高影响的 USD 新闻?” |
WebSocket 就是为 cTrader 准备的:云端的 cBot 根本发不了 HTTP 请求,而多数 cTrader 用户都在云端运行。这个 WebSocket 接受同样的四个参数,返回同样的 CSV。
🧭 过滤器怎么设计
API 回答的是什么时候,怎么做由策略决定。常见的选择有:
- 时间窗口。高影响数据公布前后各 30 分钟,是常见的默认值。剥头皮策略会把公布后的窗口拉长;波段系统有时只在公布那一分钟里禁止入场。
- 看哪些货币。所交易货币对的两种货币都要看。黄金和指数通常只看
USD。 - 持仓。不开新仓是容易的那一半。数据公布前平仓或收紧止损,是一个策略决定,有它自己的代价。
- 失败时怎么办。下载失败、手里没有日历时,机器人该照常交易还是等待?要明确定下来;示例代码选择照常交易,而且会把这一点说出来。
⚖️ 这个 API 不是什么
它只是一份时间表:从公开的日历数据源汇总而来,原样提供。数据发布有时会改期或取消,突发公告本来就不可能在表上,影响级别也只是一种分类,不是对行情波动的预测。它是搭建过滤器用的信息,不是交易信号。
❓ 常见问题
真的免费吗?商业机器人也免费? 是的。不要密钥,不要账户,也不分等级。如果能注明出处(Economic calendar by ShowMyTrades,链接到财经日历页面),我们很感谢,但从不强制。
机器人多久调用一次合适?
每 15 分钟一次。这正好是缓存的有效期,日历本身也不会变得更快。带上 If-None-Match,日历没变时这次请求不产生任何开销。
时间用的是哪个时区?
一律是 UTC。ts 是以秒为单位的 Unix 时间;time 是同一时刻的 ISO 8601 写法,末尾带 Z。机器人自己往往不知道现在几点(经纪商时间的时差不明,VPS 的时区不明),所以每个响应都带有 server_time,即当前的 UTC 时间:每次下载时算一次它和您自己时钟的偏差,歧义就没有了。
能拿到历史数据,用来回测新闻过滤器吗? 这个端点不行:窗口只往回看六小时,往后最多 30 天。用于回测的历史日历是另一种产品,条款也不一样。
数据从哪里来? 来自公开的财经日历数据源,由 ShowMyTrades 合并并统一格式。本站的日历页面用的也是这份数据。
🔗 相关内容
知道什么时候该离场观望的机器人,业绩记录才拿得出手。免费连接它,新闻前后那些按兵不动的半小时,会清清楚楚地显示在回撤图表上。