Polymarket盈亏计算误区:你的收益可能算错了

作者:技术拾光

时间:2026-05-07

浏览:516

Polymarket的盈亏计算存在多个陷阱,导致结果严重失真。官方API的cashPnl字段不包含已结算盈利,直接求和可能盈亏符号相反。makerPnl字段与链上现金流不符,不应使用。交易数据不能仅按txHash去重,否则会遗漏真实成交。/activity接口使用offset翻页超过3000条会报错,应改用end参数。排行榜数据因缓存或聚合窗口可能略有差异。

文章目录

Polymarket PnL精准计算:为什么你算的盈亏可能是错的?

Polymarket盈亏计算误区:你的收益可能算错了

在Polymarket上搞了半年自动化交易,踩过最大的坑是什么?不是策略失效,而是连自己到底赚了多少钱都算不清楚。

这还真不是水平问题。Polymarket的盈亏计算本身就是一个雷区。官方API给的数据可能是错的,第三方分析网站展示的排名也可能是错的。你自己动手写脚本算?大概率还是错的。

偏差能有多离谱?拿排行榜上那位排名第三的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(赎回)的已实现盈亏。赢了的仓位一旦被自动赎回成USDC,这个仓位就会从API的响应里消失。留下来的,基本都是尚未结算的持仓——而这些持仓,往往以浮亏为主。

你以为在计算全部盈亏,其实只抓到了未结算的那部分。

坑 2:makerPnl 字段与链上现金流不一致

交易数据的JSONL里有个makerPnl(做市盈亏)字段,看名字就是用来算盈亏的。千万别信。

在做市数据中可以观察到,对makerPnl字段求和得到的结果,与根据链上现金流核算出来的数字,能差出一个数量级。具体倍数可能因场景而异,但方向一致:makerPnl的内部计算逻辑,与实际发生的USDC流动根本对不上。

不管偏差具体是多少,结论都一样:不要用这个字段来计算PnL。

坑 3:不能按 txHash 单独去重

这个坑最反直觉。

看到同一个txHash(交易哈希)对应着多条记录,正常人的第一反应是:重复数据,去重。

但恰恰不能这么做。Polymarket的CLOB(链上限价订单簿)机制,允许在一笔链上交易里撮合多个做市商订单。因此,同一个txHash下的多条记录,很可能对应着真实的、独立的成交记录。

曾经尝试按txHash和asset去重,结果在BUY侧少算了133美元。上Polygon链验证后发现,一个交易哈希里确实存在多个独立的USDC转账事件,每一条都对应一笔真实成交。

结论很明确:不能仅按txHash去重。要准确计算PnL,必须直接对/activity的原始数据求和。

坑 4:offset 翻页有天花板

使用/activity接口翻页时,如果用offset(偏移量)参数?一旦超过3000条,直接返回400错误。文档里可没提这茬。

上面提到的三个地址全部验证过:请求GET /activityoffset=3100会返回HTTP 400,错误信息是“max historical activity offset of 3000 exceeded”。对于交易动辄上万笔的头部玩家来说,3000条根本不够用。

正确的做法是使用end参数(传入上一页最后一条记录的时间戳减1)进行游标翻页,这种方法没有上限限制。

坑 5:排行榜 PnL 口径差异

自己算完一个地址的PnL,兴冲冲去和排行榜对比,发现差了一点。

大多数情况下,差距在10美元以内(这通常来自持仓市值的实时波动)。但如果差距明显更大,可能的原因包括:排行榜的聚合时间窗口、缓存刷新延迟,或者用户绑定了多个袋里钱&包。

实测表明,用现金流法算出的单地址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购买代币(记为支出)

· TRADE SELL:卖出代币回收USDC(记为收入)

· REDEEM:获胜的仓位赎回为USDC(记为收入)

· SPLIT:将USDC铸造为代币对(记为支出)

· MERGE:将代币对合并回USDC(记为收入)

· MAKER_REBATE:做市商返佣(记为收入)

· REWARD:奖励或空投(记为收入)

数据来源:

调用GET /activityuser=&limit=500,使用end参数翻页,拉取全量数据后按上述类型分别求和。

持仓市值:

调用GET /positionsuser=,计算每个仓位的size × curPrice并加总。

交叉验证:

将计算结果与Polymarket排行榜API(lb-api.polymarket.com/profitwindow=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 去重后计算 → 不行。动辄少算上百美元,删除了真实成交记录。

· offset 翻页 + 求和 → 不行。数据会被截断,超过3000条直接报错。

· Data API 现金流法 → 目前最可靠,误差可控制在10美元以内。

说到底,做量化的第一步不是寻找阿尔法收益,而是先确保你算得对。

以上结论全部来自实盘踩坑,而非理论推导。必须提醒的是,Polymarket的API行为随时可能调整,建议定期用排行榜API交叉验证你的计算结果。

点击了解律动BlockBeats 在招岗位

欢迎加入律动 BlockBeats 官方社群:

Telegram 订阅群:https://t.me/theblockbeats

Telegram 交流群:https://t.me/BlockBeats_App

Twitter 官方账号:https://twitter.com/BlockBeatsAsia

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章