Skip to main content
Glama
FindDataTechnology

fd-paper-trading MCP Server

Official

Part of the Wire line (寻数·柏讯) of FindData — the B2B data platform line.

English · 简体中文

fd-paper-trading

Multi-tenant paper-trading service exposed via a FastAPI REST + WebSocket API and an MCP server. Users can own multiple paper trading accounts and place orders through the API against real-time market data with simulated fills — no broker, no real capital.

Features

  • Multi-user auth — JWT + revocable API tokens (fdt_ prefix)

  • Multi-account management — each user can create and manage multiple isolated paper accounts

  • Order execution — market and limit orders with simulated fills via a stateless pure-Python fill calculator

  • Position & cash ledgering — real-time P&L, average cost, realized gains

  • Real-time streaming — WebSocket endpoint (/ws) pushes live quotes, order-status, and fill events

  • MCP server — 19 tools (accounts, orders, positions, instrument search, bars, strategy lifecycle) on stdio and streamable HTTP. Caller identity is delegated: HTTP callers present their own Authorization credential and act as themselves on a shared deployment; stdio falls back to the configured token

  • Market data — SimulatedMarketDataProvider (deterministic, for dev/tests), PolygonMarketDataProvider (real prices, end-of-day on free tier), and FdOpenDataMarketDataProvider (real daily bars + close-derived quotes from the fd-open-data-mcp ontology)

  • Quant strategies - dual-track authoring: fixed templates (SMA cross, RSI reversion, Bollinger breakout, MACD cross, DCA) and sandboxed custom code (on_bar(ctx)); backtest with equity-curve stats; live paper runs that place attributed signals on your account. Per-user group limits (active strategies, daily orders, custom-code gate, symbol allowlist)

  • Web UI — React + TypeScript SPA with professional trading dashboard featuring:

    • Three-column workspace: watchlist (live quotes), price chart, and order panel

    • Click-to-trade: select any symbol from watchlist to instantly update chart and order form

    • Position management: quick close/reduce actions with confirmation dialogs

    • Daily P&L tracking: real-time calculation from realized + unrealized components

    • Strategies pages: create/edit strategies (template param form or code editor), run backtests with equity curves, and monitor live paper runs + history

    • Typeahead symbol search, interactive charts (TradingView lightweight-charts), and live streaming

Related MCP server: TradingAgent

Tech Stack

  • Backend: Python 3.12+, FastAPI + Uvicorn, SQLAlchemy 2.0 async, Alembic

  • Database: PostgreSQL (prod) / SQLite (tests)

  • Auth: JWT (python-jose) + bcrypt + revocable API tokens

  • Execution: stateless pure-Python fill calculator (no trading framework)

  • Frontend: React 18 + TypeScript + Vite, TanStack Query + Zustand, TradingView lightweight-charts

  • Testing: pytest (backend), Vitest + React Testing Library (frontend), Playwright (e2e)

Quick Start

# 1. Install Python dependencies
uv sync

# 2. Configure environment
cp .env.example .env   # edit DATABASE_URL, JWT_SECRET, market-data keys

# 3. Provision PostgreSQL and apply migrations
brew services start postgresql@14
createdb paper_trading
uv run alembic upgrade head

# 4. (Optional) Build the web UI so FastAPI serves it at /
cd web && npm install && npm run build && cd ..

# 5. Run the API (OpenAPI docs at http://localhost:8000/docs)
uv run fd-paper-trading

Note: On macOS with Homebrew, postgresql@14 may run on port 5433 if 5432 is occupied. Adjust DATABASE_URL in .env accordingly.

Admin bootstrap: to manage user groups (custom-code access, symbol allowlists, limits), set FD_ADMIN_EMAILS=you@example.com in .env and register with that email - the account is promoted to admin. Admins manage groups at POST /api/v1/groups and assign users at POST /api/v1/users/{id}/group.

fd-open-data market data (optional)

To trade/backtest on real daily bars from the fd-open-data-mcp ontology instead of simulated quotes:

# One-time bootstrap of the ontology DB (migrate, catalog import, concepts,
# bindings, entity seeds). Set FD_OPEN_DATA_MCP_DATABASE_URL to override the
# default sqlite location.
uv run python scripts/setup_fd_open_data.py

# Then select the provider
MARKET_DATA_PROVIDER=fd-open-data uv run fd-paper-trading

