You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Looking for input from anyone who's written their own Polymarket fill reconciliation. This is the corner where I burned the most hours building pnl-truthteller and I want to know if I solved it the same way everyone else does or if I'm still missing something.
The problem
For every market order I post, the CLOB API returns a single order_id even when the order fills across N maker orders. When I later pull /data/trades and /data/transactions to reconcile, I get:
Multiple trade rows that share the same parent order_id
Multiple transaction rows that point to the same underlying maker fill in some edge cases
Occasionally a single fill split into two rows because of how OrderFilledQuantity events get emitted when a sweep retry lands on the same maker
If you sum naively, you double-count shares on the trades-side and triple-count fees on the transactions-side. Net effect: reported slippage looks better than reality, which is the opposite of the bug I was trying to surface.
What I'm doing in pnl-truthteller right now
Dedup key = (order_id, maker_order_id, transaction_hash, log_index) collapsed via a stable hash. I keep the row with the largest match_amount, drop the rest. For transactions, I dedup on (tx_hash, log_index) alone since the same op_hash can show up under two orders in proxy-wallet flows.
That was enough to get my 320-trade self-audit (+$34.31 DB → -$90.72 on-chain) to reconcile to within $0.02 of the wallet's actual USDC balance change. So I think it's right. But I built it solo, didn't have anything to cross-check against, and the random-wallet replication (0x1417…, 65 trades, +$32.36 DB → -$30.29 on-chain) is the only external data point I have.
Two questions
Anyone using a different dedup key? Specifically: do you trust transaction_hash + log_index as a primary key, or have you seen the CLOB emit the same (tx_hash, log_index) for distinct fills?
Edge case I'm unsure about: when a proxy-wallet executeTransaction bundles multiple maker fills, my current logic counts each maker fill independently. Should I be deduping at the bundle level instead? I haven't seen this affect totals but my N is small.
If you want to reproduce against your own wallet first:
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Looking for input from anyone who's written their own Polymarket fill reconciliation. This is the corner where I burned the most hours building
pnl-truthtellerand I want to know if I solved it the same way everyone else does or if I'm still missing something.The problem
For every market order I post, the CLOB API returns a single
order_ideven when the order fills across N maker orders. When I later pull/data/tradesand/data/transactionsto reconcile, I get:traderows that share the same parentorder_idtransactionrows that point to the same underlying maker fill in some edge casesOrderFilledQuantityevents get emitted when a sweep retry lands on the same makerIf you sum naively, you double-count shares on the trades-side and triple-count fees on the transactions-side. Net effect: reported slippage looks better than reality, which is the opposite of the bug I was trying to surface.
What I'm doing in
pnl-truthtellerright nowDedup key =
(order_id, maker_order_id, transaction_hash, log_index)collapsed via a stable hash. I keep the row with the largestmatch_amount, drop the rest. For transactions, I dedup on(tx_hash, log_index)alone since the sameop_hashcan show up under two orders in proxy-wallet flows.That was enough to get my 320-trade self-audit (
+$34.31 DB → -$90.72 on-chain) to reconcile to within $0.02 of the wallet's actual USDC balance change. So I think it's right. But I built it solo, didn't have anything to cross-check against, and the random-wallet replication (0x1417…, 65 trades,+$32.36 DB → -$30.29 on-chain) is the only external data point I have.Two questions
transaction_hash + log_indexas a primary key, or have you seen the CLOB emit the same(tx_hash, log_index)for distinct fills?executeTransactionbundles multiple maker fills, my current logic counts each maker fill independently. Should I be deduping at the bundle level instead? I haven't seen this affect totals but my N is small.If you want to reproduce against your own wallet first:
Read-only, no private key needed. Output is a markdown report — the "by exit reason" table is the one that surfaced my TIMEOUT-exit bleed.
If your slippage delta lands wildly different from mine (mine: ~5–7% on volume), I want to know — drop the number here.
Beta Was this translation helpful? Give feedback.
All reactions