Polymarket 跟單系統:從 6700 萬筆成交裡篩出值得跟的錢包
Back to Projects
blockchaintradingprediction-marketssmart-moneycopy-trading

Polymarket 跟單系統:從 6700 萬筆成交裡篩出值得跟的錢包

跟著預測市場的贏家下單,你永遠慢一到三秒。這套系統先算清楚誰的獲利是慢一拍也拿得到的,再決定跟不跟。

Polymarket 跟單系統:從 6700 萬筆成交裡篩出值得跟的錢包

Polymarket 是目前最大的鏈上預測市場,大家在上面對選舉、球賽、加密貨幣價格這類事件的結果下注。這個專案是我做的一套跟單系統。所有成交都留在鏈上,誰在長期穩定獲利一查就知道,所以最自然的策略只有一句話:他買什麼,我就買什麼。

我照做了,用的是真錢。結果是他繼續賺,我在賠。


延遲約束:跟單者慢一到三秒

賠錢的原因藏在物理層,不在選人。跟單者從看到成交、解析,到掛出自己的單,比被跟的人慢一到三秒。別小看這一小段延遲,它足夠造出系統性的逆選擇:當對方買到便宜的好單,那個價位的掛單早就被吃光,輪不到你;當對方買貴了,那張單安安穩穩地留在那裡等你成交。好單搶不到,爛單全收下。模擬裡勝率 65% 的策略,真實下單後掉到 50%,跟丟銅板沒兩樣。

更麻煩的是,事前完全看不出來。我一開始用歷史成交重放來模擬,它默認你能和對方同價成交,估出來每個候選都大賺。後來換成會模擬真實掛單簿加延遲的回測引擎重跑,同一批候選,全部判虧。回測不是不準,是它默認了一個不存在的世界:你和對方同時到場。


系統定位:這套系統回答什麼問題

認清這件事之後,要解的問題本身就變了。排行榜回答「誰賺最多」。這套系統問的是另一個問題,「誰的獲利,是慢一到三秒的人也拿得到的」。聽起來像同一件事對吧?實際跑出來,答案的重疊少得可憐。而且系統的預設答案是不跟。


三系統分工:一條單行道

回答這個問題的工作,我切成三個各自獨立的 repo,邊界只有一條,「碰不碰錢」:

