原文標題:《交易平台無限印鈔的秘密:從加密現貨、合約、期權到預測市場的訂單簿撮合引擎註解》
原文作者:danny,加密分析師
打開 Binance 現貨和永續,訂單簿幾乎一模一樣。但在「賣出」的瞬間,背後是兩個完全不同的機制。
為什麼 perp 要維護兩套價格?為什麼 Iron Condor 必須四條腿一起成交?為什麼預測市場的手續費在 p=0.5 時最貴?這些問題表面在問機制,本質在問同一件事——撮合引擎從來不是獨立的工程模塊,它是被它服務的資產塑造出來的。
現貨、永續、期權、預測市場四種形態之間的差異遠比相似更深。這篇文章把它們拆開,看清是什麼力量讓「撮合」分化成幾乎不相關的工程實體。
如果你只看過現貨交易的撮合實現,可能會覺得「撮合引擎」是一類成熟、收斂、幾乎沒什麼技術含量的事情——一個排序的訂單簿、一個價格時間優先的匹配循環、加上一個一次性結算路徑,end of the story。
那你就大錯特錯了。。。
當你把視角從 Coinbase 的 BTC/USDT 拉到 Binance 的 BTCUSDT 永續合約,再拉到 Deribit 的 BTC-26DEC25-50000-C,最後落到 Polymarket 上某個事件市場,你會發現這四個市場背後的撮合引擎在結構上幾乎是四種不同的機器。
它們共享某種算法上的相似性——都有買方、賣方、價格、數量——但當你深入到狀態機、風控耦合、交易邊界、信任假設這些層面,差異大到讓「撮合引擎」這個詞本身顯得過於抽象。
這篇文章想做的,是把這四種典型形態拆開,看清是什麼力量讓同一個底層概念在不同標的下分化成不同的工程實體。
現貨撮合是一個標準模型,幾乎所有教科書和開源項目(LMAX Disruptor、CME Globex 的簡化版、各類開源 matching engine)都從這裡開始。
核心資料結構通常是兩棵價格樹(bid 側、ask 側),每個價格節點掛一條 FIFO 佇列。撮合循環非常直接:當一個吃單(taker)到達,從對手方的最優價格檔位開始掃描,按時間順序消耗 maker 佇列,直到吃單數量耗盡或價格越過限價。
核心特徵有幾個關鍵點值得專門拎出來:
第一,資產是同質且可分離的。買方持有 quote 資產(USDT),賣方持有 base 資產(BTC),撮合的本質就是一次資產置換。帳本上的操作是一對綁定在事務裡的餘額加減,結算和撮合在同一個事務內完成。撮合引擎幾乎不需要外部依賴——撮合即結算,沒有下游鏈路。
第二,風險是即時清零的。一筆現貨交易完成的瞬間,所有頭寸關係就消失了,不存在「持倉」這個概念在撮合層面的延續。引擎不需要關心你下一秒會不會因為價格波動而爆倉,因為根本沒有「倉位」這回事。
第三,訂單類型相對收斂。Limit、Market、IOC、FOK、Post-only、Stop——這些都是訂單生命週期管理上的變體。

