Documentation

Input Parameters

Input parameters let you turn values inside your strategy code (for example a lookback length or a maximum number of open longs) into knobs you set from the Test (backtest) dialog — without editing the file every time you want to try a new number. Test is described in Running code; multi-run sweeps are covered under Optimization. Params are read during Backtests, not plain Run.

This page covers the two halves of that flow:

  • Declaring params in your Python file
  • Wiring those params to the Test / backtest modal so you can set, save, and optimize them

How it works at a glance

  1. In your strategy file, you import a special params object and read attributes off it (e.g. params.PERIOD).
  2. The IDE scans your code to discover those names and lists them in the Test dialog.
  3. You enter a type and value for each name in the dialog (or define a sweep when you optimize).
  4. When you click Test, the engine fills params with your values before your script runs, so the values are available the moment your file is imported.

Inputs are populated only for backtests (the Test button). They are not populated for plain Run — use plain Python defaults if you want a runnable script outside backtests. See Strategy lifecycle for when params are visible to callbacks.


Declaring params in your strategy

Add a single import and reference each parameter name as an attribute on params:

from ide.inputs_module import params PERIOD = params.PERIOD MAX_OPEN_LONGS = params.MAX_OPEN_LONGS USE_FILTER = params.USE_FILTER LABEL = params.LABEL

A few rules apply:

  • The import must be from ide.inputs_module import params exactly (whitespace is OK). The IDE looks for this line specifically.
  • Each parameter name must be a valid Python identifier (A–Z, a–z, 0–9, _, not starting with a digit).
  • You can use params.NAME anywhere in the file — top‑level, inside on_init, inside on_bar, etc. Each unique reference becomes one input the dialog will ask you about.
  • There is no schema in the module itself — the names you reference are the schema.

Common idioms:

def on_init(): global lookback lookback = int(params.PERIOD) def on_bar(bar_index, bar, fundamentals=None, symbol=None): if bar.bars_back < lookback: return ...

Tip: read the value once into a local/global so you don’t pay attribute lookups on every bar.


Wiring the Test / backtest modal

Open the Test dialog from the editor toolbar (the Test button) and look for the Script Parameters & Optimization (ide.inputs_module) section. The IDE has already scanned your active file for params.NAME references, so each parameter you used appears as a row.

For each row you set:

ColumnWhat you enter
ParameterThe name (read-only — comes from your code).
TypeOne of int, float, str, bool.
ValueThe value to use for the run.

Notes on Type choices:

  • int — whole numbers (e.g. 14).
  • float — decimals (e.g. 0.5, 1e-3); commas in numbers are stripped.
  • bool — accepts true / false, yes / no, y / n, on / off, and 1 / 0.
  • str — free text, kept as-is (trimmed of surrounding whitespace).

When you click Test, the dialog packages your rows and sends them to the engine. The engine sets the values on params before your on_init() runs, so:

from ide.inputs_module import params PERIOD = params.PERIOD # <- already filled by the time this line executes

If a parameter name has no row in the dialog (you removed the dialog entry, or your file references a brand‑new name you haven’t set yet), params won’t have that attribute and reading it will raise AttributeError. Add the row in the dialog and re‑run — or fall back with getattr(params, "NAME", default).

Your dialog values are remembered between runs, so you don’t need to retype them every time.


Optimizing parameters

The same dialog can drive an optimization that runs your strategy many times with different parameter combinations. Tick Optimize script parameters (brute grid or genetic search) and pick a mode:

Brute force

For each parameter row, the dialog adds Step and Max columns where it makes sense:

  • int / float — define a discrete grid: start value → step → max.
  • bool — both true and false are tried.
  • str — kept fixed (string parameters don’t form a grid).

The engine runs every combination of those discrete values and reports each run separately in the Test Results view.

Useful for small grids (a handful of parameters with a few values each). Combinations explode quickly — keep your search space modest.

Genetic

For larger search spaces, switch to Genetic to let an evolutionary search find good combinations without trying every cell:

  • Population size — number of parameter combinations evaluated each generation.
  • Generations — how many generations to run (each is one full population of backtests).
  • Elitism — top individuals copied unchanged into the next generation.
  • Crossover rate (01) — chance two parents produce a mixed child.
  • Mutation rate (01) — chance a gene jumps to another value.
  • Fitness metric — which metric to optimize (Sharpe, Sortino, total return, etc.).
  • Random seed (optional) — reproducibility of the population and operators.

Both modes show live progress in the Output Panel (a progress bar in the header) and a Stop button so you can end a long run.

When optimization finishes, the Test Results view shows the runs sorted by your fitness metric, and you can drill into each one.


Tips

  • Names are discovered from your file: if a row doesn’t appear, double‑check your params.NAME references and that the import line matches exactly.

  • Keep names UPPER_SNAKE_CASE — by convention they read as constants in your code.

  • Provide sensible types in the dialog so coercion does what you expect (e.g. don’t set int for a value like 0.5).

  • Booleans aren’t case-sensitiveTrue, true, 1, yes all evaluate to true.

  • Use Optimize for parameter searches, not editor scripts: brute force is exhaustive, genetic is for larger spaces.

  • Inputs are backtest‑only: when you click Run, params is not populated. Guard with defaults if you want the same file to be runnable both ways:

    from ide.inputs_module import params PERIOD = getattr(params, "PERIOD", 14)