Skip to content

rohanthomas1202/truthlayer

Repository files navigation

EdgeTerminal

Real-time cross-market arbitrage monitoring for prediction market traders.

Python 3.12 Next.js 16 React 19 FastAPI PostgreSQL 16 Deployed on Railway Deployed on Vercel

Live Demo →

Unified multi-platform signal view — v1.2 preview

v1.2 preview — EdgeTerminal × TruthLayer. Aggregating Polymarket, Kalshi, Metaculus, PredictIt, and Manifold into a single canonical probability per event with confidence, trend, and cross-venue disagreement scoring. This is the unified signal view shipping in v1.2 (in progress). The live demo currently runs v1.1 — Polymarket × Kalshi arb feed with historical P&L proof — documented below.


EdgeTerminal continuously ingests prediction markets from Polymarket and Kalshi (with Metaculus, PredictIt, and Manifold arriving in v1.2), matches equivalent contracts across venues using a multi-tier pipeline (keyword similarity → FAISS embeddings → Claude LLM verification → entity extraction), and surfaces fee-adjusted arbitrage opportunities in a live streaming dashboard — with historical P&L proof that every detected opportunity was real.

Core value: When two prediction markets disagree on the same event, show the trader exactly where, by how much, and with what confidence — in real time, with a historical record that detected opportunities were real.

EdgeTerminal is a research and analysis tool, not financial advice. It surfaces price discrepancies and does not execute trades automatically. See the Disclaimer below.


Why EdgeTerminal

Prediction market arbitrage is operationally fragile. Retail traders manually refresh Polymarket and Kalshi tabs and still miss the best windows.

The problem

  • Contract wording varies — "Will Trump win?" vs "Trump to win 2024 presidential election" reference the same event with potentially different resolution criteria.
  • Settlement sources differ — Two venues may resolve the same contract against different data sources or at different times.
  • Liquidity is thin — Apparent arbs can vanish the moment you try to fill both sides.
  • Pricing models differ — Polymarket uses AMM + CLOB hybrid; Kalshi is pure CLOB with different tick sizes and fee structures.
  • False positives destroy trust — Showing a "10% arb" that isn't real is worse than missing a real one.

What EdgeTerminal does

  • Continuous 30-second polling of both venues with circuit breakers, retry, and freshness tracking.
  • Precision-first matching — keyword similarity → FAISS candidate discovery → Claude LLM verification → entity extraction → framing-pattern taxonomy (17 patterns). False positives are treated as worse than misses.
  • Fee-adjusted spreads with lifecycle tracking: DETECTED → CONFIRMED → STALE → EXPIRED.
  • Historical P&L proof — every detected arb is tracked through settlement so the scoreboard is verifiable, not theoretical.

✨ Features

🔍 Matching Pipeline

  • Multi-tier matcher — keyword similarity, FAISS candidate discovery, Claude LLM verification, entity extraction.
  • Framing pattern taxonomy — 17 patterns for complementary contracts and false-match rejection.
  • Seed-list bootstrap for high-traffic recurring events (sports, elections, macro).
  • Multi-leg decomposition for composite contracts.

💹 Arb Detection

  • Fee-adjusted spreads across every venue pair carrying the same canonical event.
  • Lifecycle trackingDETECTED → CONFIRMED → STALE → EXPIRED.
  • Confidence scoring with venue-pair trust multipliers.
  • Settlement-risk indicator (green / yellow / red) based on resolution-criteria comparison.

📡 Live Dashboard

  • SSE streaming arb feed — sub-second updates, no polling on the client.
  • Sortable & filterable cards with venue deep links.
  • Side-by-side pair comparison with historical spread charts (lightweight-charts).
  • OHLC candlestick price charts per market.
  • Category + full-text search across every matched event.
  • Mobile-responsive terminal layout.

🧠 Market Intelligence

  • Market regime bar — live VIX, BTC, S&P 500, and DXY as macro context.
  • Correlated-asset ticker mapping — prediction market events auto-tagged with underlying tickers (e.g., BTC > $120KBTCUSDT).
  • Arb enrichment panel — TA summary (tradingview-ta), Reddit sentiment, and Google News headlines for the correlated underlying.
  • News catalyst badges (Google News RSS) with click-through to the source.
  • Volume breakout warnings — Binance + Yahoo Finance scans flag unusual underlying activity.
  • GDELT news-heat signal — live article volume + top headline (GDELT 2.0 DOC API) over a 24h window, scored 0–100 per matched event; surfaces whether an arb is news-driven or stale.

