[POST /optimize]

Strategy hyperparameter search — N interpret Runtime runs with input.* overrides, TPE/random/grid, holdout or walk-forward.

POST /optimize

Abstract

/optimize searches Pine input.* values for a strategy() script. It loops the package Runtime (same interpret path as /run) with different overrides, scores closed trades, and returns the best assignment plus every trial.

This is not /backtest/quick (that route is a demo SMA simulator). It is not a Pine language surface — there is no optimize.* builtin.

AXIS Hyperparameter Optimisation calls this when the active engine is the Pro API (server). Pyodide / edge engines fall back to a client-side loop.

Conceptual model

Request

FieldTypeRequiredDefaultNotes
scriptstringyesMust declare strategy(
datalistyesSame OHLCV objects as /run
spaceobjectyes{ params: [{ name, kind, min, max, step?, choices? }] }
n_trialsintno30Capped at 200
samplerstringnoautoauto | random | tpe | grid (auto → random if N<20 else TPE)
objectivestringnocompositenet_pnl | profit_factor | calmar | composite
validationobjectno{ mode: "holdout" }holdout | walk-forward | in-sample
min_tradesintno5Trials below this score -inf
seedintnoRNG seed
symbolstringnoCHART
oos_every_trialboolnotrueHoldout: score every trial on the test slice
fixed_inputsobjectno{}Current input.* values for names not in space (trial params win on overlap)
librarieslistno[]Same AXIS git-publish list as /run

space.params[].kind: int | float | bool | categorical. Numeric axes require min and max.

validation extras: holdout_frac (default 0.3), train_bars / test_bars / step_bars for walk-forward.

Estimated engine runs are capped at 400 (n_trials * folds).

Success

{
  "status": "success",
  "sampler": "tpe",
  "objective": "composite",
  "n_trials": 30,
  "trials": [
    {
      "index": 0,
      "params": { "Fast": 8 },
      "is_score": 12.4,
      "oos_score": 3.1,
      "is_stats": { "total_pnl": 10, "trades": 8, "max_dd": 0.1 },
      "error": null
    }
  ],
  "best_index": 4,
  "best_params": { "Fast": 6 },
  "best_is_score": 15.0,
  "best_oos_score": 4.2,
  "engine_runs": 60,
  "ms": 8421.2,
  "warning": null
}

Full event arrays are not returned (memory). Re-run the winner via /run + inputs.

Errors

HTTPcodeWhen
400NOT_A_STRATEGYScript is not strategy()
400INVALID_SPACEMissing bounds / empty params
400TOO_MANY_RUNSEstimated runs exceed 400
400NO_SCRIPT / NO_DATAEmpty body
413 / 429same as /runFree-tier caps

Invariants

  1. Always interpret (input overrides skip compile).
  2. Train and test are bar slices, not trade filters on a full-sample run.
  3. In-sample mode is allowed and warned.
  4. Ranking prefers OOS score when validation is holdout or walk-forward.

CLI

pyne optimize strat.pine --trials 20 --sampler tpe \
  --space '{"params":[{"name":"Fast","kind":"int","min":3,"max":12}]}'

See also