Polymarket Copytrading Bots: Tracking Smart Wallets On-Chain
Build a Polymarket copytrading bot that mirrors smart wallets from on-chain Polygon fills and the Data API, with slippage-aware entry that skips dead trades.
A wallet that turned $4,000 into $180,000 shorting election longshots is public information on Polygon. Every fill it took, every price it paid, every size — all of it sits in the CTF Exchange contract logs, timestamped and immutable. The question a copytrading bot answers is narrow: can you see that wallet's fill, decide it's worth copying, and get your own order in before the edge evaporates? On Polymarket the answer is usually yes, but the window is measured in seconds and the naive version of this bot loses money on slippage alone.
I've built a few of these. The mechanics are less exotic than people expect, and the hard parts are exactly the parts nobody writes about.
Where the fills actually live
Polymarket settles trades through the CTF Exchange contract on Polygon. When a maker and taker match, the contract emits an OrderFilled event carrying the maker, taker, the asset IDs (the ERC-1155 conditional token positions), the amounts on each side, and the fee. That event is your ground truth. It's already happened, it's confirmed, and it can't be spoofed the way an off-chain feed can.
There are two ways to watch it, and you want both:
- The Data API (
data-api.polymarket.com) exposes a/tradesendpoint you can filter byuser(a proxy wallet address). It's enriched — you get the market slug, outcome, price, and side already decoded, which saves you a pile of ABI work. Latency is typically 1–3 seconds behind the chain. - Raw event logs via a websocket to a Polygon node (your own, or a provider with a low-latency
eth_subscribe). This is faster but you decode the log yourself and map asset IDs back to markets. You'll want an archive-capable RPC because you'll be backfilling wallet history constantly.
Run the Data API as your enrichment and discovery layer, and raw logs as your real-time trigger. If you build only on the Data API you inherit its polling cadence, and a few extra seconds is the difference between copying a fill and copying a corpse.
One catch that bites everyone: Polymarket accounts trade through proxy wallets (Gnosis Safe or the magic-link proxy), not the EOA that funded them. The address you track is the proxy. If you scrape a leaderboard address and subscribe to the EOA, you'll see nothing. Resolve the proxy first, then subscribe to that.
Picking wallets worth copying
Raw PnL is a trap. A wallet up 900% might have done it on one resolved market that already paid out — there's nothing left to copy. What you want is a wallet whose live, open behavior has predictive value.
I score candidates on a few axes computed from their trade history:
- Realized win rate on resolved markets, weighted by size, over at least 50–80 settled positions. Fewer than that and you're fitting noise.
- Median hold time. A wallet that flips positions in minutes needs a completely different execution path than one that accumulates over days. Match your bot to the style you're copying.
- Entry-vs-resolution edge — how far below fair value they typically buy. This tells you whether they're an information trader or just a momentum chaser you can't keep up with.
The optimistic-oracle mechanics matter here too, because a wallet's edge often comes from correctly reading how a market will resolve. If you're serious about following resolution-driven traders, it's worth understanding how UMA's optimistic oracle actually settles Polymarket markets so you can tell a genuine edge from a lucky guess on a market that hadn't been disputed yet.
Slippage-aware entry, or why the naive copy loses
Here's the part that separates a toy from a working Polymarket copytrading bot. The wallet you're copying got a price. You will not get that price. By the time your trigger fires, their fill has already moved the book, and copiers ahead of you have moved it more.
So you never blindly market-buy. You compute a max acceptable price relative to the observed fill and walk the book:
def plan_entry(observed_fill, book, budget_usdc, max_slip_bps=150):
target = observed_fill["price"] # e.g. 0.42
cap = target * (1 + max_slip_bps / 10_000) # 0.4263
filled, cost = 0.0, 0.0
for level in book["asks"]: # ascending price
if level["price"] > cap:
break # never chase past the cap
take = min(level["size"], (budget_usdc - cost) / level["price"])
filled += take
cost += take * level["price"]
if cost >= budget_usdc:
break
return filled, cost # may be a partial or zero fill
A zero fill is a feature. If the book has already run past your cap, the edge is gone and the correct copy size is nothing. Bots that force the fill "to stay in sync with the target" are the ones bleeding to the market makers. Sizing gets its own rule: cap each position as a fraction of the target's stake scaled to your own bankroll, and never let one hot market blow past a per-market limit. The signing and order-placement details for these entries live in the CLOB, and if you haven't wired that up yet, the order-signing deep dive covers the EIP-712 payload and the pitfalls around nonces and expirations.
A pragmatic architecture
Keep the pieces separate so you can reason about each:
- Watcher — websocket to Polygon, filtered to your tracked proxy set. Emits normalized fill events onto an internal queue with sub-second latency.
- Scorer — periodically re-ranks the tracked set from Data API history and prunes wallets that went cold. Runs on a slow loop, minutes not seconds.
- Executor — consumes fills, pulls the live book, runs the slippage plan, signs and submits. This is where your risk limits live.
- Position manager — because copying entries is only half the job. Do you mirror their exit too, or run your own stop? I lean toward mirroring exits for fast wallets and running independent take-profit logic for slow accumulators.
Watch for the gotchas that don't show up in a backtest. Fee tiers on the exchange eat into thin edges. Market resolution during a hold can strand you if the target exited on information you didn't act on. And wash-trading wallets exist purely to look profitable on a leaderboard — a wallet trading mostly against one counterparty is a red flag your scorer should catch.
Copytrading also composes well with other strategies. A wallet-following signal is a decent seed for a Polymarket news-driven bot when the copied trades cluster right after a headline, and the plumbing overlaps heavily with what you'd build for a spread bot on the CLOB. If you're coming from the liquidity-provision side, the same book-walking logic underpins market making on Polymarket's CLOB — copytrading just runs it in reverse, as a taker instead of a maker.
The uncomfortable truth is that most public "profitable wallets" are not copyable in any way that survives fees and slippage. The ones that are get crowded fast. Your durable edge isn't the copying itself — it's faster wallet discovery, honest scoring that throws out the noise, and the discipline to take a zero fill when the price has already moved.
If you'd rather have that discovery-and-execution stack built and tuned for you, that's exactly what our Polymarket copytrading bot service exists to do.
Need a bot like this built?
We design, build and run trading bots on Solana, Hyperliquid and Polymarket.
Start a projectMore from the blog
Public vs Paid RPC: How to Run a Fair Benchmark
A fair comparison of public and paid RPC endpoints must account for quotas, workload, freshness and support guarantees.
Read articleRPC Benchmark Percentiles Explained: p50, p95 and p99
Why averages hide the latency spikes that break trading bots, wallets and production blockchain applications.
Read articleHyperliquid REST vs WebSocket Benchmark: What to Measure
A benchmark plan for Hyperliquid market data that separates request latency from streaming freshness and recovery.
Read article