Skip to content

Latest commit

 

History

History
208 lines (159 loc) · 5.42 KB

File metadata and controls

208 lines (159 loc) · 5.42 KB

API Reference

Base URL (development): http://localhost:8000

Interactive documentation generated by FastAPI is available at /docs (Swagger UI) and /redoc while the server runs. This file is a hand-written companion describing the shapes the official clients rely on.

All endpoints exist under a versioned prefix (/api/v1/...). Non-versioned aliases (/api/...) are also mounted for backward compatibility and are hidden from the schema.

Conventions

  • Requests and responses are JSON.
  • Money and ratios are numbers, not strings. Percentages in allocation are 0–100; fractions like maxDrawdown and volatility are 0–1 unless noted.
  • The data endpoints (portfolio, strategies, risk, backtest, market data, trading, research, alternative data) are currently open. Authentication applies to /api/auth.

Health

GET /health
GET /

Returns a small status object indicating the service is alive.

Authentication - /api/auth

Tokens are HS256 JWTs. Send the token as Authorization: Bearer <token> on subsequent requests.

Register

POST /api/auth/register
{
  "email": "trader@example.com",   // email or username
  "name": "Ada Lovelace",          // optional
  "password": "a-strong-password"
}
→ 201 { "token": "<jwt>", "user": { "id", "email", "name" } }

Login

POST /api/auth/login
{ "email": "trader@example.com", "password": "a-strong-password" }
→ 200 { "token": "<jwt>", "user": { ... } }
→ 401 on bad credentials

Refresh / Profile

POST /api/auth/refresh   → { "token": "<jwt>" }
GET  /api/auth/profile   → { "id", "email", "name" }

Portfolio - /api/v1/portfolio

GET /api/v1/portfolio/
→ {
    "totalValue": number,
    "cash": number,
    "dailyPnL": number,
    "totalPnL": number,
    "allocation": [ { "ticker": string, "value": number, "percentage": number } ]
  }

GET /api/v1/portfolio/positions
→ [ { "ticker", "quantity", "entryPrice", "currentPrice", "unrealizedPnL", "weight" } ]

GET /api/v1/portfolio/holdings
→ [ { "symbol", "value", "weight" } ]

GET /api/v1/portfolio/performance
→ {
    "equityCurve": [ { "timestamp": string, "value": number } ],
    "metrics": { "sharpeRatio": number, ... }
  }

Strategies - /api/v1/strategies

GET /api/v1/strategies/
→ [ {
    "id", "name", "status",
    "performance": {
      "sharpeRatio", "maxDrawdown", "profitFactor",
      "winRate", "totalReturn", "volatility", "alpha", "beta"
    }
  } ]

GET /api/v1/strategies/{id}/equity-curve
→ { "equityCurve": [ { "day": number, "value": number, "benchmark": number } ] }

Risk - /api/v1/risk

GET /api/v1/risk/metrics
→ {
    "var": number,           // value at risk (% of NAV)
    "cvar": number,
    "sharpeRatio": number,
    "sortinoRatio": number,
    "maxDrawdown": number,   // fraction
    "beta": number,
    "correlation": number,
    "volatility": number     // fraction
  }

GET /api/v1/risk/stress-scenarios
→ [ { "name", "pnl", "duration", "recovery", "portfolioImpact" } ]

GET /api/v1/risk/radar
→ [ { "metric": string, "value": number } ]

Backtest - /api/v1/backtest

POST /api/v1/backtest/
{
  "strategyId": string,
  "startDate": "YYYY-MM-DD",
  "endDate": "YYYY-MM-DD",
  "initialCapital": number
}
→ {
    "totalReturn", "annualisedReturn", "sharpeRatio", "sortinoRatio",
    "maxDrawdown", "winRate", "profitFactor", "finalCapital"
  }

The result fields are flat (not nested under a metrics object).

Market Data - /api/v1/market-data

GET /api/v1/market-data/quotes
→ [ {
    "ticker", "timestamp", "bid", "ask", "last",
    "volume", "high", "low", "open", "close",
    "source": "live" | "synthetic"
  } ]

GET /api/v1/market-data/quote/{ticker}
→ single quote object (shape as above)

GET /api/v1/market-data/historical/{ticker}?days=90
→ [ { "timestamp", "open", "high", "low", "close", "volume" } ]

source reports whether the row came from a live connector (Yahoo Finance / Polygon) or the synthetic fallback.

Trading - /api/v1/trading

Trading is simulated in-process; there is no live broker.

GET    /api/v1/trading/orders            → [ Order ]
GET    /api/v1/trading/orders/{id}       → Order
POST   /api/v1/trading/orders            → 201 Order
DELETE /api/v1/trading/orders/{id}       → 204

OrderCreate (POST body):
{
  "ticker": string,
  "side": "BUY" | "SELL",
  "quantity": number,
  "orderType": "MARKET" | "LIMIT" | "STOP",
  "price": number        // required for LIMIT and STOP
}

Order:
{
  "id", "ticker", "side", "quantity", "orderType",
  "price?", "filledPrice?", "status", "timestamp?", "filledAt?"
}

MARKET orders fill immediately and cannot be cancelled. LIMIT and STOP orders stay pending and can be cancelled with DELETE.

Research - /api/v1/research

GET /api/v1/research/papers
→ [ { "id", "title", "authors": [string], "abstract", "category", "year", "url?" } ]

Also available as /api/research/papers.

Alternative Data - /api/v1/alternative-data

GET /api/v1/alternative-data/sources
→ [ {
    "id", "name",
    "type": "satellite" | "sentiment" | "sec" | "social",
    "status": "active" | "inactive",
    "lastUpdate", "dataPoints",
    "description?", "latency?"
  } ]

CORS

In development the API accepts cross-origin requests from localhost, 127.0.0.1, and private LAN IP ranges on any port, so the web dashboard (port 3000) and the Expo web build (port 8081) can both call it. Configure with CORS_ORIGINS.