Install
openclaw skills install polymarket-soccer-shock-ladderFade sharp in-play price shocks on Polymarket soccer markets with a laddered limit-buy strategy (Roan's FIFA-quant framework). Pro skill. Currently scoped to 2026 World Cup markets. Simmer's server detects shocks in real time and emits pre-sized signals; this skill places the recovery ladder and manages the exit.
openclaw skills install polymarket-soccer-shock-ladderFade sharp price shocks on Polymarket World Cup markets. When a market's price drops hard during a match, this skill places a laddered set of limit buys below the pre-shock price, betting on a partial recovery, then exits each fill at a fixed target.
The strategy follows @RohOnChain's published "Trade FIFA Like A Quant" framework. The heavy lifting (detecting the shock, classifying it, sizing the rungs from historical depth distributions) runs on Simmer's server in real time. This skill is the thin execution layer: it reads the pre-sized signal and works the orders.
🚨 Framework, not a guaranteed edge. Read DISCLAIMER.md before going live. Runs in dry-run by default. Edges depend on spreads, fees, latency, and whether shocks actually recover. Start in dry-run, then go live small.
Requires Simmer Pro. Shock signals are delivered over the Pro reactor stream. Upgrade at simmer.markets/dashboard if you hit a 402 on connect.
Polymarket only. The ladder is a CLOB limit-order strategy.
$SIM(the LMSR venue) has no order book to rest bids on, so--venue simis a plumbing smoke test only, not a real run.
A "shock" is a fast price drop on one outcome during an in-play match. Simmer's server watches every WC market's live order flow, detects the drop, and figures out how deep shocks like this one usually go (from its own accumulated history, bucketed by favoritism, order-book depth, match minute, and goal state). It emits a signal with the pre-shock price and the depth percentiles.
This skill turns that signal into Roan's ladder:
pre_price - depth for
the 50th, 75th, 90th, and 95th depth percentiles. Deeper rungs only fill if the
price keeps falling.By default the skill only acts on moderate-favorite markets (pre-shock price 0.75 to 0.85), Roan's most profitable band. You can widen or change that.
Install the Simmer SDK (0.17.0 or newer):
pip install -U 'simmer-sdk>=0.17.0'
Set your Simmer API key (Pro plan required):
export SIMMER_API_KEY=... # simmer.markets/dashboard → SDK tab
Set your Polymarket wallet key (only for --live; not needed in dry-run):
export WALLET_PRIVATE_KEY=0x...
The SDK signs orders locally. External and OWS wallets work with no extra setup.
Arm for shock signals (self-serve, Pro required). Shock-ladder delivery is opt-in. Turn it on for your account:
curl -X PATCH https://api.simmer.markets/api/sdk/shock-ladder/config \
-H "Authorization: Bearer $SIMMER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
You get {"shock_ladder_enabled": true} back. The server starts fanning World Cup
shocks to your reactor pending feed within ~5 minutes. Check your state anytime with
a GET to the same URL, and disarm with {"enabled": false}.
Dry-run is the default. It shows the exact ladder and exits it would place, without trading. Review that before going live.
# Dry-run, single poll (safe; good for a cron)
python shock_ladder_trader.py --once
# Dry-run, continuous (poll every 2s)
python shock_ladder_trader.py
# LIVE, single poll
python shock_ladder_trader.py --once --live
# LIVE, continuous
python shock_ladder_trader.py --live
Recommended: cron with --once. Shock signals are time-sensitive; a 1-minute
cron gives reliable coverage even across restarts. A single --once run places a
ladder and then manages its fills and exits over the TTL window before exiting, so
one run fully handles one shock.
# crontab
*/1 * * * * cd /path/to/skill && python3 shock_ladder_trader.py --once --live
# OpenClaw cron
openclaw cron add --name "shock-ladder" --cron "*/1 * * * *" --tz UTC --session isolated \
--message "Run: cd /path/to/skill && python3 shock_ladder_trader.py --once --live"
All parameters are skill-side (no server config). Defaults are conservative.
| Setting | Env var | CLI flag | Default | Notes |
|---|---|---|---|---|
| Per-shock stake | SHOCK_LADDER_STAKE_USD | --stake | 15 | Total USDC split across the 4 rungs. |
| Venue | SHOCK_LADDER_VENUE | --venue | polymarket | sim is a smoke test only. |
| Order TTL | (CLI only) | --ttl | 60 | Seconds before unfilled rungs are cancelled. |
| Exit target | (CLI only) | --exit-cents | 4 | Cents above the fill for the exit sell. |
| Bucket filter | (CLI only) | --buckets | moderate | Comma-separated favoritism bands. Empty string acts on all. |
| Poll cadence | SHOCK_LADDER_POLL_INTERVAL_S | --interval | 2 | Fill-check / loop cadence in seconds. |
Favoritism bands (set with --buckets): heavy, moderate, slight, balanced,
underdog. Roan's tuning favored moderate. Example, act on moderate and slight:
python shock_ladder_trader.py --once --live --buckets moderate,slight
GET /api/sdk/reactor/pending, keep only type: "shock_ladder" signals
(so it never collides with copytrading signals on the same feed).pre_price and the depth percentiles.--live. Keep --stake small to start."0 pending shock signals" every run
GET https://api.simmer.markets/api/sdk/shock-ladder/config
(with your SIMMER_API_KEY) should return {"shock_ladder_enabled": true}. If not, re-run
Setup step 4. Pro plan required.402 on connect
Orders rejected in --live
WALLET_PRIVATE_KEY is set and the wallet holds USDC on Polymarket."venue=sim" warning
--venue polymarket.