Skip to content

Fix a strategy error

Start with the reported line and error code. Make the smallest correction, then check the draft again.

Common mistakes

Problem Check Correction
Unknown section Spelling and colon entry: instead of enrty:
Invalid version header If present, place one valid header before declarations //@version=1, or omit it to use version 1
Missing instrument symbol or fixed universe symbol: TCS
Missing size Explicit quantity or objective size: 5% per instrument
Invalid percentage phrase Number spacing, basis and scope size: 5% of portfolio per instrument; keep 5% together.
Unknown indicator Name and parameters rsi(14) instead of ris(14)
Incomplete condition Comparisons and connectors rsi(14) > 45 and close > ema(20)
Lookahead Historical index close[1] for previous bar; never close[-1]
Conflicting stops Inline and separate stops Use one consistent percentage.

Error or warning?

An error blocks validation. A warning/advisory asks you to check behaviour or capability. Some validators report an unknown function as an advisory; this does not establish that it is available when the strategy runs.

Python builtin names are reserved except for the intentional expression helpers abs, min, max, len, sum and round. This includes execution/reflection names such as eval, exec, compile, getattr and double-underscore names, as well as quit, exit, help, print and type. For example, quit() > 0 is a TS-RESERVED error, not a custom provider. Reserved names cannot be passed as arguments or introduced through a define, even if an environment could supply them. The price series open remains valid in close > open, but open(...) is reserved.

Earlier non-stub runs could accidentally call Python builtins for unsupported provider names. Those names now fail validation and lowering. Ordinary custom providers remain supported: use a non-reserved name, arrange its binding in the execution environment, and update both places if you rename it. The language header remains //@version=1.

TS-MEMBER means an expression tries to read an unsupported object member. Only documented fields on a declared session_range(...) binding are allowed, such as orb.high. Use an injected plain-name provider such as custom_signal(10), not library.custom_signal or a local alias of that member. Lowering now rejects these expressions even when validation was skipped; demo stubs do not bypass this check. A reserved base such as __builtins__ also produces TS-RESERVED. Do not suppress the error to load an older generated strategy: correct the expression and regenerate it.

An unresolved name during a real-provider run means the environment has not supplied that value or function when the expression needs it. A catalog entry or a successful demo-stub run is not evidence of a real binding. For example, custom_signal(10) > 0.7 needs the custom score provider; it cannot borrow an unrelated function from the host. See provider availability for a complete entry/exit example and the information to confirm with its owner.

Resolve unknown names using the supported catalog. Errors and warnings maps each code to a cause and correction.

TS-LOOKAHEAD also covers invalid bar offsets. An offset must calculate to a finite, non-negative constant integer: close[1000-1000] reads the current bar, and close[4/2] reads two bars ago. Division by zero, an overflowing power, a fractional result such as close[3/2], or a dynamic value is rejected. Use a small explicit integer when debugging. Before 4.11.0, unrelated arithmetic could overflow while validating a valid subtraction; this is now diagnosed or evaluated using only the operation actually written.

Valid syntax, unexpected behaviour

Check the instrument, schedule, sizing, data, and position state. Validation does not promise a fill, data availability, or profit. Use the backtest checklist and supported features.

Fix the first cause, then check again

A missing parenthesis or section delimiter can cause several later diagnostics. Start with the earliest relevant syntax error, fix it, then re-check before changing unrelated lines. Keep a working version of the draft so you can compare the last edit.

Diagnostic situation Next step
A name has a suggested spelling Compare with the function catalog and correct the spelling.
An unknown name is only an advisory Confirm that the execution environment actually supplies it.
A size or allocation is rejected Check the full phrase, strategy shape and allowed combination.
A valid rule produces no entry Check history, schedule, position state and quantity/capital limits.
A position remains open unexpectedly Read the explicit exit; false entry does not imply exit.

If you need to report the problem

Include the relevant strategy excerpt, exact diagnostic code and line, selected language, instrument and signal interval. For an unexpected trade, include its timestamp and the values used by the condition. This makes the issue reproducible without guessing what the editor or backtest saw.