The bootstrap prints a coverage report mapping the curated symbol universe to ontology entity IDs; unresolved symbols return no bars/quotes until the ontology seeds them (e.g. via the library's migrate-astock-daily or entity import commands).

Concept family — the provider reads one concept, configured as code/entity-type/frequency (default nav.unit/fund/daily — fund NAV, the family with real production data, updated daily). CRYPTO_* and IDX_* concepts are live in the catalog but currently carry no observations:

FD_OPEN_DATA_CONCEPT=CRYPTO_PRICE FD_OPEN_DATA_ENTITY_TYPE=symbol MARKET_DATA_PROVIDER=fd-open-data uv run fd-paper-trading

A deprecated concept degrades to a data gap (no bars, no quotes), never an error. The stock price.* family is deprecated by curation policy and must not be re-registered.

Development

# Terminal 1: FastAPI backend on :8000
uv run fd-paper-trading

# Terminal 2: Vite dev server on :5173 (proxies /api and /ws to backend)
cd web && npm install && npm run dev

Production

# Build the SPA and serve everything from FastAPI on a single origin
cd web && npm run build
uv run fd-paper-trading   # SPA + API + /ws all at http://localhost:8000/

Architecture

┌─────────────────────────────────────────────────────────┐
│  Web UI (React + Vite + TypeScript)                     │
│  - TanStack Query for data fetching                     │
│  - Zustand for state management                         │
│  - TradingView lightweight-charts for charting          │
│  - WebSocket client for real-time streaming             │
└────────────────────┬────────────────────────────────────┘
                     │ REST (/api/v1) + WebSocket (/ws)
┌────────────────────▼────────────────────────────────────┐
│  FastAPI Backend                                        │
│  - Auth (JWT + API tokens)                              │
│  - Account management                                   │
│  - Order placement & cancellation                       │
│  - Position & cash ledgering                            │
│  - Market data API                                      │
└────────────────────┬────────────────────────────────────┘
                     │
        ┌────────────┼────────────┐
        ▼            ▼            ▼
┌──────────┐  ┌──────────┐  ┌──────────┐
│PostgreSQL│  │  Filling │  │  Market  │
│(ledger)  │  │  (fills)  │  │  Data    │
└──────────┘  └──────────┘  └──────────┘

Execution model (v1): Fills are computed by a stateless pure-Python calculator (one quote + one order in, fill outcome out). Account state lives in the database, isolated by account_id.

Trading Dashboard

The web UI provides a professional trading workspace optimized for active trading:

┌───────────────────────────────────────────────────────────────┐
│ Watchlist (left) │ Price Chart  │ Order Ticket (right) │
├──────────────────┼──────────────┼─────────────────────────────┤
│ AAPL    $175.50▲│              │ Side: [Buy ▼] Sell          │
│ TSLA    $250.20▼│ │ Type: [Market ▼] Limit       │
│ NVDA    $890.10▲│   [graph]    │ Qty: [100]       Limit:$175  │
│ SPY     $450.00▶│              │                             │
│ QQQ     $400.25▶│              │ [BUY AAPL] [SELL AAPL] │
│              Total PnL: (+$127)│                             │
├──────────────────┴──────────────┴─────────────────────────────┤
│ Positions Table (quick close/reduce buttons on each row)      │
└───────────────────────────────────────────────────────────────┘

Key features:

  • Watchlist: Live quotes for tracked symbols (AAPL, TSLA, NVDA, SPY, QQQ), updated via WebSocket

  • Click-to-trade: Click any symbol in the watchlist to instantly update the chart and order panel

  • Order panel: Always-visible order entry form bound to the selected symbol

  • Position actions: Quick close/reduce buttons with confirmation dialogs

  • Daily P&L: Real-time calculation from realized gains + unrealized mark-to-market

Note: Daily P&L is indicative (frontend-calculated) and may differ slightly from backend calculations. Mobile-responsive layout and user-configurable watchlists are planned for future releases.

Commands

# Backend
uv run pytest                    # all backend tests (in-memory SQLite)
uv run pytest tests/unit/        # unit tests only
uv run pytest tests/e2e/         # end-to-end flows only
uv run alembic upgrade head      # apply database migrations
uv run alembic downgrade -1      # rollback last migration

# Frontend
cd web && npm test               # Vitest component tests
cd web && npx playwright test    # Playwright e2e tests
cd web && npm run build          # production build
cd web && npm run dev            # dev server with hot reload

API Overview

Method

Path

Description

POST

/api/v1/auth/register

Register a user

POST

/api/v1/auth/login

Obtain a JWT access token

POST

/api/v1/tokens

Create a revocable API token

GET

/api/v1/tokens

List API tokens

DELETE

/api/v1/tokens/{id}

Revoke an API token

GET

/api/v1/accounts

List your accounts

POST

/api/v1/accounts

Create a paper account

GET

/api/v1/accounts/{id}

Account summary (balance, equity, counts)

POST

/api/v1/accounts/{id}/deposit

Deposit / withdraw (signed amount)

POST

/api/v1/accounts/{id}/reset

Reset account (cancel orders, flatten, restore balance)

GET

/api/v1/accounts/{id}/positions

List open positions

GET

/api/v1/accounts/{id}/orders

List orders (optional ?status=)

POST

/api/v1/orders

Place a market/limit order (simulated fill, returns 202)

DELETE

/api/v1/orders/{id}

Cancel an open order

GET

/api/v1/orders/{id}

Query a single order

GET

/api/v1/instruments/search?q=

Search instruments by symbol/name

GET

/api/v1/instruments/{symbol}/bars

Historical OHLCV bars (?timeframe=&limit=)

WS

/ws

Stream quotes + order/fill events (auth in first message)

Authentication: Authorization: Bearer <jwt> or Authorization: Bearer <api-token> (tokens start with fdt_).

WebSocket: Send {"type":"auth","token":"<jwt>"} as the first message, then {"type":"subscribe","symbol":"AAPL"} / {"type":"unsubscribe","symbol":"AAPL"}.

Errors: Standardized format: {"error": {"code": "...", "message": "...", "fields": [...]}}.

Contributing

  1. Fork the repository

  2. Create a feature branch: git checkout -b feature/your-feature

  3. Make your changes and add tests

  4. Run the test suite: uv run pytest && cd web && npm test

  5. Commit with a descriptive message: git commit -m "Add your feature"

  6. Push to your fork: git push origin feature/your-feature

  7. Open a Pull Request

Please ensure your code follows the existing style and all tests pass before submitting.

License

MIT — see LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants like Claude to run backtests, fetch market data, list strategies, and analyze trading algorithms via natural language.
    24 PyPI
    1,107
    GPL 3.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables natural-language paper trading with real-time market data, FinBERT sentiment analysis, conditional orders, and price alerts.
    -
  • F
    license
    A
    quality
    C
    maintenance
    Enables agents to generate alpha signals, retrieve market snapshots, compute portfolio risk, validate and submit paper orders, and trigger a kill switch, all under deterministic pre-trade risk controls and audit logging.
    5
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables natural-language paper trading with per-user JWT authentication, allowing simulated market quotes, buy/sell orders, portfolio tracking, and order history through Claude.
    -