Skip to content

API Reference

The Redhound Trading API is a FastAPI application providing comprehensive endpoints for trading signal management, market data retrieval, analytics, and session management. All endpoints are built on a service layer architecture that provides business logic abstraction, transaction management, and caching.

  • Swagger UI: http://localhost:8000/docs
  • ReDoc: http://localhost:8000/redoc
  • OpenAPI JSON: http://localhost:8000/openapi.json

Running the API Server

# Development
uvicorn backend.api.app:app --reload --host 0.0.0.0 --port 8000

# Production
uvicorn backend.api.app:app --host 0.0.0.0 --port 8000 --workers 4

Configuration

Web server settings are controlled via environment variables with the REDHOUND_WEB_ prefix:

Variable Default Description
REDHOUND_WEB_HOST 0.0.0.0 Bind host
REDHOUND_WEB_PORT 8000 Bind port (1–65535)
REDHOUND_WEB_CORS_ORIGINS ["http://localhost:3000","http://localhost:8080"] Allowed CORS origins
REDHOUND_WEB_RATE_LIMIT_PER_MINUTE 60 Max requests/min per client
REDHOUND_WEB_ENABLE_DOCS true Enable /docs and /redoc
REDHOUND_WEB_API_KEY_REQUIRED false Require API key header

Core Endpoints

GET /

Returns API name, version, and documentation links.

Response 200:

{
  "name": "Redhound Trading API",
  "version": "0.1.0",
  "status": "running",
  "docs_url": "/docs",
  "redoc_url": "/redoc"
}


GET /health

Aggregated dependency health check. Returns 200 when all required dependencies are healthy, 503 otherwise.

Response 200 (healthy):

{
  "status": "healthy",
  "timestamp": "2024-01-15T10:30:00.000000+00:00",
  "dependencies": {
    "database": "healthy",
    "redis": "healthy"
  },
  "errors": {}
}

Response 503 (unhealthy):

{
  "status": "unhealthy",
  "timestamp": "2024-01-15T10:30:00.000000+00:00",
  "dependencies": {
    "database": "unhealthy",
    "redis": "healthy"
  },
  "errors": {
    "database": "Connection refused"
  }
}

Health check timeouts and required/optional dependencies are configurable:

Variable Default Description
REDHOUND_HEALTHCHECK_ENABLED true Enable health endpoint
REDHOUND_HEALTHCHECK_REQUIRED_DEPENDENCIES database,redis Comma-separated required deps
REDHOUND_HEALTHCHECK_TIMEOUT_DEFAULT 1.0 Per-probe timeout (seconds)

GET /metrics

Exposes Prometheus metrics in text format. Returns 503 when metrics are disabled.

curl http://localhost:8000/metrics

Enable metrics collection:

export REDHOUND_METRICS_ENABLED=true


API Endpoints

Signals API (/api/v1/signals)

Trading signal management endpoints for creating, retrieving, and analyzing signals.

POST /api/v1/signals

Create a new trading signal.

Request Body:

{
  "symbol": "AAPL",
  "action": "buy",
  "confidence": 0.85,
  "price": 152.30,
  "quantity": 100,
  "reasoning": "Strong RSI reversal with volume confirmation",
  "session_id": "optional-uuid",
  "metadata": {}
}

Response 201:

{
  "id": "uuid",
  "symbol": "AAPL",
  "action": "buy",
  "confidence": 0.85,
  "price": 152.30,
  "quantity": 100,
  "reasoning": "Strong RSI reversal with volume confirmation",
  "created_at": "2024-01-15T10:30:00Z"
}

GET /api/v1/signals

List signals with optional filters and pagination.

Query Parameters: - symbol (required): Stock ticker symbol - action (optional): Filter by action (buy, sell, hold) - min_confidence (optional): Minimum confidence (0-1) - start_date (optional): Start date (YYYY-MM-DD) - end_date (optional): End date (YYYY-MM-DD) - limit (optional): Page size (1-1000, default: 100) - offset (optional): Page offset (default: 0)

