策略設計的上界由執行層決定。一個需要 50 毫秒反應的策略,在一個每秒只能送 40 筆訂單的帳號上不成立;一個需要 0.5¢ 精度的策略,在一個 tick size 是 1¢ 的市場上不存在。這篇把執行層的硬邊界列清楚,後面所有策略的可行性都以此為準。


混合式架構:鏈下撮合、鏈上結算

Polymarket 的 CLOB 是中心化撮合 + 鏈上結算

  1. 你用私鑰簽署一筆訂單(EIP-712 結構化簽章),送到 Polymarket 的撮合引擎。
  2. 撮合在鏈下完成,延遲是網路延遲等級,不是區塊時間。
  3. 撮合後的成交非同步地在 Polygon 上結算。

第三點對程式設計是關鍵:下單回應成功 ≠ 部位已存在。 你必須等待結算完成才能查到正確持倉。任何「下單後立刻依持倉決定下一步」的邏輯,都會在高頻情境下讀到過期狀態。正確做法是維護一份本地的樂觀部位帳本(下單即扣、失敗即回沖),並用鏈上狀態定期對帳,而不是每次都查鏈。

這也意味著:你的競爭對手不是在跟你比誰的鏈上交易先被打包,而是比誰的訂單先到撮合引擎。這讓地理位置與連線品質變成真實的因素,但也讓「搶跑 mempool」這類鏈上策略在 CLOB 上不適用(在 UMA 預言機那一層則適用,見 提案信譽搶跑)。


Tick size:不是一個常數

不同市場有不同的最小報價單位:0.1、0.01、0.001、0.0001。此外部分高流動性體育市場(世界盃晉級、讓分、大小分、獨贏)被進一步細分到 0.0025(0.25¢)

三個實務後果:

一、tick size 決定策略的最小 edge。 在 1¢ tick 的市場上,任何小於 0.5¢ 的 edge 都無法透過改善報價來表達——你要嘛跟現有最佳價同價排隊,要嘛跨一整個 tick。這直接與 手續費門檻 交互:政治類在 50¢ 的費用門檻是 1¢,剛好等於一個 tick。「門檻等於一個 tick」代表沒有安全邊際的空間。

二、tick size 會變,而且客戶端會快取錯。 py-clob-client 有一個已知問題(issue 122):客戶端會在本地快取 tick size,市場調整後仍用舊值送單,導致訂單被拒。任何生產系統都要把「tick size 被拒」當成正常路徑處理,而不是例外——收到拒絕就重查、重算、重送。

三、細 tick 的市場適合做市,粗 tick 的市場適合方向。 0.25¢ tick 的體育市場可以做出有意義的兩側報價;0.1 tick 的市場(通常是極冷門或極端價格)連掛單都沒有意義。


最小單量與尾巴部位

CLOB 有 5 股的最小訂單量。這產生一個容易被忽略的問題:

部分成交後留下的殘餘部位若小於 5 股,你無法透過 CLOB 平掉它。

唯一的出路是持有到結算,或者用 merge(若你同時有 YES 和 NO)。對做市策略來說,這代表每個市場都會累積一層無法清理的沉澱部位。這不致命,但做市系統必須把「殘餘部位」當成一個獨立的會計科目,否則你的部位限制計算會慢慢失真。

設計上的解法:把訂單量對齊到 5 的倍數,並且在部分成交後,主動把殘餘量湊到可交易的規模再平倉,而不是試圖平掉零頭。


速率限制:分層的令牌桶

這是很多人第一次做系統時撞到的牆。Polymarket 有兩層限制。

第一層:IP 層(Cloudflare)

端點群組限制
CLOB 一般9,000 / 10 秒
CLOB 市場資料(/book/price/midprice)單筆1,500 / 10 秒
CLOB 市場資料 批次500 / 10 秒
Gamma API 一般4,000 / 10 秒
Gamma /events500 / 10 秒
Gamma /markets300 / 10 秒
Gamma 搜尋350 / 10 秒
Data API1,000 / 10 秒

