GitHub: https://github.com/abrownfox0/abrownfox001-twap60-prediction-trigger-system
YouTube walkthrough: https://www.youtube.com/watch?v=XzhugRL6BV4
Part 1: the venues settle on different official averages.
Part 2: 5 minutes and 15 minutes are different products.
Part 3 is the implementation fork. If you already have a Polymarket BTC 5m engine, this is the list of things that break when you point it at Kalshi.
Live profile: @abrownfox001
1. Do Not Ship One Brain With a Venue Flag
This is the failure mode:
if venue == "kalshi":
symbol = "KXBTC15M"
else:
symbol = "btc-updown-5m"
# same features, same thresholds, same scratch timer
That is not a dual-venue system. That is one calibrated clock wearing a costume.
Correct shape:
shared risk + logger
├─ Polymarket adapter → TWAP60 path engine (5m)
└─ Kalshi adapter → CF-close engine (15m)
Share process. Do not share the probability model.
2. Change the Primary Series First
| Layer | Polymarket 5m | Kalshi 15m |
|---|---|---|
| Live official series | Chainlink 60s TWAP via RTDS | CF Benchmarks Real-Time Index |
| Decision question | Is the TWAP path beating open? | Will the final-minute CF average clear the strike? |
| Open / strike | Pin twap_open from the same TWAP feed |
Read the contract strike / floor from Kalshi |
| Freshness field | TWAP observation timestamp | Index sample time vs close clock |
| Label for training | gamma resolution + TWAP60 path | Kalshi expiration value / official CF close |
If this table is wrong, every downstream “optimization” is theater.
3. Rebuild Labels Before You Rebuild Features
A 5m model trained on Polymarket outcomes is labeled against Chainlink TWAP versus slot open.
A 15m model trained on Kalshi outcomes is labeled against a final-minute CF average versus strike.
Those label sets are not interchangeable.
Minimum migration work:
- Collect official Kalshi settlement values, not Binance closes
- Reconstruct the last 60 seconds of the CF index
- Measure how often CEX last tick disagrees with that average
- Only then fit
P(up) - Shadow-trade before size
Do not fine-tune a Polymarket 5m checkpoint and call it a Kalshi bot.
4. Rewrite Time Features
5m constants that must not travel:
- median entry near 47 seconds
- re-score every 10–30 seconds as a universal law
- late-slot behavior copied from a 300-second market
- scratch after a 5m-sized “decay”
On Kalshi 15m, time has a different meaning:
- first 8–10 minutes can be noise relative to a 60s close
- the last 90 seconds are where reconstruction quality matters most
- a 52% read at t=60s is not the same object as a 52% read at t=840s
Make seconds_to_close and fraction_of_close_window_elapsed venue-specific features. Do not reuse raw seconds_after_open weights.
5. Split the Trigger Logic
Polymarket 5m trigger
stream TWAP60
P = f(path vs twap_open, lead-lag, t_left)
if abs(P-0.5) >= edge and ask in 45–55¢:
accumulate small clip
Kalshi 15m trigger
track CF index + basis vs your proxy
as close approaches, reconstruct running 60s average
P = f(reconstructed_avg vs strike, remaining uncertainty)
if EV clears fees + confidence gate:
trade
The first is path-following.
The second becomes late-window estimation.
Keep both honest about which one they are.
6. Retune Scratch, Don’t Copy It
Scratch is still useful on both venues. The schedule is not.
On Polymarket 5m:
- books are often tradeable near 50¢
- a decaying 20-second-old thesis can be flattened quickly
- capital can be reused in the next slot
On Kalshi 15m:
- exiting too early can dump a ticket before the close average even exists
- exiting too late can mean paying the full official miss
- depth and fees around the strike change the meaning of “breakeven”
Re-estimate:
- minimum hold time
- probability drop required to flatten
- max adverse move
- last-N-seconds “no new entries / no panic scratch” policy
7. Execution and Ops Fork
These are not strategy details. They still break bots.
| Ops item | Polymarket | Kalshi |
|---|---|---|
| Auth | wallet / CLOB v2 signing | KYC account + exchange API |
| Position record | on-chain outcome tokens | centralized account ledger |
| Rate limits | volume-tiered CLOB buckets | exchange API limits |
| Reconciliation | chain + data API | fill + settlement reports |
| Identity / geo | wallet-native internationally | full onboarding first |
| Failure mode | stale RTDS + wrong TWAP window | wrong strike + proxy basis drift |
A working 5m Windows binary does not become a Kalshi engine because you added an API key field.
8. Shared Layers That Should Travel
Keep these common:
- daily loss cap
- per-slot exposure cap
- kill switch
- structured logs
- refuse stale data
- no trade if official series is missing
- paper harness before live size
That is the risk brain. It can supervise two adapters.
9. Migration Checklist
- [ ] Separate model files per venue
- [ ] Separate open/strike pinning code
- [ ] Separate label pipeline
- [ ] Separate scratch config
- [ ] Shadow 200+ Kalshi slots before capital
- [ ] Compare CEX-last vs official close disagreement rate
- [ ] Log
venue,index,window,strike_or_open,resolution_srcon every decision - [ ] Keep Polymarket 5m production untouched while Kalshi stays in paper
If you cannot diff a Polymarket decision log from a Kalshi decision log in one glance, the fork is incomplete.
10. What Part 4 Will Cover
After the fork exists, the only remaining question is economic:
- where a mid-band directional read still has room
- where last-minute reconstruction is the real game
- where fees, basis, and crowding erase both
- what I would actually run, and what I would not
Links
- Repo: https://github.com/abrownfox0/abrownfox001-twap60-prediction-trigger-system
- Video: https://www.youtube.com/watch?v=XzhugRL6BV4
- Live activity: https://polymarket.com/@abrownfox001?tab=activity
Not financial advice. Paper or micro-size first.
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 #Kalshi #TWAP #TradingBot #BTC #AlgoTrading #PredictionMarkets #QuantTrading
Top comments (0)