原文標題:《Polymarket PnL 精準計算:為什麼你算的盈虧可能全是錯的》 原文作者:Leo,加密分析師
我在 Polymarket 自研自動化交易半年,踩過的最大坑不是策略失靈,是連自己賺了多少錢都算不對。
不是我菜。是 PM 的 PnL 計算本身就是雷區。官方 API 給你的數字是錯的,第三方分析網站展示的排名也是錯的。你自己寫腳本算?大概率還是錯的。
偏差有多離譜?排行榜第 3 名 kch123,用錯誤方法算出來虧 $350 萬,實際盈利 $1140 萬。不是差幾個百分點——是盈虧符號都反了。
這篇把我踩過的每個坑拆開講。做交易的、寫工具的、看排行榜的,遲早會遇到。
最直覺的做法:拉 /positions 接口,求和 cashPnl(現金盈虧)字段。
拿排行榜前 15 的三個地址實測:
**swisstony:**cashPnl 求和 +$3.5 萬,排行榜實際 +$560 萬,差 158 倍
**kch123:**cashPnl 求和 -$352 萬,排行榜實際 +$1140 萬,符號反轉
**gmanas:**cashPnl 求和 -$264 萬,排行榜實際 +$502 萬,符號反轉
三個地址,兩個盈虧符號直接反了。
原因:/positions 接口返回的 cashPnl 不包含已 closed/redeemed 的 realized PnL。贏了的倉位被自動贖回成 USDC 後,這個 position 就從 API 響應裡消失了。留下來的是未結算的持倉——往往以浮虧為主。
你以為在算全部盈虧,其實只拿到了未結算的部分。
交易數據 JSONL 裡有個 makerPnl(做市盈虧)字段,看名字就是給你算 PnL 用的。別信。
我在做市數據中觀察到,SUM(makerPnl) 算出來的數字跟鏈上現金流核算結果差了一個數量級。具體倍數可能因場景不同而變化,但方向一致:makerPnl 的內部計算邏輯跟實際 USDC 流動對不上。
不管偏差多大,結論一樣:不要用這個字段算 PnL。
這個最反直覺。
同一個 txHash(交易哈希)出現了多條記錄,正常人第一反應:重複數據,去重。
不能這麼做。PM 的 CLOB(鏈上限價訂單簿)在一筆鏈上交易裡可以撮合多個 maker 訂單,同一個 txHash 下的多條記錄是真實的獨立 fill。
我之前按 txHash + asset 去重,BUY 側少算了 $133。上 Polygon 鏈驗證,一個交易哈希裡確實有多個獨立的 USDC Transfer 事件,每條都對應一筆真實成交。
結論:不能按 txHash alone 去重。要算 PnL,直接對 /activity 原始數據求和。
/activity 接口翻頁,用 offset(偏移量)?超過 3000 條直接 400 報錯。文件裡沒寫。
上面三個地址全部驗證過:GET /activity?offset=3100 返回 HTTP 400,錯誤信息 max historical activity offset of 3000 exceeded。頭部玩家動輒上萬筆交易,3000 條根本不夠。
用 end 參數(傳上一頁最後一條的時間戳 - 1)做游標翻頁,沒有上限。
你算完一個地址的 PnL,去排行榜一對比,差了一點。
大多數情況下差距在 $10 以內(來自持倉市值的實時波動)。但如果差距明顯更大,可能的原因包括:排行榜的聚合窗口、快取刷新延遲、或者用戶綁定了多個 proxy wallet。
實測中,用現金流法算出的單地址 PnL 跟 lb-api 返回值高度一致。如果你的結果差距較大,先檢查翻頁是否完整(坑 4)、是否用了錯誤字段(坑 1-2)。
試了各種歪路之後,我驗證下來最可靠的方法是 Data API 現金流匯總。不用任何預計算字段,直接從原始交易記錄算資金進出。
公式:
PnL = SUM(TRADE where side=SELL) + SUM(REDEEM) + SUM(MERGE) + SUM(MAKER_REBATE) + SUM(REWARD) - SUM(TRADE where side=BUY) - SUM(SPLIT) + 持倉市值
· TRADE BUY:花 USDC 買 token(支出)
· TRADE SELL:賣 token 回收 USDC(收入)
· REDEEM:贏的倉位贖回 USDC(收入)
· SPLIT:USDC 鑄造成 token 對(支出)
· MERGE:token 對合併回 USDC(收入)
· MAKER_REBATE:Maker 返佣(收入)
· REWARD:獎勵/空投(收入)
· 數據來源:
GET /activity?user=
· 持倉市值:
GET /positions?user=
· 交叉驗證:
拿計算結果跟 Polymarket 排行榜 API(lb-api.polymarket.com/profit?window=all&address=X)對比,差 <$10 就算過。差距來自持倉市值的實時波動。
用現金流法算完後,拿排行榜 API 交叉驗證:
swisstony:現金流法 +$560.1 萬,排行榜 +$560.1 萬,差距 < $10
kch123:現金流法 +$1139.6 萬,排行榜 +$1139.6 萬,差距 < $10
gmanas:現金流法 +$502.4 萬,排行榜 +$502.4 萬,差距 < $10
三個地址誤差均在 $10 以內,差距來自持倉市值的實時波動。
方法跑通之後,我拿它分析了上百個頭部地址的真實盈虧。那是另一回事了。
SUM(cashPnl) from /positions → 不行,不含已結算盈利,符號可能反轉
makerPnl 字段求和 → 不行,與鏈上現金流不一致
按 txHash 去重後計算 → 不行,$100+,刪了真實 fill
offset 翻頁 + 求和 → 不行,數據截斷,>3000 報錯
Data API 現金流法 → 目前最可靠,<$10
做量化的第一步不是找 alpha。是先確認你算得對。
以上全部來自實盤踩坑,不是理論推導。PM 的 API 隨時可能調整行為,建議定期用排行榜 API 交叉驗證你的計算結果。
原文連結
點擊了解律動BlockBeats 在招崗位
歡迎加入律動 BlockBeats 官方社群:
Telegram 訂閱群:https://t.me/theblockbeats
Telegram 交流群:https://t.me/BlockBeats_App
Twitter 官方帳號:https://twitter.com/BlockBeatsAsia
54.73萬 熱度
5876.76萬 熱度
103.17萬 熱度
4.36萬 熱度
1019.63萬 熱度
Polymarket PnL 精準計算:為什麼你算的盈虧可能是錯的?
我在 Polymarket 自研自動化交易半年,踩過的最大坑不是策略失靈,是連自己賺了多少錢都算不對。
不是我菜。是 PM 的 PnL 計算本身就是雷區。官方 API 給你的數字是錯的,第三方分析網站展示的排名也是錯的。你自己寫腳本算?大概率還是錯的。
偏差有多離譜?排行榜第 3 名 kch123,用錯誤方法算出來虧 $350 萬,實際盈利 $1140 萬。不是差幾個百分點——是盈虧符號都反了。
這篇把我踩過的每個坑拆開講。做交易的、寫工具的、看排行榜的,遲早會遇到。
坑 1:cashPnl 不包含已結算的盈利
最直覺的做法:拉 /positions 接口,求和 cashPnl(現金盈虧)字段。
拿排行榜前 15 的三個地址實測:
**swisstony:**cashPnl 求和 +$3.5 萬,排行榜實際 +$560 萬,差 158 倍
**kch123:**cashPnl 求和 -$352 萬,排行榜實際 +$1140 萬,符號反轉
**gmanas:**cashPnl 求和 -$264 萬,排行榜實際 +$502 萬,符號反轉
三個地址,兩個盈虧符號直接反了。
原因:/positions 接口返回的 cashPnl 不包含已 closed/redeemed 的 realized PnL。贏了的倉位被自動贖回成 USDC 後,這個 position 就從 API 響應裡消失了。留下來的是未結算的持倉——往往以浮虧為主。
你以為在算全部盈虧,其實只拿到了未結算的部分。
坑 2:makerPnl 字段與鏈上現金流不一致
交易數據 JSONL 裡有個 makerPnl(做市盈虧)字段,看名字就是給你算 PnL 用的。別信。
我在做市數據中觀察到,SUM(makerPnl) 算出來的數字跟鏈上現金流核算結果差了一個數量級。具體倍數可能因場景不同而變化,但方向一致:makerPnl 的內部計算邏輯跟實際 USDC 流動對不上。
不管偏差多大,結論一樣:不要用這個字段算 PnL。
坑 3:不能按 txHash 單獨去重
這個最反直覺。
同一個 txHash(交易哈希)出現了多條記錄,正常人第一反應:重複數據,去重。
不能這麼做。PM 的 CLOB(鏈上限價訂單簿)在一筆鏈上交易裡可以撮合多個 maker 訂單,同一個 txHash 下的多條記錄是真實的獨立 fill。
我之前按 txHash + asset 去重,BUY 側少算了 $133。上 Polygon 鏈驗證,一個交易哈希裡確實有多個獨立的 USDC Transfer 事件,每條都對應一筆真實成交。
結論:不能按 txHash alone 去重。要算 PnL,直接對 /activity 原始數據求和。
坑 4:offset 翻頁有天花板
/activity 接口翻頁,用 offset(偏移量)?超過 3000 條直接 400 報錯。文件裡沒寫。
上面三個地址全部驗證過:GET /activity?offset=3100 返回 HTTP 400,錯誤信息 max historical activity offset of 3000 exceeded。頭部玩家動輒上萬筆交易,3000 條根本不夠。
用 end 參數(傳上一頁最後一條的時間戳 - 1)做游標翻頁,沒有上限。
坑 5:排行榜 PnL 口徑差異
你算完一個地址的 PnL,去排行榜一對比,差了一點。
大多數情況下差距在 $10 以內(來自持倉市值的實時波動)。但如果差距明顯更大,可能的原因包括:排行榜的聚合窗口、快取刷新延遲、或者用戶綁定了多個 proxy wallet。
實測中,用現金流法算出的單地址 PnL 跟 lb-api 返回值高度一致。如果你的結果差距較大,先檢查翻頁是否完整(坑 4)、是否用了錯誤字段(坑 1-2)。
正確做法
試了各種歪路之後,我驗證下來最可靠的方法是 Data API 現金流匯總。不用任何預計算字段,直接從原始交易記錄算資金進出。
公式:
PnL = SUM(TRADE where side=SELL) + SUM(REDEEM) + SUM(MERGE) + SUM(MAKER_REBATE) + SUM(REWARD) - SUM(TRADE where side=BUY) - SUM(SPLIT) + 持倉市值
· TRADE BUY:花 USDC 買 token(支出)
· TRADE SELL:賣 token 回收 USDC(收入)
· REDEEM:贏的倉位贖回 USDC(收入)
· SPLIT:USDC 鑄造成 token 對(支出)
· MERGE:token 對合併回 USDC(收入)
· MAKER_REBATE:Maker 返佣(收入)
· REWARD:獎勵/空投(收入)
· 數據來源:
GET /activity?user=
&limit=500,用 end 翻頁,全量拉取後按類型求和。· 持倉市值:
GET /positions?user=
,size × curPrice。· 交叉驗證:
拿計算結果跟 Polymarket 排行榜 API(lb-api.polymarket.com/profit?window=all&address=X)對比,差 <$10 就算過。差距來自持倉市值的實時波動。
驗證:排行榜前 15 實測
用現金流法算完後,拿排行榜 API 交叉驗證:
swisstony:現金流法 +$560.1 萬,排行榜 +$560.1 萬,差距 < $10
kch123:現金流法 +$1139.6 萬,排行榜 +$1139.6 萬,差距 < $10
gmanas:現金流法 +$502.4 萬,排行榜 +$502.4 萬,差距 < $10
三個地址誤差均在 $10 以內,差距來自持倉市值的實時波動。
方法跑通之後,我拿它分析了上百個頭部地址的真實盈虧。那是另一回事了。
匯總
SUM(cashPnl) from /positions → 不行,不含已結算盈利,符號可能反轉
makerPnl 字段求和 → 不行,與鏈上現金流不一致
按 txHash 去重後計算 → 不行,$100+,刪了真實 fill
offset 翻頁 + 求和 → 不行,數據截斷,>3000 報錯
Data API 現金流法 → 目前最可靠,<$10
做量化的第一步不是找 alpha。是先確認你算得對。
以上全部來自實盤踩坑,不是理論推導。PM 的 API 隨時可能調整行為,建議定期用排行榜 API 交叉驗證你的計算結果。
點擊了解律動BlockBeats 在招崗位
歡迎加入律動 BlockBeats 官方社群:
Telegram 訂閱群:https://t.me/theblockbeats
Telegram 交流群:https://t.me/BlockBeats_App
Twitter 官方帳號:https://twitter.com/BlockBeatsAsia