polymarket-maker-rebate-bot
Polymarket Maker Rebate Bot
For Claude: How to Use This Skill
Skill instructions are preloaded in context when this skill is active. Do not perform filesystem searches or tool-driven exploration to rediscover them; use the guidance below directly.
When to Use
- run a fast 90-day backtest on Polymarket maker-rebate logic before trading
- market make on Polymarket with rebate-aware quoting and inventory controls
- compare paper backtest outcomes, then decide whether to run quote mode
On Invoke
Immediately run the default 90-day backtest without asking. Do not present a menu of modes. Execute:
cd ~/.config/seren/skills/polymarket-maker-rebate-bot && source .venv/bin/activate && python3 scripts/agent.py --config config.json
Display the full backtest results to the user. Only after results are displayed, present available next steps (quote mode, unwind, monitor). If the user explicitly requests a specific mode in their invocation message, run that mode instead.
Workflow Summary
fetch_backtest_universeloads candidate markets from Seren Polymarket publishers (or local fixtures).replay_90d_historyruns an event-driven, stateful replay with inventory and cash carried forward.score_edge_and_pnlestimates realized edge and PnL using order-book-aware fills plus pessimistic spread decay.summarize_backtestreturns return %, drawdown, fill telemetry path, quoted rate, and market-level results.filter_marketsremoves markets outside the default safe band ($0.30-$0.70midpoint), below the default daily-volume floor ($5,000), or inside the default resolution buffer (14days).inventory_guardtracks held inventory across cycles, forcessell_onlybehavior on policy-breaching markets, and escalates to a marketable unwind after the default3-cycle hold limit or when inventory drifts outside the safe midpoint band.emit_quotesproduces quote intents inquotemode after backtest review.live_guardblocks live execution unless both config and explicit CLI confirmation are present.
Execution Modes
backtest(default): runs a 90-day historical replay and outputs results immediately.quote: computes current quote intents with inventory/risk guards.monitor: alias for quote-style dry monitoring output.live: requires bothexecution.live_mode=truein config and--yes-liveCLI confirmation.
Live execution also requires:
POLY_PRIVATE_KEY(orWALLET_PRIVATE_KEY) for EIP-712 order signingPOLY_API_KEY,POLY_PASSPHRASE, andPOLY_SECRETfor authenticated submission
Trade Execution Contract
When the user gives a direct exit instruction (sell, close, exit, unwind, flatten), execute the exit path immediately.
Do not editorialize or argue against recovering remaining funds.
If the user request is ambiguous, ask only the minimum clarifying question needed to identify the positions to exit.
CLOB Exit Rules
py-clob-clientviaDirectClobTraderis the canonical live execution path.- For immediate sells, use a marketable limit priced at the market minimum tick from the live order book. Do not hardcode
$0.001; use the currenttick_size. - Never place a passive sell above the best bid when the user asked for an immediate exit.
- Estimate recovery by sweeping visible bid levels (
price x size) across the full book, not just the best bid. - If visible bid depth cannot cover the full exit size, report the partial-depth estimate and remaining unfilled size.
Pre-Trade Checklist (Mandatory)
Before any live buy, sell, or unwind:
- Fetch the live order book for every token involved.
- Snap prices to the market
tick_sizeand compute visible-book recovery or cost across all levels. - Verify the current environment can legally and technically reach the Polymarket CLOB API. If access is blocked, stop and report the restriction; do not suggest bypasses.
- Verify
py-clob-clientis installed andPOLY_PRIVATE_KEYorWALLET_PRIVATE_KEY,POLY_API_KEY,POLY_PASSPHRASE, andPOLY_SECRETare loaded. - If any dependency check fails, fail closed with a concrete remediation message.
Emergency Exit
Immediately liquidate held inventory with:
python3 scripts/agent.py --config config.json --unwind-all --yes-live
The unwind path cancels open orders first, then submits marketable min-tick sells and reports visible-book exit estimates.
Runtime Files
scripts/agent.py- rebate-aware quoting engine with risk guardsscripts/setup_cron.py- create/update the skill-local seren-cron local-pull runner and jobscripts/run_local_pull_runner.py- poll seren-cron and execute due local jobs on this machineconfig.example.json- baseline strategy and 90-day backtest parameters.env.example- optional fallback auth/env template (SEREN_API_KEYonly if runtime auth is unavailable)requirements.txt- installspy-clob-clientfor live order signing/submission
API Key Setup
Before running this skill, check for an existing Seren API key in this order:
- Seren Desktop auth — if the skill is running inside Seren Desktop, the runtime injects
API_KEYautomatically. Check:echo $API_KEY. If set, no further action is needed. - Existing
.envfile — check ifSEREN_API_KEYis already set in the skill's.envfile. If set, no further action is needed. - Shell environment — check if
SEREN_API_KEYis exported in the current shell. If set, no further action is needed.
Only if none of the above are set, register a new agent account:
curl -sS -X POST "https://api.serendb.com/auth/agent" \
-H "Content-Type: application/json" \
-d '{"name":"polymarket-maker-rebate-bot"}'
Extract the API key from the response at .data.agent.api_key — this key is shown only once. Write it to the skill's .env file:
SEREN_API_KEY=<the-returned-key>
Verify:
curl -sS "https://api.serendb.com/auth/me" \
-H "Authorization: Bearer $SEREN_API_KEY"
Do not create a new account if a key already exists. Creating a duplicate account results in a $0-balance key that overrides the user's funded account.
Reference: https://docs.serendb.com/skills.md
Quick Start
cd ~/.config/seren/skills/polymarket-maker-rebate-bot
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
cp .env.example .env
cp config.example.json config.json
python3 scripts/agent.py --config config.json
This runs the default 90-day backtest and returns a decision hint to keep paper-only or proceed to quote mode. If you are already running inside Seren Desktop, the runtime can use injected auth automatically.
Live market data only. Always leave
"markets": []and"state": {"inventory": {}}empty in your config.json. The skill fetches live markets automatically from the Polymarket API viabacktest.gamma_markets_url. Never add placeholder or example market IDs (e.g.MKT-001) — they do not exist on Polymarket and will cause the backtest to fail with "No markets with sufficient history". Leave"state.inventory_cycles": {}empty as well. The runtime increments hold-cycle state from live positions and uses it to trigger inventory unwinds.
Run Quote Mode (After Backtest Review)
python3 scripts/agent.py --config config.json --run-type quote
Optional Backtest Input
By default the runtime fetches backtest data from Polymarket market/history APIs. You can also pass local history:
python3 scripts/agent.py \
--config config.json \
--run-type backtest \
--backtest-file tests/fixtures/backtest_markets.json
Each backtest market object should include:
market_id(string)question(string)token_id(string)end_tsorendDate(market resolution timestamp)historyarray of{ "t": unix_ts, "p": probability_0_to_1 }- optional
orderbooksarray of{ "t": unix_ts, "best_bid": ..., "best_ask": ..., "bid_size_usd": ..., "ask_size_usd": ... } - optional
rebate_bps(number; otherwise default rebate from config)
Seren Predictions Intelligence
After a backtest completes, the output will suggest enabling Seren Predictions if it is not already active. This optional feature uses cross-platform consensus and divergence signals from Kalshi, Manifold, Metaculus, PredictIt, and Betfair to:
- Boost market selection scores for markets where Polymarket diverges from consensus
- Add directional skew to quotes based on cross-platform price differences
- Filter for higher-edge opportunities where platforms disagree
To enable, set predictions_enabled: true in the backtest section of your config.json. Estimated cost: ~$0.30 SerenBucks per backtest run.
Safety Notes
- Live execution is never enabled by default.
- Live quote cycles cancel stale orders, fetch fresh market snapshots, and then poll open orders/positions after requoting.
- Backtests are estimates and can materially differ from live outcomes.
- Replay enforces the same market, total, and position caps used by quote mode.
- Replay now blocks new exposure outside the default
0.30-0.70midpoint band, below the default$5,00024-hour volume floor, and inside the default14-day resolution buffer. - Held inventory is not allowed to drift indefinitely. The runtime persists hold cycles, switches policy-breaching inventory to
sell_only, and forces a marketable unwind once the configured hold limit is reached or the midpoint drifts outside the safe band. - Backtests emit JSONL quote/fill telemetry for later calibration when
backtest.telemetry_pathis set. - Quotes are blocked when estimated edge is negative.
- New entries close to resolution are excluded.
- Position and notional caps are enforced before orders are emitted.
- This strategy can lose money during fast information updates, gaps, liquidity changes, or rebate policy changes.
Seren-Cron Integration
Use the skill-local seren-cron local-pull runner for scheduling. The schedule lives in Seren, but a local polling process must stay online on the machine that will execute the strategy.
Requirements: Seren Desktop login or a valid SEREN_API_KEY. Live schedules also require Polymarket credentials plus funded SerenBucks.
Current Seren funding flow:
- Buy SerenBucks at
https://serendb.com/serenbucksorhttps://console.serendb.com - Stripe deposits start at
$5 - A verified email is required before Stripe deposits
- API-first users can fund with
POST /wallet/deposit
Step 1 — Check seren-cron is available
publisher: seren-cron
path: /api/health
method: GET
Step 2 — Create or update the local pull schedule
Create or upsert the runner plus the local-pull job:
python3 scripts/setup_cron.py create --config config.json --schedule "*/30 * * * *"
For live mode, include --yes-live after you have set execution.live_mode=true in config.json.
Step 3 — Start the local pull runner
Start the polling process that claims due work and runs scripts/agent.py locally:
python3 scripts/run_local_pull_runner.py --config config.json
Leave this process running on the machine that should execute the strategy.
Step 4 — Manage the schedule and runner
python3 scripts/setup_cron.py list
python3 scripts/setup_cron.py list-runners
python3 scripts/setup_cron.py pause --job-id <job_id>
python3 scripts/setup_cron.py resume --job-id <job_id>
python3 scripts/setup_cron.py delete --job-id <job_id>
python3 scripts/setup_cron.py delete-runner --runner-id <runner_id>
Pause the job immediately if live execution fails because trading funds or SerenBucks are exhausted.
More from serenorg/seren-skills
polymarket-bot
Autonomous trading agent for Polymarket prediction markets using Seren ecosystem
9saas-short-trader
Alpaca-branded SaaS short trader with MCP-native execution: scores AI disruption risk, builds capped short baskets, and tracks paper/live PnL in SerenDB.
2high-throughput-paired-basis-maker
Run a paired-market basis strategy on Polymarket with mandatory backtest-first gating before trade intents.
2seren-bounty
Work with Seren Bounty affiliate bounties: customers create and fund verifier-backed bounties; agents join to receive a referral_code and accrue earnings as qualifying events are verified; a release sweep pays matured earnings out of escrow.
2budget-tracker
Compare actual Wells Fargo spending against user-defined monthly budgets per category, calculate variance, and track budget adherence over time.
1net-worth-tracker
Track account balances from Wells Fargo statement data with optional manual asset and liability entries to produce a simplified balance sheet and net worth trajectory over time.
1