Add sports/esports game matching and resolve-time filterβ
AJAY KASU
26a2b4f
Near-term overlap between the venues is mostly game winners, which Polymarket
lists as two-team moneylines (not Yes/No) and Kalshi as one market per team.
- Fetch Polymarket moneylines day by day (Gamma caps offsets at ~2,100) and
Kalshi game series directly (the events listing omits many of them)
- Pair games on league + Eastern date + both teams; same-day first so series
games on back-to-back days stay unambiguous; NFL/NHL nickname aliases
- Leagues without draws only: MLB, NFL, CFB, NHL, NBA, WNBA, KBO, CS2, LoL,
Valorant, Dota 2, R6
- Track each pair's resolution time and whether the game is in progress
- App: "Resolves within" filter (today / week / month / any), optional
in-progress games, annualized return column, sort by annualized return
Merge Space history: microstructure study + curated market pairsβ
AJAY KASU
71e881a
Combines the Space's hand-verified CURATED_PAIRS scanner fix with the
auto-matching live scanner. Curated pairs are fetched by conditionId and
always included as verified matches; auto-matching fills in everything
else. Keeps the Kalshi tick collector and microstructure study pipeline.
Fix live scanner: auto-match all markets, YES+NO arbitrage, real order-book depthβ
AJAY KASU
0773962
The live scan could never report an opportunity:
- scan_opportunities() read market_mappings while app.py filled market_map
- Polymarket outcomePrices is a JSON string, so float() always failed
- Kalshi v2 now returns *_dollars string fields instead of integer cents
Moves fetching/matching into src/live_scan.py:
- Polymarket: paginate Gamma (capped at 100/request), Yes/No markets only,
real top-of-book depth from the CLOB for matched markets
- Kalshi: walk all open events with nested markets instead of the flat
listing, which is dominated by sports props
- IDF-weighted token matching; numbers and outcome-defining words must agree
so "win" vs "run for" or "at least 4" vs "4" never pair; one-to-one
Arbitrage engine now models buy YES on one venue + buy NO on the other
(the flat "sell YES" leg isn't possible without inventory), uses Kalshi's
0.07*P*(1-P) taker fee, and drops the duplicate 2% filter in app.py.
Also: certifi CA bundle for aiohttp, st.secrets crash without secrets.tβ¦
Add microstructure signal study pipelineβ
AJAY KASU
0bf767e
Runs on the ticks gathered by the collector and answers the edge-source
question directly: does order-book imbalance predict the next mid move,
and does that move survive the spread?
- build_dataset(): turns ticks into (features, forward-return) rows with
strict no-lookahead β each market labelled independently, final `horizon`
ticks dropped, no cross-market leakage.
- evaluate_signal(): parameter-free descriptive test β correlation of
imbalance/microprice edge with the forward move, directional hit rate,
and the decisive comparison of the captured move against the spread you
must cross to trade it.
Add Kalshi order-book tick collector for microstructure studyβ
AJAY KASU
a5c7715
Level-2 tick history is not downloadable, so the microstructure strategy
needs data collected live. Adds:
- src/microstructure/orderbook.py: pure Kalshi book reconstruction. Maps
the yes/no bid arrays to a YES book (ask = 100 - best no bid) and emits
microstructure features β mid, spread, top-of-book imbalance, and the
size-weighted microprice. No I/O, fully unit-tested.
- src/microstructure/collector.py: async websocket collector. Auto-discovers
the most liquid open markets, subscribes to orderbook_delta, applies
snapshots/deltas, detects sequence gaps and resyncs, and appends feature
rows to date-partitioned Parquet under data/ticks/.
websockets + pyarrow added to requirements (websockets was already imported
but missing from the file).
Fix live arbitrage scanner with verified market pairsβ
AJAY KASU
7d83f06
The scanner always reported "No opportunities" due to three bugs that
each broke the pipeline on their own:
- Polymarket: outcomePrices is a JSON string, so float() always threw;
switched to the real bestBid/bestAsk fields.
- Kalshi: the API now returns yes_bid_dollars/yes_ask_dollars (string
dollars) instead of yes_bid/yes_ask (int cents), and the default feed
only surfaces same-day combo markets.
- scan_opportunities() read market_mappings while app.py populated a
differently-named attribute, so the scan never saw matched markets.
Replaced unreliable fuzzy name matching β which paired unrelated markets
and emitted phantom arbs β with a curated table of 94 hand-verified
Polymarket/Kalshi pairs (2028 US presidential markets). Markets are now
fetched by ID, so every opportunity is the same real-world event on both
platforms.