# run_backtest

> Launches a backtest under a run id Claude mints, spends credits, and returns the run id at once.

Source: https://orbitalaip.com/docs/claude-and-chatgpt/tools/run_backtest

Run a backtest · backtests · run

> [!IMPORTANT] Disclaimer
> Backtest results are hypothetical and do not predict future performance. Nothing here is investment advice: Orbital computes the rules you supplied and recommends nothing. Orbital is not a registered investment adviser or broker-dealer. Costs are as modelled by the chosen cost profile and may differ from live trading.

## What it does

Launches a backtest of a strategy over a period and returns `run_id` at once. Daily runs finish in seconds and intraday runs in minutes. It spends credits. Claude reaches for it after [estimate_backtest](https://orbitalaip.com/docs/claude-and-chatgpt/tools/estimate_backtest), then polls [get_backtest](https://orbitalaip.com/docs/claude-and-chatgpt/tools/get_backtest) every 10 to 15 seconds until the status is completed, failed or cancelled. With `wait_seconds` set, the call itself waits up to a minute and answers with the verdict when the run finished in time.

Claude mints `request_id` itself, a fresh UUID per intended run, and it becomes the run id. Replaying the same id with the same arguments returns the same run instead of starting a second one, so a retry after a lost reply is safe. The same id with different arguments is refused. Passing `version_id` and `universe_hash` from the estimate's `confirm` makes the launch refuse when the strategy or its universe changed in between.

It takes the arguments of `estimate_backtest`: the strategy id, the period, and optionally the starting capital, margin, the [cost profile](https://orbitalaip.com/docs/glossary#cost-profile), a rank clause and values for the strategy's declared parameters. The same refusals apply, and the data coverage check runs again on the spec that submits.

It needs the run permission, shown on the consent page as **Run backtests, which spends credits**, and a project role that may write: project owner, editor or member, or workspace owner or admin. A viewer's call is refused: a read-only role cannot use write or run tools. By default a workspace may have 4 runs queued or running at once and may start 200 in a rolling 24 hours. A launch over either ceiling is refused.

One caveat: a run the engine refuses on arrival comes back at once with the status failed and the engine's reason in its record. Claude reads it with `get_backtest` rather than launching again unchanged.

## Parameters

| Parameter | Type | Required | Description | Example |
| --- | --- | --- | --- | --- |
| request_id | string | yes | A UUID Claude mints for this launch. It becomes the run id. Replaying it with the same arguments returns the same run; the same id with different arguments is refused. | 0193c2b4-9e21-7a6c-8f3d-5b7a9c1e2d48 |
| strategy_id | string | yes | The strategy id, a UUID. Not the workflow id. | 0193c2a1-5b7e-7f10-9c3d-2a6b8e4f1d07 |
| period_start | string | yes | The first session, as YYYY-MM-DD. | 2022-01-03 |
| period_end | string | yes | The last session, as YYYY-MM-DD. It must be after period_start. | 2025-06-30 |
| initial_capital | number | no | Starting cash in USD. Default 100000. At least 100. | 50000 |
| margin_enabled | boolean | no | A Reg-T margin account, required for shorts. Default false: cash only. | true |
| cost_profile | string | no | Whose costs to model: alpaca_us_equities (the default), ibkr_pro_tiered, zero or custom. ibkr_pro_tiered and custom are refused through these tools. | alpaca_us_equities |
| rank | object | no | Cross-sectional ranking of one bar's entry candidates, as for estimate_backtest: by (required, score or screen_rank), max_new_positions and max_concurrent_positions (integers, at least 1, default no cap), and min_score (a number, only under by score, default no floor). | {"by": "screen_rank", "max_new_positions": 5} |
| parameters | object | no | Values for the knobs the strategy declares, by name. Each value is a string or a number. | {"period": 21} |
| version_id | string | no | From confirm.version_id of estimate_backtest, a UUID. With universe_hash, it makes a drifted estimate refuse. | 0193c2a9-1c4e-7d2b-8a6f-3e5d7c9b1a20 |
| universe_hash | string | no | From confirm.universe_hash of estimate_backtest. With version_id, it makes a drifted estimate refuse. | 7b1e3d5f9a2c4e6081a3c5e7f9b1d3a5c7e9f1b3d5a7c9e1f3b5d7a9c1e3f5b7 |
| wait_seconds | integer | no | How long to wait for the verdict before answering, 0 to 60. Default 0. The answer carries the run's status and progress as of the last reading. | 30 |

## What comes back

- `run_id`: the run id, equal to request_id.

- `status`: `queued` for a fresh launch. A replayed id returns the run's current status. A run the engine refused on arrival is `failed` at once.

- `estimate`: the same estimate `estimate_backtest` returns, computed for the spec that submitted.

- `warnings`: the compiler's warnings for the spec.

- `verdict`: with `wait_seconds` above 0, the compact verdict of `get_backtest` when the run finished in time.

- `progress`: with `wait_seconds` above 0, the status and progress as of the last reading when the run did not finish in time. It holds the engine's `progress` and `engineStatus`, and either may be null: `progress` is set only while the engine itself reports the run as running, and both are null when the engine could not be asked.

- `disclaimer`: the backtest disclaimer, word for word.

## Try saying

- "Run it from 2022-01-03 to 2025-06-30 with 50,000 starting capital and margin on."
- "Backtest the RSI strategy on AAPL, MSFT and NVDA with a 5% stop from 2022-01-03 to 2024-12-31."
- "Run the same period again with the period parameter set to 21 and wait for the verdict."

## If it fails

- **run_backtest needs the 'run' scope, which this connection was not granted. Ask the user to reconnect Orbital with it.** — The connection was made without the Run backtests permission. Connect Orbital again and leave that permission on. Claude can still estimate without it.
- **Your role in this project (viewer) cannot change strategies or spend credits.** — Your role in the connected project is read-only. The message names the role it found. Ask a project owner for a role that may write, or run the backtest in Orbital.
- **Backtesting is not active in this project — turn it on under Settings → Apps in Orbital, then try again** — The Backtesting app is off in the project you connected. In Orbital open Settings, then Apps, and turn Backtesting on for the project you connected.
- **The strategy or its universe changed after the estimate was shown — re-propose for a fresh estimate.** — version_id or universe_hash no longer matches the strategy's admitted version or its universe. Someone saved the strategy, or its watchlist changed, after the estimate. Claude calls estimate_backtest again and launches with the fresh confirm handoff.
- **This run id already names a different run — mint a new id.** — request_id was used before for a run with different arguments, or in another project. Claude mints a fresh UUID and launches again.
- **this workspace already has <count> runs in flight — the ceiling is <ceiling> at a time** — The workspace is at its ceiling of queued or running backtests, 4 by default. Wait for a run to finish, or cancel one with cancel_backtest, then launch again.
- **<count> runs in the last 24h — the ceiling is <ceiling>** — The workspace has started its daily ceiling of backtests, 200 by default, in the last 24 hours. Wait until a run falls out of the rolling 24 hours, then launch again.
- **This run is quoted at <credits> credits and <credits> can still be spent — <credits> short. Add credits to start it.** — The quoted credits exceed what the workspace can still spend. The answer carries estimatedCredits, remainingCredits and shortfallCredits. Shorten the period or the universe and estimate again, or add credits as the message says.
- **Backtest pricing is on for this project but the run could not be quoted — the rate card is missing. The run was not started.** — The project is priced, but no rate card was available to quote the run. Nothing on your side. Contact Orbital support.
- **The backtesting engine is not configured on this deployment.** — The deployment has no backtesting engine. Nothing on your side. Contact Orbital support.
- **No such strategy in this project.** — The id names no strategy in this project, or names a workflow id. Claude takes the strategy id from list_strategies or from the create receipt.
- **two submits raced to name this strategy’s next version — try again** — Two launches of the same strategy arrived at the same moment. Claude launches again with the same request_id.
- **<the engine's coverage sentence>** — The data does not cover the period for one or more symbols. The code is DATA_UNAVAILABLE and the details name the feed, the symbols and the gaps. Claude moves the period inside the covered range or drops the symbols the details name.
- **The period must be two dates, start before end.** — period_start is not before period_end, or a date is malformed. Every other refusal of estimate_backtest can answer here too, in the same words. Claude fixes the arguments as the message says. It never retries unchanged.

## Related

- [Estimate a backtest](https://orbitalaip.com/docs/claude-and-chatgpt/tools/estimate_backtest)
- [Read a backtest run](https://orbitalaip.com/docs/claude-and-chatgpt/tools/get_backtest)
- [Cancel a backtest](https://orbitalaip.com/docs/claude-and-chatgpt/tools/cancel_backtest)
- [Your first backtest](https://orbitalaip.com/docs/getting-started/your-first-backtest)