Response 200:

{
  "signals": [...],
  "total": 150,
  "limit": 100,
  "offset": 0
}

GET /api/v1/signals/{signal_id}

Get a signal by its ID.

GET /api/v1/signals/latest/{symbol}

Get the latest signal for a symbol.

GET /api/v1/signals/stats/{symbol}

Get signal statistics for a symbol.

Query Parameters: - start_date (optional): Start date (YYYY-MM-DD) - end_date (optional): End date (YYYY-MM-DD)

Response 200:

{
  "symbol": "AAPL",
  "total_signals": 45,
  "by_action": {"buy": 25, "sell": 15, "hold": 5},
  "avg_confidence": 0.72,
  "most_common_reasoning": "RSI reversal"
}

GET /api/v1/signals/performance/{symbol}

Get signal performance metrics.

Response 200:

{
  "symbol": "AAPL",
  "win_rate": 0.65,
  "avg_profit_per_signal": 2.5,
  "confidence_accuracy_correlation": 0.78
}

POST /api/v1/signals/{signal_id}/outcome

Update signal outcome with actual results.

Request Body:

{
  "outcome": {
    "profit": 5.2,
    "accuracy": true,
    "notes": "Signal executed successfully"
  }
}


Market Data API (/api/v1/market-data)

Market data retrieval endpoints with vendor fallback and caching.

GET /api/v1/market-data/stock/{symbol}

Get stock price data (OHLCV) for a symbol.

Query Parameters: - start_date (optional): Start date (YYYY-MM-DD) - end_date (optional): End date (YYYY-MM-DD)

Response 200:

{
  "symbol": "AAPL",
  "start_date": "2024-01-01",
  "end_date": "2024-01-31",
  "data": {
    "prices": [
      {
        "date": "2024-01-01",
        "open": 150.0,
        "high": 152.0,
        "low": 149.0,
        "close": 151.0,
        "volume": 1000000
      }
    ],
    "_metadata": {
      "symbol": "AAPL",
      "source": "fmp",
      "timestamp": "2024-01-15T10:30:00Z"
    }
  }
}

Cache Headers: Cache-Control: public, max-age=300 (5 minutes)

GET /api/v1/market-data/indicators/{symbol}

Get technical indicators for a symbol.

Query Parameters: - indicators (optional): Comma-separated indicator names (e.g., MACD,RSI,SMA)

Response 200:

{
  "symbol": "AAPL",
  "indicators": ["MACD", "RSI"],
  "data": {
    "MACD": {...},
    "RSI": {...}
  }
}

Cache Headers: Cache-Control: public, max-age=300 (5 minutes)

GET /api/v1/market-data/fundamentals/{symbol}

Get fundamental data (financial metrics and ratios).

Response 200:

{
  "symbol": "AAPL",
  "data": {
    "pe_ratio": 28.5,
    "market_cap": 3000000000000,
    "dividend_yield": 0.5
  }
}

Cache Headers: Cache-Control: public, max-age=3600 (1 hour)

GET /api/v1/market-data/news/{symbol}

Get news articles for a symbol.

Query Parameters: - limit (optional): Maximum number of articles (1-100, default: 20)

Response 200:

{
  "symbol": "AAPL",
  "articles": [
    {
      "title": "Apple Reports Record Earnings",
      "url": "https://...",
      "published_at": "2024-01-15T10:00:00Z",
      "source": "Reuters"
    }
  ],
  "total": 20
}

Cache Headers: Cache-Control: public, max-age=300 (5 minutes)


Analytics API (/api/v1/analytics)

Advanced analytics endpoints for volatility, correlation, trends, and backtesting.

GET /api/v1/analytics/volatility/{symbol}

Calculate volatility metrics for a symbol.

Query Parameters: - window (optional): Rolling window size (2-252, default: 20) - start_date (optional): Start date (YYYY-MM-DD) - end_date (optional): End date (YYYY-MM-DD)

Response 200:

{
  "symbol": "AAPL",
  "volatility": 0.25,
  "daily_std": 0.015,
  "var_95": -2.5,
  "var_99": -3.5,
  "window": 20,
  "num_observations": 252
}

GET /api/v1/analytics/correlation

Calculate correlation matrix between multiple symbols.

Query Parameters: - symbols (required): Comma-separated symbols (e.g., AAPL,MSFT,GOOG) - method (optional): Correlation method (pearson or spearman, default: pearson) - start_date (optional): Start date (YYYY-MM-DD) - end_date (optional): End date (YYYY-MM-DD)

Response 200:

{
  "symbols": ["AAPL", "MSFT", "GOOG"],
  "matrix": [[1.0, 0.85, 0.78], [0.85, 1.0, 0.82], [0.78, 0.82, 1.0]],
  "pairs": [
    {"symbol1": "AAPL", "symbol2": "MSFT", "correlation": 0.85}
  ],
  "method": "pearson"
}

GET /api/v1/analytics/trends/{symbol}

Analyze price trends for a symbol.

Query Parameters: - short_window (optional): Short SMA window (2-200, default: 20) - long_window (optional): Long SMA window (5-500, default: 50) - start_date (optional): Start date (YYYY-MM-DD) - end_date (optional): End date (YYYY-MM-DD)

Response 200:

{
  "symbol": "AAPL",
  "trend": "bullish",
  "trend_strength": 0.75,
  "sma_short": 150.0,
  "sma_long": 145.0,
  "support": 140.0,
  "resistance": 160.0,
  "slope": 0.5
}

POST /api/v1/analytics/backtest

Run a backtest simulation.

Request Body:

{
  "symbols": ["AAPL"],
  "start_date": "2024-01-01",
  "end_date": "2024-01-31",
  "config": {
    "initial_capital": 100000,
    "weights": {"technical": 0.3, "fundamental": 0.4}
  }
}

Response 200:

{
  "symbols": ["AAPL"],
  "start_date": "2024-01-01",
  "end_date": "2024-01-31",
  "results": {
    "total_return": 0.15,
    "sharpe_ratio": 1.2,
    "max_drawdown": -0.05
  }
}


Sessions API (/api/v1/sessions)

Session management endpoints for triggering and monitoring multi-agent analysis workflows.

POST /api/v1/sessions

Start a new analysis session.

Request Body:

{
  "symbol": "AAPL",
  "config": {
    "selected_analysts": ["technical", "fundamental"],
    "debug": false
  },
  "metadata": {}
}

Response 201:

{
  "id": "uuid",
  "symbol": "AAPL",
  "status": "running",
  "start_time": "2024-01-15T10:30:00Z",
  "config": {...},
  "created_at": "2024-01-15T10:30:00Z"
}

GET /api/v1/sessions

List historical sessions with optional filtering.

Query Parameters: - symbol (optional): Filter by symbol - status (optional): Filter by status (pending, running, completed, failed) - limit (optional): Page size (1-1000, default: 100) - offset (optional): Page offset (default: 0)

GET /api/v1/sessions/{session_id}

Get session status and full report.

Response 200:

{
  "id": "uuid",
  "symbol": "AAPL",
  "status": "completed",
  "start_time": "2024-01-15T10:30:00Z",
  "end_time": "2024-01-15T10:35:00Z",
  "result": {
    "unified_signal": {...},
    "reports": {...}
  }
}

POST /api/v1/sessions/{session_id}/cancel

Cancel a running or pending session.

WS /api/v1/ws/sessions/{session_id}

WebSocket endpoint for real-time session event streaming.

Events: - status_change: Session status updates - output: Agent outputs and signals - error: Error messages - heartbeat: Keep-alive messages


Stock Profile API (/api/v1/stocks)

