What it does

Compiles the strategy, estimates what a run would spend in credits, checks that the data covers the period, and returns the confirm handoff that run_backtest takes. Nothing is spent and nothing starts. Claude calls it before every run. It is where most refusals surface: a graph that is not backtestable, a short strategy on a cash account, a period the data does not cover, or a cost profile the engine cannot model.

It takes the same arguments as run_backtest: the strategy id, the period, and optionally the starting capital, margin, the cost profile, a rank clause and values for the strategy's declared parameters. The estimate is computed from the version of the strategy admitted at the time. confirm.version_id and confirm.universe_hash bind that version and its universe, and run_backtest refuses when either changed in between.

Four cost profiles exist. alpaca_us_equities, the default, models a zero-commission US equities broker. zero is a frictionless research setting, not an account you can open. ibkr_pro_tiered is refused, because the engine cannot model its per-order minimum faithfully. custom needs a commission rate these tools do not take, so it is refused too.

It needs the read permission, which every connection has. Every project role may call it, a viewer included.

One caveat: estimate.credits is null when the project is not priced. Claude then states the usage dimensions instead of a credit figure.

Parameters

ParameterTypeRequiredDescription
strategy_idstringyesThe strategy id, a UUID. Not the workflow id.Example: 0193c2a1-5b7e-7f10-9c3d-2a6b8e4f1d07
period_startstringyesThe first session, as YYYY-MM-DD.Example: 2021-01-04
period_endstringyesThe last session, as YYYY-MM-DD. It must be after period_start.Example: 2024-12-31
initial_capitalnumbernoStarting cash in USD. Default 100000. At least 100.Example: 100000
margin_enabledbooleannoA Reg-T margin account, required for shorts. Default false: cash only.Example: false
cost_profilestringnoWhose costs to model: alpaca_us_equities (the default), ibkr_pro_tiered, zero or custom. ibkr_pro_tiered and custom are refused through these tools.Example: alpaca_us_equities
rankobjectnoCross-sectional ranking of one bar's entry candidates. by (required) is score or screen_rank. max_new_positions (integer, at least 1) admits that many entries out of one bar's candidates, best-ranked first; default no turnover cap. max_concurrent_positions (integer, at least 1) caps positions held or resting after a bar's admissions; a full book opens nothing; default no book cap. min_score (number) cuts candidates scoring strictly below it before the caps apply; only under by score; default no floor.Example: {"by": "score", "max_new_positions": 3, "max_concurrent_positions": 5}
parametersobjectnoValues for the knobs the strategy declares, by name. Each value is a string or a number.Example: {"period": 21}

What comes back

  • strategy: id and name.
  • estimate: universeKind (static or screen), symbols, calendarDays, approxTradingDays, approxBars, executionFeed, decisionTimeframe (a Program's bar; null on a rule strategy), warmupSessions, pricing and credits. credits is null when the project is not priced.
  • coverage: the engine's data coverage for the spec, or null when the engine could not be asked: gaps, message, feed, symbols, dataThrough, effectiveTo and notYetDue.
  • warnings: the compiler's warnings, such as symbols with too little history for the period.
  • cost_profile: the profile that will apply.
  • quota_note: present only when the workspace is at its ceiling of runs in flight. It says how many are running and that a run will be refused until one finishes.
  • confirm: version_id and universe_hash, which run_backtest takes.
  • disclaimer: the backtest disclaimer, word for word.

Try saying

If it fails

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.
No such strategy in this project.
The id names no strategy and no workflow in this project.Claude takes the strategy id from list_strategies or from the create receipt.
That id names the workflow “<name>”, not a strategy. Its strategy id is the one to backtest.
Claude passed the workflow id where the strategy id goes. The answer carries the strategy and says to call run_backtest again with its id.Claude calls again with the strategy id the answer names.
The workflow “<name>” is not a strategy, so it has nothing to backtest. It does not qualify: <reason>
The saved graph does not qualify as a strategy. The reason says why.Claude fixes the graph with update_strategy. A saved graph that qualifies is tracked as a strategy automatically, and list_strategies names its id.
The workflow has no admitted version to test — save it first.
The strategy's workflow has never been saved with an admitted graph.Claude saves the graph with update_strategy, then estimates again.
This strategy graph is not backtestable yet.
The compiler refused the graph. The named diagnostics come back as details, such as an entry rule with no indicator behind it or risk sizing with no stop.Claude relays the diagnostics, fixes the graph with update_strategy and estimates again.
Program '<label>' has source that was never built — build the program before running it.
The Program node holds source but no built module. The same refusal reads "changed since its last build" when the source changed after the build.Claude calls build_program, then estimates again.
The period must be two dates, start before end.
period_start is not before period_end, or a date is malformed.Claude sends two YYYY-MM-DD dates with the start first.
Starting capital must be a number of at least $100.
initial_capital is below 100.Claude sends 100 or more, or omits it for the default of 100000.
This strategy sells short — run it on a margin account (toggle Margin in the launcher).
A rule-card strategy has a short entry and margin_enabled is false.Claude sets margin_enabled to true.
IBKR Pro Tiered is $0.0035 per share with a $0.35 minimum per order and a cap at 1% of trade value. The engine's cost model is a single rate — per share, in basis points, or zero — with no per-order minimum and no cap, so this schedule cannot be simulated faithfully yet. Running it as a bare $0.0035 per share would drop the minimum, which flatters exactly the small-order, high-turnover strategies the minimum is there to punish. Test under Alpaca or a custom rate until the engine carries a minimum.
cost_profile was ibkr_pro_tiered.Claude uses alpaca_us_equities or zero.
The Custom rate profile needs a commission of its own — send a model (zero, bps, per_share) and a rate, or choose a named broker.
cost_profile was custom. These tools carry no commission rate, so the profile cannot be satisfied here.Claude uses alpaca_us_equities or zero. Orbital's run dialog does not offer a custom rate either.
Ranking by score orders candidates by the conviction a program expressed in enter(side, score), and this strategy is a rule-based one — rules express no score. Rank by the screen’s position instead, on a strategy that screens for its universe.
rank.by was score on a rule-card strategy. Other rank refusals name their own reason, such as a clause with no cap, a screen that is not ranked, a minimum score under screen_rank, or an intraday decision bar.Claude drops the rank clause or uses screen_rank on a strategy that screens and sorts its universe.
This run’s parameters do not match what the strategy declares.
A parameter names a knob the strategy does not declare, has the wrong type, or is out of its bounds. The details name each one.Claude reads the declared parameters with get_strategy and sends matching values.
<count> symbols exceeds the 500-symbol ceiling.
The strategy's universe names more than 500 symbols.Claude narrows the universe with update_strategy.
At <bars>, <count> symbols allow a window of up to <span> — this run asks for <start> to <end>. Shorten the period, test fewer symbols, or run on daily bars.
The period times the universe exceeds what one run may read on that bar size.Claude shortens the period, tests fewer symbols, or runs on daily bars.
<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.