Skip to content

Backtests

Backtesting lets you evaluate a strategy revision on historical data before committing capital in live markets. This page summarizes what a backtest is and how it fits into the rest of the system.

A backtest is a simulation that:

  • Runs a specific strategy revision over a chosen time window.
  • Feeds it historical market data instead of live prices.
  • Records the resulting positions, trades, and P&L as if the strategy had been running during that period.

Backtests are:

  • Repeatable – the same revision and the same inputs produce the same simulated behavior.
  • Versioned – they are tied to a particular revision so you always know what logic was tested.

Every backtest is created with:

  • A strategy (the high‑level idea).
  • A specific revision (the exact version of the logic).
  • A set of arguments, which may include:
    • Time range.
    • Execution assumptions.
    • Initial conditions.

Internally, these inputs are combined into a hash that:

  • Uniquely identifies the backtest configuration.
  • Allows Structure to detect and reject exact duplicates (for example, accidentally submitting the same backtest twice).

This tight coupling means:

  • You can always trace a backtest back to the exact revision it tested.
  • When you change logic, you know you are creating a new revision and therefore a potentially different backtest series.
  1. Creation:
    • You select a strategy and revision.
    • You specify the time window and any other configuration exposed in the UI.
    • Structure checks that:
      • The strategy belongs to your user account.
      • The revision exists and is valid.
    • A backtest record is created with status pending.
  2. Execution:
    • A workflow engine runs the simulation using historical data and the chosen revision.
    • Status becomes running while computation is in progress.
  3. Completion:
    • On success, status becomes completed.
    • Two primary artifacts are produced:
      • A result file with detailed time‑series data.
      • A statistics file with summary metrics.
  4. Failure:
    • If something goes wrong, status becomes failed.
    • An error message is stored explaining the reason where possible.

The UI mirrors this lifecycle so you can monitor progress and act accordingly.

Backtests become heavier or slower in proportion to:

  • The length of the time window.
  • The complexity of the strategy and its calculations.
  • The number of markets or instruments involved.

Backtests provide a feedback loop for your strategy development process:

  • Validate concepts:
    • Does the strategy make sense across different market regimes?
    • Are returns and drawdowns consistent with your risk appetite?
  • Compare revisions:
    • How does v3 compare to v2 on the same history?
    • Do parameter changes actually improve robustness?
  • Calibrate risk:
    • Use drawdown and volatility metrics to choose leverage and position sizes.

Common patterns:

  • Run a backtest before promoting a revision to live.
  • Periodically re‑backtest the live revision on recent history to check for drift or degradation.
  • Maintain a library of backtests as part of your research and governance documentation.

As with any backtesting framework:

  • Results are conditional on:
    • The quality and coverage of historical data.
    • The realism of execution and slippage assumptions.
    • The absence (or presence) of look‑ahead and survivorship biases.
  • Past performance is not a guarantee of future results.

Best practices include:

  • Test across multiple regimes (bull, bear, high‑volatility, low‑volatility).
  • Favor strategies that are robust to parameter changes, not just tuned to a narrow window.
  • Use backtests as one input to your decision making, not as the sole arbiter of deploy/no‑deploy.
  • Backtests are versioned, reproducible experiments attached to specific strategy revisions.
  • They provide deep insight into behavior before risking capital.
  • Used thoughtfully, they help you build a disciplined, data‑driven strategy lifecycle inside Structure.