Live Kalshi algotrader with two fully independent execution paths: a Markov-gated quant pipeline and an autonomous Grok AI agent with full capital authority. All price data sourced exclusively from Coinbase Exchange β the same feed Kalshi settles against.
Sentient connects to Kalshi's live KXBTC15M and KXBTCD prediction markets β binary YES/NO contracts that resolve based on whether BTC's price is higher at the end of each 15-minute or 1-hour window β and runs an autonomous agent pipeline to analyze the market and place trades.
Two fully independent execution modes:
Continuous scanning. A Markov chain momentum model acts as a hard regime gate β if momentum isn't locked-in and directionally decisive, no LLM calls are made and no trade is placed. When the gate passes, the full multi-agent pipeline runs:
- MarketDiscovery β scans Kalshi for the active KXBTC15M window, extracts strike price and time to expiry
- PriceFeed β live BTC/USD from Coinbase Exchange, 1h momentum computed from candle history
- Markov Gate β 9-state 1-min momentum model; Chapman-Kolmogorov propagation; requires β₯80% momentum persistence and β₯65% directional confidence to proceed
- SentimentAgent β ROMA multi-agent solve via the roma-dspy Python service; supports multi-provider ensemble
- ProbabilityModelAgent β ROMA recursive solve with Cornish-Fisher skew-adjusted binary model, fat-tail Student-t fallback, Garman-Klass vol, multi-timeframe trend alignment (1h + 4h)
- ExecutionAgent β BUY YES / BUY NO / PASS signal; fires only when Markov and Probability agree on direction
Stages 3β6 are replaced by a single Grok AI agent that receives the full market picture β candles across 1m/15m/1h/4h timeframes, orderbook, derivatives, Markov momentum signal, live session state β and makes ALL decisions autonomously:
- Direction (YES or NO)
- Probability estimate
- Position size (full capital authority, quarter-Kelly suggested)
- Optional hedge leg
In AI mode, Markov is advisory context passed to Grok β not a hard gate. Grok weighs it alongside all other signals and has final decision authority.
Hard session circuit breakers (daily loss limit, trade count cap) are enforced before the Grok call regardless.
A separate dashboard for Kalshi's KXBTCD hourly BTC prediction markets. Grok must first predict where BTC will trade at the end of the hour, then bet the correct side. Multi-timeframe trend (4h β 1h β 15m) drives the prediction; Markov provides supporting momentum context.
The Markov agent is the core momentum signal. It is genuinely predictive: "given current 1-min momentum, will BTC close above or below the strike?"
State space: 9 bins of 1-min BTC % price changes (large down β large up).
Prediction method: Chapman-Kolmogorov propagation over T minutes, then Gaussian approximation of cumulative drift to compute P(YES) and P(NO).
Gate thresholds (quant mode):
- Momentum persistence (
Ο) β₯ 80% β the dominant momentum state must self-reinforce - Directional gap β₯ 15pp from 50% β model must be β₯65% confident
Sizing: Quarter-Kelly using Markov's P(win), scaled inversely by Garman-Klass vol. Sizing is owned by the server agent (not Markov output) and is computed from the configured Kelly bankroll.
History: Minimum 20 transitions before trusting the matrix. Seeded from 1-min live candles; falls back to 15-min candles.
All BTC price and candle data comes exclusively from Coinbase Exchange (api.exchange.coinbase.com) β the same source Kalshi uses to settle KXBTC15M contracts.
| Granularity | Endpoint | Used For |
|---|---|---|
| Spot ticker | /products/BTC-USD/ticker |
Live BTC price |
| 1-min candles | /candles?granularity=60 |
Markov momentum states |
| 15-min candles | /candles?granularity=900 |
GK vol, d-score, indicators |
| 1h candles | /candles?granularity=3600 |
Intraday trend (trend1h) |
| 4h candles | /candles?granularity=14400 |
Macro trend (trend4h) |
| Signal | Role |
|---|---|
| Markov momentum | Primary regime gate β must pass before any LLM calls |
| Garman-Klass vol | Intrabar vol estimator; scales position size inversely |
| Cornish-Fisher skew-adjusted binary | LLM-stage probability anchor; adjusts d2 for realized skew/kurtosis |
| Student-t fat-tail fallback (Ξ½=4) | When skew/kurt unavailable |
| Brownian prior fallback | Final probability fallback |
| Trend alignment | When 1h and 4h both agree with BTC's position, boosts pModel +7pp |
| Direction agreement gate | Execution fires only when Markov and Probability agree on YES/NO |
| Parameter | Value |
|---|---|
| Sizing | Quarter-Kelly (0.25Γ) from configured bankroll |
| Vol scalar | Inverse GK vol, clamped [0.3, 1.5] |
| Max trade size | 15% of portfolio |
| Max contracts | 500 |
| Maker fee | 1.75% Γ P Γ (1-P) per contract |
| Daily loss limit | max(5% portfolio, $50), capped $150 |
| Max trades/day | 48 |
| Min time before close | 2 min (stale pipeline guard) |
| Scan start | 14 min before close (~1 min into each 15-min window) |
| Scan interval | Every 5s (Markov pipeline) |
Order execution: All orders are placed as IOC (immediate-or-cancel). Two attempts: ask+3Β’ then ask+5Β’. Fills at best available or cancels.
Error recovery: Pipeline errors retry in 5 seconds (not minutes) to avoid missing windows. Displayed as "Pipeline error β retrying" not "Next window in X:XX".
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SENTIENT PIPELINE β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Coinbase Exchange βββΊ BTC spot + 1m/15m/1h/4h candles β
β Kalshi API ββββββββββΊ KXBTC15M/KXBTCD market + orderbook β
β Bybit βββββββββββββββΊ BTC perp funding rate + basis β
β β
β Stage 1 Β· MarketDiscovery (rule-based) β
β Stage 2 Β· PriceFeed (rule-based) β
β Stage 2.5 Β· Markov Gate (Chapman-Kolmogorov momentum) β
β β β
β ββ [quant: blocked] ββΊ NO_TRADE (no LLM calls)β
β β β
β ββββ QUANT MODE (gate passed) βββββββββββββββββββββββββββββββββ β
β β Stage 3 Β· SentimentAgent (ROMA β roma-dspy) β β
β β Stage 4 Β· ProbabilityModel (ROMA β Cornish-Fisher) β β
β β Stage 5 Β· ExecutionAgent (fires if Markov + Prob β β
β β agree on direction) β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β ββ or ββ β
β ββββ AI MODE ββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Grok Agent (stages 3-5 unified) β β
β β Full candle context: 1m Β· 15m Β· 1h Β· 4h β β
β β Markov signal (advisory) Β· orderbook Β· derivatives β β
β β Full capital authority β direction + size + hedge β β
β β Hard circuit breakers enforced before call β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β Server Agent: scans every 5s Β· starts 14 min before close β
β Error retry: 5s Β· gap between windows: ~1 min β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ROMA (Recursive Open Meta-Agent) is an open-source multi-agent reasoning framework by Sentient Foundation. Instead of sending one prompt and hoping for a coherent answer, ROMA breaks a complex goal into sub-problems, solves them in parallel across independent Executor agents, and synthesizes the results.
Goal
ββ Atomizer β atomic or needs decomposing?
ββ [atomic] β Executor answers directly
ββ [complex] β Planner generates 3β5 subtasks
β Executors run all in parallel
β Aggregator synthesizes result
Used in the Quant pipeline for Sentiment and Probability stages when the Markov gate passes. In AI mode, Grok replaces ROMA entirely.
max_depth=0 in roma-dspy is not "atomic" β it is interpreted as "no depth limit." A pipeline that was supposed to make 5β7 LLM calls instead recursed to depth 5 and made 40+ calls (wall time: 3m40s). Always use ROMA_MAX_DEPTH=1. A Math.max(1, ...) guard prevents zero from ever reaching the SDK.
Switch the entire pipeline with one env var:
| Tier | Grok | Claude | GPT | OpenRouter |
|---|---|---|---|---|
| blitz | grok-4-1-fast-non-reasoning |
claude-haiku-4-5-20251001 |
gpt-4o-mini |
any model |
| sharp | grok-3-mini-fast |
claude-haiku-4-5-20251001 |
gpt-4o-mini |
any model |
| keen | grok-3 |
claude-haiku-4-5-20251001 |
gpt-4o-mini |
any model |
| smart | grok-4-0709 |
claude-sonnet-4-6 |
gpt-4o |
any model |
The Provider Split Config lets you route different pipeline stages to different providers simultaneously. Multi-provider ensemble for Sentiment runs parallel ROMA solves; answers are merged before passing to Probability.
The server-side agent (lib/server-agent.ts) runs entirely in Node.js β immune to browser tab throttling.
- Scans continuously β Markov pipeline every 5s starting 14 min before each window's close
- Fast-path IOC entry β
fastEntry()places an order in ~5s when momentum triggers, before the full pipeline completes - Kelly auto-compounding β bankroll updates after each settled trade; allowance = bankroll Γ kellyPct
- Error recovery β pipeline errors retry in 5s; phase shows "Pipeline error β retrying" not a fake countdown
- Phases: idle β waiting β bootstrap β monitoring β pipeline β bet_placed / pass_skipped / order_failed / error
- Persistence β state and trade log survive HMR and cold starts via Vercel KV (with local file fallback)
| Layer | Tech |
|---|---|
| Framework | Next.js 16 App Router (React 19) |
| Language | TypeScript (strict) |
| AI β Grok | xAI Grok-3 / Grok-4 family via openai SDK (custom baseURL) |
| AI β Claude | Anthropic claude-sonnet-4-6 / claude-haiku-4-5 via @anthropic-ai/sdk |
| AI β GPT | OpenAI gpt-4o / gpt-4o-mini via openai SDK |
| AI β OpenRouter | Any model via OpenRouter API |
| Multi-Agent | Official Sentient roma-dspy Python SDK via FastAPI microservice |
| Momentum Model | Markov chain β 9-state 1-min price change bins, Chapman-Kolmogorov propagation |
| Prediction Markets | Kalshi Trade API v2 (KXBTC15M Β· KXBTCD series) |
| Price Data | Coinbase Exchange exclusively (api.exchange.coinbase.com) |
| Derivatives | Bybit perp funding rate + basis |
| Auth | RSA-PSS request signing (crypto.createSign) for Kalshi |
| Session State | Vercel KV β daily P&L, trade count, bankroll persist across cold starts |
| Charts | Recharts |
| Styling | CSS design tokens |
- Node.js 18+
- Python 3.10+ (for the roma-dspy microservice β use a venv outside the Next.js project dir to avoid Turbopack symlink issues)
- A Kalshi account with API access and RSA key pair
- API key for at least one LLM provider: xAI Β· Anthropic Β· OpenAI Β· OpenRouter
git clone https://github.com/Julian-dev28/sentient-market-reader.git
cd sentient-market-reader
npm install
# Set up the Python roma-dspy service (venv outside project root)
python3 -m venv ~/.sentient-venv
source ~/.sentient-venv/bin/activate
pip install -r python-service/requirements.txt# .env.local
# ββ LLM Provider βββββββββββββββββββββββββββββββββββββββββββββββββ
AI_PROVIDER=grok # anthropic | grok | openai | openrouter
ROMA_MODE=keen # blitz | sharp | keen | smart
ROMA_MAX_DEPTH=1 # NEVER set 0 β means unlimited recursion in roma-dspy
XAI_API_KEY=xai-...
# ANTHROPIC_API_KEY=sk-ant-...
# OPENAI_API_KEY=sk-...
# OPENROUTER_API_KEY=sk-or-...
# ββ Kalshi βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
KALSHI_API_KEY=your-kalshi-api-key-id
KALSHI_PRIVATE_KEY_PATH=./kalshi_private_key.pem
# ββ Python Service βββββββββββββββββββββββββββββββββββββββββββββββ
PYTHON_ROMA_URL=http://localhost:8001Place your Kalshi RSA private key at ./kalshi_private_key.pem (already .gitignored).
# Terminal 1 β Python roma-dspy service
source ~/.sentient-venv/bin/activate
cd python-service && python3 -m uvicorn main:app --port 8001 --host 0.0.0.0
# Terminal 2 β Next.js
npm run dev
# β http://localhost:3000Important:
python3 main.pydoes nothing (no__main__block). Always useuvicorn.
Open /dashboard for the 15-min pipeline, /dashboard/hourly for the KXBTCD 1h market, or /agent for the autonomous agent. Paper mode is the default β no real orders until you toggle Live Trading and start the agent.
βββ app/
β βββ api/
β β βββ pipeline/route.ts # Main pipeline endpoint + SSE stream
β β βββ agent/ # Agent start/stop/state/stream
β β βββ place-order/ # Kalshi IOC order placement
β β βββ market-quote/[ticker]/ # Fresh quote fetch (staleness gate)
β β βββ balance/ # Kalshi account balance
β β βββ orders/ # Order history
β βββ dashboard/page.tsx # 15-min KXBTC15M dashboard
β βββ dashboard/hourly/page.tsx # 1h KXBTCD dashboard
β βββ agent/page.tsx # Autonomous agent panel
β
βββ lib/
β βββ agents/
β β βββ markov.ts # Markov chain agent β momentum gate + sizing
β β βββ grok-trading-agent.ts # AI mode β unified Grok agent (stages 3-5)
β β βββ market-discovery.ts # Kalshi KXBTC15M/KXBTCD scanner
β β βββ price-feed.ts # BTC price + distance from strike
β β βββ sentiment.ts # ROMA sentiment (multi-provider ensemble)
β β βββ probability-model.ts # ROMA probability + trend alignment
β β βββ execution.ts # Order generation
β β βββ index.ts # Pipeline orchestrator β Markov gate + quant/AI branch
β βββ markov/
β β βββ chain.ts # Transition matrix, Chapman-Kolmogorov, Gaussian forecast
β β βββ history.ts # Per-market momentum history (15m / 1h keys)
β βββ server-agent.ts # Autonomous server-side agent (singleton)
β βββ agent-shared.ts # AgentPhase type + shared constants
β βββ indicators.ts # GK vol, Cornish-Fisher, RSI, MACD, d-score, quant signals
β βββ llm-client.ts # Unified LLM interface β all providers + tiers
β βββ kalshi-auth.ts # RSA-PSS request signing
β βββ kalshi-trade.ts # placeOrder, getBalance, getPositions
β βββ types.ts # Shared TypeScript interfaces
β
βββ components/
β βββ AgentPipeline.tsx # Live pipeline grid with streaming agent results
β βββ AgentAllowancePanel.tsx # Agent start/stop, Kelly config, Momentum Monitor
β βββ MarkovPanel.tsx # Markov state + transition matrix visualizer
β βββ MarketCard.tsx # Live Kalshi market + orderbook
β βββ SignalPanel.tsx # Edge %, probability bars, sentiment meter
β βββ PriceChart.tsx # BTC/USD area chart with strike line
β βββ TradeLog.tsx # Trade history with P&L
β
βββ python-service/
βββ main.py # FastAPI β roma-dspy solve() wrapper
βββ run_backtest.py # Quant backtest (30-day, live Kalshi data)
βββ requirements.txt
- Base URL:
https://api.elections.kalshi.com/trade-api/v2/ - Auth headers:
KALSHI-ACCESS-KEYΒ·KALSHI-ACCESS-TIMESTAMP(milliseconds) Β·KALSHI-ACCESS-SIGNATURE - Signature payload:
{timestampMs}{METHOD}{path}β direct concat, no separators, no query params in path - RSA padding:
RSA_PKCS1_PSS_PADDINGwithRSA_PSS_SALTLEN_DIGEST - Market discovery:
?event_ticker=KXBTC15M-{YY}{MON}{DD}{HHMM}in US Eastern Time - Active markets:
yes_ask > 0;floor_strike= BTC price to beat; useclose_timefor countdown - Trading hours: ~11:30 AM β midnight ET weekdays
- Order type: Always
time_in_force: immediate_or_cancelβ GTC orders fill at stale prices - NO orders: Send
no_pricedirectly β do not complement toyes_price
| Variable | Required | Description |
|---|---|---|
AI_PROVIDER |
Yes | grok | anthropic | openai | openrouter |
ROMA_MODE |
No | blitz | sharp | keen | smart β default keen |
ROMA_MAX_DEPTH |
No | ROMA decomposition depth β default 1; never set 0 |
XAI_API_KEY |
If Grok | xAI API key |
ANTHROPIC_API_KEY |
If Claude | Anthropic API key |
OPENAI_API_KEY |
If OpenAI | OpenAI API key |
OPENROUTER_API_KEY |
If OpenRouter | OpenRouter API key |
KALSHI_API_KEY |
Yes | Kalshi API key ID (UUID) |
KALSHI_PRIVATE_KEY_PATH |
Yes | Path to RSA private key PEM |
PYTHON_ROMA_URL |
No | roma-dspy service URL (default http://localhost:8001) |
KV_REST_API_URL |
If Vercel | Vercel KV URL for session state persistence |
KV_REST_API_TOKEN |
If Vercel | Vercel KV token |
Architecture and agent framework integrations are subject to change as we continue researching multi-agent and single-agent approaches. The pipeline described here reflects the current implementation.
This project is for educational and research purposes. Paper trading is the default. Live trading places real orders with real money on a regulated prediction market exchange. Use live mode at your own risk. Nothing here is financial advice.
MIT