Polymarket Bot 教程 · 第 30 章,共 32 章

面向 Polymarket bots 的生产级风控代码:仓位上限、每日亏损限制、halt 哨兵、成交率 watchdog、重启时对账、幂等重试。来自真实生产 trader 的代码模式。

本章内容

风控代码占了生产交易 bot 的大部分。策略逻辑只是最容易的部分;真正决定 bot 能否熬过第一个糟糕周的,是周边的上限、停机、watchdog 和对账机制。本章讲的是生产级风控模式。

  • 为什么风控代码占据了真实 trading bot 的大部分
  • 仓位上限(单市场、单策略、总计)
  • 每日亏损 kill switch
  • halt 哨兵(基于文件的紧急停止)
  • 成交率 watchdog
  • 重启时对账 diary 与链上状态
  • 代码:生产级、支持 halt 的循环

为什么风控代码占据了真实 trading bot 的大部分

我们在自有 bot codebase 上做过一个统计:60% 的 LOC 是风控代码(上限、停机、watchdog、reconciliation)。30% 是策略。10% 是 glue。

这个比例是对的。策略很简单-描述何时进场、何时退出,只需要几十行代码。风控代码则是其他一切:当价格比预期更快地反向移动时怎么办,成交开始消失时怎么办,WebSocket 掉线时怎么办,策略被证明无利可图时怎么办。

大多数 builder 的失败故事都有同样的模式:策略本身是对的,但 bot 因为没有触发 halt 而在 regime change 中持续交易。先写 halt,再写策略。

仓位上限(单市场、单策略、总计)

三个上限,必须在代码里强制执行。

  • 单市场上限:无论 edge confidence 多高,每个市场最多 $X。典型值:小型 bot 为 $25-100,生产环境为 $200-500。用于限制单个市场判断错误时的爆炸半径。
  • 单策略上限:如果你运行多个策略,每个策略分配总资本的一部分。典型值:每个策略 30-50%。防止某个策略糟糕的一天吞掉其他策略的资金。
  • 总上限:同时部署的最大钱包余额百分比。典型值:50-70%。为意外机会或 bot 自身记账 bug 预留资金缓冲。

这三个上限都应该在下单函数内部强制执行,而不只是写在策略逻辑里。策略可能有 bug;下单门禁是最后一道防线。

每日亏损 kill switch

最重要的单一风控:每日亏损 kill switch。

规则:如果自 UTC 午夜以来,已实现 + 未实现 PnL 低于起始日余额的 -X%,bot 停止开新仓位,并且(可选)平掉现有仓位。典型 X:5-10%。

数学上看:一个预期胜率 60% 的 bot,可能有 5% 的概率出现 10 连败。没有 kill switch 时,这种连败会不断叠加:亏损 $200 → bot 继续交易 → 再亏 $200 → 钱包回撤 40%。如果在 -10% 时触发开关,坏日子的损失就封顶在 $200,而第二天 bot 可以重新开始。

这个开关要在服务端强制执行:写入 halt 文件,或设置数据库标志,并由 trading loop 每次迭代检查。只有人工复核后才能重启。

halt 哨兵(基于文件的紧急停止)

最简单的 halt 机制:bot 在每次循环迭代时检查一个文件(例如 /opt/pmt/HALT),如果文件存在就停止交易。

def trading_loop():
    while True:
        if os.path.exists("/opt/pmt/HALT"):
            log("HALT file detected, sleeping")
            time.sleep(30)
            continue
        run_one_iteration()
        time.sleep(5)

要从任何地方立即停止(SSH、Telegram bot、监控系统):touch /opt/pmt/HALT。要恢复:rm /opt/pmt/HALT

这种基于文件的方法是故意保持低技术门槛的,因为它在更复杂的 halt 机制失效时仍然可用:比如 bot 部分崩溃、数据库不可达、API key 受限速影响时。文件系统访问始终可用。

成交率 watchdog

策略假设 FOK orders 以某个比例成交(通常 60-80%)。当这个比例明显下降时,说明情况变了:市场 maker 撤走了,你的策略被识别了,或者 API 故障正在发生。无论原因是什么,驱动策略 PnL 计算的假设已经失效。

