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.

معلومات المصدر

المستودع
runesleo/polymarket-toolkit
آخر نشاط في المصدر
٣١ مارس ٢٠٢٦ في ٠٤:٢٦
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٩٨
التفرعات
٢٩

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
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 | % |
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub