DEV Community

Blockchain Rust Engineer
Blockchain Rust Engineer

Posted on • Originally published at dev.to

I Reverse-Engineered a Polymarket Trader's Strategy From Their Public Trade History

Every trade on Polymarket is public. Wallet address, market, side, price, size, timestamp - all sitting in an API response, for any wallet you want to look at.

So I built a toolkit that takes any Polymarket wallet address and answers four questions: what did they trade, when and under what conditions, how much per trade, and - the hard one - UP or DOWN, and why. Then it turns those answers into a config-driven bot that replays the discovered rules. Not a copy-trading bot. It doesn't mirror the wallet in real time — it extracts the strategy and runs it independently, in paper mode by default.

Here's how it works, and the one finding that made this actually interesting instead of just a data-collection exercise.

The pipeline

collect → enrich → signals → analyse → report

Collect pulls full trade history for a wallet from Polymarket's Data API (handles 100k+ fills via cursor pagination), plus market metadata for everything they traded.

Enrich joins external context onto every single trade at the moment it happened: Binance and Coinbase OHLCV, the Chainlink ETH/USD oracle price on Polygon, order book spread and imbalance from the Polymarket CLOB, and how close the trade was to market close (I bucket this into early, mid, late, urgent phases).

Signals computes candidate features on every row - momentum z-scores, oracle-vs-price agreement, spread percentage, timing phase.

Analyse runs statistical analysers across all of it - win rate, Sharpe, Brier score, sizing patterns, and the core piece: strategy discovery.

The interesting part: one rule doesn't work

My first assumption was that a trader has a strategy - pick a direction rule, measure how well it holds. That assumption was wrong, and testing it wrong is what made the real pattern visible.

Running this on a real wallet (~65k trades in ETH 5-minute Up/Down markets), a single global rule like "always follow the Chainlink oracle" doesn't hold. But segmenting by phase and price bucket reveals two genuinely different behaviors:

Mode 1 - cheap lottery. In the late/urgent phase, when a token is priced 0–35¢, the trader buys the cheaper side. Win rate is only ~20% - but the payoff structure makes it positive EV. This mode barely correlates with the Chainlink oracle at all (~19% agreement).

Mode 2 - oracle follow. At any phase, once a token is priced 50¢+, the trader follows Chainlink's price vs. the window-open price. Win rate here is ~78%, with a smaller payoff per win.

Two completely different behaviors, cleanly separated by price and timing, both consistently profitable in their own regime - but only visible once you stop assuming one global rule and start segmenting. There's a gap between 35-50¢ in mid-phase where no rule reaches significance, and the bot is built to skip that gap rather than force a signal that isn't there.

That's the actual deliverable: a strategy_config.json with a direction.strategies[] array, each entry a phase/price-scoped rule with its own logic, no hardcoded strategy in the bot itself. Re-run the analysis, restart the bot, get new behavior - nothing to redeploy.

The bot side

Phase 2 loads that config and runs a ~5-second scan loop: find active markets, match phase+price to a strategy mode, pull the mode-specific signal (oracle diff or cheap-side book price), run an EV/sizing check, execute paper or live. Daily loss limits and max-position caps sit underneath all of it, independent of which strategy mode is active.

What this isn't

Worth being upfront about: this isn't a guaranteed-profit system, it's not real-time copy trading (it extracts rules, it doesn't mirror the wallet), and it's not a general ML platform - it's segmented statistical rule discovery. Fill history also isn't full intent - you see what someone traded, not what they considered and skipped. Historical validity isn't future validity either; paper trading before live is the whole point of the default config.

I build tooling like this for clients working on Polymarket - custom strategy extraction, market-making bots, or ongoing maintenance on an existing system. Full source, no black-box logic, paper-trading validation before anything goes live. If that's useful, reach out: Telegram @casatrick.

Top comments (1)

Collapse
 
jbowz profile image
jbowz

The two-mode split is the most useful thing here, and it suggests one more cut: slice that 0-35c band into narrow price buckets and check whether the win rate inside each bucket clears the bucket's own price. Before fees, a 20% win rate is house money in the 10c bucket and a money furnace in the 30c one, and the per-bucket excess tells you whether each discovered mode had real edge or just a shape. Same trick validates the replay bot cheaply: paper-trade both modes and track wins minus price-implied wins instead of P&L, and you will see drift from the source wallet's edge much sooner.