SkillAgentSearch skills...

Polycopier

An algorithmic copy-trading daemon for Polymarket. Written in Rust, it features real-time proxy wallet tracking, proportional fractional sizing, chronological position scanners, aggressive slippage guards, and synthetic auto-liquidations to automatically defend bankrolls and dynamically duplicate winning market strategies on autopilot.

Install / Use

npx skills add cbaezp/polycopier

Installs into whichever agent you are using.

README

polycopier

<p align="center"> <img src="poly_ui.png" alt="Polycopier Web UI" width="48%"> &nbsp; <img src="poly_img.png" alt="Polycopier Terminal UI" width="48%"> </p>

A high-performance, terminal-based copy trading bot for Polymarket prediction markets, built in Rust against the official polymarket-client-sdk.

License: MIT Built with Rust Status: Experimental CI Release

Experimental Software. This project is in active development and has not been audited for production use. It executes real trades on your behalf. Run it only with capital you can afford to lose, keep MAX_TRADE_SIZE_USD low while testing, and review all risk parameters before increasing position sizes. See the Disclaimer section for full details.


Overview

polycopier monitors one or more target wallets on Polymarket and automatically mirrors their trades into your own account in real time.

Two independent signal sources feed the same execution engine:

  1. Real-time listener - polls the Data API every 2 seconds and copies new fills the moment they appear, using transaction-hash deduplication to handle burst activity.

  2. Adaptive position scanner - scans the target's full open-position portfolio and evaluates catch-up entries (positions the target had open before the bot started). Scan frequency adapts dynamically between 10 and 60 seconds based on how close each target position's current price is to their original entry - scanning most aggressively when a catch-up entry is still at a favorable price.

Trade intent classification — every event is verified against:

  1. The copy ledger (copy_ledger.json) — a persistent record of which target we copied each token from.
  2. A live Polymarket API call at decision time — our wallet and the target wallet are both queried in parallel (5 s timeout, falls back to scanner cache if the API is slow).

This gives the engine authoritative, race-proof answers:

| Live: we hold? | Live: target holds? | Ledger entry? | Event | Decision | |---|---|---|---|---| | No | No | None | BUY | Copy — fresh long entry | | No | Yes | None | BUY | Copy — fresh long entry | | Yes | Any | token X from A | BUY | Skip — one-position-per-token rule | | Yes | No | None | BUY | Skip — target closing short we never entered | | Yes | Any | token X from A | SELL from A | Close — correct source | | Yes | Any | token X from A | SELL from B | Skip — irrelevant; hold for A | | Yes | Any | None (orphan) | SELL | Defensive close — ledger lost, close to be safe | | No | Any | open entry | SELL | Skip + sync ledger — position already closed while bot was down | | No | Yes | None | SELL | Skip — closing long we never entered | | No | No | None | SELL | Skip — target opening short (not supported) |

The bot never enters the same token from two different targets. The first target to enter a token "owns" it in the ledger; all subsequent entries for that token from other targets are ignored until the position is fully closed.

The bot provides two powerful interfaces:

  1. Web Dashboard - A sleek, modern React frontend hosted natively at http://localhost:3000 for live monitoring, position tracking (including exact source wallets), and interactive hot-swappable configuration.
  2. Terminal UI (TUI) - A lightweight, six-panel ratatui interface directly in your console.

The bot can also run headless (no TUI) as a systemd daemon on a Linux server.