Stock profile, fundamental metrics, and screener endpoints.

GET /api/v1/stocks/{symbol}

Unified stock profile: current price, fundamentals, and technical indicators.

Response 200:

{
  "symbol": "AAPL",
  "name": "Apple Inc.",
  "sector": "Technology",
  "market_cap": 3000000000000,
  "current_price": 195.42,
  "price_change_pct": 1.23,
  "pe_ratio": 28.5,
  "piotroski_score": 7,
  "rsi": 55.3,
  "macd_signal": "bullish",
  "updated_at": "2026-02-25T14:00:00Z"
}

GET /api/v1/stocks/{symbol}/signals

Last N trading signals for a symbol.

Query Parameters: - limit (optional): Number of signals to return (default: 10)

POST /api/v1/stocks/{symbol}/quickscreen

Fast deterministic screen on a single symbol — no LLM calls.

Response 200:

{
  "symbol": "AAPL",
  "opportunity_score": 72,
  "signals": {
    "rsi_oversold": false,
    "macd_bullish": true,
    "volume_spike": false,
    "near_52w_low": false
  },
  "recommendation": "HOLD"
}

POST /api/v1/stocks/screen

Bulk screen across a universe of symbols with configurable conditions.

Request Body:

{
  "universe": "SP500",
  "conditions": {
    "rsi_max": 35,
    "piotroski_min": 6,
    "price_near_52w_low_pct": 10
  },
  "limit": 20
}

Response 200:

{
  "results": [
    {
      "symbol": "XYZ",
      "opportunity_score": 85,
      "matched_conditions": ["rsi_oversold", "piotroski_strong"]
    }
  ],
  "total_screened": 503,
  "total_matched": 12
}

GET /api/v1/stocks/browse

Browse all stocks in an index with price sparklines.

Query Parameters: - index (optional): SP500 or NASDAQ100 (default: SP500) - limit (optional): Page size (default: 50) - offset (optional): Page offset (default: 0)


Price Feed WebSocket (/api/v1/ws/prices)

WS /api/v1/ws/prices

Live price streaming for one or more symbols.

Connection URL:

ws://localhost:8000/api/v1/ws/prices?symbols=AAPL,MSFT,GOOGL

Query Parameters: - symbols (required): Comma-separated list of ticker symbols (max 50)

Server Messages:

{"event": "price_update", "symbol": "AAPL", "price": 195.42, "change_pct": 1.23, "timestamp": "2026-02-25T14:00:00Z"}
{"event": "heartbeat", "timestamp": "2026-02-25T14:00:30Z"}

Prices are broadcast every 30 seconds during market hours (09:30–16:00 ET). Outside market hours, the connection remains open with heartbeats only.


Additional Route Groups

The following route groups are available. See Swagger UI (/docs) for full schema details.

Route group Base path Description
Portfolio /api/v1/portfolios Create/manage portfolios, positions, transactions, and P&L
Watchlists /api/v1/watchlists Multiple watchlists with items and tags
Alerts /api/v1/alerts Price, technical, fundamental, and signal alerts
Scanner /api/v1/scanner Market scanner configs, run/pause/resume, scan results
Opportunities /api/v1/opportunities Detected opportunities with status lifecycle (new → viewed → acted_on)
Monitor /api/v1/monitor Scanner status, history, resource usage
Backtest /api/v1/backtest Run backtests, walk-forward validation, strategy management
Strategies /api/v1/strategies Save/share/compare strategy configurations
Agents /api/v1/agents Analyst registry, adaptive weights, config, and weight history
Fund /api/v1/fund Autonomous fund dashboard: universe sweeps, paper trading, and aggregate performance
Catalyst /api/v1/catalyst Catalyst events (earnings, dividends, splits) and scheduled scans
Journal /api/v1/journal Trade journal entries and performance attribution
Push /api/v1/push Web push notification subscription management
Market Intelligence /api/v1/market-intelligence Macro overview, sector heatmaps, economic calendar
Config /api/v1/config Runtime configuration management
Data Providers /api/v1/data-providers Vendor status and health

Request/Response Models

Request Models

All request models are in backend.api.models.requests. Ticker symbols and dates are validated using backend.utils.validation.

AnalysisRequest

{
  "ticker": "AAPL",
  "start_date": "2024-01-01",
  "end_date": "2024-01-31",
  "analysts": ["technical", "sentiment"],
  "research_depth": "standard"
}
Field Type Required Description
ticker string Yes Ticker symbol (e.g. AAPL, ^VIX)
start_date string Yes Start date in YYYY-MM-DD format
end_date string Yes End date in YYYY-MM-DD format
analysts string[] No Analyst types to run. Defaults to all.
research_depth "quick"\|"standard"\|"deep" No Defaults to "standard"

SignalRequest

{
  "ticker": "AAPL",
  "signal_type": "buy",
  "timeframe": "1d"
}
Field Type Required Description
ticker string Yes Ticker symbol
signal_type "buy"\|"sell"\|"hold" Yes Signal type
timeframe "1d"\|"1w"\|"1m" No Defaults to "1d"

MarketDataRequest

{
  "symbol": "AAPL",
  "start_date": "2024-01-01",
  "end_date": "2024-01-31",
  "interval": "1d"
}
Field Type Required Description
symbol string Yes Market symbol
start_date string Yes Start date in YYYY-MM-DD format
end_date string Yes End date in YYYY-MM-DD format
interval "1d"\|"1h"\|"5m" No Defaults to "1d"

Validation Rules

Ticker Symbols

  • Consists of 1-5 uppercase alphanumeric characters, optionally prefixed with a ^ for indices
  • Total length: 1-6 characters (1 for optional ^ prefix + 1-5 alphanumeric characters)
  • Automatically normalized to uppercase
  • Valid examples: AAPL, MSFT, GOOGL, SPY, ^VIX, ^GSPC
  • Invalid examples: TOOLONG123, invalid-ticker, empty string

Dates

  • Must be in YYYY-MM-DD format
  • Cannot be before 1970-01-01
  • Cannot be in the future
  • Invalid examples: 01/15/2024, 2099-12-31, not-a-date

Error Responses

All errors return a structured JSON body:

{
  "error": "validation_error",
  "message": "Request validation failed",
  "details": [
    {
      "field": "ticker",
      "message": "Invalid ticker symbol format: 'TOOLONG'. Expected 1-5 uppercase alphanumeric characters, optionally prefixed with ^ for indices.",
      "value": "TOOLONG",
      "valid_format": "^[\\^]?[A-Z0-9]{1,5}$"
    }
  ],
  "request_id": "a1b2c3d4e5f6"
}

HTTP Status Codes

Status error field When
400 validation_error Pydantic model validation failed
400 ticker_validation_error Invalid ticker symbol
400 date_validation_error Invalid or future date
400 range_validation_error Numeric value out of range
404 http_error Route not found
429 rate_limit_exceeded Too many requests
500 internal_server_error Unhandled server error
503 varies Service unavailable

Rate Limiting

When the rate limit is exceeded the response includes a Retry-After header:

HTTP/1.1 429 Too Many Requests
Retry-After: 45
Content-Type: application/json

{
  "error": "rate_limit_exceeded",
  "message": "Rate limit of 60 requests per minute exceeded",
  "retry_after": 45
}

Request Tracing

Every response includes an X-Request-ID header containing a correlation ID:

X-Request-ID: a1b2c3d4e5f6789012345678

Clients can supply their own ID to trace requests end-to-end:

curl -H "X-Request-ID: my-trace-id" http://localhost:8000/health

CORS

The API supports CORS for frontend integration. Configure allowed origins via environment variable:

export REDHOUND_WEB_CORS_ORIGINS='["https://app.example.com","http://localhost:3000"]'