區塊做什麼為什麼獨立存在
選人管線(sm_pipeline, Python)從全市場歷史成交篩出跟得上的錢包,輸出一份名單 CSV純資料分析,不持有私鑰,跑一百次也不可能下錯一張單
驗證與跟單引擎(Kronos用模擬掛單簿加延遲重放候選錢包,是名單升降級的唯一依據;即時側逐筆判斷「這一筆要不要跟」驗證標準必須獨立於選人邏輯,同一份資料既選人又驗人,驗證就失去意義
執行服務(PolyHermes, Kotlin + React)監控名單錢包的成交、實際簽名下單、帳戶管理與儀表板碰真錢的服務,部署節奏和測試策略跟研究管線完全不同,混在一起互相拖累

三塊怎麼串起來,一張圖說完:

Polymarket API / Dune (鏈上成交資料)
        |  raw events (JSONL)
        v
[sm_pipeline]  收集 -> 聚合 -> 稽核 -> 硬性門檻
        |  名單 CSV (action + stars, 每日重建)
        v
[Kronos]  backtest: 名單升降級的唯一依據
          即時引擎: 逐筆過 13 道執行期 gate
        |  放行的跟單訊號
        v
[PolyHermes]  雙路監控 -> 去重 -> 簽名下單 -> 成交追蹤
        |
        v
Polymarket CLOB (真實成交)

三塊之間唯一的介面是那份名單 CSV,而且是單行道:選人端不知道下游怎麼下單,執行端不知道名單怎麼算出來的,中間沒有共享資料庫,沒有回呼。這條單行道的代價是新鮮度,名單每天重建而不是即時更新;換到的是研究端永遠碰不到錢,我可以放心讓分析管線整晚亂跑。


篩選漏斗:從 6700 萬筆成交到 24 個錢包

單行道的最上游是一個漏斗。選人管線的輸入是約 6700 萬筆原始成交。這個量級,人工覆核想都不用想,所有判斷只能走規則。成交先聚合成「回合」:一個錢包在一個市場從進場到結算算一回合,這是評估勝率的最小單位。回合再壓成「錢包 x 市場類型」的聚合列,因為同一個錢包在體育盤和加密盤的行為可能是兩種人。50 多萬個這樣的候選過完硬性門檻後,剩下約 24 個。十萬裡挑不到五個,這個比例本身就是設計:門檻篩的不是「誰賺錢」,是「誰的賺法抄得到」。

所有門檻的閾值只活在一個常數檔 gates.py 裡,其他模組只准 import,不准自己寫死數字。而門檻的執行不只一層:

Kronos sims --> 稽核快取 (批次產出, 可能過期)
                    |
  LAYER 1  discover: 50 多萬候選 x 硬性門檻 -> 約 24 個
                    |
  LAYER 2  pipeline: 對這 24 個即時重跑稽核, 同一組門檻再過一次
                    |
  LAYER 3  dashboard: 純顯示, 不做任何判斷

看到這裡你可能想問,Layer 1 和 Layer 2 跑同一組門檻,不是寫重複了嗎?還真不是。全量稽核太慢,只能批次跑,批次結果就會過期:一個錢包可能拿三天前的快取數字通過 Layer 1,而它的行為早就惡化。對已經縮到 24 個的集合即時重算很便宜,所以 Layer 2 用重複計算把「快取過期」這個洞補上。用算力換一致性,這筆帳在名單只有二十幾列時怎麼算都划算。

每個通過的錢包,最後收斂成一個決策物件:

@dataclass
class Decision:
    action: str            # COPY | OBSERVE | SKIP
    stars: int             # 1-5, 信心分級
    edge_score: float      # 0-1, 有沒有真實優勢
    capital_score: float   # 0-1, 資金行為健康度
    behavior_score: float  # 0-1, 交易行為健康度
    capture_ratio: float   # 跟單模擬能吃到本尊獲利的比例
    why: str               # 前三個入選理由
    watchout: str          # 前三個風險

這個 Decision 是來清算舊系統的:之前並行存在好幾套評分,彼此打架,連我自己都說不清一個錢包到底為什麼入選。物件裡少了一個欄位,下注金額。這是故意的。倉位是執行端的決策,不同 bot 風險偏好不同,選人端只給訊號不給倉位,邊界才不會滲漏。而 capture_ratio 是整個物件裡最誠實的欄位,它量的是跟在後面的人實際吃得到的獲利比例,跟這個錢包自己賺多少無關。


執行期 gates:逐筆再過 13 道檢查

Decision 是錢包層級的結論,下單卻是逐筆的事。Kronos 的即時引擎在每一筆訊號進來時再過一層執行期 gate,共 13 道:進場是否已經太晚,市場是否臨近結算,盤口有沒有價格,當日虧損是否觸頂,總曝險是否超限。兩層的責任刻意分開:名單回答「這個人值不值得跟」,執行期 gate 回答「此刻跟這一筆會不會死」。


下單服務:假設外部依賴一定會斷

過完 gate 放行的訊號,才交給 PolyHermes 下單。它同時聽兩路資料來源:一路延遲不到 0.1 秒,快到能趕在掛單被吃光前跟上,但偶爾掉線;一路慢 2 到 3 秒但不會漏,當備援。兩路必然重複,中間放一層去重,保證同一筆成交只觸發一次跟單。這是把「外部依賴一定會斷」當前提的設計。監控、下單、帳戶管理、事後追蹤在它內部各自是獨立服務,細節我就不展開了,因為對整個系統來說,PolyHermes 的契約就一句話:給它一個放行的訊號,它把單下出去,記好帳。


決策演進:十八條決策記錄

上面是系統現在的樣子。長成這樣之前,它整個方向被推翻過好幾次。專案的決策日誌從第 101 條寫到第 118 條(每條記錄一次「選了什麼,放棄了什麼,代價是什麼」),記的全是同一個問題,地址級跟單到底可不可行。

最早的一整個階段都在找「一個值得長期跟的人」,模擬估出好幾個大賺的人選,真錢跟單的下場寫在本文開頭。轉折點是我跑去研究了一個真的在賺錢的跟單者。把他的下單行為重建出來一看,他的勝率和「進場前已經有幾個獨立聰明錢包押在同一邊」強相關。同押的只有 0 到 2 個時勝率 33%,這正是單一 leader 跟單的處境;11 個以上同押時 77%。整個框架於是從「找誰來跟」改成「數有幾個人同意」,也就是共識訊號。

之後的記錄更難堪也更誠實。我一度正式宣告地址級路線死亡,過陣子又撤回,因為發現當初用錯了族群和參數。再後來又發現,先前的否定其實是倉位算法造成的假象,這條路又活了。十八條記錄,幾次自我推翻,我到現在也不敢說哪一條是終局。

其中最痛的一條和策略無關。早期設計過一組硬性黑名單,四種確定危險的行為模式直接擋掉。三個月後三路獨立 code review 一查,我盯著結果愣了半天:因為比對的是人類可讀的名字而不是機器代碼,這個黑名單在 21.6 萬列資料上命中 0 次。安全網掛在牆上,從來沒接上過。同一輪修正順帶重跑了統計檢定,舊名單 364 個通過者只剩 107 個,七成是統計噪音。

教訓寫在文件裡,不等於教訓寫進了 code。

這句話後來變成整個專案數值紀律的來源:閾值集中在單一常數檔,修好的黑名單用 regression test 釘死,每次改判斷邏輯先讓新舊版本對同一批資料各跑一次,看名單差在哪裡再上線。


現況:真錢 30 天的成績單

紀律建起來之後,真實成績是多少?真錢跑 30 天,+$656。不是會讓任何人辭職的數字,而且九成九的收益集中在最近 7 天,樣本遠不足以宣稱什麼。共識訊號那條路線,文件裡最後的狀態還停在紙上驗證,邊際薄到滑點惡化 2% 就轉負,我不敢推上實盤。系統裡還躺著一筆我明知道的債:兩份欄位不同的名單 CSV 並存,一份給 bot 讀一份給儀表板,合併還是廢棄,這個決定拖到現在沒下。

這個專案真正教我的是怎麼對待「看起來成立的結論」,跟單技巧反而其次。在一個你永遠慢一秒的市場裡,回測給的每一個好消息,預設都是假的,直到真錢和鏈上事實投了同意票為止。

Joey Chen

Joey Chen

Build things that are interesting. All made by AI.

AIWeb3