Skip to main content

Backtest API

The Backtest API powers the Sequency rule-driven backtester, enabling R&D engineers to stress-test intraday signal strategies against historical market data, optimize parameters, and analyze edge quality. This group includes two versions: the original /v1 (fixed-request, blocking) and the modern /v2 (async, Redis-driven, out-of-process workers). Base path: /api/graph/v1/backtest Auth: Public routes require a Supabase JWT (user) OR an X-Internal-Secret header (service principal). Strict auth is enforced in production (anon → 401).

Core Backtest Run (v1)

POST /api/graph/v1/backtest

Start a backtest run Launches a historical backtest of intraday signal strategies. The request registers a pending run and spawns a background task to execute it (no longer blocks the HTTP call). Poll GET /{run_id} for results. Parameters: None (all config in request body) Request body:
Response 200:
Constraints:
  • Max 50 symbols per run
  • Max 365-day date range
  • Max 3 concurrent pending/running backtests per user (returns 429 if exceeded)
  • end_date must be after start_date

GET /api/graph/v1/backtest/

Get backtest run status Poll the status and full results of a backtest run. Returns the same shape as the response above, plus computed metrics once the run completes. Parameters:
  • run_id (path, required): UUID of the backtest run
Response 200:
Status lifecycle: pendingrunningcompleted | failed | cancelled

GET /api/graph/v1/backtest//trades

Get backtest trades (paginated) Retrieve individual trades from a completed backtest run with optional filtering by symbol, signal type, or direction. Parameters:
  • run_id (path, required): UUID of the backtest run
  • page (query, optional): Page number (default 1, min 1)
  • page_size (query, optional): Trades per page (default 50, max 200)
  • symbol (query, optional): Filter by symbol (e.g., “NVDA”)
  • signal_type (query, optional): Filter by signal type
  • direction (query, optional): Filter by direction (“long” | “short”)
Response 200:

GET /api/graph/v1/backtest//trades/export

Export backtest trades Export all trades from a run as CSV or JSON. Parameters:
  • run_id (path, required): UUID of the backtest run
  • format (query, optional): "csv" or "json" (default “csv”)
Response 200: File download (CSV or JSON array)

POST /api/graph/v1/backtest//cancel

Cancel a backtest run Cancel a running or pending backtest. Returns 409 if the run is already completed or failed. Parameters:
  • run_id (path, required): UUID of the backtest run
Response 200:

POST /api/graph/v1/backtest//analyze

AI analysis of backtest results Run LLM analysis on a completed backtest to assess edge quality, signal insights, and risk factors. Parameters:
  • run_id (path, required): UUID of the backtest run
Response 200:

History & Optimization (v1)

GET /api/graph/v1/backtest/history

List backtest history Retrieve the user’s past backtest runs (most recent first). Parameters:
  • limit (query, optional): Max results (default 50, max 100)
Response 200: Array of BacktestRunResponse objects (see GET /{run_id} for structure)

POST /api/graph/v1/backtest/optimize

Start parameter optimization Run a grid search over stop/target ATR multiplier combinations to find optimal parameters. Request body:
Response 200:
Poll the id returned by calling GET /api/graph/v1/backtest/{run_id} to retrieve results as they complete.

GET /api/graph/v1/backtest/field-availability

Per-field coverage for rule-driven backtester Reports which scoring/indicator/regime fields are populated in backtest_universe for a given date range, so the Visual Canvas can render honest “available from” badges and block rules that depend on fields with insufficient coverage. Parameters:
  • from (query, required): YYYY-MM-DD (inclusive)
  • to (query, required): YYYY-MM-DD (inclusive)
  • symbols (query, optional): Comma-separated filter. Omit for universe-wide coverage (fastest). Provide the same symbols you intend to backtest for accuracy.
Response 200:
Status values:
  • available: ≥90% coverage; rules can run with confidence
  • partial: ≥10% coverage; rules run but results exclude uncovered bars
  • missing: <10% coverage; rules are effectively inoperable
  • forward_only: field only exists in live score_history, never in historical backtest_universe

Modern Async Backtest (v2)

The /v2 endpoints use ClickHouse-backed async execution with out-of-process workers, supporting advanced features like walk-forward analysis, Monte Carlo simulation, regime fitness, and detailed equity-curve metrics.

POST /api/graph/v1/backtest/v2/run

Start async backtest run (v2) Launches a modern async backtest with advanced parameters. Returns immediately with status pending; poll GET /run/{run_id} for progress. Request body:
Response 200:
Constraints:
  • Max 3 concurrent runs per user (returns 429)
  • Max 365-day range
  • sizing_method: equal_weight, score_weighted, risk_parity, or kelly
  • Max 50 symbols
  • mse_signal conditions not yet supported (use indicator/price-action/pattern/volume instead)

GET /api/graph/v1/backtest/v2/run/

Get run status (v2) Poll the status and progress of a v2 backtest run. Parameters:
  • run_id (path, required): Run UUID
Response 200:

GET /api/graph/v1/backtest/v2/run//results

Get full backtest results (v2) Retrieve complete results including trades, portfolio metrics, equity curve, Monte Carlo analysis, and validation gate. Parameters:
  • run_id (path, required): Run UUID
Response 200:
Returns 202 with progress info while the run is still in progress. When a backtest produces fewer than 5 trades, includes a diagnostics field showing the condition funnel.

GET /api/graph/v1/backtest/v2/run//results/by-symbol

Get per-symbol attribution (v2) Breakdown of metrics by symbol. Parameters:
  • run_id (path, required): Run UUID
Response 200: Array of per-symbol metrics (trades, win_rate, profit_factor, sharpe, max_drawdown)

GET /api/graph/v1/backtest/v2/run//results/regime-fitness

