2026-02-23 23:03:06 +07:00
# Polymarket Terminal
2026-02-22 15:38:13 +07:00
2026-02-23 23:03:06 +07:00
> An automated trading terminal for [Polymarket](https://polymarket.com) — copy trades, provide liquidity, and snipe low-priced orderbook fills, all from your command line.
**Created by [@direkturcrypto](https://twitter.com/direkturcrypto)**
---
## Table of Contents
- [Features ](#features )
- [Prerequisites ](#prerequisites )
- [Installation ](#installation )
- [Configuration ](#configuration )
- [Usage ](#usage )
2026-02-26 02:11:20 +07:00
- [Running on VPS with PM2 ](#running-on-vps-with-pm2 )
2026-02-23 23:03:06 +07:00
- [How It Works ](#how-it-works )
- [Project Structure ](#project-structure )
- [Important Warnings ](#important-warnings )
- [License ](#license )
---
2026-02-22 15:38:13 +07:00
## Features
2026-02-26 02:11:20 +07:00
### Copy Trade Bot
2026-02-23 23:03:06 +07:00
- **Watch Trader** — Monitor any Polymarket wallet address in real time via WebSocket
- **Copy Buy** — Automatically mirror buy orders with configurable position sizing
- **Copy Sell** — Automatically mirror sell orders (market or limit)
- **Auto Sell** — Place a GTC limit sell at a target profit % immediately after a buy fills
- **Auto Redeem** — Periodically check and redeem winning positions on-chain
2026-02-26 02:11:20 +07:00
- **Market Expiry Guard** — Skip buys if market closes within `MIN_MARKET_TIME_LEFT` seconds
- **GTC Fallback** — Falls back to a GTC limit order when copying "next market" trades with no liquidity
- **Per-Market Queue** — Concurrent events for the same market are serialized to prevent duplicate buys
2026-02-23 23:03:06 +07:00
- **Dry Run Mode** — Simulate the full flow without placing real orders
2026-02-22 15:38:13 +07:00
2026-02-26 02:11:20 +07:00
### Market Maker Bot
2026-02-23 23:03:06 +07:00
- **Automated Liquidity** — Splits USDC into YES+NO tokens and places limit sells on both sides at $0.50 entry
- **Cut-Loss Protection** — Merges unsold tokens back to USDC before market close
- **Recovery Buy** — Optional directional bet after a cut-loss triggers
- **Multi-Asset** — Supports BTC, ETH, SOL, and any 5m/15m Polymarket market
2026-02-26 02:11:20 +07:00
- **Simulation Mode** — Full dry-run with P&L tracking
2026-02-22 15:38:13 +07:00
2026-02-26 02:11:20 +07:00
### Orderbook Sniper Bot
2026-03-03 14:52:37 +07:00
- **3-Tier Strategy** — Places GTC BUY orders at 3c, 2c, and 1c with weighted sizing (20%/30%/50%)
2026-02-23 23:03:06 +07:00
- **Multi-Asset** — Targets ETH, SOL, XRP, and more simultaneously
2026-02-26 02:11:20 +07:00
- **Simulation Mode** — Preview orders without spending funds
2026-03-03 14:52:37 +07:00
- **Session Scheduling** — Per-asset time windows (UTC+8) for selective trading
2026-02-23 23:03:06 +07:00
---
## Prerequisites
| Requirement | Details |
|---|---|
| Node.js | v18 or higher (ESM support required) |
| Polygon Wallet | An EOA wallet with a private key |
| Polymarket Proxy Wallet | Your proxy wallet address (visible on your Polymarket profile → Deposit) |
| USDC.e on Polygon | Deposited via Polymarket's deposit flow |
| MATIC on Polygon | A small amount for gas fees (redeem & on-chain operations) |
2026-02-26 02:11:20 +07:00
| PM2 *(optional)* | For running on a VPS: `npm install -g pm2` |
2026-02-23 23:03:06 +07:00
---
## Installation
2026-02-22 15:38:13 +07:00
```bash
2026-02-23 23:03:06 +07:00
# 1. Clone the repository
git clone https://github.com/direkturcrypto/polymarket-terminal.git
cd polymarket-terminal
# 2. Install dependencies
2026-02-22 15:38:13 +07:00
npm install
2026-02-23 23:03:06 +07:00
# 3. Copy the environment template
2026-02-22 15:38:13 +07:00
cp .env.example .env
2026-02-23 23:03:06 +07:00
2026-02-26 02:11:20 +07:00
# 4. Fill in your credentials
nano .env
2026-02-22 15:38:13 +07:00
```
2026-02-23 23:03:06 +07:00
---
## Configuration
All settings are controlled via the `.env` file. **Never commit your `.env` file** — it is already listed in `.gitignore` .
### Wallet Setup
| Variable | Description | Required |
|---|---|---|
| `PRIVATE_KEY` | Your EOA private key (signing only, does not hold USDC) | Yes |
| `PROXY_WALLET_ADDRESS` | Your Polymarket proxy wallet address | Yes |
| `POLYGON_RPC_URL` | Polygon JSON-RPC endpoint | Yes |
> **How to find your Proxy Wallet:** Log in to polymarket.com → click your profile → Deposit → copy the wallet address shown.
### Polymarket API Credentials (Optional)
Leave these blank to have the client auto-derive credentials from your private key.
| Variable | Description |
|---|---|
| `CLOB_API_KEY` | CLOB API key |
| `CLOB_API_SECRET` | CLOB API secret |
| `CLOB_API_PASSPHRASE` | CLOB API passphrase |
### Copy Trade Bot Settings
2026-02-22 15:38:13 +07:00
| Variable | Description | Default |
|---|---|---|
2026-02-23 23:03:06 +07:00
| `TRADER_ADDRESS` | Proxy wallet address of the trader to copy | (required) |
| `SIZE_MODE` | `percentage` (of `MAX_POSITION_SIZE` ) or `balance` (of your USDC balance) | `balance` |
| `SIZE_PERCENT` | Percentage to use per trade | `10` |
| `MIN_TRADE_SIZE` | Minimum trade size in USDC (skip if below) | `1` |
| `MAX_POSITION_SIZE` | Maximum USDC per market position | `10` |
| `AUTO_SELL_ENABLED` | Place a limit sell after each buy fills | `true` |
| `AUTO_SELL_PROFIT_PERCENT` | Target profit % for the auto-sell limit order | `10` |
| `SELL_MODE` | `market` or `limit` when copying a sell | `market` |
| `REDEEM_INTERVAL` | Seconds between redemption checks | `60` |
2026-02-26 02:11:20 +07:00
| `MIN_MARKET_TIME_LEFT` | Skip buy if market closes within this many seconds | `300` |
| `GTC_FALLBACK_TIMEOUT` | Seconds to wait for GTC fill when FAK finds no liquidity | `60` |
2026-02-23 23:03:06 +07:00
| `DRY_RUN` | Simulate without placing real orders | `true` |
2026-02-22 15:38:13 +07:00
2026-02-23 23:03:06 +07:00
### Market Maker Bot Settings
| Variable | Description | Default |
|---|---|---|
| `MM_ASSETS` | Comma-separated assets to market-make (e.g. `btc,eth` ) | `btc` |
| `MM_DURATION` | Market duration: `5m` or `15m` | `5m` |
| `MM_TRADE_SIZE` | USDC per side (total exposure = 2× ) | `5` |
| `MM_SELL_PRICE` | Limit sell price target (e.g. `0.60` ) | `0.60` |
| `MM_CUT_LOSS_TIME` | Seconds before close to trigger cut-loss | `60` |
| `MM_MARKET_KEYWORD` | Keyword to filter market questions | `Bitcoin Up or Down` |
| `MM_ENTRY_WINDOW` | Max seconds after open to enter (0 = open only) | `45` |
| `MM_POLL_INTERVAL` | Seconds between new market polls | `10` |
| `MM_RECOVERY_BUY` | Enable recovery buy after cut-loss | `false` |
| `MM_RECOVERY_THRESHOLD` | Minimum dominant-side price to qualify for recovery | `0.70` |
| `MM_RECOVERY_SIZE` | USDC for recovery buy (0 = use `MM_TRADE_SIZE` ) | `0` |
### Orderbook Sniper Settings
2026-03-03 14:52:37 +07:00
**3-Tier Strategy:** Places orders at 3 price levels with weighted sizing
2026-02-23 23:03:06 +07:00
| Variable | Description | Default |
|---|---|---|
| `SNIPER_ASSETS` | Comma-separated assets to snipe (e.g. `eth,sol,xrp` ) | `eth,sol,xrp` |
2026-03-03 14:52:37 +07:00
| `SNIPER_TIER1_PRICE` | Highest price tier (e.g. `0.03` = 3c) | `0.03` |
| `SNIPER_TIER2_PRICE` | Mid price tier (e.g. `0.02` = 2c) | `0.02` |
| `SNIPER_TIER3_PRICE` | Lowest price tier (e.g. `0.01` = 1c) | `0.01` |
| `SNIPER_MAX_SHARES` | Max total shares per side (min 5 per tier) | `15` |
**Allocation:**
- Tier 1 (3c): 20% of max shares (min 5)
- Tier 2 (2c): 30% of max shares (min 5)
- Tier 3 (1c): 50% of max shares (min 5)
**Example with `SNIPER_MAX_SHARES=15`:**
- 3 shares @ 3c = $0.09
- 5 shares @ 2c = $0.10
- 7 shares @ 1c = $0.07
- **Total per side:** 15 shares = $0.26
2026-02-23 23:03:06 +07:00
---
## Usage
2026-02-22 15:38:13 +07:00
2026-02-26 02:11:20 +07:00
### Terminal UI (local)
Runs with an interactive split-panel dashboard (blessed TUI).
2026-02-22 15:38:13 +07:00
```bash
2026-02-26 02:11:20 +07:00
# Copy Trade Bot
npm start # live trading
npm run dev # live + auto-reload on file changes
2026-02-22 15:38:13 +07:00
2026-02-26 02:11:20 +07:00
# Market Maker Bot
npm run mm # live trading
npm run mm-sim # simulation (DRY_RUN=true)
npm run mm-dev # simulation + auto-reload
2026-02-23 23:03:06 +07:00
2026-02-26 02:11:20 +07:00
# Orderbook Sniper Bot
npm run sniper # live trading
npm run sniper-sim # simulation
npm run sniper-dev # simulation + auto-reload
2026-02-22 15:38:13 +07:00
```
2026-02-26 02:11:20 +07:00
### Plain Log Mode (no TUI)
Writes plain timestamped text to stdout — suitable for piping, `tail -f` , or PM2.
```bash
# Copy Trade Bot
npm run bot # live trading
npm run bot-sim # simulation
npm run bot-dev # simulation + auto-reload
# Market Maker Bot
npm run mm-bot # live trading
npm run mm-bot-sim # simulation
npm run mm-bot-dev # simulation + auto-reload
```
> **Always test with `DRY_RUN=true` (or `*-sim` scripts) first** before committing real funds.
---
## Running on VPS with PM2
Each bot has its own PM2 config file inside the `pm2/` folder.
### Install PM2
```bash
npm install -g pm2
```
### Copy Trade Bot
```bash
# Live trading
pm2 start pm2/copy.config.cjs
# Simulation
pm2 start pm2/copy.config.cjs --env sim
# View logs
pm2 logs polymarket-copy
tail -f logs/copy-out.log
# Management
pm2 restart polymarket-copy
pm2 stop polymarket-copy
pm2 delete polymarket-copy
```
### Market Maker Bot
```bash
# Live trading
pm2 start pm2/mm.config.cjs
# Simulation
pm2 start pm2/mm.config.cjs --env sim
# View logs
pm2 logs polymarket-mm
tail -f logs/mm-out.log
# Management
pm2 restart polymarket-mm
pm2 stop polymarket-mm
pm2 delete polymarket-mm
```
### Auto-start on reboot
```bash
pm2 startup # generates a startup command — run the command it prints
pm2 save # saves current process list
```
2026-02-23 23:03:06 +07:00
---
2026-02-22 15:38:13 +07:00
## How It Works
2026-02-23 23:03:06 +07:00
### Copy Trade Bot Flow
2026-02-22 15:38:13 +07:00
```
2026-02-26 02:11:20 +07:00
WebSocket (RTDS) — real-time trade events from trader
│
▼
Per-market queue (prevents concurrent duplicate buys)
│
┌────┴──────┐
│ │
BUY SELL
│ │
├─ Expiry guard (MIN_MARKET_TIME_LEFT)
├─ Max position cap ├─ Cancel open orders
├─ FAK market buy ├─ Reconcile on-chain balance
│ └─ 0 fill? → GTC fallback ├─ FAK market sell / limit sell
├─ Place auto-sell GTC └─ Remove position
└─ Save position
│
▼
Redeemer loop (every REDEEM_INTERVAL seconds)
→ Check on-chain payout → redeemPositions via Gnosis Safe
2026-02-23 23:03:06 +07:00
```
### Market Maker Flow
```
New Market Detected
│
▼
Split USDC → YES + NO tokens ($0.50 each, zero slippage)
│
▼
Place limit SELL on both sides at MM_SELL_PRICE
│
▼
Monitor fills every few seconds
│
┌────┴────┐
│ │
2026-02-26 02:11:20 +07:00
Fill Time < MM_CUT_LOSS_TIME
2026-02-23 23:03:06 +07:00
│ │
▼ ▼
Collect Cancel orders → Merge YES+NO back to USDC
profit (recovery buy optional)
```
---
## Project Structure
```
polymarket-terminal/
2026-02-22 15:38:13 +07:00
├── src/
2026-02-26 02:11:20 +07:00
│ ├── index.js — Copy trade bot (TUI)
│ ├── bot.js — Copy trade bot (plain log / PM2)
│ ├── mm.js — Market maker bot (TUI)
│ ├── mm-bot.js — Market maker bot (plain log / PM2)
│ ├── sniper.js — Orderbook sniper bot
2026-02-23 23:03:06 +07:00
│ │
│ ├── config/
│ │ └── index.js — Environment variable loading & validation
│ │
2026-02-22 15:38:13 +07:00
│ ├── services/
2026-02-23 23:03:06 +07:00
│ │ ├── client.js — CLOB client initialization & USDC balance
│ │ ├── watcher.js — Poll-based trader activity detection
│ │ ├── wsWatcher.js — WebSocket real-time trade listener
│ │ ├── executor.js — Buy & sell order execution logic
│ │ ├── position.js — Position state management (CRUD)
│ │ ├── autoSell.js — Auto limit-sell placement
│ │ ├── redeemer.js — Market resolution check & CTF redemption
2026-02-26 02:11:20 +07:00
│ │ ├── ctf.js — On-chain CTF contract interactions
2026-02-23 23:03:06 +07:00
│ │ ├── mmDetector.js — Market detection for market maker
│ │ ├── mmExecutor.js — Market maker strategy execution
│ │ ├── sniperDetector.js — Market detection for sniper
│ │ └── sniperExecutor.js — Orderbook sniper order placement
│ │
│ ├── ui/
│ │ └── dashboard.js — Terminal UI (blessed)
│ │
│ └── utils/
2026-02-26 02:11:20 +07:00
│ ├── logger.js — Timestamped logging (TUI + plain modes)
2026-02-23 23:03:06 +07:00
│ ├── state.js — Atomic JSON state file management
│ └── simStats.js — Simulation P&L statistics
│
2026-02-26 02:11:20 +07:00
├── pm2/
│ ├── copy.config.cjs — PM2 config for copy trade bot
│ └── mm.config.cjs — PM2 config for market maker bot
│
2026-02-23 23:03:06 +07:00
├── data/ — Runtime state files (gitignored)
2026-02-26 02:11:20 +07:00
├── logs/ — PM2 log files (gitignored)
2026-02-23 23:03:06 +07:00
├── .env.example — Configuration template
2026-02-22 15:38:13 +07:00
├── .gitignore
└── package.json
```
2026-02-23 23:03:06 +07:00
---
2026-02-22 15:38:13 +07:00
2026-02-23 23:03:06 +07:00
## Important Warnings
- **Never commit your `.env` file.** Your private key must remain secret. The `.gitignore` already excludes it.
2026-02-26 02:11:20 +07:00
- **Always start with `DRY_RUN=true` ** (or a `*-sim` script) to verify the bot behaves as expected before using real funds.
2026-02-23 23:03:06 +07:00
- **Use a small `SIZE_PERCENT` ** for initial live runs to limit exposure.
- **Keep MATIC in your EOA wallet** for gas fees (redeem operations and on-chain CTF calls).
- **This software is provided as-is, with no guarantees.** Prediction market trading carries significant financial risk. You are solely responsible for any losses.
---
## Credits
Built and maintained by ** [@direkturcrypto ](https://twitter.com/direkturcrypto )**.
---
## License
ISC License — see [LICENSE ](LICENSE ) for details.