SamYbarra/Polymarket-Copytrading-Bot
Polymarket copy trading bot Polymarket copytrading bot Polymarket copy trading bot Polymarket copytrading bot Polymarket copy trading bot Polymarket copytrading bot Polymarket copy trading bot Polymarket copytrading bot Polymarket copy trading bot Polymarket copytrading bot Polymarket copy trading bot Polymarket copytrading bot
Polymarket Copy Trading Bot
A copy trading bot for Polymarket that mirrors trades from target wallets in real time. Built with TypeScript: WebSocket or API polling for trade detection, Polymarket CLOB for execution, with risk controls and optional auto-redemption.
Table of contents
- Overview
- Prerequisites
- Quick start: run the bot in 5 steps
- How to run the bot
- How to set environment variables (.env)
- Target wallets (config.json)
- Environment variable reference
- Scripts reference
- Project structure
- Security & disclaimer
Overview
- Real-time trade mirroring – Monitors target wallets via WebSocket or API and copies their trades.
- Configurable sizing – Per-wallet order size in
src/config/config.json(USDC or token amount). - Risk management – Buy threshold, stop-loss (SELL_PRICE), take-profit (PROFIT_SELL_THRESHOLD).
- Auto-redemption – Optional scheduled redemption of resolved positions.
- Telegram – Optional notifications when target wallets trade.
Prerequisites
Before you start, ensure you have:
| Requirement | Details |
|---|---|
| Node.js | Version 18 or higher. Check with node -v. |
| npm | Comes with Node.js. Check with npm -v. |
| Polygon wallet | A wallet (e.g. MetaMask) on Polygon with some USDC for trading. |
| Polymarket account | You need your proxy (smart) wallet address from Polymarket (see Finding your proxy wallet). |
Quick start: run the bot in 5 steps
-
Clone and install
cd Polymarket-Copytrading-Bot npm install -
Create your
.envfilecp .env.example .env
-
Edit
.env– set these required valuesPRIVATE_KEY– Your wallet private key (e.g. from MetaMask: Account → three dots → Account details → Export Private Key). Must start with0x.PROXY_WALLET_ADDRESS– Your Polymarket proxy wallet address (see Finding your proxy wallet).DRY_RUN=false– So the bot places real orders (settrueto only log, no orders).
-
Edit
src/config/config.json– add target wallets- Add the Polymarket wallet addresses you want to copy. The number is the order size (tokens or USDC depending on
ORDER_SIZE_IN_TOKENS).
{ "0xAddressOfTrader1": 1, "0xAddressOfTrader2": 5 } - Add the Polymarket wallet addresses you want to copy. The number is the order size (tokens or USDC depending on
-
Run the bot
npm start
Or use API polling instead:
npm run copytrade.
On first run, the bot will create src/data/credential.json (Polymarket API credentials). Keep that file and .env secret and never commit them.
How to run the bot
Two ways to run copy trading
| Mode | Command | When to use |
|---|---|---|
| WebSocket | npm start |
Real-time; uses Polymarket’s live feed. Best for low latency. |
| API polling | npm run copytrade |
Fetches trades on an interval (default 30s). Simpler, no WebSocket. |
Both use the same .env and src/config/config.json. Use one at a time.
Step-by-step: first run
-
Install dependencies (once)
npm install
-
Copy and fill
.envcp .env.example .env
Open
.envand set at least:PRIVATE_KEY=0x...(your EOA private key)PROXY_WALLET_ADDRESS=0x...(your Polymarket proxy)DRY_RUN=false(to allow real buy/sell)
-
Add target wallets in
src/config/config.json
Format:"0xWalletAddress": number. The number is the size per copy-trade (see Target wallets). -
Optional: test without placing orders
SetDRY_RUN=truein.env, then run the bot. It will log what it would do but not send orders. -
Start the bot
npm start
or
npm run copytrade
-
First-run behaviour
- If
src/data/credential.jsonis missing, the bot creates it (Polymarket API key). - It may prompt or run allowance/balance checks. Ensure your proxy wallet has USDC and approvals on Polygon.
- If
Other useful commands
- Check wallet and balance (no trading):
npm run balance
- Monitor one wallet (log trades only, no copying):
npm run monitor
- Auto-redeem resolved positions:
npm run auto-redeem
- Clear copy-trade history (e.g. to reprocess old trades):
npm run clear-history
How to set environment variables (.env)
The bot reads configuration from a .env file in the project root. Never commit .env or share it.
Creating .env
cp .env.example .envThen open .env in a text editor and replace the placeholder values.
Required variables (must set)
| Variable | Example | Description |
|---|---|---|
PRIVATE_KEY |
0xabc123... |
Your wallet (EOA) private key. Used to sign every order. Export from MetaMask (Account → ⋮ → Account details → Export Private Key). Keep secret. |
PROXY_WALLET_ADDRESS |
0x875058B4... |
Your Polymarket proxy (smart) wallet address. This is where the exchange holds your positions. Required for the CLOB client. |
Finding your proxy wallet
- Option A: In the Polymarket app or website, go to your profile / account or deposit/withdraw. The proxy address is often shown there (it’s the “smart wallet” or “proxy” address).
- Option B: Set only
PRIVATE_KEYin.env, runnpm run balance. The script can derive and print the proxy address for your EOA; then copy it intoPROXY_WALLET_ADDRESSin.env.
Enabling real buy/sell orders
| Variable | Value | Effect |
|---|---|---|
DRY_RUN |
false |
Bot places real orders (buy/sell). |
DRY_RUN |
true or unset |
Bot only logs; no orders are sent. Safe for testing. |
Set DRY_RUN=false in .env when you want the bot to actually trade.
Copy-trading switch
| Variable | Value | Effect |
|---|---|---|
ENABLE_COPY_TRADING |
true or unset |
Copy trading is on (bot will copy target wallets). |
ENABLE_COPY_TRADING |
false |
Copy trading is off (e.g. only monitor or redeem). |
Chain and RPC
| Variable | Example | Description |
|---|---|---|
CHAIN_ID |
137 |
137 = Polygon mainnet (production). 80002 = Amoy testnet. |
RPC_URL |
https://polygon-mainnet.g.alchemy.com/v2/YOUR_KEY |
Full RPC URL. Use https (not wss). If set, RPC_TOKEN is ignored. |
RPC_TOKEN |
your_alchemy_key |
If RPC_URL is not set, the bot builds the RPC URL using this (e.g. Alchemy API key). |
You can leave RPC unset; the bot has default endpoints (rate limits may apply).
Trading behaviour
| Variable | Example | Description |
|---|---|---|
ORDER_TYPE |
FAK |
FAK (fill-and-kill) or FOK (fill-or-kill). |
TICK_SIZE |
0.01 |
Price step: 0.1, 0.01, 0.001, or 0.0001. |
ORDER_SIZE_IN_TOKENS |
true |
If true, numbers in config.json = token count. If false, they’re treated as USDC (or balance-based). |
ORDER_SIZE_IN_USDC |
true |
If true, config.json numbers = fixed USDC amount (no price fetch). |
Risk and thresholds
| Variable | Example | Description |
|---|---|---|
BUY_THRESHOLD |
0.45 |
Only copy a BUY when the token’s price is above this (e.g. 0.45 = 45¢). |
SELL_PRICE |
0.35 |
Stop-loss: sell when token price goes below this. |
PROFIT_SELL_THRESHOLD |
0.99 |
Take-profit: sell when token price reaches this (e.g. 0.99). |
PENDING_BUY_TIME_THRESHOLD_SECONDS |
160 |
For “pending” buys: only buy after this many seconds past the 5m boundary. |
Slippage and retries
| Variable | Example | Description |
|---|---|---|
BUY_SLIPPAGE_BPS |
200 |
Buy slippage in basis points (200 = 2%). |
SELL_SLIPPAGE_BPS |
100 |
Sell slippage in basis points (100 = 1%). |
ORDER_RETRY_ATTEMPTS |
5 |
How many times to retry placing an order. |
ORDER_RETRY_DELAY_MS |
200 |
Delay between retries (ms). |
API polling (for npm run copytrade)
| Variable | Example | Description |
|---|---|---|
POLL_INTERVAL_MS |
30000 |
How often to fetch new trades (ms). 30000 = 30 seconds. |
WALLET_FETCH_DELAY_MS |
800 |
Delay between each target wallet request (rate limiting). |
Optional: Telegram
| Variable | Example | Description |
|---|---|---|
TELEGRAM_BOT_TOKEN |
123456:ABC... |
Bot token from @BotFather. Leave empty to disable. |
TELEGRAM_CHAT_ID |
7744299798 |
Chat ID to receive alerts. Leave empty to disable. |
When both are set, the bot can send a notification when a target wallet trades.
Optional: auto-redeem and CLOB
| Variable | Example | Description |
|---|---|---|
REDEEM_DURATION |
120 |
Run auto-redeem every N minutes. Empty or 0 = disabled. |
CLOB_API_URL |
https://clob.polymarket.com |
CLOB API base URL. Default is production. |
Debug
| Variable | Example | Description |
|---|---|---|
DEBUG |
true |
Enable extra debug logging. |
Minimal .env example (real orders)
PRIVATE_KEY=0xYourPrivateKeyHere
PROXY_WALLET_ADDRESS=0xYourPolymarketProxyAddress
DRY_RUN=false
ENABLE_COPY_TRADING=trueEverything else can be omitted to use defaults, or copy from .env.example and adjust.
Target wallets (config.json)
Target wallets are not in .env. They are configured in src/config/config.json.
Format
{
"0xWalletAddressToCopy1": 1,
"0xWalletAddressToCopy2": 5
}- Key – Polymarket wallet address (proxy or EOA) of the trader you want to copy.
- Value – Number: order size per copy-trade.
- If
ORDER_SIZE_IN_TOKENS=true(default): size = number of tokens to buy/sell. - If
ORDER_SIZE_IN_TOKENS=false: size = USDC amount (or balance-based depending on config).
- If
Where to get target addresses
Use the Polymarket profile or activity URL of the trader; the address shown there (often the proxy) is what you put in config.json. The bot matches trades by this address.
Example
Copy two traders: one with 1 token per trade, one with 5 tokens per trade:
{
"0xaac8e98e05cf679616dec6c47755748b4cb0bff1": 1,
"0x4c353dd347c2e7d8bcdc5cd6ee569de7baf23e2f": 5
}Save the file; the bot reads it on startup. No need to restart for every edit if you only change config occasionally (restart after editing for changes to apply).
Environment variable reference
Quick reference for all supported variables. See How to set environment variables for details.
| Variable | Required | Default | Description |
|---|---|---|---|
PRIVATE_KEY |
Yes | — | EOA private key. |
PROXY_WALLET_ADDRESS |
Yes | — | Polymarket proxy wallet. |
DRY_RUN |
No | true |
false = place orders; true = log only. |
ENABLE_COPY_TRADING |
No | true |
false = disable copy trading. |
CHAIN_ID |
No | 137 |
137 = Polygon mainnet, 80002 = Amoy. |
RPC_URL |
No | — | Full RPC URL (https). |
RPC_TOKEN |
No | — | e.g. Alchemy key to build RPC URL. |
CLOB_API_URL |
No | https://clob.polymarket.com |
CLOB API base. |
ORDER_TYPE |
No | FAK |
FAK or FOK. |
TICK_SIZE |
No | 0.01 |
0.1, 0.01, 0.001, 0.0001. |
NEG_RISK |
No | false |
Negative-risk exchange. |
ORDER_SIZE_IN_TOKENS |
No | true |
config.json = token count. |
ORDER_SIZE_IN_USDC |
No | false |
config.json = fixed USDC. |
BUY_THRESHOLD |
No | 0.5 |
Min price to copy a BUY. |
SELL_PRICE |
No | 0.45 |
Sell when price below this. |
PROFIT_SELL_THRESHOLD |
No | 0.98 |
Sell when price ≥ this. |
PENDING_BUY_TIME_THRESHOLD_SECONDS |
No | 210 |
Pending buy delay (seconds). |
BUY_SLIPPAGE_BPS |
No | 200 |
Buy slippage (bps). |
SELL_SLIPPAGE_BPS |
No | 100 |
Sell slippage (bps). |
ORDER_RETRY_ATTEMPTS |
No | 5 |
Order retries. |
ORDER_RETRY_DELAY_MS |
No | 200 |
Retry delay (ms). |
POLL_INTERVAL_MS |
No | 30000 |
API poll interval (ms). |
WALLET_FETCH_DELAY_MS |
No | 800 |
Delay between wallet fetches (ms). |
USER_REAL_TIME_DATA_URL |
No | wss://ws-live-data.polymarket.com |
WebSocket URL. |
TELEGRAM_BOT_TOKEN |
No | — | Telegram bot token. |
TELEGRAM_CHAT_ID |
No | — | Telegram chat ID. |
REDEEM_DURATION |
No | — | Auto-redeem interval (minutes). |
DEBUG |
No | false |
Extra logging. |
Scripts reference
| Command | Description |
|---|---|
npm start |
WebSocket copy-trade bot (real-time). |
npm run copytrade |
API polling copy-trade bot. |
npm run monitor |
Monitor one wallet (no copying). |
npm run balance |
Show EOA, proxy, and USDC balances. |
npm run auto-redeem |
Auto-redeem resolved positions. |
npm run clear-history |
Clear processed-trades / bought/sold history. |
npm run redeem |
Manual redeem (CONDITION_ID / INDEX_SETS in script or env). |
npm run manual-add-holdings |
Add holdings to token-holding.json. |
npm run sync-holdings |
Sync holdings from wallet. |
Project structure
polymarket-copytrading-bot-ts/
├── .env # Your secrets (create from .env.example)
├── .env.example # Template for .env
├── package.json
├── src/
│ ├── index.ts # WebSocket copy-trade entry (npm start)
│ ├── copytrade.ts # API copy-trade entry (npm run copytrade)
│ ├── auto-redeem-copytrade.ts
│ ├── config/
│ │ ├── env.ts # Reads .env
│ │ └── config.json # Target wallets + sizes
│ ├── copy-trade/
│ │ ├── core.ts # processTrade() – shared copy logic
│ │ └── risk-manager.ts
│ ├── data/
│ │ ├── credential.json # API credentials (auto-created)
│ │ └── token-holding.json
│ ├── providers/
│ │ ├── clobclient.ts # CLOB (uses PRIVATE_KEY + PROXY_WALLET_ADDRESS)
│ │ └── wssProvider.ts
│ ├── security/
│ │ ├── createCredential.ts
│ │ └── allowance.ts
│ ├── other/
│ │ ├── redeem.ts
│ │ ├── monitor-wallet.ts
│ │ └── wallet-balance.ts
│ └── utils/
│ ├── proxyWallet.ts
│ ├── balance.ts
│ └── redeem.ts
└── README.md