🦈 MiroShark Integration (optional)

  • One-click crowd-reaction simulation — trigger a MiroShark multi-agent simulation directly from any arb in the feed. The arb's event title, both venues' descriptions, prices, and active news catalyst are packaged as a document bundle and handed off via MiroShark's graph-build → simulation-create → start API chain.
  • Live SSE progress stepper — 7-stage stepper (preparing, fetching catalyst, ontology, graph, sim, personas, start) streams updates from the backend; the final done event auto-opens the simulation in a new tab on MiroShark's own results UI.
  • Idempotentmiroshark_sim_id is stored on the arb row, so repeat clicks deep-link to the existing simulation instead of wasting LLM work.

Local-dev only. The button is hidden in production unless MIROSHARK_URL (backend) and NEXT_PUBLIC_MIROSHARK_URL (frontend) are set, since MiroShark runs locally against its own LLM credits.

🎯 Trader's Toolkit

  • Configurable alerts — in-app toasts + webhook delivery (Discord, Slack, generic JSON), 30-minute cooldown dedupe.
  • Personal watchlist — anonymous session identity (no login), JSON export / import.
  • Performance analytics — confidence calibration curves, venue-pair P&L breakdowns, category stats over configurable time ranges.
  • Backtest conviction scoring — data-backed TA → prediction-market correlation per arb.

📜 Historical Proof

  • Per-event P&L tracking through settlement.
  • Immutable price-snapshot history (PostgreSQL, append-only, indexed).
  • OHLC candle rollups and top-of-book depth capture (top 5 levels).

🏗️ Architecture

Polymarket and Kalshi are polled asynchronously, normalized into a common schema, matched into canonical events, and streamed to the dashboard over SSE. Enrichment sources attach to each arb as a side branch.

graph LR
    subgraph Ingest["🛰️ Ingest (async httpx)"]
        P[Polymarket CLOB]
        K[Kalshi API<br/>RSA-signed]
    end

    subgraph Scheduler["⏱️ APScheduler"]
        PL[pricing_loop<br/>30s]
        ML[matching_loop<br/>15m]
    end

    subgraph Data["🗄️ PostgreSQL 16"]
        RM[raw_markets]
        CE[canonical_events]
        PS[price_snapshots]
        AO[arb_opportunities]
    end

    subgraph Matching["🧩 Matching Pipeline"]
        KW[keyword similarity]
        FA[FAISS embeddings<br/>all-MiniLM-L6-v2]
        LLM[Claude LLM<br/>verification]
        EE[entity extraction]
    end

    subgraph Enrich["🧠 Enrichment"]
        TV[TradingView TA]
        RD[Reddit sentiment]
        GN[Google News RSS]
        BY[Binance + Yahoo volume]
    end

    subgraph Frontend["💻 Next.js 16 Dashboard"]
        UI[Arb feed · Watchlist · Analytics]
    end

    subgraph Miro["🦈 MiroShark (local-only, optional)"]
        MS[Multi-agent simulation]
    end

    P --> RM
    K --> RM
    PL --> RM
    ML --> KW
    KW --> FA --> LLM --> EE --> CE
    RM --> PS
    CE --> AO
    PS --> AO

    TV -.-> UI
    RD -.-> UI
    GN -.-> UI
    BY -.-> UI

    AO -->|/api/arbs/stream SSE| UI
    CE -->|/api/events| UI

    UI -.->|POST + SSE<br/>optional| MS
Loading

🚀 Quick Start

Prerequisites

  • Docker & Docker Compose — for the one-command stack
  • Python 3.12 — for backend-only development
  • Node.js 20 — for frontend-only development

One-command local setup

git clone <repo-url> edgeterminal
cd edgeterminal
cp .env.example .env   # fill in KALSHI_KEY_ID, ANTHROPIC_API_KEY, etc.
docker compose up

Then open:

Required environment variables

Variable Purpose
DATABASE_URL PostgreSQL async connection string (asyncpg)
KALSHI_KEY_ID Kalshi API key identifier
KALSHI_PRIVATE_KEY_PATH Path to RSA private key used for Kalshi request signing
ANTHROPIC_API_KEY Claude API key for LLM match verification
POLLING_INTERVAL_SECONDS Pricing-loop cadence (default: 30)
MATCHING_INTERVAL_MINUTES Matching-loop cadence (default: 15)
NEXT_PUBLIC_API_URL Backend URL consumed by the Next.js frontend
MIROSHARK_URL Optional; enables MiroShark button in ArbDetail (local dev). Backend reads this to reach a self-hosted MiroShark instance.
NEXT_PUBLIC_MIROSHARK_URL Optional; enables MiroShark button in ArbDetail (local dev). Frontend reads this to construct deep-links to simulation results.

See CLAUDE.md for the complete list including logging and Supabase pooler settings.


🌍 Live Deployments

Service URL
Frontend (Vercel) https://frontend-indol-five-84.vercel.app
Backend (Railway) https://backend-production-228e.up.railway.app
Database (Supabase) Capstone project, us-west-2, session pooler at aws-1-us-west-2.pooler.supabase.com:5432

