After August 7, Polymarket’s short-horizon crypto Up/Down markets settle on the 60-second TWAP, not a single-price snapshot.
If your bot still scores or trains against a closePrice snapshot, you are now optimizing against the wrong target.
This post documents the exact changes I made to align both live resolution and training labels with the official settlement source.
Goal
After the cutover:
- Resolve pending paper (and live) positions using the real 60s TWAP that Polymarket uses.
- Prefer the official RTDS feed when available.
- Keep
gamma outcomePricesas the authoritative fallback. - Drop the old single-price snapshot path for post-cutover slots.
1. New RTDS TWAP Client
Created btc15m/data/rtds.py — a dedicated WebSocket client for Polymarket’s Real-Time Data Service.
Key requirements:
- HMAC authentication using Username + HMAC Secret (signed connect/subscribe messages per RTDS spec)
- API key for the candlestick stream
- Subscribe to:
{
"topic": "crypto_prices_twap_sixty",
"type": "update",
"filters": "{\"symbol\":\"btc/usd\"}"
}
- Maintain an in-memory latest 60s TWAP value + timestamp
- Automatic reconnect with exponential backoff + ping keepalive
Credentials are never hardcoded. They live in:
-
state/rtds.json(gitignored), or - Environment variables:
BTC15M_RTDS_USERBTC15M_RTDS_HMAC_SECRETBTC15M_RTDS_API_KEY
2. Live Resolution Logic (score_pending)
In paper_loop.py, the resolution order for any slot with slot_end >= TWAP_CUTOVER_TS is now:
- gamma outcomePrices (still authoritative)
-
RTDS 60s TWAP at slot end →
up_won = twap_60s > open_price - Old crypto-price-snapshot
closePricepath is completely skipped for post-cutover slots
Open price source remains unchanged (Chainlink / Binance open at slot start).
3. Training Labels Prefer TWAP
In dataset.py:
-
label_from_binancenow prefers the real 60s TWAP when RTDS history is available; falls back to the previous typical-price proxy only when necessary. -
build_slot_tableprioritizes:up_won_gamma- RTDS TWAP-derived label
This keeps the training distribution aligned with actual settlement.
4. Existing TWAP Helpers Left Intact
-
inround/fairvalue.py → twap_fair_up_probabilityalready blends observed ticks in the final minute — left untouched. -
fairvalue.fair_up_for_roundalready routes post-cutover final-minute logic to TWAP fair value.
No regression risk on the in-round path.
5. Config Changes
In config.py:
-
TWAP_CUTOVER_TSwas already set to August 7 - Added
RTDS_ENABLEDtoggle - Added credential path / env var support
No other config changes required.
6. Validation Plan
Pre-cutover (shadow mode):
- Run the RTDS client in parallel
- Log TWAP vs snapshot closePrice on every completed slot
- Measure flip rate live (previously observed ~26% divergence)
Post-cutover:
- Confirm
score_pendingresolution source shows eitherrtds_twaporgamma - Verify paper PnL and training labels use the correct target
File Summary
| File | Change |
|---|---|
btc15m/data/rtds.py |
New – RTDS WebSocket client |
btc15m/paper_loop.py |
Updated score_pending resolution order |
btc15m/dataset.py |
TWAP-first labels |
btc15m/config.py |
RTDS toggle + credential path |
state/rtds.json |
New (gitignored) – credentials |
Why This Matters
A 26% flip rate between snapshot close and the official 60s TWAP is not noise — it is systematic label error.
Any model or paper-trading system that continues scoring against the old closePrice after the cutover is training on (and evaluating against) a different market than the one Polymarket actually settles.
Aligning resolution and labels with the real TWAP is therefore not an optional improvement. It is required for correctness.
If you are running any short-horizon BTC Up/Down system, check what you are currently resolving against after August 7.
If you have more questions, please feel free to contact me at any time: https://t.me/abrownfox001
My Polymarket Activity: https://polymarket.com/@abrownfox001?tab=activity
#Polymarket #BTC #TWAP #RTDS #TradingBot #PredictionMarkets #QuantTrading #CryptoBot
Top comments (0)