Skip to content

Julian-dev28/sentient-market-reader

Repository files navigation

Sentient β€” Autonomous BTC Prediction Market Trader

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.

Next.js TypeScript xAI Grok Anthropic OpenAI OpenRouter Kalshi License


What It Does

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:

Quant Mode (default)

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:

  1. MarketDiscovery β€” scans Kalshi for the active KXBTC15M window, extracts strike price and time to expiry
  2. PriceFeed β€” live BTC/USD from Coinbase Exchange, 1h momentum computed from candle history
  3. Markov Gate β€” 9-state 1-min momentum model; Chapman-Kolmogorov propagation; requires β‰₯80% momentum persistence and β‰₯65% directional confidence to proceed
  4. SentimentAgent β€” ROMA multi-agent solve via the roma-dspy Python service; supports multi-provider ensemble
  5. 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)
  6. ExecutionAgent β€” BUY YES / BUY NO / PASS signal; fires only when Markov and Probability agree on direction

AI Mode (Grok)

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.

KXBTCD Hourly Mode

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.


Markov Chain Engine

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.


Price Feed

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)

Quant Signal Model

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

Risk Management

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".


Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      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                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

What is ROMA?

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.

Key Lesson: max_depth=0 = Unlimited Recursion

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.


Provider Support

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.


Autonomous Agent

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)

Tech Stack

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

Getting Started

Prerequisites

  • 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

Install

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

Configure

# .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:8001

Place your Kalshi RSA private key at ./kalshi_private_key.pem (already .gitignored).

Run

# 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:3000

Important: python3 main.py does nothing (no __main__ block). Always use uvicorn.

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.


Project Structure

β”œβ”€β”€ 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

Kalshi API Notes

  • 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_PADDING with RSA_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; use close_time for 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_price directly β€” do not complement to yes_price

Environment Variables

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

Note

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.


Disclaimer

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.


License

MIT

Releases

No releases published

Packages

 
 
 

Contributors