RealTest User Guide
RealTest User Guide

 

 

Navigation: Backtest Engine Details >

Backtest Loop Overview

 

 

 

 

The RealTest Backtest Engine is written to support multi-strategy portfolio-level backtesting as effectively and efficiently as possible.

In most other software, portfolio-based backtesting is implemented by first generating all the entry and exit signals for each symbol for the entire date range, and then running a second pass that models the portfolio for each date using the generated signals.

In contrast to this, RealTest loops through the data by date first, then loops through each strategy, then finally each symbol for that strategy.

Use of this loop hierarchy models a daily trading process in the most realistic way.

Test Initialization

Before the daily loop begins (unless using Dynamic Sizing mode, which re-evaluates sizing each bar):

1.Apply the Settings (if present and applicable) to the Settings Panel (where they will persist until next changed)

2.Load the specified Data File if not already in memory

3.Determine the current Parameter values (the defaults for a single test or the next optimization values for multiple tests)

4.Adjust the test date range to match the data date range and/or the next optimization interval

5.Recalculate Data Section items (arrays) as needed

Daily Loop: Three Phases

For each date in the test range, trading is processed in three time-of-day phases. The order in which exits and entries are processed within each phase is designed to model realistic daily trading as closely as possible:

Phase 1 — At the Open

Process exits first, then entries. Exits are processed first to free capital for new positions being entered at the open.

Phase 2 — Intraday

Process entries first, then exits. This is the opposite of the other phases. Since the sequence of intraday fills is unknown, the engine cannot assume that exiting one position would free capital in time for another entry on the same bar. To avoid this unrealistic assumption, entries are processed before exits.

See Intraday Fill Sequence Assumptions for more detail.

Phase 3 — At the Close

Process exits first, then entries. Same as the open: exits free capital for new entries.

After all three phases, daily stats are updated and allocation is recalculated for each strategy.

Which phase a given entry or exit executes in is determined by EntryTime and ExitTime, as well as whether the entry or exit uses a limit or stop price that would be filled intraday.

Exit Processing

In each phase, exits are evaluated for all open positions. A position is exited if any of the following are true:

1.ExitRule evaluates to TRUE and ExitTime matches the current phase

2.ExitLimit or ExitStop price was touched without ambiguity (exit at that price)

3.ExitLimit and/or ExitStop price were touched with ambiguity and the Ambiguity setting permits exit anyway

4.This is the last bar of data or last date of the test (exit at close, subject to EndOfTestExits)

Entry Processing

Entry processing uses a multi-pass approach to fairly allocate capital across multiple strategies while respecting all capacity constraints.

Pass 1 — Setup Detection

For each strategy, loop through all stocks and evaluate EntrySetup, making a list of stocks for which it returns TRUE (setups). Sort this list by SetupScore and truncate at MaxSetups (if specified).

Pass 2 — Constraint-Aware Setup Selection

Setups are selected in a round-robin fashion across strategies to ensure fair allocation:

1.For each turn (loop from 1 to the most setups in any strategy):

a.For each strategy in StrategyScore sequence (highest score first):

1.Select the next unprocessed setup (ranked by SetupScore)

2.Check if adding it would exceed any Max... constraint for the strategy, any StatsGroups it belongs to, or Combined

3.If no constraints are exceeded, add the setup and update all constraint values; otherwise skip it

4.If MaxPerTurn setups have been added on this turn, yield to the next strategy

Pass 3 — Order Finalization

For each strategy, now that the complete setup list is known with all constraints accounted for:

1.Sort setups by EntryScore if provided

2.Evaluate QtyFinal for each setup to optionally adjust the order quantity

3.Evaluate EntrySkip if provided and skip the entry if true

4.Enter the position if EntryLimit and/or EntryStop have been touched or were not specified

Key Points

1.Position sizes for constraint-checking purposes are always based on OrderPrice, not on FillPrice (which can't be known yet at setup-processing time)

2.All constraints are applied to the setup list prior to processing any entries

3.Setups for strategies that enter with limit or stop orders count towards all constraints whether or not they are filled

4.This model assumes that all orders are placed in advance of the market open each day with no real-time order management (e.g. live cancellation when a capacity is reached)

 

 

 

Copyright © 2020-2026 Systematic Solutions, LLC