Polymarket Bot 教程 · 第 13 章,共 32 章
在 Polymarket 上做做市:如何报价买一卖一、捕捉价差、赚取 maker rebates(taker fees 的 20-25%)、库存风险数学,以及做市(MM)在预测市场中何时可行。
本章涵盖什么
在 Polymarket 上做市,指的是持续在市场订单簿两侧同时报价,并在每次来回交易中赚取价差。这个策略在传统金融中早已被充分理解;Polymarket 的特殊之处在于 maker rebate 计划,以及预测市场中的 adverse-selection 特征--它比 CFD 平台更高。本章讲的是诚实的数学。
- 用通俗语言解释做市
- spread + rebate 优势
- 库存风险与偏斜
- Polymarket 上 MM 何时可行(以及何时不可行)
- 代码骨架:在 +/- N 美分处双边报价
- 根据 news flow 调整报价
- 在逆向选择激增时关闭机器人
用通俗语言解释做市
market maker 会持续报价一个买价(bid)和一个卖价(ask),两边都围绕 mid,以固定 spread 拉开。有人打到 bid 时,maker 以便宜价格买入;有人抬走 ask 时,maker 以较高价格卖出;bid 和 ask 之间的差额就是 maker 每次来回交易的收入。
这个策略是由 order flow 驱动的,而不是方向性交易。maker 不对 YES 是否获胜发表看法;他们的假设是,交易流会持续,spread 会不断被支付。
风险在于 adverse selection:打你 bid 的人可能掌握你没有的信息。随着时间推移,MM 的利润取决于 spread 是否足够宽,能够覆盖 informed traders 带来的滑点。
spread + rebate 优势
Polymarket maker 的两条收入来源。
Spread capture:围绕 0.46 的 mid 报 bid 0.45 和 ask 0.47。你在 bid 上成交后,若之后能在 ask 上退出,就能赚 2 美分。净优势取决于成交不平衡和价格漂移。
Maker rebate:Polymarket 的 liquidity-rewards program 会对符合条件市场中的 maker 成交按每股发放 rebate。数值会变化;请查看官方 rewards 页面获取当前值。rebate 以 pUSD 定期发放,独立于交易本身。
对大多数市场而言,spread capture 是更大的收入来源。对于可以报更宽 spread 的市场(大选年、重大体育季后赛),Polymarket 会提高 rebate 以吸引流动性,此时 rebate 才更有意义。
库存风险与偏斜
一个不断被 bid 打中的 MM 会积累多头头寸。风险在于 mid 下跌,而你持有的是多头;即使算上 spread 收入,maker 仍可能在头寸上亏损。
防御手段:quote skew(当库存偏多时压低 bid,当库存偏空时抬高 ask,以抑制单边成交);inventory cap(在你已经过度偏多的一侧停止报价);active rebalancing(当库存接近上限时,偶尔主动跨 spread 平掉部分仓位)。
数学上:如果 bid 上 60% 的成交在价格向不利方向移动 2 美分之前都无法退出,那么仅这些成交就会让策略亏钱。当成交不平衡超过 65/35 时,要积极 skew。
Polymarket 上 MM 何时可行(以及何时不可行)
当以下三个条件成立时,MM 在 Polymarket 上才可行。
- Liquid book:有足够多的报价竞争,你的 spread 既有竞争力又不是零。2024 大选市场、重大 NFL/NBA 比赛、BTC 上涨/下跌 5m 都符合。
- Two-sided flow:买卖双方都活跃。单边市场(接近 0.95+ 的“已接近结算”市场)没有 maker 可捕捉的空间。
- Bounded price moves:spread capture 不会被 5 美分的跳动吞没。稳定的中间区间市场(0.40-0.60)最友好。
MM 在以下情况会失败:新闻驱动型市场,mid 的跳动比你重新报价更快;流动性不足的订单簿,你是唯一报价者,而下一笔交易会连续扫过 5 个档位;接近结算的市场,一侧正收敛到 0 或 1。
代码骨架:在 +/- N 美分处双边报价
一个最简单、可用的 maker 的伪代码。
SPREAD_CENTS = 2
INVENTORY_CAP_SHARES = 50
def make_loop(token_id):
while True:
book = fetch_book(token_id)
mid = (book.best_bid + book.best_ask) / 2
inv = chain_balance(token_id)
# Skew: pull the side we are too long on
bid_px = mid - SPREAD_CENTS/200 - (0.005 if inv > INVENTORY_CAP_SHARES * 0.6 else 0)
ask_px = mid + SPREAD_CENTS/200 + (0.005 if inv < -INVENTORY_CAP_SHARES * 0.6 else 0)
cancel_my_existing_quotes(token_id)
if inv < INVENTORY_CAP_SHARES:
place_gtc(token_id, side="BUY", price=bid_px, size=5)
if inv > -INVENTORY_CAP_SHARES:
place_gtc(token_id, side="SELL", price=ask_px, size=min(5, inv))
time.sleep(2)
生产环境里的 makers 还会加入:按单边库存跟踪、先撤后挂的顺序控制、重新报价间隔加入 jitter 以避免可预测性,以及 adverse selection 的 kill-switch(下一节)。
根据 news flow 调整报价
当新闻事件发生时,fair value 会先移动,而你的报价还停留在原地。一个在 news flow 期间不撤单的 MM 会被迅速扫出。
信号:在 30 秒内,incoming fills 的 cancel rate 跳升到基线的约 3 倍以上;或者通过更广泛的事件流交叉检查(Polymarket Twitter/Discord、Bloomberg headline feed)。检测到后,maker 会在 60-120 秒内撤掉所有报价,等新的 mid 稳定后,再围绕新的中心重新报价。
最简单的实现是监控该 token 的 last-trade-price stream。若相对于滚动窗口均值出现超过 2 个标准差的跳跃,就触发暂停。当价格稳定 30 秒以上后,bot 再重新接入。
在逆向选择激增时关闭机器人
这是硬性退出条件。如果 bot 最近 50 笔成交的 fill PnL 明显转负,就说明出了问题:要么市场已经变成新闻驱动,不适合做市;要么你设置的 spread 对当前 adverse-selection 水平来说太紧了。
应编码的 kill conditions:
- 连续 5 次 bid 成交且没有 ask 成交,自第一笔成交以来 mid 下跌超过 1c。
- 最近 25 笔 round-trip 成交的 realized PnL 低于预期的 -25%。
- WebSocket 断开或检测到 stale book。
- 任一方向库存超过上限,持续超过 5 分钟。
触发后,取消所有订单,以 market 方式平掉库存,并暂停 15 分钟以上。没有 kill switch 的 market maker 会在波动期持续亏损,直到 trader 手动注意到--而这总比你想的更慢。


