Claude/reverse engineer polymarket trades 7wk dr#254
Open
predictx28 wants to merge 27 commits intomsitarzewski:mainfrom
Open
Claude/reverse engineer polymarket trades 7wk dr#254predictx28 wants to merge 27 commits intomsitarzewski:mainfrom
predictx28 wants to merge 27 commits intomsitarzewski:mainfrom
Conversation
Senior quant/HFT agent that reverse-engineers Polymarket user trading strategies from on-chain data and replicates them as a live trading bot. Covers 5-phase workflow: data acquisition, behavioral fingerprinting, signal extraction, quantitative model building, and bot deployment. Includes Kelly sizing, Bayesian fair value modeling, CLOB integration, and full risk management framework. https://claude.ai/code/session_01BuzQm3qUEWju6yFae46sDx
- Add trades_k9Q2mX4L8A7ZP3R.csv (50,201 on-chain trades, 323 markets, 9.3hr window) - Add reverse_engineer_trades.py: full 5-phase quant analysis pipeline Findings: target wallet is an automated two-sided LP seeding bot - 79.7% of inter-trade gaps <1ms (confirmed bot) - 97.8% of markets have both Up+Down positions (LP not directional) - Size scales linearly with price (Spearman ρ=0.466, p≈0) - 68.2% of orders fragmented at same price level (impact minimization) - $375k deployed across 319 markets at ~$40k USDC/hour - Primary strategy: Hypothesis C (LP/AMM seeding) — 9/10 confidence - Replicability score: 8/10 https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
Full automated trading bot replicating the reverse-engineered LP strategy
from trades_k9Q2mX4L8A7ZP3R.csv (Hypothesis C: two-sided AMM seeding bot).
Architecture:
- polymarket_bot/config.py — all settings via env vars / .env file
- polymarket_bot/market_scanner.py — async Gamma API market fetcher with
volume/spread/price filters
- polymarket_bot/sizer.py — reverse-engineered sizing rule
(size = 26.74×price − 1.59, 2 fragments)
- polymarket_bot/risk.py — per-market cap (10%), daily loss kill
switch (5%), total exposure cap (80%)
- polymarket_bot/paper_trader.py — simulated fills with slippage model
- polymarket_bot/executor.py — live CLOB execution via py-clob-client
- polymarket_bot/monitor.py — CSV trade log + real-time P&L dashboard
- polymarket_bot/bot.py — async scan→signal→risk→execute loop
- run_bot.py — CLI entry point (paper default)
- requirements_bot.txt — dependencies
- .env.example — configuration template
Default mode: paper trading (BOT_MODE=paper)
Live mode requires: py-clob-client + funded Polygon wallet
https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
Polymarket no longer has active "5 min / 15 min / 1 hour" price-feed markets, so the timeframe filter was dropping all 44 otherwise-qualifying markets to 0. Set MARKET_TIMEFRAMES default to empty (no filter) so the bot trades any crypto market matching the coin keywords. Also align MIN_MARKET_VOLUME_USDC default with the 10_000 threshold used in diagnose_bot.py. https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
Adds a dedicated step that prints all markets mentioning BTC/XRP/SOL (ignoring all filters) so the user can see whether their target price-feed markets actually exist on Polymarket right now. https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
… search Scans up to 500 markets via pagination AND does targeted keyword searches (bitcoin/BTC/XRP/solana/SOL) using the Gamma API search param, then merges results. Shows all matching crypto markets sorted by volume so user can see exactly what titles/formats exist on Polymarket. https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
…tered pages Adds 4 parallel search strategies: 1. Paginate /markets with NO active filter (includes inactive/upcoming) 2. Search /events endpoint for grouped markets 3. Direct slug lookups for known crypto price-feed URL patterns 4. Tag/category filter params (crypto, bitcoin, price) This will conclusively find any BTC/XRP/SOL markets regardless of how they are structured on Polymarket. https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
Polymarket's 5-minute BTC/XRP/SOL up/down markets use slugs like btc-updown-5m-1773792600 (Unix timestamp rounded to 300s boundary). These are too short-lived to appear in paginated /markets results and must be fetched directly by slug each cycle. Changes: - market_scanner.py: add fetch_updown_markets() that computes current 5-min boundary timestamp, constructs slugs for configured assets, and fetches them directly; uses relaxed _passes_updown_filter() that skips lifetime volume check (brand-new markets have near-zero volume) - config.py: add UPDOWN_ASSETS env var (default "btc|xrp|sol") - diagnose_bot.py: add Step 4 that probes current + adjacent 5-min window slugs and reports what it finds (active, price, spread, vol) https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
…ashboard
- Scan interval reduced to 5s (was 60s) for near-continuous market coverage
- Bot now detects when 5m/15m/1h markets close and queries Gamma API for the
outcome; winning positions are redeemed at $1.00/token, losing at $0.00
- bot_trades.csv is reset (header-only) on every bot startup so each run is clean
- Market.end_time and OrderIntent.end_time flow through the full stack so the
settlement checker knows when each position expires
- New CSV columns: question, market_end_ts, pnl_usdc (replaces empty question field)
- Dashboard completely rewritten as a dark terminal UI with:
* Stats bar: trades, open, won, lost, win-rate, realised P&L, exposure
* Open positions table with live countdown timer (colour-coded urgency)
* Won / Lost side-by-side tables with P&L per trade
* Rolling trade log (last 80) with BUY / SETTLE / WIN / LOSS colour coding
https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
Adds an EXPORT TRADES section at the bottom of the terminal dashboard: - Download button generates a CSV matching the original trade file format - Columns: timestamp, market, outcome, entry_price, size_usdc, tokens, market_end_ts, payout_price, pnl_usdc, settled_at, result (WIN/LOSS/OPEN) - 10-row preview inline with win/loss/open counts shown - Filename includes timestamp for easy versioning https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
…pytrader.py) Dashboard (dashboard.py): - Replaced Streamlit with FastAPI + WebSocket — serves http://localhost:8001 - Design matches copytrader.py exactly: dark glassmorphism, DM Mono + Outfit fonts, radial gradient background, macOS traffic lights in topbar - Tab navigation: Overview / Trades / Analytics / Log - Overview: 6-stat grid, last trade card, open positions list, Chart.js P&L curve, win-rate-by-price bar chart, open-exposure doughnut chart - Trades: filterable table (All/Open/Win/Loss) with live expiry countdown + Export CSV - Analytics: win rate by side (UP/DOWN) and by entry price bucket with bar charts - Log: auto-rendered from trade history with colour-coded WIN/LOSS/BUY tags - WebSocket push every 3 s; reconnects automatically on drop - /export endpoint serves comparison CSV (same columns as original account trades) Settlement / Claiming (ported from copytrader.py): - market_scanner.py: parse end_time from endDateIso/end_date_iso for all markets - sizer.py + OrderIntent: carry token_id (ERC-1155) through from market.clob_token_ids - risk.py: track token_id per PositionRecord + market_token_ids lookup dict - paper_trader.py: pass token_id to risk.record_buy - config.py: add FUNDER_ADDRESS field for on-chain sweep step - executor.py: replace NotImplementedError stub with real _resolve_token_id from risk state; add 3-step redeem_position() (transfer EOA→Safe, redeem, sweep USDC) - bot.py: check ALL open positions every 60 s (not just those with known end_times); CLOB price ≥ 0.95 fast path + Gamma API fallback; redeem_queue with 3-min delay and 5-min retry (identical to copytrader.py); process queue in live mode only https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
When a position's token price reaches TAKE_PROFIT_PRICE (default 0.98), the bot automatically sells the full position each cycle. The exit is logged to CSV with side="TP" and pnl_usdc populated so win/loss is visible in the trade log. Configurable via TAKE_PROFIT_PRICE env var. https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
record_sell() computed tokens_sold = payout_usdc / price. For losses, payout_usdc=0, so tokens_sold=0 and tokens_held was never decremented. The position stayed open, getting re-settled every 60s and hammering daily PnL repeatedly. Fix: add tokens_override param to record_sell() so settle_position() can pass the actual token count directly, bypassing the division math. https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
…le to 5s Two bugs causing positions to show as OPEN: 1. dashboard.py only looked for side="SETTLE" rows to mark positions closed. Take-profit exits (side="TP") were invisible to the export and build_state, so every TP-exited position appeared permanently OPEN. Fixed by treating both "SETTLE" and "TP" sides as exit events throughout build_state() and the /export endpoint. Win/loss for TP rows uses pnl_usdc > 0. 2. The 60s settle throttle was too slow for 5-minute markets — if Gamma hadn't resolved by the first check, the window could be missed. Reduced to 5s so each market gets multiple resolution attempts within its window. https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
…adence - bot.py: add _refresh_market_cache() + _cached_markets; market list refreshed every market_rescan_sec (default 30s) instead of every cycle. run_once() now trades against the cache (no Gamma API call per burst). run() calls initial cache load at startup, then re-scans on schedule. Removed 0.1s asyncio.sleep between markets in run_once(). - paper_trader.py: removed asyncio.sleep(order_delay_sec) from execute_buy and execute_sell — paper fills are instant, matching original wallet's sub-ms within-burst timing. Live mode delay unchanged. - config.py: scan_interval_sec default 2s (matches original wallet cadence), order_delay_sec default 0.1s, added market_rescan_sec=30 and take_profit_price=0.98. - .env.example: updated SCAN_INTERVAL_SEC=2, ORDER_DELAY_SEC=0.1, added MARKET_RESCAN_SEC=30. https://claude.ai/code/session_01GVCktVy3tZRf6CoVMAaFrY
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Agent Information (if adding/modifying an agent)
Checklist
name,description,color