This repo is now tuned for an NBA-first workflow:
- Elo is the primary probability engine.
- LLM does not set probabilities directly.
- LLM can only provide bounded Elo adjustments for context like injuries/rest/lineups.
- Final trade probability always comes from Elo math.
kaggleGameData.csv -> Elo ratings -> base probability -> LLM Elo adjustment -> adjusted Elo -> final probability -> edge/risk checks -> execution
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtcp .env.example .envSet at least:
KALSHI_API_KEYKALSHI_PRIVATE_KEYorKALSHI_PRIVATE_KEY_FILE(live mode)OPENAI_API_KEYand/orANTHROPIC_API_KEY
cp advanced_config.template.json advanced_config.jsonRecommended for NBA dry runs:
analysis.provider = "openai"(or"claude")analysis.nba_elo_enabled = trueanalysis.nba_elo_data_path = "context/kaggleGameData.csv"analysis.context_json_path = "context/llm_context.json"trading.dry_run = trueplatforms.kalshi.enabled = trueplatforms.polymarket.enabled = false
python -m app --set-allowed-series-tickers KXNBAGAMEpython -m app --set-config filters.min_volume=0 --set-config filters.min_liquidity=0python -m app --mode trade --once --dry-run --skip-setup-wizard --non-interactiveFor one-cycle dry runs, the bot writes JSON output to reports/dry_run_analysis/ and does not print the full table.
python -m app --mode trade --once --dry-runThis mode supports:
- setup wizard edits
- market picker
- pre-scan NBA scope discovery and manual series selection
- Dry-run analysis JSON:
reports/dry_run_analysis/ - Daily trade journal (dry + live):
reports/trade_journal/YYYY-MM-DD.json - Heartbeat:
reports/heartbeat.json - SQLite DBs:
- Dry-run:
kalshi_dryrun.sqlite - Live:
kalshi.sqlite
- Dry-run:
When NBA Elo mode is enabled, logs now include:
ELO_DECISION: final Elo-derived probability and edgeELO_SUGGESTION: raw LLM Elo-delta suggestion + injury/rest metadata
Dry-run analysis JSON rows also include:
elo_adjustmentllm_suggestioninjury_report
- Duplicate market/event guards (no overlapping same-event positions in cycle).
- Buy-NO Kelly sizing fix (uses NO-side probability).
- Execution-time revalidation:
- price drift
- minimum edge at execution
- submit slippage
- Risk guards:
- per-cycle order/notional caps
- daily loss guard
- optional kill switch via env var
- market/day frequency cap
- Execution-path exposure enforcement:
risk.max_new_exposure_per_day_fractionrisk.max_total_exposure_fraction
- Structured pre-trade logs:
TRADE_DECISIONMODEL_DIVERGENCE_WARNING(logging only, no block)
- Live bankroll startup check:
- verifies Kalshi cash >=
trading.initial_bankrollbefore live run
- verifies Kalshi cash >=
python -m app --show-config
python -m app --verify-config --mode trade
python -m app --set-config analysis.provider=openai
python -m app --set-config trading.dry_run=truepython -m app --set-allowed-series-tickers KXNBAGAME
python -m app --set-allowed-market-ids KXNBAGAME-26FEB19DETNYK-DET
python -m app --set-allowed-event-tickers KXNBAGAME-26FEB19DETNYKpython -m app --mode trade --once --dry-run
python -m app --mode trade --once --dry-run --skip-setup-wizard --non-interactive
python -m app --mode trade --dry-run
python -m app --mode tradepython -m app --discover-series --category Sports
python -m app --backup
python scripts/kalshi_user_details.py
python scripts/walkback_nba_matchup_analysis.py --output reports/walkback_analysis/latest.jsonAdd custom context in context/llm_context.json (or your configured analysis.context_json_path).
This context is loaded into analysis prompts as supplemental information.
Before enabling live:
- Keep strict scope (
KXNBAGAMEor narrower). - Start with small bankroll and conservative risk caps.
- Run at least one full dry-run cycle on VPS using your production command.
- Confirm journals/logs/heartbeat update correctly.
Kill switch:
export BOT_DISABLE_TRADING=1Run non-interactive autonomous style:
python -m app --mode trade --skip-setup-wizard --non-interactiveModuleNotFoundError: app: run from repo root and use the venv..env parse warning: fix malformed.envline format (KEY=value).- No markets found: verify scope and filters.
- Live startup fails bankroll check: fund account or lower
trading.initial_bankroll.
TECHNICAL_DOCS.mdOPERATIONS.mdLIVE_AUTONOMOUS_V1_GAP_LIST.md