Features

  • Real-time trade copying - polls the Polymarket Data API every 2 seconds with a rate limit of 20 fills per cycle. Deduplicates by transaction hash (not timestamp) so burst activity is never silently dropped.

  • Adaptive open-position scanner - catches positions the target opened before the bot started. Scan interval scales from 10s (target position still at entry price) to 60s (price has moved significantly or no enterable positions exist). Catch-up orders are priced at the target's average entry price (not the current market price), so you pay what the target paid — not whatever the market is at when the scanner fires.

  • Intent classification - every incoming BUY and SELL is checked against the target's last-known positions to determine true intent (fresh entry, adding to long, closing long, closing short). Short entries and short closures by the target are correctly skipped.

  • SELL execution guards:

    • 97% collateral buffer applied to all SELL sizes to satisfy the CLOB's fee reserve requirement.
    • SELL quantities are based on our own held size, not the target's order size.
    • SELL is never submitted for a token we don't hold.
  • BUY floor - entry size targets a minimum of $1.10 notional to prevent rounding errors from dropping below the CLOB's $1.00 minimum order size.

  • Interactive setup wizard - prompts for all credentials on first run and saves to .env.

  • Live balance tracking - CLOB balance polled every 10 seconds.

  • Four-mode proportional sizing - choose how each trade is sized:

    | Mode | Formula | When to use | |---|---|---| | self_pct (default) | our_balance * COPY_SIZE_PCT | Fixed % of our balance per trade — consistent and predictable | | target_usd | target_size * target_price | Mirror the target's exact dollar bet | | target_scalar | target_notional * wallet_scalar | Scale target sizes fractionally per-wallet (e.g. 1% of a $500 bet = $5) | | fixed | Always MAX_TRADE_SIZE_USD | Simple deterministic size |

    All modes enforce a $5.00 CLOB minimum and MAX_TRADE_SIZE_USD ceiling.

  • Risk engine — multi-layer defence applied to every trade event:

    • Micro-trade filter — rejects orders with < $1.00 notional (anti-spoofing)
    • Size capMAX_TRADE_SIZE_USD ceiling on every trade
    • Target Position USD Bounding — filters out targets whose notional trade size falls outside min_amount and max_amount configured in the scanner block
    • Daily volume limitMAX_DAILY_VOLUME_USD (0 = disabled); counts both BUY and SELL side; resets at UTC midnight
    • Consecutive-loss circuit breakerMAX_CONSECUTIVE_LOSSES (0 = disabled); pauses trading for LOSS_COOLDOWN_SECS after N consecutive losses
    • Rapid-flip guard — 60-second cooldown per token prevents the bot from immediately re-entering a position it just exited
    • Scanner guards applied only to catch-up (scanner) entries:
      • MAX_COPY_LOSS_PCT — skip if target is already this far underwater
      • MAX_COPY_GAIN_PCT — skip if target is already this far in profit (chasing adds slippage)
      • Expiry guard — skip if redeemable=true (market resolved on-chain) or end_date is strictly in the past (< today). Same-day markets are not blocked — redeemable is the authoritative settlement signal; end_date < today is only a backstop for stale API data
  • Web Dashboard - a pristine glassmorphism React application hosted at http://localhost:3000:

    • Account overview (total balance, PnL, target tracker)
    • Beautiful Copied & Open positions table featuring exactly which Source Wallet initiated the trace.
    • Interactive Config Settings Panel with intuitive range sliders, dynamic system toggles, and one-click Seamless Hot Rebooting.
  • Terminal UI - six-panel ratatui interface:

    • Account dashboard (balance, PnL, API-sourced Copied counter)

    • Live copy feed (pass/fail, skip reason per event)

    • Copied & Open positions table (only positions confirmed open in both our wallet and a target wallet; shows SOURCE WALLET, entry quality, OUR_PNL%)

    • Opportunity scanner table (color-coded by status, live refresh timing):

      | Status | Meaning | |---|---| | [W] WATCH | Valid candidate — will be entered next cycle | | [Q] QUEUED | Order already submitted this session | | [H] HELD | We already own this token | | [X] LOSS | Target too far underwater (MAX_COPY_LOSS_PCT) | | [^] GAIN | Target already too far in profit (MAX_COPY_GAIN_PCT) | | [-] RANGE | Current price outside MIN/MAX_ENTRY_PRICE | | [E] EXPRD | Market resolved or past end date — never entered |

    • Settings panel (live config summary, [s] to open wizard)

    • System Logs panel (WARN+ captured in-memory, never corrupts the TUI)

  • Entry quality analysis - the Copied & Open table shows per-row entry comparison:

    | Column | Description | |---|---| | SOURCE | Target wallet the position was copied from (shortened) | | TOKEN | First 12 chars of the token ID | | OUR ENTRY | Our average entry price | | TGT ENTRY | Target's average entry price | | DELTA% | (our_entry - tgt_entry) / tgt_entry: how much more we paid | | CUR PRICE | Current market price (refreshed independently every 20s) | | OUR PNL% | (cur_price - our_entry) / our_entry: our estimated P&L |

    Row color codes: green (DELTA <= +5%), yellow (+5-15%), red (>+15% -- chased).

  • Live refresh timing - scanner panel header shows: scan: 12s ago next: 48s prices: 7s ago so you can always see exactly when each data source last refreshed.

  • Independent price refresh task - CUR PRICE and OUR_PNL% are refreshed every 20 seconds regardless of scanner urgency. The scanner's adaptive interval can reach 60s when all positions are deeply in-t

Related Skills

View on GitHub
GitHub Stars5
CategoryDevelopment
Updated6d ago
Forks3

Languages

Rust

Security Score

90/100

Audited on Aug 2, 2026

No findings