舉一個具體場景。BTC/USDT 賣一檔 50,001 × 1.5 BTC(maker A 在 09:30:00.100 掛單),賣二檔 50,002 × 3.0 BTC(maker B 在 09:30:00.200 掛 1.0,maker C 在 09:30:00.300 掛 2.0)。
一筆 4.0 BTC 的市價買單到達。撮合循環:先吃 A 全部 1.5 @ 50,001,然後到下一檔按 FIFO 順序——B 先於 C,先吃 B 全部 1.0 @ 50,002,再吃 C 部分 1.5(C 剩 0.5 留簿)。
Taker 帳戶在同一事務裡扣減 200,006.5 USDT、增加 4.0 BTC,三個 maker 帳戶對應反向更新。這一連串操作在一個數據庫事務裡完成,撮合即結算。值得注意的是 B 先於 C 成交不是因為價格(同檔),是因為先掛——這就是 price-time priority 的實際體現。
现货撮合工程上的难点其实不在逻辑,而在性能:如何在百万级 TPS 下保持微秒级延迟,如何处理冷热路径的 cache locality,如何做到 deterministic replay。但这些是优化问题,不是机制问题。
如果你把 Binance 永续合约的订单簿截圖放在現貨訂單簿旁邊,肉眼可能看不出區別。但底層就是另一个風景了。
關鍵變化在於:撮合引擎不是結算的終點,只是一個事件源。(aka 一個多米諾骨牌)
每一筆 perp 撮合的完成都觸發一條複雜的下游鏈路:標記價格更新、倉位更新、保證金重算、未實現盈虧刷新、可能的強平觸發。撮合引擎和風險引擎在 perp 這裡是深度耦合的,耦合方式決定了整個系統的性格。
雙價格體系是 perp 的第一個獨特結構。撮合本身依然按「最新成交價」驅動(last traded price),但維持保證金、強平觸發、UPnL 計算用的是「標記價格」(mark price),後者是多個現貨市場的指數加上 funding adjustment 合成出來的。這是一個反操縱設計:如果撮合價和標記價合一,攻擊者可以用一筆小資金把訂單簿拉到某個極端價格,瞬間引爆所有反向倉位的強平。雙軌制把這個攻擊面消滅了。
舉一個具體場景說明雙價格的作用。某交易者 50x 多 1 BTC,入場 60,000,初始保證金 1,200 USDT,維持保證金 300 USDT。某一時刻訂單簿被一筆大額市價單瞬間打穿到 last price = 58,500——按 last 算未實現虧損 1,500 USDT,已經穿倉。
但同一時刻 mark price(多現貨指數加權 + funding adj)= 59,400,按 mark 算未實現虧損 600 USDT,帳戶淨值 600 > 維持保證金 300,強平不觸發。幾秒後 last price 回歸 59,400,這位交易者沒有被插針毛刺掃掉。
如果撮合和強平共用 last price,攻擊者用一筆小資金在訂單簿薄弱時刻把價格拉到極端位置,就能觸發反向倉位連鎖爆倉再低價吃回——這正是 BitMEX 早期頻繁發生的事件類型。雙軌制不是「為了精確」,是「為了不被攻擊」。

Pre-trade 風控是另一個關鍵插入點。在現貨裡,吃單到達就直接撮合;在 perp 裡,吃單首先要過保證金檢查——你的可用保證金能否覆蓋這筆成交帶來的倉位變化?如果是 cross-margin 模式,這個檢查還要考慮你帳戶內所有倉位的相互對沖。這個檢查必須在撮合循環裡同步完成,否則會出現「成交後才發現保證金不夠」的狀態不一致。
強平的特殊撮合通道是 perp 引擎最有趣的部分。當帳戶保證金率跌破維持線,強平引擎會接管——它會以帳戶的破產價(或某個保護價格)向訂單簿發送 IOC 訂單,嘗試把倉位平掉。如果訂單簿太薄,吃不動這筆強平單怎麼辦?這裡有幾種工程選擇:一是接入保險基金兜底,二是觸發 ADL(自動減倉),由系統強制減少盈利對手方的倉位。
ADL 本質上是「撮合的最後一環」:當訂單簿、保險基金都失效時,系統跳過訂單簿,直接在兩個帳戶之間做強制結算。這是一種把「撮合」概念從「自願匹配」擴展到「非自願匹配」的設計——它已經不屬於傳統意義上的撮合了,但它必須存在,否則系統在極端行情下會破產。

