Skip to content

p-matt/sympoly-api

Repository files navigation

Sympoly API

A FastAPI-based analytics platform that aggregates and analyzes data from Polymarket to provide insights into market dynamics and top trader behaviors.

Overview

Sympoly API fetches data from Polymarket's public API to compute statistics about prediction markets, focusing on:

  • Active market dynamics and sentiment analysis
  • Top trader positions and behaviors
  • Consensus metrics derived from trader positions
  • Market liquidity and volume statistics

The API runs background workers that periodically fetch data from Polymarket and store it in a PostgreSQL database, making it available through REST endpoints for frontend consumption.

Features

  • Real-time Market Stats: Aggregated statistics on active prediction markets
  • Smart Consensus Calculation: Analyzes top traders' positions to identify market sentiment
  • Position Tracking: Monitors positions of top-performing traders across all active markets
  • Market Search: Fast autocomplete search for active markets
  • Async Data Pipeline: Background workers continuously sync data from Polymarket API

Architecture

Technology Stack

  • Framework: FastAPI (Python 3.14)
  • Database: PostgreSQL with SQLAlchemy (async)
  • Task Queue: Celery with Redis broker
  • Scheduler: Celery Beat for periodic tasks
  • API Client: Custom Polymarket API wrapper
  • Data Processing: Pandas for statistics computation

Project Structure

sympoly-api/
├── main.py                     # FastAPI application entry point
├── alembic/                    # Database migrations
│   └── versions/               # Migration scripts
├── app/
│   ├── celery_app.py          # Celery configuration and beat schedule
│   ├── config.py              # Application settings
│   ├── database.py            # Database connection and session management
│   ├── utils.py               # Utility functions
│   ├── libs/
│   │   └── polymarket_api.py  # Polymarket API client
│   ├── models/                # SQLAlchemy ORM models
│   │   ├── base.py            # Base model class
│   │   ├── batch.py           # Batch tracking models
│   │   └── polymarket.py      # Polymarket data models
│   ├── routers/               # API route handlers
│   │   └── symbiosis.py       # Main API endpoints
│   ├── schemas/               # Pydantic models for request/response
│   │   └── symbiosis.py       # API schemas
│   ├── services/              # Business logic layer
│   │   ├── active_market_service.py
│   │   ├── batch_service.py
│   │   ├── leaderboard_service.py
│   │   ├── symbiosis_service.py
│   │   └── user_position_service.py
│   └── tasks/                 # Celery background tasks
│       ├── active_markets_worker.py    # Fetches active markets
│       ├── leaderboard_worker.py       # Fetches top traders
│       └── user_positions_worker.py    # Fetches trader positions
└── scripts/
    └── notebooks/             # Jupyter notebooks for analysis

Background Tasks (Celery)

The application uses Celery Beat to schedule periodic data synchronization tasks:

Active Markets Worker

  • Task: fetch_active_markets
  • Function: Fetches all active prediction markets from Polymarket
  • Frequency: Configurable (currently disabled in production)
  • Processing: Filters markets by active status and end date

Leaderboard Worker

  • Task: fetch_leaderboard
  • Function: Retrieves the monthly leaderboard of top traders
  • Frequency: Configurable (currently disabled in production)
  • Processing: Fetches top 5000 traders ranked by performance

User Positions Worker

  • Task: fetch_user_positions
  • Function: Collects all positions for top traders across active markets
  • Frequency: Configurable via user_positions_interval setting
  • Processing:
    • Fetches positions for all top traders
    • Filters positions by active markets only
    • Deduplicates and stores in database
    • Takes ~20 minutes for 5000 users (300K+ positions)

Each task includes:

  • Automatic retry with exponential backoff
  • Error handling and logging
  • Batch tracking to prevent duplicate processing
  • Database transaction management

API Endpoints

Base URL

  • Development: http://localhost:8000

Endpoints

GET /

Root endpoint with API information.

Response:

{
  "message": "Welcome to Sympoly API",
  "version": "0.1.0",
  "docs": "/docs"
}

GET /api/stats

Get symbiosis statistics for markets based on top trader positions.

Query Parameters:

  • top_n_traders (int, default=5000): Number of top traders to include (1-5000)
  • sort_by (string, default="count_traders"): Column to sort by
    • Options: count_traders, smart_consensus, median_trade_price, median_pnl_pct, etc.
  • sort_asc (bool, default=false): Sort order (true=ascending, false=descending)
  • page (int, default=1): Page number (1-indexed)
  • page_size (int, default=50): Items per page (max 100)
  • slug (string, optional): Filter by specific market slug

Response:

{
  "total": 9372,
  "page": 1,
  "page_size": 50,
  "total_pages": 188,
  "items": [
    {
      "slug": "market-slug",
      "question": "Market question?",
      "count_traders": 149,
      "label_outcome_1": "Yes",
      "count_outcome_1": 89,
      "pct_outcome_1": 59.73,
      "label_outcome_2": "No",
      "count_outcome_2": 60,
      "pct_outcome_2": 40.27,
      "smart_consensus": 59.73,
      "liquidity": 123456.78,
      "volume": 987654.32,
      "endDate": "2025-12-31T23:59:59Z"
    }
  ]
}

GET /api/markets/search

Search for active markets by question text (optimized for autocomplete).

Query Parameters:

  • q (string, required): Search query (min 1 character, case-insensitive)
  • limit (int, default=6): Maximum results (max 20)

Response:

{
  "items": [
    {
      "slug": "market-slug",
      "question": "Market question?",
      "icon": "https://...",
      "endDate": "2025-12-31T23:59:59Z"
    }
  ]
}

GET /api/positions/{slug}

Get user positions for a specific market, balanced by outcome.

Path Parameters:

  • slug (string, required): Market slug

Query Parameters:

  • top_n_traders (int, default=5000): Number of top traders (1-5000)
  • page (int, default=1): Page number
  • page_size (int, default=50): Items per page (max 100)

Response:

{
  "total": 149,
  "page": 1,
  "page_size": 50,
  "total_pages": 3,
  "items": [
    {
      "proxyWallet": "0x...",
      "userName": "TraderName",
      "rank": 42,
      "outcome": "Yes",
      "size": 1234.56,
      "avgPrice": 0.65,
      "cashPnl": 123.45,
      "percentPnl": 12.34
    }
  ]
}

API Documentation

  • Swagger UI: /docs
  • ReDoc: /redoc

Installation

Prerequisites

  • Python 3.14+
  • Poetry
  • Docker

Setup

  1. Clone the repository
git clone <repository-url>
cd sympoly-api
  1. Install dependencies with Poetry
poetry install
  1. Configure environment variables Create a .env file

  2. Run database migrations

poetry run alembic upgrade head
  1. Start the API server
poetry run uvicorn main:app --reload
  1. Start Celery worker (in another terminal)
poetry run celery -A app.celery_app worker --loglevel=info -Q polymarket
  1. Start Celery Beat scheduler (in another terminal)
poetry run celery -A app.celery_app beat --loglevel=info

Jupyter Notebooks

Analysis notebooks are available in scripts/notebooks/ for data exploration.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published