---
title: "Backtest a condition"
method: POST
path: "/v1/backtest"
tags: ["Analysis"]
---

# Backtest a condition

`POST /v1/backtest`

## Request

- Base URL: `https://api.traderspy.app`
- URL: `https://api.traderspy.app/v1/backtest`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

What price did after a condition on one symbol: occurrences, forward returns, win rate and the edge over the baseline. Same data as the MCP tool `backtest_condition`.

## Request body

- object
  - `symbol` string, required: Trading pair (`BTCUSDT`, or a bare `BTC`).
  - `interval` '1m' | '5m' | '15m' | '1h' | '4h' | '1d': Candle timeframe.
  - `conditions` Condition[], required: Up to 3 conditions, AND-ed: `{ "metric", "op", "value", "period"?, "period2"? }`. `lt`/`gt` compare the latest bar; `crossAbove`/`crossBelow` are one-bar events. Examples: RSI oversold `{"metric":"rsi","op":"lt","value":30}`; above the 200 EMA `{"metric":"priceVsEma","op":"gt","value":0,"period":200}`; golden cross `{"metric":"emaSpread","op":"crossAbove","value":0,"period":50,"period2":200}`.
    - `metric` 'rsi' | 'stochastic' | 'cci' | 'mfi' | 'williamsR' | 'adx' | 'roc' | 'macdHistogram' | 'atrPct' | 'volumeRatio' | 'bbPercentB' | 'bbWidthPct' | 'priceVsEma' | 'emaSpread' | 'supertrend' | 'changePct' | 'price', required
    - `op` 'lt' | 'gt' | 'crossAbove' | 'crossBelow', required
    - `value` number, required
    - `period` integer
    - `period2` integer
  - `horizons` integer[]: Bars ahead to measure returns over (default ≈ 4h / 1d / 3d for the interval).

## Response `200`

OK

- object

## Other responses

- `400`: `invalid_request`: A parameter is missing, unknown or out of range. `details` names it.
- `401`: `missing_api_key`: No API key was sent. Send it as `Authorization: Bearer tspy_…` or `X-API-Key`. `invalid_api_key`: The key does not exist, was revoked, or its account is closed.
- `403`: `plan_not_included`: The account’s plan does not include API access. `ip_not_allowed`: The key only works from the IP addresses set on it; this request came from another one. `origin_not_allowed`: The key only works from the websites set on it; this request named another website, or none.
- `404`: `not_found`: No such endpoint, or the record (signal, trader) does not exist. `no_data`: TraderSpy has no data for that symbol or timeframe.
- `413`: `body_too_large`: The JSON body is over 32 KB (a screener or backtest body is under 4 KB).
- `429`: `rate_limited`: More than the per-minute limit. Wait `Retry-After` seconds. `daily_limit_reached`: The plan’s calls for this UTC day are used. Resets at 00:00 UTC. `key_daily_limit_reached`: The key’s own daily cap is used (the account may have calls left). Resets at 00:00 UTC.
- `500`: `internal_error`: Something failed on our side. Quote the `requestId` to support.
- `503`: `service_unavailable`: A data source did not answer in time. Retry after `Retry-After` seconds; the call was not counted.

---

[API](https://skmtc.dev/traderspy/apis/traderspy-signals-api.md) · [All operations](https://skmtc.dev/traderspy/apis/traderspy-signals-api/llms.txt) · [OpenAPI document](https://skmtc.dev/traderspy/apis/traderspy-signals-api/revisions/3ef61545eec6?raw)