自成交防止(STP)的複雜化也是 perp 特有的。在現貨裡,自成交防止主要防止洗單;在 perp 裡,同一個帳戶可以同時持有多空(hedge mode),所以 STP 的語義需要細分:是按 sub-account、按 user ID、還是按 master account?不同交易平台選擇不同。
總結一下:perp 撮合的「難」不在訂單簿本身,而在訂單簿後面那整套和風險引擎綁定的狀態機。設計者必須想清楚:哪些檢查在撮合主路徑上(同步),哪些可以異步;強平的執行模型用什麼;保險基金怎麼計提;ADL 觸發的優先級隊列怎麼排序(通常按「盈利百分比 × 槓桿倍數」排序,讓最賺的、槓桿最高的人先被減倉)。
perp 撮合還有一層值得專門拎出來討論:強平這條路徑在撮合環節和普通訂單合流,但在合流前後是另一套完全不同的邏輯。理解這層分層對設計或調試 perp 引擎至關重要——否則會反覆混淆「撮合」和「清算」的邊界。
把強平拆成三層來看:
第一層是觸發判定。用 mark price——目的是「是否應該清算」這個決策不被訂單簿瞬時操縱影響。這一層完全脫離場內深度,是一個獨立的風控判斷。
第二層是訂單構造。強平引擎決定清算後,構造一個 IOC 訂單送進訂單簿。
這個訂單和用戶的普通訂單在多個維度上結構性不同:價格不是用戶選的而是引擎按破產價作為限價;類型永遠是 IOC 不允許 rest in book;手續費走清算費率(0.5–1.5%)而不是 taker 費率,且流向保險基金;下單權限屬於系統而非帳戶——帳戶在被清算時甚至會先被強制撤銷自己掛在簿上的所有掛單(避免自成交汙染清算);失敗 fallback 不一樣——用戶 IOC 吃不到就消失,強平 IOC 吃不到則觸發保險基金 → ADL 的級聯。
第三層是撮合執行。一旦進入訂單簿,強平 IOC 和普通 IOC 遵守完全相同的 price-time priority 規則去吃對手方流動性。這一層是對稱的,撮合引擎不會「特殊對待」強平單的撮合優先級——撮合循環不該有這種 if-else,否則就破壞了 deterministic replay。
所以精確的描述是:撮合循璃本身不分兩套,但訂單的來源、構造、計費、失敗路徑分兩套。從撮合主路徑的視角看,強平和普通訂單是平等的;從事務全景看,它們走的是兩條平行的管道,僅在撮合環節合流。

這裡還有一個值得注意的點——mark price 決定「應該以什麼價格清算」(觸發條件),但 last price(場內深度)決定「實際能以什麼價格清算」。當訂單簿薄、深度跑光,強平 IOC 沿簿吃下來的實際成交價遠差於破產價,這個 gap 就是保險基金的「盈虧來源」。保險基金本質是吸收「mark 給出的理論清算價」與「場內執行的實際成交價」之間的偏差。如果兩者總是一致,保險基金根本不需要存在。
更激進的設計(dYdX 早期的 backstop liquidator 網路)幹脆在訂單簿前面加一層「給清算路徑獨立的對手方通道」——讓 backstop vault 或者白名單的清算人優先接走整個倉位,繞開訂單簿這條慢路徑。這本質是把「強平執行」從場內撮合中完全獨立出來,給清算路徑自己的撮合通道。這是另一種回答雙路徑問題的方式:有些交易平台認為兩條路徑塞進同一個訂單簿是一種妥協,幹脆讓它們用不同的撮合通道。
回到 perp 撮合複雜性的核心:撮合主循環本身可以保持簡潔,但它周圍的狀態機——風控、清算、保險基金、ADL、可能還有 backstop liquidator 網路——構成了一個比訂單簿本身複雜得多的系統。
「order book 長得和現貨一樣」的視覺錯覺背後,實際上有兩條獨立的入口管道和四種不同的退出路徑。這就是 perp 撮合「難」的真實形狀。(據聞有些交易平台還做了 b book)
期權是這四類標的裡唯一一個「標的物本身有數量爆炸」的類別。一個 BTC 現貨市場只有一個訂單簿;一個 BTC 永續也只有一個;但 BTC 期權——以 Deribit 為例——在任何一個時點都有幾百個活躍合約,由 strike × expiry × call/put 三個維度組合出來。每個合約都需要獨立的訂單簿。
這就帶來了第一個根本性問題:流動性稀疏。深度 in-the-money 或者 out-of-the-money 的合約一天可能只有幾筆成交,訂單簿上經常是空的或者只有做市商的兩個掛單。這種稀疏性使得純 LOB 模型幾乎不可用——一個普通買家掛限價單可能要等幾天才能成交。
行業的解法是混合三種模式:
LOB 用於流動性最深的合約,主要是 ATM 期權和近月合約。這部分和現貨邏輯沒本質區別。
RFQ(Request For Quote)用於流動性稀疏的合約。交易者發出報價請求,多個做市商響應,交易者從中選擇最優。這套流程在 LOB 之外運行,撮合的是「詢價單 vs 多個報價回覆」,本質上是一個反向拍賣。
区块交易(Block Trade)用于超大单。两个对手方在场外谈好价格,将交易报告给交易平台登记结算,订单簿不参与撮合,只参与登记。
多腿同步撮合是期权撮合的另一个核心要求。一个常见的策略——例如铁甲鹰式(Iron Condor)——需要同时买卖四个不同的期权合约。如果四条腿分别在四个订单簿上独立撮合,结果可能是其中两条腿成交了,另外两条没成交,交易者的风险敞口完全不是想要的。
因此,期权撮合引擎必须支持组合订单簿(combo book)或多腿原子执行(multi-leg atomic execution):四条腿要么全部成交,要么全部不成交,作为一个整体处理。
Deribit 的做法应该算是目前行业参考标准:它有一个独立的组合订单簿,组合订单可以独立挂单,也可以与单腿订单簿之间进行暗含撮合——系统会自动从单腿流动性合成组合价格,反之亦然。这是非常精妙的设计,但也意味着撮合主路径上必须维护「虚拟订单簿」的状态同步。
举一个具体场景说明多腿同步撮合为什么不是可选项。ETH 现价为 3,000,交易者预判未来 7 天将在 [2,900, 3,100] 区间内震荡,构建铁甲鹰式:卖出 3,100 认购期权、买入 3,200 认购期权、卖出 2,900 认沽期权、买入 2,800 认沽期权。四条腿的净收入是组合的最大盈利,最大亏损由于有保护腿而被严格封顶——这是策略成立的前提。
如果四笔订单各自独立提交到四个订单簿撮合,最常见的失败场景是:前两笔(看涨期权价差部分)成交了,ETH 在毫秒内跳至 2,950,后两笔(看跌期权价差部分)的对手方报价已失效,做市商撤单或大幅调整,C、D 未成交。结果交易者持有一个裸的看涨期权价差——方向性敞口完全相反,原本的「震荡获利」策略变为「看跌亏损」,最大亏损也不再受限。
组合订单簿将四条腿打包为一个整体:要么全部成交,要么全部不成交;暗含撮合进一步使单腿订单簿的流动性可以实时合成组合报价,反之,组合订单簿的流动性也会回流到单腿,两层流动性相互补充。

