polycopy — Whale copy-trading bot

Mirrors trades from profitable Polymarket wallets within seconds. Per-whale WR gate ≥55% after 10 trades, 24h stale exit, $0.10 best-bid collapse exit. Adaptive 3s polling after whale activity.

Version v1.0.0 · One-time payment · Source code download
Strategy typeCopy trading
AssetMulti-market
TimeframeEvent-driven
Market typeAll Polymarket markets
Minimum capital$50
Dependencies@polymarket/clob-client, ethers, puppeteer, puppeteer-extra, puppeteer-extra-plugin-stealth

What it does

polycopy watches a configurable list of profitable Polymarket wallets ("whales") and mirrors their trades within seconds. It does not blindly copy: each whale has an independent win-rate gate, position size is your own (not the whale's), and exits are managed by polycopy independently of what the whale does.

The watcher uses Puppeteer with stealth plugins because Polymarket's Data API rate-limits aggressive polling and the on-chain trade tape is slower than the UI feed. The Puppeteer client masquerades as a regular browser session.

The edge

Profitable Polymarket wallets are public. Their PnL is on-chain. The hard part is acting fast enough that the price hasn't moved before you can copy. polycopy's polling cadence (adaptive 3s after recent whale activity, 30s+ when quiet) and independent exit discipline let you ride the whale's signal without depending on the whale's exit timing.

The WR gate is the key safety: a whale who stops being profitable gets paused automatically. You only copy whales who have a verified track record on your own observed trades.

How it works

Edit polycopy/config.json to define your whale list:

{
  "whales": [
    { "address": "0x7c3db7...", "label": "Car", "enabled": true, "betPct": 0.05 },
    { "address": "0xab94...", "label": "Mango", "enabled": true, "betPct": 0.03 }
  ],
  "settings": {
    "betPct": 0.05, "maxBetUsd": 5,
    "pollIntervalMs": 30000, "pollStaggerMs": 2000
  }
}

Main loop:

  1. Init: cancel any stale orders from previous runs, load whale state from polycopy/state.json
  2. Poll each whale on stagger (default 30s, with 2s stagger between whales to avoid bursting)
  3. Detect new trade: compare whale's recent trades to last known set
  4. WR gate: skip if this whale has fewer than 10 observed trades (WHALE_MIN_TRADES_FOR_GATE) or WR below 55% (WHALE_MIN_WIN_RATE)
  5. Compute size: betPct of your balance, capped at maxBetUsd
  6. Copy buy: FOK taker at the whale's entry price ± slippage
  7. Adaptive poll: after any whale activity, drop poll interval to 3s for 5 minutes (FAST_POLL_MS, FAST_POLL_WINDOW_MS)

Independent exits:

  • Stale position exit: 24 hours held (STALE_POSITION_HOURS)
  • Bid collapse exit: best bid drops below $0.10 (BID_COLLAPSE_THRESHOLD)
  • Daily loss limit: tracked since Paris midnight

Sample output

[24/05/2026, 12:00:01] 🐋 PolyCopy [🔴 LIVE $50.00] [24/05/2026, 12:00:01] Whales: Car, Mango [24/05/2026, 12:00:01] Bet: 5% of balance (max $5) [24/05/2026, 12:00:01] Poll: every 30s (fast: 3s after activity), stagger 2s [24/05/2026, 12:00:01] 🚀 Watching for new whale trades... [24/05/2026, 12:14:32] Whale Car: BUY Yes "Will SCOTUS rule by July?" @ $0.34 [24/05/2026, 12:14:34] Copying: BUY (FOK) 7sh @ $0.35 ($2.45 incl fee) [24/05/2026, 12:14:34] Filled: 0xc8b1e9... [24/05/2026, 12:14:34] 🐋 Fast-poll mode for 5min

Design targets

Per-whale tracking: each whale has an observed-trades counter and an observed-WR. Trades only fire when both gates pass. Realistic expectation: 70-90% of trades are filtered by the gate during normal operation, so copy frequency is roughly 10-30% of whale activity.

Capital efficiency: maxBetUsd default is $5 per trade. With $50 starting bank, that's 10 simultaneous positions max. Bank can grow without changing position size (the bet-cap dominates the bet-pct calculation).

FAQ

How do I find whales?

Use polycopy/scripts/search-whale.js and polycopy/scripts/analyze-whale.js. They query the Polymarket Data API for top wallets by PnL and let you inspect a wallet's trade history. Once you've picked a list, add them to config.json.

Why Puppeteer instead of just the API?

Polymarket's Data API rate-limits aggressive polling and the on-chain tape lags the UI feed by 30-60 seconds. Puppeteer with stealth plugins gets the same WebSocket the UI does, which is real-time.

Will my orders move the price?

Default bet of $5 is too small to move any market with $1k+ volume. The volume filter in your whale list already enforces this.

What's included

  • polycopy/polycopy.js
  • polycopy/lib/{watcher, copier, state, utils}.js
  • polycopy/scripts/{find-wallet, search-whale, check-whale, analyze-whale}.js
  • polycopy/package.json (Puppeteer + stealth deps)
  • README with whale discovery workflow and gate tuning notes

Configuration

FlagDefaultDescription
--livePlace real orders. Default is dry-run.
--sim-balance 3030Starting balance in dry-run mode (USD).
--max-balance 500Cap the balance used for sizing (USD). 0 = use full balance.

Related bots