Gamma /markets 的 300/10s 是最緊的一條,也是最容易撞到的一條——因為掃描全市場找機會的策略(條款掃描LP 套利)正是靠這個端點。結論很明確:市場元資料要建本地快取+增量更新,不能每輪重抓。

第二層:簽章者層(令牌桶,依做市量分級)

下單與撤單有各自獨立的桶,按近 30 天累計 maker 錢包成交量分級,每三小時重新評估:

層級下單持續速率下單爆發容量撤單持續速率撤單爆發容量
Standard40 /s6080 /s120
Copper60 /s90120 /s180
Bronze80 /s120160 /s240
Silver200 /s300400 /s600
Gold400 /s600800 /s1,200
Platinum450 /s675900 /s1,350
Diamond525 /s7871,050 /s1,575
Elite600 /s9001,200 /s1,800

三個策略層面的推論:

推論一:撤單額度恰好是下單額度的兩倍。 這不是隨意的設計——它讓「掛單後撤掉」的成本低於「掛單」,也就是交易所在結構上鼓勵做市者頻繁調整報價而非留著陳舊報價。做市策略應該利用這個不對稱:以高頻撤改換取更緊的報價,而不是掛遠一點的單少調整。

推論二:分層是按 maker 量,這是一個正回饋迴圈。 你做市越多,能下越多單,越能做市。對新進者來說 Standard 的 40/s 是硬牆——一個要同時報 100 個市場兩側的做市系統,光是每分鐘更新一輪就要 200 次下單 + 200 次撤單,在 40/s 下是 5 秒一輪。這決定了新系統應該集中在少數市場做深,而不是廣撒

推論三:爆發容量 ÷ 持續速率 = 1.5 秒,所有層級一致。這是你能維持全速下單的最長時間。任何「事件觸發、瞬間重報所有市場」的設計,都必須在 1.5 秒的爆發預算內完成,之後降到持續速率。這應該直接寫進執行層的排程器:優先權隊列 + 令牌桶模擬,重要的市場先送。


WebSocket vs 輪詢

官方明確建議:即時資料用 WebSocket,不要輪詢;能用批次端點就用批次;追蹤 rate limit 標頭。

這在架構上的意思是訂閱與查詢要分離

  • WebSocket:訂單簿變動、自己的成交回報。這是熱路徑。
  • REST 批次:定期對帳、快取重建。這是冷路徑。
  • 絕不用 REST 輪詢當作即時價格來源——會撞 IP 限制,而且延遲不可控。

WebSocket 帶來的最大風險是靜默斷線:連線看似還在,但沒有訊息進來,你的系統以為市場沒動,繼續用陳舊的報價掛單,而市場已經跑掉了。這是做市系統最典型的死法。解法是 heartbeat + dead-man switch,見 系統藍圖


訂單類型與生命週期

  • 限價單(GTC):掛在簿上,是 maker,零手續費,且有資格領流動性獎勵。
  • 市價單 / FOK 型:對現有流動性成交,未成交部分直接取消而非留在簿上。是 taker,付費。
  • 撮合成功後非同步鏈上結算,需等待結算完成才能驗證持倉。

maker/taker 的區分在 Polymarket 上比在多數交易所重要得多,因為費率差是 0 vs φ·p(1−p),而且 maker 還有回饋與流動性獎勵兩層收入。這在 下一篇 會量化成一個明確的決策式:掛單的價值恰好等於 φ·p(1−p) 加上獎勵,所以你願意為了掛單承受的「不成交風險」有一個精確上限。


這篇的重點

硬邊界數值策略含意
tick size0.1 / 0.01 / 0.001 / 0.0001,部分體育 0.0025決定最小可表達 edge;會變,客戶端會快取錯
最小訂單5 股殘餘部位無法平倉,要獨立記帳
Gamma /markets300 / 10s全市場掃描必須快取+增量
下單(Standard)40 /s,爆發 60新系統只能做深、不能做廣
爆發持續時間1.5 秒(所有層級)事件觸發的重報必須有優先權排程
撤單 : 下單2 : 1結構上鼓勵高頻改價
結算非同步下單成功 ≠ 持倉存在,要維護樂觀帳本

下一步:手續費即變異數稅