做市商的定價演算法主要用 IV Implied Volatility,而不是價格(這也是選擇權特有的)。做市商不會掛「50000 行权价調用 $1500」,他們會掛「買入 65 波動率,賣出 67 波動率」,系統在每次報價生效時根據當前基礎資產價格使用 BSM(或更複雜的模型)計算出實際報價。
這意味著做市商的報價是動態跟隨基礎資產的,訂單簿在基礎資產價格變動時會自動調整——這讓「掛單」在選擇權中變成了一個連續函數而不是離散事件。
Greeks 化的組合保證金讓風險管理也變得不同。在永續合約中,每個持倉獨立算保證金;在選擇權中,做市商可能同時持有幾百個合約,單獨算每個合約的保證金會讓資本效率低到無法運營。
所以選擇權交易平台通常採用基於希臘字母(delta、gamma、vega、theta)的組合保證金,把整個 portfolio 看作一個淨敞口,按淨 Greeks 計算保證金。這又反過來影響撮合——一筆成交的「保證金成本」取決於它是否對沖了你已有的持倉。
深入探討之前之前先回答一個可能的質疑:為什麼單列 Polymarket,為什麼不討論 AMM? 而不是把它合併進一個泛化的「DEX 撮合」類別?
因為 Polymarket 的特異性不在「鏈上」這個標籤上。Polymarket 真正獨特的地方是三個機制的疊加:[0, 1] 價格鉗制 + CTF 互補鑄造 + UMA 結果判定(類似 mark price)。這三個一起塑造了一種與現貨、永續合約、選擇權和其他 DEX 都不同的狀態機形態——價格空間離散有界、流動性來源無中生有、生命周期有終點。
下面按這三個機制和它們背後的信任假設為主線展開。
Polymarket 是一個(最先?)建在 Polygon 上的預測市場,所有頭寸都是 ERC-1155 代幣,由 Gnosis 的條件式代幣框架(CTF)發行。一個市場——比如某個總統選舉的二元預測——會發行兩種代幣:YES 代幣 和 NO 代幣,市場結束時一種代幣價值 $1,另一種價值 $0。
互補鑄造機制是 CTF 的核心。任何人都可以存入 1 USDC,得到 1 YES + 1 NO。任何人也可以銷毀 1 YES + 1 NO,贖回 1 USDC。這個機制的存在讓做市商可以「無中生有」地為市場提供流動性——做市商不需要先持有代幣才能賣出,他可以即時鑄造然後賣出。從撮合引擎角度看,這等價於做市商有一個無限的初始庫存,但成本約束在保證金裡——這是 Polymarket 與傳統 CLOB 的一個關鍵差別。
鏈下撮合 + 鏈上結算是 Polymarket 的整體架構。具體流程:用戶用 EIP-712 簽名一個限價訂單,發送到 Polymarket 的中心化撮合伺服器;伺服器維護一個傳統的 LOB;當兩筆訂單匹配時,伺服器把這兩個簽名打包成一筆鏈上交易,調用 exchange 合約完成結算。所以撮合本身是鏈下的(毫秒級),但結算是鏈上的(秒級)。
這個架構在 trust 層面有一個特別之處:撮合伺服器不能偽造交易,因為它沒有用戶的私鑰;但它可以審查交易——拒絕某些訂單的撮合。
Gas 經濟學塑造的是結算路徑而不是用戶行為。一個常見的誤解是把 Polymarket 的 gas 成本歸到用戶身上——實際上 gas 是 relayer(Polymarket 的 operator)付的。用戶用 EIP-712 簽訂單,relayer 在撮合後把成交批量提交上鏈,gas 由 Polymarket 承擔,再通過交易手續費回收。這意味著對用戶而言,掛單和撤單都是免費的——撤單甚至根本不上鏈,只是通知撮合伺服器把訂單移除,邏輯上和 CEX 撤單沒本質區別。
但這並不代表 gas 沒有約束力,只是約束轉移到了 relayer 一側:每筆成交的鏈上結算成本由 Polymarket 承擔,relayer 的 gas 預算 + Polygon 的吞吐上限共同決定了系統的最大成交頻率。做市商在極端擁擠時感受到的不是「掛單貴」,而是結算延遲和吞吐瓶頸——這是和 CEX 完全不同的擁擠傳導路徑。
這個架構施加給撮合引擎的真正塑形是:必須讓 relayer 能夠把多筆成交批量結算(amortize gas),同時保持每筆交易在結算合約裡獨立可驗證(防止 relayer 篡改或私吞)。
所以 Polymarket 的 exchange 合約設計為接受「多筆簽名訂單 + 一筆批量提交」的結構。Gas 沒有讓 Polymarket 變成「低頻市場」,但讓它的撮合-結算耦合方式與 CEX 和純鏈上 DEX 都不同——撮合層完全繼承 CEX 的輕量化(毫秒撤單、零 gas 掛單),結算層卻繼承了鏈上 DEX 的可驗證性約束。
預言機結果判定的終局性是預測市場撮合最特別的一點。其他三類市場都是「持續運行」的——價格永遠在變,市場永遠開放。但預測市場有一個明確的「終止時刻」:事件發生,結果被預言機(Polymarket 用 UMA 的 optimistic oracle)解析,YES 或 NO 被判定(也有被 argue 的時候,本文不討論),所有持倉按 1:0 或 0:1 結算。
這意味著撮合引擎要處理一個「市場凍結」的狀態機:在解析窗口內禁止新訂單,在 dispute 窗口內允許挑戰,最終結算後停止所有交易活動。這個狀態機在 CEX 現貨裡是沒有對應物的。
價格被鉗制在 [0, 1] 是另一個機制約束。這看起來是優勢(不會爆倉到無窮),但這味著訂單簿的價格檔位空間有限——通常是 1 cent 一檔,最多 100 檔。這對撮合數據結構是一個強約束(你可以用一個 fixed-size array 而不是 tree),但也意味著價格發現的精度有上限。

