Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Polymarket Real-Time Dashboard

A full-stack real-time dashboard for Polymarket prediction markets, featuring live order books, probability charts, and WebSocket-driven updates.

Architecture Overview

Polymarket Gamma API → PolymarketProvider → MarketService → PostgreSQL/TimescaleDB
Polymarket CLOB API  → PolymarketProvider → OrderBookService → In-memory cache
Polymarket CLOB WS   → IngestionWorker → ConnectionManager → Frontend WebSocket

Tech Stack

  • Backend: Python 3.12, FastAPI, async SQLAlchemy 2, asyncpg, Alembic, httpx
  • Database: PostgreSQL 16 + TimescaleDB (hypertable for time-series probability data)
  • Frontend: React 18, TypeScript, Vite, Tailwind CSS, React Query
  • Infrastructure: Docker Compose (all services containerized)

Quick Start (Docker Only)

Prerequisites: Docker Desktop only. No Python, Node, or database installation needed on the host.

cp .env.example .env
# Edit .env if needed (defaults work out of the box)
make up

Services:

Commands

make up              # Start all services (build if needed)
make down            # Stop all services
make migrate         # Run Alembic migrations inside container
make test            # Run pytest inside container
make logs            # Tail all service logs
make backend-shell   # Shell into backend container
make db-shell        # psql into database container
make lint            # Run ruff linter
make format          # Run ruff formatter

API Examples

# Health check
curl http://localhost:8000/api/v1/health

# List active markets
curl http://localhost:8000/api/v1/markets

# Get market detail
curl http://localhost:8000/api/v1/markets/{market_id}

# Price history (last 24h)
curl "http://localhost:8000/api/v1/markets/{market_id}/history?hours=24"

# Order book for a specific outcome
curl "http://localhost:8000/api/v1/markets/{market_id}/order-book?outcome_id={outcome_id}"

# WebSocket (use wscat or similar)
wscat -c ws://localhost:8000/api/v1/ws/markets/{market_id}

DB Schema

  • markets: Market metadata, synced from Gamma API on startup
  • outcomes: YES/NO outcomes per market with current probability
  • probability_ticks: TimescaleDB hypertable — every probability change event, partitioned by time
  • order_book_snapshots: Periodic JSONB snapshots of bids/asks (live data kept in memory)

Indexing Strategy

  • probability_ticks uses TimescaleDB automatic time-partitioned chunks for efficient range queries
  • Composite index on (outcome_id, observed_at DESC) for fast per-outcome history lookups
  • external_token_id unique index on outcomes for O(1) lookup during WebSocket event routing

Provider Abstraction

Adding a KalshiProvider would require:

  1. Implement MarketDataProvider ABC in app/providers/kalshi.py
  2. Register it in the DI container in app/main.py
  3. No changes needed to services, repositories, routers, or DB models

The provider column on the markets table already accommodates multi-provider data.

WebSocket Flow

  1. Frontend connects to ws://localhost:8000/api/v1/ws/markets/{market_id}
  2. ConnectionManager registers the client for that market
  3. IngestionWorker receives events from Polymarket CLOB WebSocket
  4. Events are normalized into typed envelopes and broadcast to registered clients
  5. Frontend components update via the useMarketSocket hook

Trade-offs & Production Notes

  • Single-process ingestion: The upstream Polymarket WebSocket runs in-process. In production, move it to a separate worker to avoid duplicate subscriptions when horizontally scaling the API.
  • In-memory order books: Live order books are kept in a dict for sub-millisecond reads; snapshots are persisted to DB periodically (not on every update) to reduce write amplification.
  • Probability deduplication: Ticks are only written when the value actually changes, preventing time-series bloat from high-frequency no-op events.
  • No auth: This is a read-only public dashboard. Production would add auth for any write operations.

What I'd Improve With More Time

  • Separate ingestion worker process with message queue (Redis Streams or Kafka)
  • Multi-provider support with provider-specific adapters (Kalshi, Manifold)
  • Caching layer (Redis) for frequently-requested market data
  • Rate limiting and circuit breaker on upstream API calls
  • Horizontal scaling with sticky WebSocket sessions or pub/sub fanout
  • E2E tests with Playwright
  • OpenTelemetry tracing

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages