Skill: simmer/polymarket-btc-up-down-trader (version 1.0.1)

--- name: polymarket-btc-up-down-trader description: Trade Polymarket BTC daily and weekly UP/DOWN markets with empirically-anchored exit discipline. Enters on CEX momentum divergence; exits automatically on time cap, volume spike, or target capture. Use when the user wants to trade BTC direction markets (hours/days duration), not fast 5-minute markets. metadata: author: Simmer (@simmer_markets) version: "1.0.1" displayName: Polymarket BTC Up-Down Trader difficulty: intermediate --- # Polymarket BTC Up-Down Trader Trade Polymarket's BTC daily and weekly UP/DOWN markets with built-in exit discipline. Enters on Binance momentum signals, exits automatically before resolution tail risk bites. > **Polymarket only.** All trades execute on Polymarket with real USDC. Use `--live` for real trades; default is dry run. > **Not for fast (5m/15m) markets.** Use `polymarket-fast-loop` for those. This skill targets daily and weekly BTC direction markets with hours-to-days of duration. > ⚠️ **BTC UP/DOWN markets carry Polymarket's crypto taker fee.** Effective rate is 3.5% at 50¢, up to ~6.6% on cheap shares. Makers pay 0% and earn a 20% rebate from collected taker fees. Factor this into your minimum edge threshold. ## When to Use This Skill Use this skill when the user wants to: - Trade BTC daily or weekly UP/DOWN prediction markets on Polymarket - Apply systematic exit discipline (don't hold to settlement) - Use CEX price momentum as the entry signal - Monitor open positions and auto-exit when targets are hit ## Setup Flow 1. **Install the Simmer SDK** ```bash pip install simmer-sdk ``` 2. **Set your API key** - Get from simmer.markets/dashboard → SDK tab - `export SIMMER_API_KEY="your-key-here"` 3. **Set wallet private key** (required for live trading) - `export WALLET_PRIVATE_KEY="0x..."` - Not needed for dry-run or managed wallets. 4. **Configure exit discipline** (optional — defaults are well-tuned) ```bash python strategy.py --config ``` ## Quick Start ```bash # Dry run — see what would happen python strategy.py # Go live python strategy.py --live # Monitor-only (check exits without new entries) python strategy.py --live --monitor # Quiet mode for cron python strategy.py --live --quiet ``` ## How to Run on a Loop **Linux crontab:** ``` # Every 30 minutes */30 * * * * cd /path/to/skill && python strategy.py --live --quiet ``` **OpenClaw native cron:** ```bash openclaw cron add \ --name "BTC Up-Down Trader" \ --cron "*/30 * * * *" \ --session isolated \ --message "Run BTC up-down trader: cd /path/to/skill && python strategy.py --live --quiet" ``` ## Configuration All settings configurable via `config.json`, environment variables, or `--set`: ```bash python strategy.py --set exit_before_resolution_hours=2.0 python strategy.py --set volume_spike_exit_multiplier=4.0 python strategy.py --set target_hit_capture_pct=0.75 ``` ### Exit Discipline Knobs | Setting | Default | Env Var | Description | |---------|---------|---------|-------------| | `exit_before_resolution_hours` | `1.0` | [REDACTED_SECRET] | Close position this many hours before scheduled resolution. Disable with `0`. | | `volume_spike_exit_multiplier` | `3.0` | [REDACTED_SECRET] | Exit when 10-minute CLOB volume hits N× the rolling baseline. Disable with `0`. | | `target_hit_capture_pct` | `0.85` | [REDACTED_SECRET] | Exit when position has captured 85% of the theoretical max gain. Disable with `0`. | | `volume_baseline_windows` | `6` | [REDACTED_SECRET] | Number of prior 10-minute windows used to compute volume baseline. | **Why these defaults?** Exit behavior on short-dated prediction markets skews heavily toward early exits — the final hours before resolution compress remaining upside while tail risk (last-minute reversals, oracle variance) stays constant. The defaults are calibrated to exit early while capturing the bulk of the move. Empirical work on short-dated crypto UP/DOWN exit patterns informed the calibration; adjust based on your own backtest results. ### Entry Knobs | Setting | Default | Env Var | Description | |---------|---------|---------|-------------| | `entry_threshold` | `0.05` | `SIMMER_BTCUD_ENTRY_THRESHOLD` | Min discount from 50¢ toward the momentum-opposing side. Entry only fires when the market *disagrees* with momentum: UP signal requires YES < 0.50 (edge = `0.50 − YES`); DOWN signal requires YES > 0.50 (edge = `YES − 0.50`). Skips when market already agrees with momentum. | | `min_momentum_pct` | `0.3` | `SIMMER_BTCUD_MOMENTUM_THRESHOLD` | Min BTC % move (30-min lookback) to trigger | | `max_position` | `10.0` | `SIMMER_BTCUD_MAX_POSITION_USD` | Max $ per trade | | `daily_budget` | `50.0` | `SIMMER_BTCUD_DAILY_BUDGET_USD` | Max total entry spend per UTC day | | `lookback_minutes` | `30` | `SIMMER_BTCUD_LOOKBACK_MINUTES` | Lookback window for BTC momentum signal | | `min_hours_to_resolution` | `4.0` | [REDACTED_SECRET] | Skip entry if market resolves in fewer than N hours | ### Example config.json ```json { "exit_before_resolution_hours": 1.0, "volume_spike_exit_multiplier": 3.0, "target_hit_capture_pct": 0.85, "entry_threshold": 0.05, "min_momentum_pct": 0.3, "max_position": 10.0, "daily_budget": 50.0 } ``` ## Exit Logic Each run cycle evaluates open positions against three triggers, in priority order: ### 1. `time_cap` — Time-based exit Closes position when the market is within `exit_before_resolution_hours` of resolution. ``` hours_to_resolution ≤ exit_before_resolution_hours → EXIT (time_cap) ``` This is the hard floor. Holding to settlement adds tail risk (oracle variance, thin liquidity, last-minute manipulation) with little remaining upside on a near-resolved market. ### 2. `target_hit` — Profit capture exit Closes position when it has captured `target_hit_capture_pct` of the theoretical maximum gain. ``` YES positions: (current_price - entry_price) / (1.0 - entry_price) ≥ 0.85 → EXIT (target_hit) NO positions: (entry_price - current_price) / entry_price ≥ 0.85 → EXIT (target_hit) ``` Example: Bought YES at $0.40. Maximum gain = 1.0 - 0.40 = $0.60/share. At $0.91, captured = (0.91 - 0.40) / 0.60 = 85% → exit. ### 3. `volume_spike` — Smart-money volume exit Closes position when 10-minute CLOB volume exceeds `volume_spike_exit_multiplier`× the rolling baseline. ``` current_10m_volume / avg_baseline_volume ≥ 3.0 → EXIT (volume_spike) ``` A sudden surge in volume near resolution typically signals that informed traders have positioned ahead of outcome certainty. Exiting into the spike captures the liquidity premium. ## Exit Reasons Every exit logs one of four reasons: | Reason | Trigger | |--------|---------| | `time_cap` | Hours to resolution ≤ `exit_before_resolution_hours` | | `target_hit` | Captured ≥ `target_hit_capture_pct` of max gain | | `volume_spike` | 10m volume ≥ `volume_spike_exit_multiplier` × baseline | | `manual` | User-initiated close via dashboard or SDK | ## CLI Reference ```bash python strategy.py # Dry run (show positions + opportunities) python strategy.py --live # Execute real trades python strategy.py --monitor # Only run exit checks (no new entries) python strategy.py --positions # Show open positions python strategy.py --config # Show current config python strategy.py --set KEY=VALUE # Update config python strategy.py --quiet # Only output on trades/errors ``` ## Source Tagging All trades are tagged `source: "sdk:btcupdown"`. This keeps BTC UP/DOWN P&L separate from other strategies in your Simmer portfolio. ## Troubleshooting **"No active BTC UP/DOWN markets found"** - Gamma API may be slow or markets may not be trading. Try again in a few minutes. - Check polymarket.com directly for active BTC UP/DOWN markets. **"Could not fetch BTC momentum"** - Binance API rate-limited. Increase `lookback_minutes` or wait. **"Momentum X% < minimum Y%"** - Signal not strong enough. Entry threshold working correctly. Adjust `min_momentum_pct` if too conservative. **Volume spike trigger not firing** - Default baseline needs 6 prior 10-minute windows of data. In low-volume markets, set `volume_baseline_windows` lower or increase `volume_spike_exit_multiplier`. **"External wallet requires a pre-signed order"** - `WALLET_PRIVATE_KEY` is not set. Export the private key for your Polymarket wallet. - The SDK handles all signing automatically once the env var is set. **"Balance shows $0 but I have funds on Polygon"** - Polymarket V2 uses pUSD (PolyUSD). Migrate at simmer.markets/dashboard (one click, ~30s).


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)