watchdog 逻辑:滚动 24 小时成交率统计。如果 < 30%(或低于预期的 50%),就报警 + 自动 halt。只在人工复核后恢复。

watchdog 也很适合做诊断。成交率突然下降,通常与外部事件相关(Polymarket deploy、Polygon 拥堵、你的 IP 被限速),无论交易影响如何,你都应该知道。

重启时对账 diary 与链上状态

bot 会维护一份 diary,记录它认为自己持有的仓位。链上维护真相。二者应该始终一致;一旦不一致,bot 就是在基于错误认知运行,并会错误交易。

对账逻辑:在每次重启时,以及正常运行期间每小时一次,获取 bot 接触过的每个 token 的链上余额。将其与 diary 比较;如果任何 token 的余额与 diary 的差异超过舍入容差,就报警 + halt。

最常见的不一致原因是:某个订单实际上成功了,但 bot 的 API 调用漏记了(超时、重试未记录)。链上已经有仓位;bot 却以为没有。没有 reconciliation,bot 就不会挂出止盈退出单,仓位会一直持有到结算。

代码:生产级、支持 halt 的循环

参考实现:带有全部风控控制的 production trading loop。

def production_loop():
    while True:
        # Halt checks
        if os.path.exists("/opt/pmt/HALT"):
            sleep_with_log(30); continue
        if daily_pnl_below_threshold():
            create_halt("daily PnL kill"); continue

        # Reconcile every hour
        if now() - last_reconcile > 3600:
            ok = reconcile_diary_vs_chain()
            last_reconcile = now()
            if not ok: create_halt("reconciliation failed"); continue

        # Fill-rate watchdog
        if recent_fill_rate() < 0.30:
            create_halt("fill rate collapse"); continue

        # Strategy
        try:
            run_strategy_once()
        except Exception as e:
            log_exception(e)
            if consecutive_exceptions >= 5:
                create_halt(f"exceptions: {e}"); continue
        time.sleep(5)

模式很清晰:每次迭代都必须通过门禁。策略 bug 不能绕过这些控制,这是结构上保证的。

常见问题

什么是 halt 哨兵?
一个文件(例如 data/halt_autobuy),bot 会在每次下单前检查它。如果文件存在,即使策略要求下单,bot 也会拒绝下单。这样你就可以用一个 touch 命令在事故进行中停止 bot。我们在 2026 年 4 月经历一次 wedged-fill 事故后,把这个精确模式加入了生产 trader。
我应该设置哪些仓位上限?
单市场:bankroll 的 1-5%。单策略:10-20%。总开放风险:bankroll 的 50-70%(保留现金缓冲)。无论策略如何,单笔订单都应限制在 bankroll 的 1-2%-一次手滑下单绝不应该接近账户规模。
如何实现每日亏损 kill switch?
按每个 UTC 日跟踪已实现 + 未实现 PnL。如果日内 PnL 低于 bankroll 的 -3% 到 -5%,就设置 halt 哨兵并通知自己。bot 停止新订单;现有仓位人工管理。每天 00:00 UTC 重置。
崩溃后重启时 bot 应该怎么做?
三个步骤:(1) 用 SDK 将 open orders 与本地 diary 对账。(2) 将链上的 open positions 与本地状态对比。(3) 如果有任何不一致,就 halt bot 并要求人工复核。绝不要在不一致状态下自动恢复运行。
怎样防止一个 bug 清空我的账户?
分层限制:代码级仓位上限、代码级订单大小上限、文件级 halt 哨兵、交易所级(Polymarket)隐含最小/最大值、以及在异常订单频率出现时 page 你的监控告警。任何单一层都不够-它们要叠加。
如果日志失败,bot 还应该继续交易吗?
不应该。如果 bot 不能写入自己的 diary,就无法在重启后对账,这意味着崩溃会导致状态不一致。日志失败时必须让 bot 硬失败。健康的生产 bots 会对自身可观测性保持高度警惕。