Railway auto-deploys from main. Vercel auto-deploys the frontend/ directory from main.


🔌 API Reference

The backend exposes a small, documented REST + SSE surface. Production base URL: https://backend-production-228e.up.railway.app.

Endpoint Purpose
GET /api/health Liveness + matched-event count
GET /api/health/scheduler Pricing-loop status + last error
GET /api/status Per-venue freshness and staleness
GET /api/debug/raw Unfiltered pipeline state (canonical events, raw markets, snapshots, arbs)
GET /api/events Matched cross-venue events with latest prices
GET /api/arbs Active arb opportunities
GET /api/arbs/stream SSE stream of active arbs (used by the dashboard)
POST /api/debug/trigger-matching Manually kick the matching loop
POST /api/debug/trigger-pricing Manually kick the pricing loop
POST /api/miroshark/simulate/arb/{arb_id} Trigger a MiroShark simulation for an arb (returns cached sim_id on repeat; 409 if MIROSHARK_URL not configured)
GET /api/miroshark/simulate/stream/{job_id} SSE progress stream for a running MiroShark simulation (events: progress, done, error)

Interactive schema browser (Swagger / OpenAPI) is available at /docs on any running backend.


🛠️ Tech Stack

Backend

  • Python 3.12 · FastAPI 0.115 · Uvicorn 0.32
  • SQLAlchemy 2.0 (async) · asyncpg 0.30 · Alembic 1.14
  • APScheduler 3.11 — background pricing (30s) + matching (15m) loops
  • httpx 0.28 — async clients for Polymarket + Kalshi (Kalshi uses RSA request signing via cryptography)
  • pytest — unit and integration tests

Frontend

  • Next.js 16 (App Router, SSR) · React 19 · TypeScript 5 (strict)
  • SWR 2.4 — stale-while-revalidate data fetching with 30s refresh
  • TailwindCSS 4 · tailwind-merge · tw-animate-css
  • lightweight-charts 5 — TradingView-style historical spread and OHLC charts

ML / AI

  • Claude via anthropic 0.43 — LLM verification of candidate matches
  • sentence-transformers 5.3 (all-MiniLM-L6-v2, ~90 MB) — semantic embeddings
  • FAISS — approximate nearest-neighbor candidate discovery
  • PyTorch 2.11 — transformer runtime

Infra & Tooling

  • Docker Compose — local dev (Postgres + backend + frontend)
  • Railway — backend hosting, auto-deploy from main
  • Vercel — frontend hosting, auto-deploy from frontend/
  • Supabase — managed PostgreSQL 16 (session pooler)

📊 Roadmap

  • v1.0 MVP — shipped 2026-04-13 (Phases 1-10: data ingestion → matching → arb detection → live dashboard → historical P&L)
  • 🚧 v1.1 Market Intelligence & Multi-Venue Expansion — in progress (Phases 11-22: foundation hardening, multi-venue via PMXT, market regime, enrichment panel, news & volume signals, alerts, watchlist, performance analytics, cloud deploy, synthetic-ID fix)
  • 🔭 v1.2 TruthLayer Merger — planned (Phases 23-27: porting the strongest primitives from the sister TruthLayer project — diff-prefilter matching quick wins, 5-level equivalence grading + hedgeability, resolution-validation backtesting harness, cross-venue signal computation, and a Fact → Interpretation → VenueMarket graph schema enabling 5-platform aggregation pictured above)

Detailed phase breakdown, success criteria, and plan-level status live in .planning/ROADMAP.md.


🤝 Contributing

EdgeTerminal is a capstone project being built in the open. Issues and pull requests are welcome — especially around matching precision, new venue adapters, and enrichment sources.

Before contributing:

  1. Read CLAUDE.md for conventions, naming patterns, and error-handling style.
  2. Browse .planning/ — the project uses the GSD (Get Shit Done) workflow; planning artifacts, phase breakdowns, and decision logs live there.
  3. Keep changes scoped and atomic; run tests locally before opening a PR.

⚠️ Disclaimer

EdgeTerminal is a research and analysis tool. It surfaces price discrepancies across prediction markets but does not provide financial advice, does not execute trades automatically, and makes no guarantees about the validity, fillability, or profitability of any detected arbitrage opportunity. Prediction market trading carries risk including total loss of capital; users are solely responsible for verifying opportunities and managing their own execution. Past performance of detected arbs is not indicative of future results.


License

No LICENSE file is currently included in this repository. Until one is added, all rights are reserved by the author under default U.S. copyright law. If you would like to use this code, please open an issue to discuss licensing.

About

Real-time cross-market arbitrage scanner for Polymarket and Kalshi. Multi-tier matching (FAISS + Claude LLM), fee-adjusted spreads, settlement-verified scoreboard.

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors