Skip to main content
When to use: The user wants to test a trading strategy historically. Any query about “backtest”, “test this strategy”, “what would have happened if”, “historical performance”, or “how does this strategy do over time” should use this tool. What it returns: Performance metrics (CAGR, Sharpe, max drawdown, Calmar, win rate, turnover), a sampled equity curve, and a trade summary. Also includes the full equity curve for use with factor_analysis.

Parameters

stages
list[object]
required
Pipeline stages defining the strategy. See Pipeline Stage Schema below.
universe
string
default:"sp500"
Stock universe: sp500, russell2000, or nasdaq100
rebalance
string
default:"monthly"
Rebalance frequency: daily, weekly, monthly, or quarterly
sizing
string
default:"equal_weight"
Position sizing method: equal_weight or inverse_volatility
start_date
string
default:"2023-01-01"
Backtest start date in YYYY-MM-DD format.
end_date
string
default:"2025-12-31"
Backtest end date in YYYY-MM-DD format.
max_position_size
float | null
default:"null"
Maximum weight per position (0–1). E.g. 0.1 caps each position at 10% of portfolio.
stop_loss
float | null
default:"null"
Per-position stop loss (0–1). E.g. 0.15 sells a position if it falls 15% from entry.
max_drawdown
float | null
default:"null"
Portfolio circuit breaker (0–1). E.g. 0.2 moves the portfolio to cash if it drawdowns 20% from peak.

Pipeline Stage Schema

Each stage is an object:
{
  "order": 1,
  "type": "screen",
  "skill": "fundamental_screen",
  "config": { "pe_lt": 15 }
}
FieldTypeDescription
orderintegerExecution order, ascending
typestring"screen", "analyze", or "signal"
skillstringAny screen type from screen_stocks (e.g. fundamental_screen, momentum_screen)
configobjectSame config object as screen_stocks

Multi-stage example

Filter value stocks, then rank survivors by momentum:
[
  {
    "order": 1,
    "type": "screen",
    "skill": "fundamental_screen",
    "config": { "pe_lt": 15, "roe_gt": 12 }
  },
  {
    "order": 2,
    "type": "signal",
    "skill": "momentum_screen",
    "config": { "lookback_days": 200, "top_pct": 0.3 }
  }
]
The pipeline is sequential:stage 2 receives the filtered output of stage 1 as its input universe. This lets you compose screens (filter → rank → select).

Example Response

{
  "strategy": {
    "universe": "sp500",
    "rebalance": "monthly",
    "sizing": "equal_weight",
    "stages": [{ "order": 1, "type": "screen", "skill": "value_screen", "config": { "pe_lt": 15 } }],
    "period": "2023-01-01 to 2025-12-31"
  },
  "metrics": {
    "total_return": 0.3241,
    "cagr": 0.1012,
    "sharpe": 1.24,
    "max_drawdown": -0.1483,
    "calmar": 0.68,
    "win_rate": 0.5312,
    "turnover": 2.41,
    "total_trades": 384
  },
  "equity_curve": [
    { "date": "2023-01-03", "value": 100000.0 },
    { "date": "2023-06-30", "value": 108234.5 },
    { "date": "2025-12-31", "value": 132410.0 }
  ],
  "equity_curve_points": 756,
  "trades": {
    "total_trades": 384,
    "buys": 204,
    "sells": 180,
    "recent_trades": [
      { "date": "2025-12-01", "ticker": "VTRS", "action": "BUY", "shares": 142.5, "price": 70.18 }
    ]
  },
  "full_equity_curve": ["...full array, pass to factor_analysis..."]
}

What to do next

Decompose returns

Pass full_equity_curve to factor_analysis to understand whether returns come from alpha or factor exposure.

Compare strategies

Run the same backtest with different screen types, rebalance frequencies, or universes side by side.

Add risk controls

Set stop_loss, max_position_size, or max_drawdown to see how risk management affects the equity curve.