舉一個具體場景說明 mint/redeem 如何塑造做市行為。某市場 YES 報 $0.65、NO 報 $0.35(YES + NO 必然等於 $1,否則套利者立即 mint 或 redeem 拉平)。做市商 M 想為這個市場提供賣一流動性但手裡沒有 YES——他向 CTF 合約存入 100 USDC,瞬間得到 100 YES + 100 NO,把 100 YES 掛 0.66 賣、100 NO 掛 0.36 賣。
兩筆都成交後 M 持有 0 淨敞口、賺到雙邊價差 0.02 × 100 = 2 USDC。這就是 Polymarket 做市的標準玩法:用 mint/redeem 把「資本佔用」換成「雙向報價利差」。
值得專門分析的是:YES + NO = 1 這個不變量撮合引擎不需要主動維護,是市場結構通過套利者自動保證的——這種「市場結構自帶的不變量」在傳統 LOB 裡是不存在的,做市商也不可能做到「手裡沒有庫存就能賣」。Polymarket 撮合引擎的設計因此可以省掉一些 CEX 必須的庫存約束檢查,但代價是必須把 mint/redeem 路徑作為一等公民整合進結算合約。
總結一下 Polymarket 撮合的特異性:信任假設是「鏈下撮合 + 鏈上結算」的混合,token 模型是 CTF 的互補鑄造,價格空間是 [0,1] 的有界離散,時間維度是有終局的,gas 由 relayer 承擔並通過手續費回收。這些約束加起來產生了一種與前三種完全不同形態的撮合引擎。
把這四種形態鋪開看,可以提煉出五個維度來解釋為什麼撮合引擎在不同標的下分化:

將五維框架放到「撮合-風控耦合度」和「流動性密度」兩個維度上,四種形態的位置一目了然:現貨在低耦合高密度的舒適區,永續在高耦合高密度(最複雜的工程現實),期權在高耦合低密度(必須用 RFQ + combo 彌補稀疏),Polymarket 落在中間——耦合度被鏈上結算抬高了,密度被互補鑄造拉上來了。

每個維度都對撮合引擎施加壓力:
資產形態決定了訂單簿的數量和稀疏度。單維同質(現貨、永續)只需要一個簿,多維稀疏(期權)需要幾百個簿且必須解決 sparsity,離散互補(Polymarket)需要將「鑄造/贖回」整合進撮合路徑。
結算時序決定了狀態機的複雜度。即時同步(現貨)讓撮合等於結算;持續記賬(永續、期權)需要維護持倉狀態、保證金狀態、PnL 狀態,並在每次撮合後更新;終局解析(Polymarket)需要狀態機從「開放」到「凍結」到「解析」的轉換。
風險拓樸決定了風險管理耦合度。線性零持倉(現貨)幾乎不需要風險管理;線性持續敞口(永續)需要 pre-trade 保證金檢查和清算引擎;凸性(期權)需要 Greeks-based 組合保證金;二元有界(預測市場)幾乎不需要風險管理(最大損失就是已支付的錢)。
流動性密度決定了流動性來源策略。高密度市場可以純 LOB;稀疏市場必須引入 RFQ、AMM、做市商激勵等補充機制。
信任邊界決定了哪些組件必須可驗證。CEX 中所有組件都在交易平台內部;純 DEX 中所有組件都在鏈上;混合架構中需要明確什麼必須上鏈(結算)、什麼可以離鏈(撮合)、攻擊模型是什麼(無法盜錢但可審查)。
回到開頭的問題——為什麼「撮合引擎」在不同市場分化成四種幾乎不同的機器?
因為撮合從來不是一個獨立的工程模塊,它是標的物自身性質、結算模型、風險結構、流動性形態、信任假設這五個變數綜合作用的產物。撮合引擎是這些變數的樣貌——你看到撮合長什麼樣,反過來就能推出這個市場的金融結構是什麼樣。
現貨撮合的簡潔,對應的是「同質資產 + 一次性結算 + 零持倉延續」的乾淨結構;
永續合約撮合的複雜,對應的是「合成資產 + 持續敞口 + 風控-撮合深度耦合」的工程現實;
期權撮合的混合形態,對應的是「維度爆炸 + 流動性稀疏 + 做市商主導」的市場結構;
Polymarket 撮合的鏈上鏈下分裂,對應的是「無審查」與「抗盜竊」兩個安全目標的工程妥協。
如果說清算是交易平台的良心,那麼撮合機制就是交易平台的底線。
原文連結
歡迎加入律動 BlockBeats 官方社群:
Telegram 訂閱群:https://t.me/theblockbeats
Telegram 交流群:https://t.me/BlockBeats_App
Twitter 官方帳號:https://twitter.com/BlockBeatsAsia