# Polyclaw

> Trade on Polymarket via split + CLOB execution. Browse markets, track positions with P&L, discover hedges via LLM. Includes automation tools: live portfolio tracking, auto-redeem, discipline scanner, and API bridge. Polygon/Web3.

- Skill: `modbender/polyclaw-2` (Agent Skill, multi-file: 10 files)
- Install (CLI): `npx skillmds@latest add modbender/polyclaw-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/modbender/polyclaw-2/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: modbender (https://skillmd.com/u/modbender)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/modbender/polyclaw-2

---


# PolyClaw

Trading-enabled Polymarket skill for OpenClaw. Browse markets, manage wallets, execute trades, and track positions.

## Features

- **Market Browsing** - Search and browse Polymarket prediction markets
- **Wallet Management** - Env-var based wallet configuration
- **Trading** - Buy YES/NO positions via split + CLOB execution
- **Position Tracking** - Track entry prices, current prices, and P&L
- **Hedge Discovery** - LLM-powered covering portfolio discovery via logical implications

## Quick Start

First, install dependencies (from skill directory):

```bash
cd {baseDir}
uv sync
```

### First-Time Setup (Required for Trading)

Before your first trade, set Polymarket contract approvals (one-time, costs ~0.01 POL in gas):

```bash
uv run python scripts/polyclaw.py wallet approve
```

This submits 6 approval transactions to Polygon. You only need to do this once per wallet.

### Browse Markets

```bash
# Trending markets by volume
uv run python scripts/polyclaw.py markets trending

# Search markets
uv run python scripts/polyclaw.py markets search "election"

# Market details (returns full JSON with all fields)
uv run python scripts/polyclaw.py market <market_id>
```

**Output options:**
- Default output is a formatted table (good for display)
- Use `--full` flag for full question text without truncation
- Use `--json` flag via `scripts/markets.py --json trending` for structured JSON output

### Wallet Management

```bash
# Check wallet status (address, balances)
uv run python scripts/polyclaw.py wallet status

# Set contract approvals (one-time)
uv run python scripts/polyclaw.py wallet approve
```

The wallet is configured via the `POLYCLAW_PRIVATE_KEY` environment variable.

### Trading

```bash
# Buy YES position for $50
uv run python scripts/polyclaw.py buy <market_id> YES 50

# Buy NO position for $25
uv run python scripts/polyclaw.py buy <market_id> NO 25
```

### Positions

```bash
# List all positions with P&L
uv run python scripts/polyclaw.py positions
```

### Hedge Discovery

Find covering portfolios - pairs of market positions that hedge each other via contrapositive logic.

```bash
# Scan trending markets for hedges
uv run python scripts/polyclaw.py hedge scan

# Scan markets matching a query
uv run python scripts/polyclaw.py hedge scan --query "election"

# Analyze specific markets for hedging relationship
uv run python scripts/polyclaw.py hedge analyze <market_id_1> <market_id_2>
```

**Output options:**
- Default output is a formatted table showing Tier, Coverage, Cost, Target, and Cover
- Use `--json` flag for structured JSON output
- Use `--min-coverage 0.90` to filter by minimum coverage (default 0.85)
- Use `--tier 1` to filter by tier (1=best, default 2)

**Coverage tiers:**
- **Tier 1 (HIGH):** >=95% coverage - near-arbitrage opportunities
- **Tier 2 (GOOD):** 90-95% - strong hedges
- **Tier 3 (MODERATE):** 85-90% - decent but noticeable risk
- **Tier 4 (LOW):** <85% - speculative (filtered by default)

**LLM model:** Uses `nvidia/nemotron-nano-9b-v2:free` via OpenRouter. Model selection matters — some models find spurious correlations while others (like DeepSeek R1) have output format issues. Override with `--model <model_id>` if needed.

## Automation Tools

### Portfolio Live Tracking

Real-time position tracking via Polymarket Data API. Groups positions by `(slug, outcome)` and displays YES/NO side, current value, and P&L with cost basis from `portfolio.json`.

```bash
uv run python portfolio_live.py
```

- Fetches live on-chain positions from `data-api.polymarket.com`
- Shows outcome side (YES/NO), current price, and unrealized P&L
- No web3 dependency — uses REST API only

### Auto Redeem

Automatically detects and redeems settled (resolved) markets. Checks `payoutDenominator` on-chain via the CTF contract. When a market resolves, submits a `redeemPositions` transaction through the NegRiskAdapter.

```bash
# Manual run
cd {baseDir} && source .env && .venv/bin/python3 auto_redeem_check.py

# Cron (every 15 minutes)
*/15 * * * * cd /path/to/polyclaw && source .env && .venv/bin/python3 auto_redeem_check.py >> /var/log/polyclaw-redeem.log 2>&1
```

- Requires `web3` (use `.venv/bin/python3`, not system python)
- Tracks redeemed positions in `redeem_state.json` to avoid duplicates
- Needs `CHAINSTACK_NODE` and `POLYCLAW_PRIVATE_KEY` env vars

### Discipline Scanner

Automated take-profit scanner. Sells positions that are up 20%+ with slippage protection. Configurable via `cfo_params.json` (`DISCIPLINE_TP_PCT` key).

```bash
# Manual run
cd {baseDir} && export $(grep -v "^#" .env | xargs) && .venv/bin/python3 discipline_scanner.py

