Open Exchange Rates 替代方案:当免费套餐只认 USD 的时候
Open Exchange Rates 免费套餐每月给你 1,000 次请求,但每一次都是以 USD 报价的。没有换算端点,没有时间序列,也没有其他基础货币,除非你每月付 $12 起。以下是这实际上意味着什么代价,以及另外四个可以考虑的方向。
你仍然可以从一个仅限 USD 的免费套餐算出 EUR/GBP 或任意交叉汇率。取 USD 汇率,一个除以另一个,交叉汇率就出来了。 这个办法可行。但也意味着代码里多一个要处理的字段、多一步除法,以及第三位小数上一点点会累积的舍入误差——大多数开票场景根本不会注意到,但有些对账工作会。
免费套餐的边界在哪里
Open Exchange Rates 给免费账号每月 1,000 次请求,每小时更新汇率,并包含每日历史数据。问题在于:每条响应都以 USD 报价,免费套餐上没有办法更改这一点。请求 base=EUR 时,API 会忽略这个参数或报错,取决于具体端点。
免费套餐还完全排除了 /convert 和时间序列调用。这两个都被锁定在付费套餐之后,付费套餐从每月 $12 起,直接解锁基础货币参数,外加换算和时间序列功能,可用于任意数量的基础货币,不额外收费。
老老实实说说 USD 基础货币的变通办法
如果你被困在免费套餐上又需要 EUR/GBP 汇率,还不用急着付费。响应中的每种货币都以 USD 报价,所以 EUR/GBP 就是 rates.GBP / rates.EUR——你自己做一遍原本该由 API 完成的除法。
有两件事需要预先考虑。代码方面:每个非 USD 货币对现在都需要一步除法,以及对缺失值或零值的保护。舍入方面:把两个已经四舍五入过的 USD 报价相除,会引入比直接对该基础货币取汇率更大的一点累积误差——对仪表盘来说无关紧要,但对精确到第四位小数的对账工作来说不是。
/convert 没有像基础货币那样干净的自己动手替代方案。时间序列意味着每天循环调用一次历史端点,很快就会耗尽 1,000 次的请求预算——比基础货币这堵墙更难绕过。另外四个可以考虑的方向
Frankfurter——免费、开源、无需密钥,仅限 ECB
Frankfurter 把欧洲央行的参考汇率封装进一个 JSON API。任何套餐都不需要 API 密钥,也没有强制配额,而且它是开源的。代价在于数据本身:ECB 汇率每个营业日发布一次,约在 16:00 CET,周末完全没有数据。如果每日一次的营业日定盘价能满足你的场景,Frankfurter 完全免费,也不需要注册。
ExchangeRate-API 开放访问——免费、无需密钥、每天更新
ExchangeRate-API 在 open.er-api.com 运行了一个真正无需密钥的端点。不用注册,不用 API 密钥。它每天更新一次,和 Frankfurter 处在同一个新鲜度等级。附带两个条件:可见的署名("Rates By Exchange Rate API" 并链接到 exchangerate-api.com)以及不得转发原始数据,不过缓存供自己应用使用是允许的。超出限制会返回 HTTP 429,20 分钟后解除;开放访问之上还有一个带密钥的免费套餐,每月 1,500 次请求。
Fixer——免费、需要密钥、仅限 EUR,100 次调用
Fixer 即便在免费套餐上也需要密钥,而且该套餐仅以 EUR 为基础货币——其他任何基础货币,加上换算功能,都被锁定在 Basic 及以上套餐。配额是每月 100 次调用,比 Open Exchange Rates 紧了一个数量级。免费套餐确实包含每小时更新、SSL 和完整历史数据。
exchangerate.dev——免费、需要密钥、任意基础货币、盘中更新
这里的免费版每月运行 465 个货币对,共 10,000 次调用,每分钟 12 个请求,无需信用卡。任何套餐都没有基础货币限制——EUR 基础货币和 USD 基础货币同样免费——追溯至 1999 年的完整每日历史数据也免费包含在内。主要货币对在交易日大约每 60 秒更新一次;其余货币对由 ECB 或 FRED 每日参考汇率支撑。匿名、无密钥调用同样可用,便于快速评估,按 IP 限速。
把套餐和任务对上号
一个只需要周一到周五收盘汇率的批处理任务,有三个免费、无需注册的选择:Frankfurter、ExchangeRate-API 开放访问,或者上面那个 USD 变通方案。需要周六汇率、或者需要 base 参数直接可用的项目,就得跳过仅限 ECB 的来源。要在交易时段内报出实时价格,则需要一个盘中更新的数据源。
USD 基础货币的变通方案不是一个你要永远绕开的缺陷——它是一步今天就能上线、等舍入误差真正成问题时再重新考虑的除法。