Skip to main content

polymarket-profile

Polymarket address profiler — input any 0x address, get a complete trading profile with PnL, win rate, positions, category breakdown, and top trades. All data from public APIs, no local database needed.

Datos de origen

Repositorio
runesleo/polymarket-toolkit
Última actividad en el origen
31 de marzo de 2026 a las 04:26
Idioma detectado de SKILL.md
inglés
Estrellas
198
Forks
29

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
polymarket-profile
description
Polymarket address profiler — input any 0x address, get a complete trading profile with PnL, win rate, positions, category breakdown, and top trades. All data from public APIs, no local database needed.
allowed-tools
Bash(curl:*) Bash(node:*) Read Write Edit
metadata
{"version":"0.2.0","openclaw":{"skillKey":"polymarket-profile","homepage":"https://leolabs.me","requires":{"anyBins":"[Truncated]"}}}
# Polymarket Address Profile Generate a complete trading profile for any Polymarket address. All data comes from public APIs in real-time — no local database or API key required. ## Trigger User provides a Polymarket identity and wants analysis, profile, or trading overview. ## Input Resolution The skill requires a **0x proxy wallet address**. Users may provide: | Input Type | Example | How to handle | |-----------|---------|---------------| | **0x address** | `0x63ce3421...` | Use directly | | **Profile URL** | `polymarket.com/profile/Theo4` | Extract username from URL, then resolve via leaderboard lookup (see below) | | **Username** | `Theo4` | Resolve via leaderboard lookup (see below) | ### When user provides a username or URL (not 0x address) **Step 1: Try leaderboard lookup** — Search `lb-api.polymarket.com/profit` to resolve username → address. ```bash # Paginate through the leaderboard searching for the username # Start with offset=0, increment by 500 until found or no more results curl -s "https://lb-api.polymarket.com/profit?window=all&limit=500&offset=0" ``` Response is an array of objects with `name`, `pseudonym`, and `proxyWallet` fields. Search for a case-insensitive match on `name` or `pseudonym`. - **Found** → use the `proxyWallet` as the 0x address, continue to Step 1 of execution - **Not found after 3 pages (1500 users)** → the account is likely unranked, fall back to Step 2 **Step 2: Manual fallback** (only if leaderboard lookup fails) > "This username isn't in the Polymarket leaderboard (only ranked users can be auto-resolved). You can find the 0x address by: > 1. Open the profile page on Polymarket > 2. Click the address/wallet icon near the username — it copies the 0x address > 3. Or check the browser URL — some profile pages show the address" NOTE: Leaderboard lookup covers all users with a PnL ranking (tens of thousands). Only very new or inactive accounts with zero trading history won't be found. ## API Endpoints All endpoints are public, no authentication needed. | Endpoint | Base URL | Purpose | |----------|----------|---------| | LB API | `https://lb-api.polymarket.com` | PnL, volume, rankings | | Data API | `https://data-api.polymarket.com` | Positions, activity, trades | | CLOB API | `https://clob.polymarket.com` | Orderbook, market prices | | Gamma API | `https://gamma-api.polymarket.com` | Market metadata, events, categories | ## Execution Steps Run steps 1-4 in parallel where possible to minimize latency. ### Step 1: PnL Snapshot ```bash curl -s "https://lb-api.polymarket.com/profit?window=all&address={ADDRESS}" ``` Response is an array. Extract `[0].amount` for total PnL, `[0].name` for username. NOTE: lb-api only returns `amount` (total PnL). It does NOT return invested/numTrades/numWins. Those must be computed from positions (Step 2) and activity (Step 3). Also fetch time-windowed PnL for trend: ```bash curl -s "https://lb-api.polymarket.com/profit?window=7d&address={ADDRESS}" curl -s "https://lb-api.polymarket.com/profit?window=30d&address={ADDRESS}" ``` ### Step 2: Current Positions ```bash curl -s "https://data-api.polymarket.com/positions?user={ADDRESS}&sizeThreshold=0&limit=100&offset=0" ``` Paginate with `offset` parameter: if response returns exactly 100 records, fetch next page with `offset=100`, `offset=200`, etc. until fewer than 100 returned. Each position object contains: | Field | Description | |-------|------------| | `title` | Market question | | `outcome` | "Yes" or "No" | | `size` | Number of shares held | | `avgPrice` | Average entry price | | `curPrice` | Current market price | | `initialValue` | Total cost (size × avgPrice) | | `currentValue` | Current value (size × curPrice) | | `cashPnl` | Realized + unrealized PnL | | `percentPnl` | PnL as percentage | | `totalBought` | Total shares ever bought | | `realizedPnl` | PnL from closed portions | | `redeemable` | Can claim settlement winnings | | `endDate` | Market expiry date | | `eventSlug` | Event identifier for Gamma API | Extract: - Number of open positions: `redeemable == false` AND `currentValue > 0` - Largest position by `currentValue` - Total portfolio value: sum of `currentValue` for open positions ### Win Rate Calculation Classify positions into three buckets: | Bucket | Condition | Meaning | |--------|-----------|---------| | **Won** | `redeemable == true` AND `currentValue > 0` | Market settled in user's favor, awaiting redemption | | **Lost** | `redeemable == true` AND `currentValue == 0` | Market settled against user | | **Open** | `redeemable == false` AND `currentValue > 0` | Market not yet settled | Win Rate = Won / (Won + Lost) IMPORTANT: Do NOT use `cashPnl > 0` to determine wins. Winning positions have `currentValue > 0` (shares worth $1) even if `cashPnl` appears negative due to partial sells. The `redeemable` flag is the definitive settlement indicator. #### Fallback: When Positions Are Empty or Incomplete For inactive accounts, the positions API may return very few records (settled positions get cleaned up). If `Won + Lost < 3`, fall back to activity-based estimation: 1. From activity, group all REDEEM records by `slug` (market) 2. From activity, group all TRADE records by `slug` 3. Markets with REDEEM volume > 0 → **Won** 4. Markets with TRADE volume > 0 but no REDEEM → **Lost** (invested but no payout) 5. Label Win Rate as "estimated from activity" when using this fallback ### Step 3: Activity History ```bash curl -s "https://data-api.polymarket.com/activity?user={ADDRESS}&limit=500" ``` IMPORTANT: You MUST paginate to get complete data. Large accounts have 10,000+ records. 500 records is NOT enough for an accurate profile. ### Activity Pagination (REQUIRED) ``` Loop: 1. First request: /activity?user={ADDRESS}&limit=500 2. Get `timestamp` of the LAST record in the response 3. Next request: /activity?user={ADDRESS}&limit=500&end={last_timestamp} 4. Repeat until response returns fewer than 500 records (= last page) 5. Merge all results ``` Inform user of progress for large accounts: "Fetching activity... page X (Y records so far)" Each activity object contains: `type`, `size`, `usdcSize`, `price`, `side`, `title`, `slug`, `timestamp`, `outcome`. Classify by `type` field: | Type | What it means | |------|--------------| | TRADE | Bought or sold shares (check `side` field: "BUY" or "SELL") | | SPLIT | Created YES+NO pairs from USDC (market-neutral entry) | | MERGE | Combined YES+NO back to USDC (exit / arbitrage capture) | | REDEEM | Claimed winnings after market settlement | | CONVERSION | Converted between YES/NO (special market operation) | | REBATE | Fee rebate from maker orders | Count and sum `usdcSize` for each type. Also track unique markets (`slug`) for diversity analysis. ### Step 4: Market Categories For each position, fetch market metadata via Gamma API using the `eventSlug` from positions: ```bash curl -s "https://gamma-api.polymarket.com/events?slug={eventSlug}" ``` Or batch multiple slugs. Each event has a `category` field and a `tags` array (each tag has a `label` field). #### Category Mapping Gamma API categories are legacy naming. Map to Polymarket's frontend categories: | Gamma category / tag label | Display Category | |---------------------------|-----------------| | `Sports`, `NBA Playoffs`, `Chess`, `Esports`, any sports team name | **Sports** | | `Crypto`, `NFTs`, `Bitcoin`, `Ethereum` | **Crypto** | | `US-current-affairs`, `Elections`, any president/congress/party keyword | **Politics** | | `Ukraine & Russia`, `Iran`, any war/military/invasion keyword | **Geopolitics** | | `Business`, any GDP/oil/fed/rate keyword | **Finance** | | `Pop-Culture`, `Art`, `Coronavirus` | **Culture** | | temperature/weather/celsius keyword in title | **Weather** | | AI/tech/SpaceX keyword in title | **Tech** | | Musk/tweet keyword in title | **Musk/Tweets** | | No match | **Other** | **Priority**: Use Gamma `category` field first. If it's missing or too generic (`All`), fall back to tag labels. If still unclear, infer from market title keywords. **NOTE**: Gamma API may return empty `[]` for old/settled markets. This is expected — fall back to keyword inference from market titles in activity data. **Optimization**: Collect all unique `eventSlug` values from positions first, then batch fetch from Gamma (avoid one API call per position). Group by slug to avoid duplicates. Compute the percentage distribution by volume invested. ### Step 5: Strategy Pattern Detection Analyze data from Steps 1-4 to classify the address into a trading pattern. Use multiple dimensions — no single metric is sufficient. #### Dimensions to compute From **activity** data: - `trade_count`: total TRADE records - `split_count` / `split_volume`: SPLIT records and USDC volume - `merge_count` / `merge_volume`: MERGE records and USDC volume - `redeem_volume`: total REDEEM volume - `unique_markets`: number of distinct `slug` values - `avg_trade_size`: total trade volume / trade count - `trade_frequency`: trade count / active days (first to last timestamp) From **positions** data: - `open_count`: open positions (not redeemable) - `settled_count`: won + lost - `concentration`: top 3 positions as % of total invested #### Pattern Classification Evaluate in this order (first match wins): | Pattern | Conditions | Description | |---------|-----------|-------------| | **SPLIT Arbitrage** | `split_volume > trade_volume × 0.2` AND `merge_volume > 0` | Enters via SPLIT (creates YES+NO pairs), sells one side or MERGEs back. Capital-efficient, market-neutral entry. | | **Market Maker** | `trade_count > 500` AND `unique_markets < 15` AND `avg_trade_size < $20` | High-frequency small trades concentrated in few markets. Provides liquidity, earns spread. | | **Whale / Concentrated** | `concentration > 60%` AND `unique_markets < 10` | Heavy capital in a few markets. High-conviction directional bets. | | **Diversified** | `unique_markets > 50` | Spread across many markets. Portfolio approach, lower per-market risk. | | **Small Trader** | `trade_count < 50` AND `total_invested < $500` | Limited activity. New or casual user. | | **Mixed** | None of the above | Combination of strategies, no dominant pattern. | #### Output format ``` 🎯 Strategy Pattern: {pattern_name} {1-2 sentence explanation based on actual numbers} Key metrics: {trade_count} trades across {unique_markets} markets, avg ${avg_trade_size}/trade ``` Do NOT reveal specific thresholds used for classification. Just state the pattern name and explain it in plain language using the trader's actual data. ### Step 6: Top Trades From **positions** data (not activity), use `cashPnl` field for settled positions: - **Top 5 Wins**: Settled positions with highest positive `cashPnl` - **Top 5 Losses**: Settled positions with most negative `cashPnl` For each: market title, outcome (Yes/No), entry price (`avgPrice`), PnL amount. NOTE: `cashPnl` from positions is approximate (affected by partial sells). This is acceptable for v0.1. Do NOT attempt to match individual BUY→SELL/REDEEM from activity — that requires complex logic and is not worth the accuracy gain for a profile overview. #### Fallback: When Positions Data Is Sparse If positions API returns very few settled records, estimate Top Trades from activity: 1. Group TRADE records by `slug`, sum `usdcSize` per market (= total invested) 2. Group REDEEM records by `slug`, sum `usdcSize` per market (= total payout) 3. PnL per market ≈ REDEEM volume - TRADE BUY volume 4. Sort by PnL for top wins/losses. Label as "estimated from activity". ### Step 7: Assemble Profile Output the complete profile in this format: ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Polymarket Profile: {ADDRESS_SHORT} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 📊 Overview Address: {ADDRESS} Total PnL: ${totalProfit} (invested ${invested}) Win Rate: {wins}/{total} ({winRate}) 7d PnL: ${pnl_7d} 30d PnL: ${pnl_30d} 📈 Current Positions ({count}) Largest: {market_name} — {direction} ${size} @ ${avg_price} Portfolio: ${total_value} | # | Market | Direction | Size | Avg Price | Current | PnL | |---|--------|-----------|------|-----------|---------|-----| | 1 | ... | YES/NO | $xx | $0.xx | $0.xx | +$x | ... 📂 Category Distribution | Category | Positions | Volume | % |
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub