Polymarket Bot 教程 · 第 32 章中的第 10 章
面向 bot 构建者的 Polymarket 订单类型详解:Fill-or-Kill (FOK)、Fill-and-Kill (FAK)、Good-til-Cancelled (GTC),以及限价 vs 市价的权衡。附生产级决策规则。
本章内容
订单类型混淆是新 bot 构建者最昂贵的一类 bug。该用 FOK 却发了 GTC,会导致错过入场;该用 GTC 却发了 FOK,会留下挂单,几个小时后在糟糕的价格成交。本章给出决策树,以及经过生产验证、在成千上万笔订单中都经受住考验的默认方案。
- 快速决策树
- FOK:必须成交否则跳过时使用
- FAK:可接受部分成交时使用
- GTC:希望挂在订单簿上等待时使用
- 限价 vs 市价,以及 spread 税
- 我们的生产默认值(FOK 买入,GTC 卖出]
- 代码:下单各类订单类型
快速决策树
三个问题决定每一笔下单。
- 你是否需要立刻保证成交,而且如果现在不能成交就完全不要?→ FOK。
- 你是否想尽可能多地立刻成交,接受部分成交,但不要挂单?→ FAK。
- 你是否希望按你的价格挂在订单簿上,等待别人来成交你?→ GTC。
就这么简单。大多数围绕订单类型的 bot bug,都是因为在你想要 #3 时选了 #1(“买入”变成了“因为 spread 太宽而没有仓位”),或者在你想要 #1 时选了 #3(“买入”变成了一个挂单,几个小时后在错误时点才成交)。
FOK:必须成交,否则跳过
Fill-or-Kill 会立即以请求的价格或更优价格撮合整笔订单。如果无法立刻把全部数量成交,这笔订单就会被拒绝,什么都不会发生。不会挂单,也不会部分成交。
FOK 适用于:新闻套利入场(你只想在新闻价格入场,不想在 30 秒后的市场价入场);在特定目标价位的止盈退出,部分成交会让记账变得混乱;任何策略假设原子执行的场景。
权衡:FOK 的拒单率比其他订单类型更高,尤其在流动性差的订单簿上。务必准备 fallback 路径-重新评估策略条件并在仍然有效时重试,或者直接跳过。
FAK:可接受部分成交时
Fill-and-Kill(也称 “immediate or cancel”)会尽可能立刻撮合,然后取消未成交的剩余部分。你可能得到全额成交、部分成交,或者零成交。
FAK 适用于:带特定价格上限的 market-buy(以不超过中间价上方 N cent 的价格抬升 ask);紧急减仓时扫单卖出;以及任何“有一点仓位总比没有好”的策略。
在操作上比 FOK 更棘手,因为 bot 必须先知道自己拿到了 100% 还是 30%,再决定下一步。成交响应里包含 filled_size 字段-一定要读取它。
GTC:希望挂在订单簿上等待时
Good-til-Cancelled 会按你的价格挂在订单簿上,直到成交或你主动取消。没有超时(v2 API 中其他订单类型包含带过期时间的 GTD)。
GTC 适用于:在入场价上方 +Nc 的止盈卖出;在入场价下方 -Nc 的止损卖出(有注意事项-见下文);双边报价的 market making;以及任何 bot 愿意等待更好价格的仓位。
硬性规则:GTC 要求 ≥ 5 shares。少于 5 shares 的订单会被 CLOB 拒绝,并返回 Size (X) lower than the minimum: 5。如果 bot 发出一个 4-share 的 GTC 卖单,会悄悄失败,退出单并未设置,仓位会一路持有到结算。发 GTC 前务必检查库存是否 ≥ 5;如果更小,则回退到 FAK 或持有到结算。
限价 vs 市价,以及 spread 税
严格来说,Polymarket 的每笔订单都是限价单-即使 bot 所谓的“market buy”也会指定一个价格上限。区别在于这个价格是最优 ask(实际上等同于市价单,会吃掉订单簿)还是低于最优 ask(会挂在订单簿上)。
这里就轮到 maker 和 taker 两个角色登场了。taker 发出的订单会立即与订单簿里已经挂着的订单成交;maker 则是挂出一个订单、停留在簿子里,等别人来跟它成交。taker 要付出 spread(以及 taker 手续费),maker 则收取 spread(并赚取返佣)。所谓 spread 税,就是 taker 为「跨价成交」付出的成本:当 bid 是 0.45、ask 是 0.47、mid 是 0.46 时,一次买 ask、卖 bid 的来回,每股要亏 2 美分。在一个胜率 60%、止盈 +3c / 止损 -4c 的策略里,这 2 美分的 spread 就是盈利和亏损之间的分界线。
Maker 模式(在 bid 或更低位置挂 GTC,等别人来吃)会收取 spread,而不是支付它。代价是不确定成交-你可能永远都不会被成交。对于高置信度交易,直接支付 spread;对于被动积累,去“工作”订单簿。
我们的生产默认值(FOK 买入,GTC 卖出]
我们大多数生产 bots 最终收敛到的模式:
- 入场:在 ask 上方 0-2 cent 使用 FOK。如果 bot 决定买入,就应该现在买,或者跳过。通常不值得把入场单挂着-触发买入决策的情况变化,往往比订单挂单等待的时间更快。
- 止盈退出:按目标价使用 GTC。在入场成交后立即挂出。我们让市场来找我们,不追着 bid 往下跑。前提是 ≥ 5 shares。
- 止损:视情况而定。对于价格变化有界的慢速策略,GTC 可行。对于快速变动的市场,如果价格直接飞过止损价,GTC 止损不会成交;我们会采用 option-D 方式持有到结算(记忆提示:trader-gtc-sell.md)。
这种模式偏保守-成交更少,滑点更低。更激进的变体会使用 FAK 入场和 FAK 出场,接受部分成交。选一种并保持一致;按交易混用决策会带来混乱。
代码:下单各类订单类型
使用 py-clob-client (v0.34.6) 的 Python 下单参考。
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import OrderArgs, OrderType
c = ClobClient(host="https://clob.polymarket.com", chain_id=137,
key=PRIVATE_KEY, signature_type=2, funder=PROXY)
c.set_api_creds(creds)
# FOK buy: fill 10 shares at price 0.45 or skip
args = OrderArgs(token_id=TOKEN, price=0.45, size=10, side="BUY")
resp = c.create_and_post_order(args, OrderType.FOK)
# FAK buy: take as much as you can at 0.45 or below
resp = c.create_and_post_order(args, OrderType.FAK)
# GTC sell: rest a sell at 0.85 for 10 shares
sell_args = OrderArgs(token_id=TOKEN, price=0.85, size=10, side="SELL")
resp = c.create_and_post_order(sell_args, OrderType.GTC)
Node 中使用 @polymarket/clob-client-v2 的同样操作:将 OrderType.FOK 替换为 clob.OrderType.GTC 等;方法是 createAndPostOrder。对于多结果市场,必须在第二个参数中设置 negRisk 标志(第 11 章)-如果缺失,会路由到错误的 exchange contract。