# Cron (every 30 minutes)
*/30 * * * * cd /path/to/polyclaw && export $(grep -v "^#" .env | xargs) && .venv/bin/python3 discipline_scanner.py >> /var/log/polyclaw-discipline.log 2>&1
```

- Skips positions worth less than $1
- Take-profit threshold defaults to 20% (configurable)

### Enhanced API (polyclaw_api.py)

CLI bridge for external integrations (e.g., Wells TG Bot via SSH). Provides structured JSON output for programmatic use.

```bash
python3 polyclaw_api.py portfolio          # All open positions with live prices (JSON)
python3 polyclaw_api.py summary            # Text summary of portfolio
python3 polyclaw_api.py balance            # CLOB + on-chain wallet balance
python3 polyclaw_api.py risk               # Current risk rules
python3 polyclaw_api.py risk_check <usd> <slug> <channel>  # Pre-trade risk check
python3 polyclaw_api.py swap auto          # Swap all non-USDC.e to USDC.e
python3 polyclaw_api.py swap status        # Show token balances
```

- `portfolio` is the **recommended command** for live position data (reads Data API, not local DB)
- `balance` requires `web3` — use `.venv/bin/python3`
- `summary` reads local DB and can be stale — prefer `portfolio` for accuracy

## Security

For the MVP, the private key is stored in an environment variable for simplicity and Claude Code compatibility.

**Security Warning:** Keep only small amounts in this wallet. Withdraw regularly to a secure wallet.

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `CHAINSTACK_NODE` | Yes (trading) | Polygon RPC URL |
| `OPENROUTER_API_KEY` | Yes (hedge) | OpenRouter API key for LLM hedge discovery |
| `POLYCLAW_PRIVATE_KEY` | Yes (trading) | EVM private key (hex, with or without 0x prefix) |
| `HTTPS_PROXY` | Recommended | Rotating residential proxy for CLOB (e.g., IPRoyal) |
| `CLOB_MAX_RETRIES` | No | Max CLOB retries with IP rotation (default: 5) |

**Security Warning:** Keep only small amounts in this wallet. Withdraw regularly to a secure wallet. The private key in an env var is convenient for automation but less secure than encrypted storage.

## Trading Flow

1. **Split Position** - USDC.e is split into YES + NO tokens via CTF contract
2. **Sell Unwanted** - The unwanted side is sold via CLOB order book
3. **Result** - You hold the wanted position, recovered partial cost from selling unwanted

Example: Buy YES at $0.70
- Split $100 USDC.e → 100 YES + 100 NO tokens
- Sell 100 NO tokens at ~$0.30 → recover ~$27 USDC.e
- Net cost: ~$73 for 100 YES tokens (entry: $0.73)

## Polymarket Contracts (Polygon Mainnet)

- **USDC.e:** `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174`
- **CTF (Conditional Tokens):** `0x4D97DCd97eC945f40cF65F87097ACe5EA0476045`
- **CTF Exchange:** `0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E`

## Dependencies

Install with uv (from skill directory):
```bash
cd {baseDir}
uv sync
```

## Limitations

- Trading requires wallet approval setup (one-time)
- CLOB sells may fail if liquidity is insufficient

### CLOB Cloudflare Blocking

Polymarket's CLOB API uses Cloudflare protection that blocks POST requests from many IPs, including datacenter IPs and some residential ISPs. This affects the "sell unwanted tokens" step.

**Solution: Residential proxy with retry logic**

The recommended setup uses a rotating residential proxy (e.g., IPRoyal, BrightData). The CLOB client automatically retries with new IPs until one works:

```bash
export HTTPS_PROXY="http://user:pass@geo.iproyal.com:12321"
export CLOB_MAX_RETRIES=10  # Default is 5
```

With this setup, CLOB orders typically succeed within 5-10 retries as the proxy rotates through IPs until finding an unblocked one.

**Alternative workarounds:**
1. **Use `--skip-sell`** — Keep both YES and NO tokens, sell manually on polymarket.com
2. **No proxy** — Split still works; only CLOB sell is affected

If CLOB fails after all retries, your split still succeeded. The output tells you how many tokens to sell manually.

## Troubleshooting

### "No wallet available"
Set the `POLYCLAW_PRIVATE_KEY` environment variable:
```bash
export POLYCLAW_PRIVATE_KEY="0x..."
```

### "Insufficient USDC.e"
Check balance with `uv run python scripts/polyclaw.py wallet status`. You need USDC.e (bridged USDC) on Polygon.

### "CLOB order failed"
The CLOB sell may fail due to:
- Insufficient liquidity at the sell price
- IP blocked by Cloudflare (try proxy)

Your split still succeeded - you have the tokens, just couldn't sell unwanted side.

### "Approvals not set"
First trade requires contract approvals. Run:
```bash
uv run python scripts/polyclaw.py wallet approve
```

## License

MIT

