Skip to content

jmazzini/poly-agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Polymarket Copy Trader

A Python bot that monitors wallets on Polymarket and mirrors their open positions at scale.
Designed to validate strategies in paper mode before risking real capital.

Project structure

poly-agent/
├── main.py          # Entry point
├── config.py        # Central configuration (edit this)
├── trader.py        # Core engine
├── api.py           # Polymarket API wrapper
├── storage.py       # Persistence (CSV trades, JSON positions, capital)
├── requirements.txt
├── .env.example     # Credentials template (copy to .env, never commit .env)
└── data/            # Created at runtime — gitignored
    ├── trades.csv       # Full trade history (opens, closes, skips)
    ├── positions.json   # Currently open positions
    ├── capital.json     # Capital state
    └── cerrados.json    # Already-closed markets (prevents re-entry)

Setup

# 1. Create and activate a virtual environment
python3 -m venv venv
source venv/bin/activate   # Mac/Linux

# 2. Install dependencies
pip install -r requirements.txt

# 3. Create .env (only needed for live mode)
cp .env.example .env
# Then fill in your POLY_PRIVATE_KEY and POLY_PROXY_WALLET

# 4. Add wallets to follow in config.py
# Edit: WALLETS = {"alias": "0x..."}

Usage

Paper mode (continuous, recommended to start)

python main.py --paper

Runs indefinitely, polling every 60 seconds. Press Ctrl+C to stop.

Single cycle (to test everything works)

python main.py --paper --once

Change polling interval

python main.py --paper --interval 30   # every 30 seconds
python main.py --paper --interval 120  # every 2 minutes

Inspect results while running

# In another terminal
cat data/trades.csv | column -t -s,

# Only closed trades with PnL
grep "CLOSE" data/trades.csv | column -t -s,

# Quick PnL summary
grep "CLOSE" data/trades.csv | awk -F',' '{sum+=$13} END {print "Total PnL: $" sum}'

Switch to live mode (once paper validates the strategy)

# Before running live:
# 1. Make sure POLY_PRIVATE_KEY and POLY_PROXY_WALLET are set in .env
# 2. Update CAPITAL_INICIAL in config.py with your real account balance
# 3. Adjust MAX_TRADE_USDC if your capital is larger

python main.py --live

In live mode the system reads the real USDC balance from the account before each trade, enabling automatic real compounding.

Configuration (config.py)

Parameter Default Description
PAPER_MODE True Paper vs live trading
CAPITAL_INICIAL 1000.0 Reference USDC for paper mode
TRADE_PCT 0.05 % of capital per trade (5% = up to 20 simultaneous slots)
MIN_TRADE_USDC 1.0 Minimum per trade
MAX_TRADE_USDC 8.0 Maximum per trade (safety cap — raise as capital grows)
MAX_PRICE_DRIFT 0.10 Max allowed drift to enter (10%)
MAX_ENTRY_PRICE 0.97 Skip if price is already >97% (minimal upside)
POLL_INTERVAL 60 Seconds between polls

Adding wallets to follow

In config.py:

WALLETS = {
    "trader_one": "0x...",
    "trader_two": "0x...",
}

Analyzing results

data/trades.csv contains all columns needed to calculate:

  • PnL per followed wallet
  • Your win rate vs the copied wallet's win rate
  • Impact of drift (skipped trades)
  • % return on capital

Key columns:

  • price_entry / price_exit → to manually calculate PnL
  • side → OPEN / CLOSE / SKIP
  • pnl_usdc / pnl_pct → automatically calculated on close
  • wallet_alias → to filter by followed wallet

Capital logic

Paper mode: capital grows/shrinks with PnL from the CSV. Each trade is capital_total × TRADE_PCT. Simulated compounding effect.

Live mode: reads real USDC balance from the account before each trade. If you gain $20, the next trade is 5% of the new total. Real automatic compounding.

With TRADE_PCT = 0.05 you have 20 simultaneous slots available. If the followed wallet opens more than 20 trades at once, the excess are queued and entered when capital is freed.

Drift logic

If a new position is detected but no capital is available:

  • It gets queued in memory
  • Each cycle checks the current price vs the price when the target wallet entered
  • If drift exceeds MAX_PRICE_DRIFT (10%) → SKIP, logged in trades.csv
  • If the price is still close → enters when capital is freed

Important notes

  • data/cerrados.json persists across restarts — already-closed markets are not reopened even if the target wallet still holds them
  • If the process crashes, on restart it restores positions and capital from data/
  • Do not delete data/ while there are open positions
  • Never commit .env — it contains your private key

Collaborations

If this project was useful to you, contributions are welcome via USDC on Polygon:

0xbc48eAebC98463c7c9521e1310C13FC1A080B419

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages