将 HFT 从 Python 迁移到 Go 1.24:Swiss Tables 如何消除我们的延迟峰值(-41%)

发布: (2026年2月17日 GMT+8 19:03)
5 分钟阅读
原文: Dev.to

Source: Dev.to

如果你在 2026 年使用 Python 运行交易机器人,你很可能在支付一笔你负担不起的延迟税。
我们是吃了苦头才学到的。

我和我的朋友花了数月时间与 J.P. Morgan 和社区所谓的 Infrastructure Hell(基础设施地狱)搏斗。我们从大家都从的地方开始:Python(使用像 CCXT 这样的库和 Freqtrade 这样的框架)。它在原型开发时运行良好,但当我们扩展到同时处理来自七大交易所(Binance、OKX、Bybit、Kraken、Gate.io、Bitget、KuCoin)的 tick 数据时,问题就显现出来了。

基础设施地狱

内存泄漏

watchOrderBook 缓存中的慢性内存累积导致 RSS 增长,约五天后使我们的容器崩溃。

GIL 与抖动

处理 > 40 k WebSocket 消息 / 秒 时阻塞了全局解释器锁,产生了“幻影延迟”:价格更新已到达,但解释器无法足够快地分发它们。

我们需要一种具有真正并行调度能力的编译语言,于是我们选择了 Go 1.24(感谢 Google!)。

Go 1.24 中的 Swiss Tables

对我们来说最关键的改进是基于 Swiss Tables 的新 map 实现。我们的系统维护着大量内存中的 ticker 状态(存放在类似 tk:SYMBOL 的 Redis 键中),导致 map 性能成为瓶颈。

Benchmark results (new engine vs. Python monolith)

指标之前之后Δ
Map 插入时间103.01 ms60.78 ms‑41 %
Map 查询时间318.45 ms240.22 ms‑25 %
内存占用726 MiB217 MiB‑70 %

通过利用元数据指纹和 SIMD 指令,我们有效地消除了过去困扰抖动缓冲区的 GC 暂停。

架构 – MIE 流水线

MIE Pipeline diagram

收集器(Ingestor)

  • 维持到七个交易所的持久 WebSocket 连接。
  • 将“脏” tick 规范化为统一的结构体。
  • 使用热存储策略:对 Redis 键 tk:SYMBOL 执行原子 HSET 操作,保证亚毫秒级快照。
  • 使用内部时间戳对事件进行排序,以校正交易所时钟漂移,然后发布到 Pub/Sub NEW_CANDLE:*

大脑

  • 订阅 Redis 流并执行大量服务器端计算(RSI、MACD、Pearson 相关系数)。
  • 实现 8 个并发 goroutine 的工作池模式。
  • 以 100 条为一批、间隔 50 ms 处理配对,最大化 CPU 缓存局部性并最小化 Redis 往返。

API

  • 只读层,从 Redis(热数据)和 TimescaleDB(冷历史)读取。
  • 严格将摄取与消费分离,用户流量高峰不会导致收集器崩溃。

“Candle Forge”

速度在数据不准确时毫无意义。我们引入了 Conscious Latency 的概念:有意的 100–200 ms 抖动缓冲区,用于交叉验证价格。

  • 如果 Binance 显示 5 % 的波动,但 OKX 和 Kraken 在缓冲窗口内未出现相应变化,Candle Forge 算法会将其标记为 “Scam Wick”(流动性空洞)并过滤掉。
  • 我们以 100 ms 的延迟换取套利的真实性。

结论

转向 Go 1.24 不仅仅是为了原始速度——更是为了可预测性。
通过使用带有 Swiss Tables 的编译语言,我们消除了导致 Python 机器人崩溃的内存膨胀。现在我们能够提供机构级别的数据——已标准化、已验证、已计算——而无需机构的高昂费用,实现了速度的民主化。

Engine screenshot

技术文档:
引擎演示:
主要开发 GitHub:

0 浏览
Back to Blog

相关文章

阅读更多 »

AI 编码工具:为什么开发者意见不合

AI‑Coding“辩论”并非真正的辩论 你会听到两个截然不同的故事: 朋友的创业公司创始人——“我们的团队现在使用 AI,功能发布速度提升了一倍。我是 e...”

谁在招聘 — 2026年2月

在以开发者为先的公司开放职位:产品工程师、Developer advocates 或 Community builders?以全新的 dev tools 机会开启新的一年。