POLY-COPY-TRADER-LIVE

DRY RUN
Loading...

Recent Cycles

Loading...
Loading...

Dry-Run Trades

Loading...

Open Positions

Loading...

Settlement History

Loading...
Loading...
Loading...
Click Refresh to load markets
Loading...

Wallet Leaderboard

Loading...

Tracked Wallets

Loading...
Loading...
Level:
Tag:
Loading...

What this bot does

This is a Polymarket copy-trading bot. Every cycle it polls a list of "smart-money" wallets, detects new trades on their accounts, and decides whether to mirror them — either for real (LIVE mode) or as paper trades for analysis (DRY RUN mode). DRY RUN still records everything; the only difference is whether an order hits the order book.

The trading cycle

Each cycle runs three phases in sequence:

  1. Collect — Poll every target wallet, look up the market each trade is on, build a TradeSignal for every candidate. Apply gating filters here (blacklist, whitelist, source size band, price band, slippage, book depth, market resolved/expired). Anything rejected is recorded as a skipped trade with a machine-readable skip_reason.
  2. Select — Size every surviving signal with one of three sizing modes (see below) and cap the bet by available order book liquidity within the slippage tolerance.
  3. Execute — Run the risk circuit-breakers (daily/ weekly loss limits, max-open-positions). If they pass, place the order and record the trade.

Sizing modes

  • kelly_copy — Kelly criterion using the source trader's historical win rate. Requires trader_win_rate (fetched from Polymarket's closed-positions API). Falls back to ratio sizing if stats are missing.
  • ratio — Bet = source_trade_size × copy_ratio, clamped between min_single_bet and max_single_bet.
  • fixed_pct — Bet = bankroll × copy_fixed_pct, same clamps. Conservative, ignores source size.

Wallet tiering

The Wallets tab tracks every wallet the monitor polls. The Settings tab then decides which of those are actually copyable:

  • off - Copy from every polled wallet.
  • whitelist_only - Copy only from wallets in the whitelist.
  • blacklist - Copy from every polled wallet except those in the blacklist.

The blacklist is always applied regardless of mode - it's a defense-in-depth ban list.

The lists themselves are not settings: they live in wallet_lists.json on the data volume, next to the date and sample size of the dataset that validated them (currently two non-overlapping June 2026 dry-run windows; only wallets whose sign holds in both windows are listed). A whitelisted wallet may carry an entry-price band; copies outside it are skipped as wallet_band_out_of_range. The bot refuses to start if the file is missing, so an old hardcoded list can never be copied by accident. Read it at GET /api/wallet-lists, replace it with PUT /api/wallet-lists.

Filters that gate copy signals

  • Slippage — Skip if the current price has moved more than max_slippage from the source trade price.
  • Price band — Skip markets outside [min_yes_price, max_yes_price]. Longshots and chalk both lose money in the data.
  • Source size band — Skip when the source bet was below min_source_trade_size (dust = noise) or above max_source_trade_size (whale exits, not alpha).
  • Book depth — Skip if the order book on our side has less than min_book_depth USD available.
  • Market state — Skip if the market is already resolved (one side > 0.95) or past its end date.

Resolution tracking & counterfactual PnL

Every cycle the bot calls check_dryrun_settlements(), which runs two parallel resolution tracks:

  • Placed trades (dry-run) get scored normally — actual would-have-PnL using the recorded bet size.
  • Skipped trades also get resolved against their market outcome, using a synthesized counterfactual bet (source_trade_size × copy_ratio, clamped to single-bet limits). This produces a "what would we have made if we had not filtered this trade out?" number per skip reason, which is what makes filter tuning data-driven instead of guesswork.

Skipped trades keep status="skipped" after resolution so realized-PnL summaries continue to exclude them. Counterfactual stats appear in a separate block of the trades summary.

DRY RUN vs LIVE

Toggle dry_run in the Settings tab to switch modes. DRY RUN never sends orders to Polymarket — it records the trade as if it had been placed, so you get full PnL and analytics without spending money. LIVE requires polymarket_private_key + polymarket_funder_address configured via env vars (secrets are never editable from the dashboard). In LIVE mode, the wallet balance overrides the configured bankroll per cycle.

Risk circuit-breakers

Before any order leaves Phase 3, can_trade() checks: daily-loss limit, weekly-loss limit, max open positions, max daily bet volume, and per-bet size bounds. Any failure blocks the trade with a machine-readable reason and records it as a risk_blocked skip — which is itself counterfactual-scored, so you can see what your risk limits cost you.