Get regime fitness breakdown (v2) Performance across different market regimes (2×3 grid: BULL/NEUTRAL/BEAR × LOW_VOL/HIGH_VOL). Parameters:
  • run_id (path, required): Run UUID
Response 200: Metrics grouped by regime

GET /api/graph/v1/backtest/v2/run//trades/

Get single trade detail (v2) Retrieve enriched data for a specific trade, including stop/target levels for chart visualization. Parameters:
  • run_id (path, required): Run UUID
  • trade_index (path, required): Trade index (0-based)
Response 200:

POST /api/graph/v1/backtest/v2/run//cancel

Cancel backtest run (v2) Parameters:
  • run_id (path, required): Run UUID
Response 200:

Annotations (v2)

PUT /api/graph/v1/backtest/v2/run//trades//annotate

Annotate a trade Add tags and notes to a trade for later reference. Parameters:
  • run_id (path, required): Run UUID
  • trade_id (path, required): Trade UUID
Request body:
Response 200: Annotation created

DELETE /api/graph/v1/backtest/v2/run//trades//annotate

Delete annotation Remove annotations from a trade. Parameters:
  • run_id (path, required): Run UUID
  • trade_id (path, required): Trade UUID
Response 200: Annotation deleted

GET /api/graph/v1/backtest/v2/run//annotations

Get run annotations List all annotations for trades in a backtest run. Parameters:
  • run_id (path, required): Run UUID
Response 200: Array of annotations

GET /api/graph/v1/backtest/v2/annotations

Search annotations Search annotations across all backtest runs by tag. Parameters:
  • tag (query, optional): Filter by tag
  • limit (query, optional): Max results
Response 200: Array of annotations

History & Groups (v2)

GET /api/graph/v1/backtest/v2/runs

List runs (v2) Paginated list of the user’s backtest runs. Parameters:
  • limit (query, optional): Max results (default 50)
  • offset (query, optional): Pagination offset
Response 200: Array of run summaries

GET /api/graph/v1/backtest/v2/history

Backtest history with filters Paginated history with optional signal type filter. Parameters:
  • signal_type (query, optional): Filter by signal type
  • limit (query, optional): Max results
  • offset (query, optional): Pagination offset
Response 200: Array of run objects

POST /api/graph/v1/backtest/v2/groups

Create symbol group Create a named group of symbols for reuse across backtests. Request body:
Response 200: Group created

GET /api/graph/v1/backtest/v2/groups

List groups Retrieve all symbol groups for the user. Response 200: Array of groups

PUT /api/graph/v1/backtest/v2/groups/

Update group Modify a symbol group’s name or member list. Parameters:
  • group_id (path, required): Group UUID
Request body: Same as POST /groups Response 200: Group updated

DELETE /api/graph/v1/backtest/v2/groups/

Delete group Remove a symbol group. Parameters:
  • group_id (path, required): Group UUID
Response 200: Group deleted

Parameter Optimization (v2)

POST /api/graph/v1/backtest/v2/optimize

Optimize parameters (v2) Run walk-forward parameter optimization to find best stop/target ATR combinations. Request body:
Response 200:

POST /api/graph/v1/backtest/v2/sweep

Parameter sensitivity sweep (async) Run a parameter sweep and retrieve results asynchronously. Request body:
Response 200:

GET /api/graph/v1/backtest/v2/sweep//status

Sweep progress Poll the status of an async parameter sweep. Parameters:
  • sweep_id (path, required): Sweep UUID
Response 200:

GET /api/graph/v1/backtest/v2/sweep//results

Sweep results matrix Retrieve the results matrix after a sweep completes. Parameters:
  • sweep_id (path, required): Sweep UUID
Response 200: Parameter combinations with metrics (Sharpe, profit_factor, win_rate, etc.)

Comparison & Analysis (v2)


Strategies & Forward Testing (v2)


Options Backtesting

POST /api/graph/v1/backtest/v2/options/run

Options backtest (single-leg) Backtest options strategies with delta targeting, DTE ranges, and contract selection logic. Request body:
Response 200: Backtest results (same structure as equity backtest, with options-specific fields like delta, theta, vega decay)

Regime & Coverage

GET /api/graph/v1/backtest/v2/regime/calendar

Get regime calendar Retrieve the 2×3 regime grid labels for a date range. Parameters:
  • date_from (query, required): YYYY-MM-DD
  • date_to (query, required): YYYY-MM-DD
Response 200:

POST /api/graph/v1/backtest/v2/regime/backfill

Trigger regime backfill Manually trigger a backfill of the 2×3 regime grid for a date range (normally automatic). Parameters:
  • date_from (query, optional): YYYY-MM-DD
  • date_to (query, optional): YYYY-MM-DD
Response 200: Backfill initiated

GET /api/graph/v1/backtest/v2/coverage

Get backtest coverage Return available data coverage (earliest/latest dates, symbol count) for the date picker. Response 200:

Key Schemas

BacktestRequest

Request to launch a v1 backtest run.

BacktestRunRequest

Request to launch a v2 backtest run (see above for full structure).

BacktestTradeResponse

Individual trade from a backtest result.

SignalType

Intraday signal types available for backtesting.

BacktestStatus

Run lifecycle status.

EquityCurvePoint

Single point on the equity curve (cumulative P&L by trade count and R-multiple).

ValidationGateResult

Aggregate validation gate (P3 Phase 3: sample size, profit factor, Sharpe, max drawdown, win rate).

TradeDetailResponse

Enriched single-trade response with stop/target levels and detailed signal metadata.

StrategyTestRequest

Simplified retail backtest request.

PromoteFromBacktestRequest

Promote a strategy (post-backtest) to a Trade Manager card.