Getting Started
Backtest Labs is a visual backtesting platform where you design trading strategies by connecting nodes on a canvas. Each node represents a distinct piece of your strategy, whether that's an indicator calculating values from market data, an operator comparing signals, or an action node executing trades when your conditions are met. Once your strategy is wired up, you can run it against historical market data to see exactly how it would have performed, complete with performance analytics, interactive charts, and detailed trade logs.
Nodes
Overview
This section documents every node available in the strategy builder. Nodes are organized into categories based on their function, and each node's entry covers what it does, the math behind it, its parameters, and its inputs and outputs.
Nodes are organized into categories:
- IndicatorsCalculate technical values from price, volume, and other market data
- ActionsExecute trades (Buy, Sell) or hold position (Wait)
- OperatorsCombine and compare signals using logic and math
- UtilitiesHelpers like crossover detection, stop losses, and scheduling
- PortfolioAccess live portfolio metrics like drawdown, exposure, and cash balance
Some indicator nodes have optional input handles that allow you to override one of their default parameter values by connecting the output of another node. Each node's documentation specifies which inputs are available and whether they're required or optional.
Wire types
Every connection between nodes carries one of three kinds of data. The strategy builder enforces type compatibility when you drag a wire from an output to an input.
- Signal — a per-bar on/off state (active or inactive). Action nodes (Buy, Sell, Wait) and signal combiners (And, Or, Sequence) consume signals on their inputs.
- Series — a per-bar numeric value (a line). Indicator value outputs like the RSI line, an MA line, or ATR×multiplier are series. Math, Relation, Crossover, Direction Filter, and the optional data_in handles on indicators accept series. A Constant is automatically treated as a broadcast-constant series, so a Numeric Value source plugs into any Series input.
- Constant — a single numeric value broadcast to every bar. The Numeric Value node is the canonical constant source. Any Series-typed input also accepts a Constant.
Multi-line outputs and the line selector
Some indicators emit more than one line at once. Bollinger Bands emits upper, middle, and lower bands; DMI emits ADX, +DI, and -DI; Ichimoku emits four lines. Every wire coming out of a multi-line indicator has a small label near the source end showing which line is flowing through.
The label is always visible. Three states:
- Auto-route (default) — the label shows the indicator's primary line name (middle band for Bollinger Bands, conversion line for Ichimoku) with a dim border. The wire carries the primary line.
- Explicit selection — after you click the label and pick a different line, the border turns brand-colored and the wire carries the chosen line. Picking the primary line again returns to auto-route.
- Stale selection — if a node config change removes the previously-picked line (for example, switching DMI from dmi_adx to adx_only after wiring +DI), the label renders with a warning-colored fill and border so you can re-pick rather than silently delivering a no-longer-available series.
Clicking the label opens a menu of the lines the source indicator currently emits. The menu adapts to the indicator's config: pivot styles, MA periods, DMI mode, support/resistance levels — each governs which lines are selectable.
EMA
The EMA node computes one or more exponential moving averages of price or any connected numeric series. It weights recent bars more heavily than an SMA of the same length and supports three signal modes (trend, crossover, ribbon).
Parameters
- Type
- Direction
- Period
Lookback in bars for each EMA. Count limits depend on Type: Trend uses 1, Crossover requires exactly 2 (labeled Fast and Slow), Ribbon accepts 3 to 8 (labeled P1 through P8). The Trend mode compares the source to the slowest (last) period.
- data_in
If connected, each EMA is computed on the connected series. If unconnected, computed on the close price of the strategy's ticker.
Outputs
- signal — Signal. Activates on bars where the configured condition holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The EMA line, or the configured set of lines (one per period in Crossover or Ribbon mode), drawn as price overlays. Any input that accepts a Series receives ema_1 (the primary line) by default; the line selector on the output handle lets you pick any of the other configured periods (ema_1 through ema_N).
Formulas
First EMA = SMA over the first N closes Then: EMA at bar t = alpha * close[t] + (1 - alpha) * EMA[t-1] where alpha = 2 / (N + 1)
Bullish: signal[t] = 1 while source[t] > EMA_slowest[t] Bearish: signal[t] = 1 while source[t] < EMA_slowest[t]
signal[t] = 1 when fast[t] > slow[t] AND fast[t-1] <= slow[t-1], else 0
signal[t] = 1 when fast[t] < slow[t] AND fast[t-1] >= slow[t-1], else 0
Bullish: signal[t] = 1 while EMA_1[t] > EMA_2[t] > ... > EMA_N[t] Bearish: signal[t] = 1 while EMA_1[t] < EMA_2[t] < ... < EMA_N[t]
MA
The MA node computes a moving average of price or any connected numeric series. It supports two calculation methods (SMA and SMMA) and three signal modes (trend, crossover, ribbon).
Parameters
- Type
- Method
- Direction
- Period
Lookback in bars for each moving average. Count limits depend on Type: Trend uses 1, Crossover requires exactly 2 (labeled Fast and Slow), Ribbon accepts 3 to 8 (labeled P1 through P8).
- data_in
If connected, the moving average is computed on the connected series. If unconnected, computed on the close price of the strategy's ticker.
Outputs
- signal — Signal. Activates on bars where the configured condition holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The moving average line, or the configured set of lines (one per period in Crossover or Ribbon mode). The chart draws these as overlays. Any input that accepts a Series receives ma_1 (the primary line) by default; the line selector on the output handle lets you pick any of the other configured periods (ma_1 through ma_N).
Formulas
SMA at bar t = (close[t-N+1] + close[t-N+2] + ... + close[t]) / N
First SMMA = SMA over the first N closes Then: SMMA at bar t = alpha * close[t] + (1 - alpha) * SMMA[t-1] where alpha = 1 / N
signal[t] = 1 when fast[t] > slow[t] AND fast[t-1] <= slow[t-1], else 0
signal[t] = 1 when fast[t] < slow[t] AND fast[t-1] >= slow[t-1], else 0
DMI / ADX
The DMI node computes the Directional Movement Index — the +DI and -DI directional lines and the ADX trend-strength line. It emits a signal from directional dominance gated by a minimum ADX threshold.
Parameters
- Period
Wilder smoothing length for the directional movement, true range, and ADX. +DI and -DI become defined after the period; ADX after roughly twice the period.
- Threshold
The minimum ADX value required for the signal to activate. Bars where ADX sits at or below the threshold produce no signal regardless of directional dominance.
- Mode
- Direction
- data_in
If connected, the high, low, and close all collapse to the connected series (a single-value bar), so the directional movement is measured on the series' own bar-to-bar change. If unconnected, the high, low, and close of the strategy's ticker are used.
Outputs
- signal — Signal. Activates on bars where the configured Direction holds with ADX above the threshold, independent of Mode. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The line or lines selected by Mode, drawn as a sub-panel. Any input that accepts a Series receives the first line of the selected set. The +DI (plus_di), -DI (minus_di), and ADX (adx) lines are each available by name on the output handle regardless of Mode.
Formulas
+DM = up move when up move > down move and up move > 0, else 0 -DM = down move when down move > up move and down move > 0, else 0 where up move = high[t] - high[t-1], down move = low[t-1] - low[t]
+DI = 100 * Wilder-smoothed(+DM) / Wilder-smoothed(true range) -DI = 100 * Wilder-smoothed(-DM) / Wilder-smoothed(true range)
DX = 100 * |+DI - -DI| / (+DI + -DI) ADX = Wilder-smoothed(DX)
Bullish: signal[t] = 1 while +DI[t] > -DI[t] AND ADX[t] > threshold Bearish: signal[t] = 1 while -DI[t] > +DI[t] AND ADX[t] > threshold
Ichimoku Cloud
The Ichimoku node computes the Ichimoku Kinko Hyo lines — the Conversion Line, Base Line, and the two leading spans that form the cloud. It emits a signal from the close's position relative to the cloud.
Parameters
- Conversion Line Period
Lookback for the Conversion Line (Tenkan-sen), the midpoint of the highest high and lowest low over the window.
- Base Line Period
Lookback for the Base Line (Kijun-sen), the midpoint of the highest high and lowest low over the window.
- Leading Span B Period
Lookback for Leading Span B (Senkou Span B), the midpoint of the highest high and lowest low over the window.
- Displacement
Number of bars the two leading spans are shifted forward. The cloud compared against the close at a given bar is the span value from this many bars earlier.
- Direction
Ichimoku has no data_in handle: the lines are built from the high, low, and close of the strategy's ticker.
Outputs
- signal — Signal. Activates on bars where the close is above (bullish) or below (bearish) both leading spans. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The Conversion Line, Base Line, Leading Span A, and Leading Span B, drawn as price overlays with the span pair shaded as the cloud. Any input that accepts a Series receives the Conversion Line; conversion_line, base_line, span_a, and span_b are each available by name on the output handle.
Formulas
Conversion Line = (highest high + lowest low) / 2 over the Conversion period Base Line = (highest high + lowest low) / 2 over the Base period Leading Span A = ((Conversion Line + Base Line) / 2) shifted forward by Displacement Leading Span B = ((highest high + lowest low) / 2 over the Span B period) shifted forward by Displacement
Bullish: signal[t] = 1 while close[t] > Span A[t] AND close[t] > Span B[t] Bearish: signal[t] = 1 while close[t] < Span A[t] AND close[t] < Span B[t]
Supertrend
The Supertrend node builds an ATR-banded trend line that locks under price in an uptrend and over price in a downtrend, flipping sides when the close breaks through. It emits a signal from the current trend side.
Parameters
- ATR Period
Wilder smoothing length for the Average True Range that sets the band width. Shorter periods make the bands react faster and flip more often.
- Multiplier
The number of ATRs the bands sit away from the midpoint of the high and low. Larger values widen the bands, so the trend flips less often.
- Direction
- data_in
If connected, the high, low, and close all collapse to the connected series (a single-value bar), so the bands track the series itself. If unconnected, the high, low, and close of the strategy's ticker are used.
Outputs
- signal — Signal. Active on every bar in the matching trend state, not only on the flip bar. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The lower and upper bands, drawn as price overlays. The Supertrend line itself (supertrend), and the lower_band and upper_band, are each available by name on the output handle.
Formulas
basic upper = (high + low) / 2 + multiplier * ATR basic lower = (high + low) / 2 - multiplier * ATR where ATR is Wilder's average true range over the ATR period
The final upper band only ratchets down unless the prior close breaks above it; the final lower band only ratchets up unless the prior close breaks below it. The Supertrend line is whichever final band the close is currently on.
Bullish: signal[t] = 1 while close[t] is above the Supertrend line (uptrend) Bearish: signal[t] = 1 while close[t] is below the Supertrend line (downtrend)
Parabolic SAR
The Parabolic SAR node plots a stop-and-reverse dot that trails price, accelerating toward it as the trend extends and flipping to the other side when price crosses it. It emits a signal on each flip.
Parameters
- Acceleration Factor
The starting acceleration and the step added each time price makes a new extreme in the current trend. Larger values pull the dot toward price faster, producing earlier flips.
- Max Acceleration
The ceiling on the acceleration factor. Once reached, the dot stops accelerating for the remainder of the trend.
- Direction
Parabolic SAR has no data_in handle: it is computed from the high and low of the strategy's ticker.
Outputs
- signal — Signal. Activates on the bar where the close crosses the SAR in the configured Direction. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The SAR dot value, drawn as a price overlay. Any input that accepts a Series receives this line.
Formulas
SAR[t] = SAR[t-1] + AF * (EP - SAR[t-1]) where EP is the extreme point (highest high in an uptrend, lowest low in a downtrend) and AF rises by the Acceleration Factor on each new extreme, capped at Max Acceleration
When price crosses the SAR, the trend flips: SAR resets to the prior EP, EP resets to the current extreme, and AF resets to the Acceleration Factor.
Bullish: signal[t] = 1 when close[t] > SAR[t] AND close[t-1] <= SAR[t-1] Bearish: signal[t] = 1 when close[t] < SAR[t] AND close[t-1] >= SAR[t-1]
Trendline
The Trendline node draws a straight line between two captured anchor points and extends it forward, optionally emitting a signal when price crosses the line. The two anchors are picked by boolean masks wired into the A and B handles.
Parameters
- Basis
- Update Mode
- Extend
- Cross Signal
- A
A boolean mask marking the bar to capture as the first anchor. The anchor's value is the basis price on that bar.
- B
A boolean mask marking the bar to capture as the second anchor. A line is drawn only once both anchors exist and B is on a later bar than A.
Outputs
- signal — Signal. Activates on bars where the basis price crosses the line in the configured Cross Signal direction. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The trendline value at each bar (NaN until a line exists), drawn as a price overlay. Any input that accepts a Series receives this line.
Formulas
slope = (B value - A value) / (B bar - A bar) line[t] = A value + slope * (t - A bar)
Cross Up: signal[t] = 1 when basis[t] > line[t] AND basis[t-1] <= line[t-1] Cross Down: signal[t] = 1 when basis[t] < line[t] AND basis[t-1] >= line[t-1]
Aroon
The Aroon node measures how recently price made a new high or low within a lookback window. It produces an Aroon Up line, an Aroon Down line, and their difference (the oscillator), and emits a signal from the relationship between the two lines.
Parameters
- Period
Lookback in bars. Aroon Up reads 100 when the highest high is the current bar and decays toward 0 as that high recedes over the period; Aroon Down does the same for the lowest low.
- Direction
- Trigger
Aroon has no data_in handle: it is defined directly on the bars since the highest high and lowest low of the strategy's ticker.
Outputs
- signal — Signal. Activates on bars where the configured Direction and Trigger condition holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The Aroon Up, Aroon Down, and oscillator lines on a 0 to 100 (oscillator -100 to 100) scale, drawn as a sub-panel. Any input that accepts a Series receives the Aroon Up line; aroon_up, aroon_down, and oscillator are each available by name on the output handle.
Formulas
Aroon Up = 100 * (period - bars since highest high) / period Aroon Down = 100 * (period - bars since lowest low) / period Oscillator = Aroon Up - Aroon Down
Bullish: signal[t] = 1 when Up[t] > Down[t] AND Up[t-1] <= Down[t-1] Bearish: signal[t] = 1 when Down[t] > Up[t] AND Down[t-1] <= Up[t-1]
Bullish: signal[t] = 1 while Up[t] > Down[t] Bearish: signal[t] = 1 while Down[t] > Up[t]
RSI
The RSI node computes the Relative Strength Index, a momentum oscillator bounded between 0 and 100 that weighs the size of recent gains against recent losses. It emits a signal from overbought and oversold threshold conditions, with a choice of edge-triggered or sustained activation.
Parameters
- Period
Lookback in bars for the average gain and average loss that feed the index. Shorter periods produce a faster, noisier oscillator; longer periods produce a smoother one.
- Oversold
The lower threshold. Must stay below Overbought; the editor keeps the two values ordered. Drives the bullish condition.
- Overbought
The upper threshold. Must stay above Oversold; the editor keeps the two values ordered. Drives the bearish condition.
- Direction
- Trigger
- data_in
If connected, RSI is computed on the connected series. If unconnected, it is computed on the close price of the strategy's ticker.
Outputs
- signal — Signal. Activates on bars where the configured Direction and Trigger condition holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The RSI line on a 0 to 100 scale, drawn as a sub-panel oscillator. Any input that accepts a Series receives this line.
Formulas
RS = average gain / average loss over the period RSI = 100 - (100 / (1 + RS))
First average = simple mean of the first N gains (or losses) Then: average[t] = (average[t-1] * (N - 1) + current[t]) / N
signal[t] = 1 when RSI[t] >= oversold AND RSI[t-1] < oversold, else 0
signal[t] = 1 when RSI[t] <= overbought AND RSI[t-1] > overbought, else 0
Bullish: signal[t] = 1 while RSI[t] < oversold Bearish: signal[t] = 1 while RSI[t] > overbought
MACD
The MACD node computes Moving Average Convergence Divergence, a momentum indicator built from the gap between a fast and a slow EMA of price. It emits a signal from the MACD line crossing its signal line, with a choice of edge-triggered or sustained activation.
Parameters
- Fast Period
Lookback in bars for the faster EMA. Must be shorter than Slow Period.
- Slow Period
Lookback in bars for the slower EMA. The MACD line is the fast EMA minus this slow EMA.
- Signal Period
Lookback for the EMA of the MACD line that forms the signal line.
- Direction
- Trigger
- data_in
If connected, MACD is computed on the connected series. If unconnected, it is computed on the close price of the strategy's ticker.
Outputs
- signal — Signal. Activates on bars where the configured Direction and Trigger condition holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The MACD line, signal line, and histogram are drawn as a sub-panel. Any input that accepts a Series receives the MACD line.
Formulas
MACD line = EMA(close, fast) - EMA(close, slow) Signal line = EMA(MACD line, signal period) Histogram = MACD line - Signal line
signal[t] = 1 when MACD[t] > Signal[t] AND MACD[t-1] <= Signal[t-1], else 0
signal[t] = 1 when MACD[t] < Signal[t] AND MACD[t-1] >= Signal[t-1], else 0
Bullish: signal[t] = 1 while MACD[t] > Signal[t] Bearish: signal[t] = 1 while MACD[t] < Signal[t]
Stochastic
The Stochastic node computes the Stochastic Oscillator, a momentum measure bounded between 0 and 100 that locates the close within its recent high-low range. It produces a smoothed %K line and a %D signal line, and emits a signal from %K/%D crossovers that occur inside the overbought or oversold zone.
Parameters
- %K Period
Lookback in bars for the highest high and lowest low that define the range. Shorter periods produce a faster, noisier oscillator.
- Slowing
Smoothing applied to the raw %K to form the slow %K line. A value of 1 leaves the raw %K unsmoothed.
- %D Period
Smoothing applied to the slow %K to form the %D signal line. A value of 1 makes %D equal to %K.
- Oversold
The lower threshold. Must stay below Overbought. Drives the bullish condition.
- Overbought
The upper threshold. Must stay above Oversold. Drives the bearish condition.
- Direction
- data_in
If connected, the connected series replaces the close used in the calculation; the high and low still come from the strategy's ticker. If unconnected, the ticker's high, low, and close are used.
Outputs
- signal — Signal. Activates on bars where the configured Direction crossover occurs inside the matching zone. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The %K and %D lines on a 0 to 100 scale, drawn as a sub-panel oscillator. Any input that accepts a Series receives the %K line.
Formulas
fast %K = 100 * (close - lowest low) / (highest high - lowest low) over the %K period
%K = simple moving average of fast %K over Slowing %D = simple moving average of %K over the %D period
signal[t] = 1 when %K[t] > %D[t] AND %K[t-1] <= %D[t-1] AND %D[t] < oversold, else 0
signal[t] = 1 when %K[t] < %D[t] AND %K[t-1] >= %D[t-1] AND %D[t] > overbought, else 0
CCI
The CCI node computes the Commodity Channel Index, an unbounded momentum oscillator that measures the typical price's distance from its moving average in units of mean deviation. It emits a signal from overbought and oversold threshold conditions, with a choice of edge-triggered or sustained activation.
Parameters
- Period
Lookback in bars for the moving average of typical price and the mean deviation. Shorter periods produce a faster, noisier oscillator.
- Constant
The scaling factor in the denominator. The conventional 0.015 places roughly 70 to 80 percent of values within the plus or minus 100 band; a smaller constant widens the range of values, a larger one compresses it.
- Oversold
The lower threshold. Must stay below Overbought. Drives the bullish condition.
- Overbought
The upper threshold. Must stay above Oversold. Drives the bearish condition.
- Direction
- Trigger
- data_in
If connected, CCI is computed on the connected series in place of typical price. If unconnected, typical price (the average of high, low, and close) of the strategy's ticker is used.
Outputs
- signal — Signal. Activates on bars where the configured Direction and Trigger condition holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The CCI line, drawn as a sub-panel oscillator. Any input that accepts a Series receives this line.
Formulas
typical price = (high + low + close) / 3 CCI = (typical price - SMA of typical price) / (constant * mean deviation)
mean of |typical price - SMA of typical price| over the period
signal[t] = 1 when CCI[t] > oversold AND CCI[t-1] <= oversold, else 0
signal[t] = 1 when CCI[t] < overbought AND CCI[t-1] >= overbought, else 0
Bullish: signal[t] = 1 while CCI[t] <= oversold Bearish: signal[t] = 1 while CCI[t] >= overbought
Williams %R
The Williams %R node computes Williams Percent Range, a momentum oscillator on an inverted 0 to -100 scale that locates the close within its recent high-low range. A value near 0 sits at the top of the range and a value near -100 at the bottom. It emits a signal from overbought and oversold threshold conditions, with a choice of edge-triggered or sustained activation.
Parameters
- Period
Lookback in bars for the highest high and lowest low that define the range. Shorter periods produce a faster, noisier oscillator.
- Oversold
The lower threshold on the inverted scale. Must stay below Overbought. Drives the bullish condition.
- Overbought
The upper threshold on the inverted scale. Must stay above Oversold. Drives the bearish condition.
- Direction
- Trigger
Outputs
- signal — Signal. Activates on bars where the configured Direction and Trigger condition holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The %R line on a 0 to -100 scale, drawn as a sub-panel oscillator. Any input that accepts a Series receives this line.
Formulas
%R = (highest high - close) / (highest high - lowest low) * -100 over the period
signal[t] = 1 when %R[t] > oversold AND %R[t-1] <= oversold, else 0
signal[t] = 1 when %R[t] < overbought AND %R[t-1] >= overbought, else 0
Bullish: signal[t] = 1 while %R[t] < oversold Bearish: signal[t] = 1 while %R[t] > overbought
Stochastic RSI
The Stochastic RSI node applies the Stochastic Oscillator formula to RSI values rather than price, producing a faster, more sensitive momentum measure bounded between 0 and 100. It produces a smoothed %K line and a %D signal line, and emits a signal from %K/%D crossovers inside the overbought or oversold zone, or from sustained zone occupancy.
Parameters
- RSI Length
Lookback in bars for the underlying RSI that the Stochastic formula is applied to.
- Stochastic Length
Lookback in bars for the highest and lowest RSI used to normalize RSI into the 0 to 100 range.
- %K Smoothing
Smoothing applied to the raw Stochastic RSI to form the %K line. A value of 1 leaves the raw line unsmoothed.
- %D Smoothing
Smoothing applied to %K to form the %D signal line. A value of 1 makes %D equal to %K.
- Oversold
The lower threshold. Must stay below Overbought. Drives the bullish condition.
- Overbought
The upper threshold. Must stay above Oversold. Drives the bearish condition.
- Direction
- Trigger
- data_in
If connected, the underlying RSI is computed on the connected series. If unconnected, it is computed on the close price of the strategy's ticker.
Outputs
- signal — Signal. Activates on bars where the configured Direction and Trigger condition holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The %K and %D lines on a 0 to 100 scale, drawn as a sub-panel oscillator. Any input that accepts a Series receives the %K line.
Formulas
RSI = Relative Strength Index over RSI Length (Wilder's smoothing) raw = 100 * (RSI - lowest RSI) / (highest RSI - lowest RSI) over Stochastic Length
%K = simple moving average of raw over %K Smoothing %D = simple moving average of %K over %D Smoothing
signal[t] = 1 when %K[t] > %D[t] AND %K[t-1] <= %D[t-1] AND %K[t] < oversold, else 0
signal[t] = 1 when %K[t] < %D[t] AND %K[t-1] >= %D[t-1] AND %K[t] > overbought, else 0
Bullish: signal[t] = 1 while %K[t] < oversold Bearish: signal[t] = 1 while %K[t] > overbought
Bollinger Bands
The Bollinger Bands node computes a simple moving average and two bands set a number of standard deviations above and below it. It emits a signal from price breaking through the selected band.
Parameters
- Period
Lookback in bars for both the moving average and the standard deviation.
- StdDev Up
Standard-deviation multiplier for the upper band. Larger values push the upper band further from the average.
- StdDev Down
Standard-deviation multiplier for the lower band. Larger values push the lower band further from the average.
- Band Side
- Trigger
- Direction
- data_in
If connected, the bands are computed on the connected series. If unconnected, computed on the close price of the strategy's ticker.
Outputs
- signal — Signal. Activates per the Trigger and Band Side selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The three bands drawn as price overlays. The upper, middle, and lower lines are each available by name on the output handle.
Formulas
middle = SMA(source, period) upper = middle + StdDev Up * stdev(source, period) lower = middle - StdDev Down * stdev(source, period) where stdev is the population standard deviation (divides by N)
Upper side: signal[t] = 1 when source[t] > upper[t] AND source[t-1] <= upper[t-1] Lower side: signal[t] = 1 when source[t] < lower[t] AND source[t-1] >= lower[t-1]
Upper side: signal[t] = 1 while source[t] > upper[t] Lower side: signal[t] = 1 while source[t] < lower[t]
Donchian Channels
The Donchian Channels node plots the highest high and lowest low over a lookback window with a midline between them. It emits a signal from price breaking the prior bar's channel.
Parameters
- Period
Lookback in bars for the highest high and lowest low.
- Band Side
- Trigger
- Direction
- data_in
If connected, the channels are the rolling max and min of the connected series and signals compare that series to its own channels. If unconnected, the upper channel is the highest High, the lower channel the lowest Low, and the close is compared against them.
Outputs
- signal — Signal. Activates per the Trigger and Band Side selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The three channel lines drawn as price overlays. The upper, middle, and lower lines are each available by name on the output handle.
Formulas
upper = highest High over the period lower = lowest Low over the period middle = (upper + lower) / 2
signal[t] = 1 when close[t] > upper[t-1] AND close[t-1] <= upper[t-2] The channel is compared one bar back because the current bar's high/low are inside the current channel.
Keltner Channels
The Keltner Channels node plots an EMA centerline with bands set a multiple of the Average True Range above and below it. It emits a signal from price breaking through the selected band.
Parameters
- EMA Period
Lookback in bars for the EMA centerline.
- ATR Period
Wilder smoothing length for the Average True Range that sets the band width. Kept separate from the EMA period.
- Multiplier
The number of ATRs each band sits away from the centerline. Larger values widen the channel.
- Band Side
- Trigger
- Direction
- data_in
If connected, the connected series replaces the close for the EMA centerline. The ATR always uses the ticker's High, Low, and Close. If unconnected, the centerline uses the close price.
Outputs
- signal — Signal. Activates per the Trigger and Band Side selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The three channel lines drawn as price overlays. The upper, middle, and lower lines are each available by name on the output handle.
Formulas
middle = EMA(source, EMA period) upper = middle + Multiplier * ATR(ATR period) lower = middle - Multiplier * ATR(ATR period) where ATR is Wilder's average true range
signal[t] = 1 when close[t] > upper[t] AND close[t-1] <= upper[t-1]
ATR (Average True Range)
The ATR node measures the average size of each bar's range. Its output line is the ATR scaled by a multiplier, and it emits a signal from that value relative to a threshold.
Parameters
- Period
Lookback in bars for the smoothing applied to True Range.
- Multiplier
Scale factor applied to the smoothed ATR. The output line and the threshold comparison both use this scaled value.
- Smoothing
- Threshold
The level the scaled ATR is compared against to produce the signal.
- Trigger
- Direction
- data_in
If connected, the connected series replaces the close in the True Range calculation. The High and Low always come from the ticker. If unconnected, the ticker's High, Low, and Close are used.
Outputs
- signal — Signal. Activates per the Direction and Trigger against the threshold. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The scaled ATR (ATR times Multiplier), drawn on its own subchart. Downstream Series inputs (such as Stop Loss or Risk Per Trade) consume this value directly.
Formulas
TR[t] = max(high[t] - low[t], |high[t] - close[t-1]|, |low[t] - close[t-1]|)
values[t] = Multiplier * smoothing(TR, period)
Bullish: signal[t] = 1 when values[t] > threshold AND values[t-1] <= threshold Bearish: signal[t] = 1 when values[t] < threshold AND values[t-1] >= threshold
Volatility Regime
The Volatility Regime node classifies a connected volatility measure into a regime score and emits a signal when the score falls in the selected regime. It does not compute volatility itself; it reads a measure wired into its input.
Parameters
- Lookback Period
Rolling window used to rank or average the input when scoring the current bar.
- Threshold Method
- High Threshold
Upper regime cutoff, interpreted per the Threshold Method.
- Low Threshold
Lower regime cutoff, interpreted per the Threshold Method.
- Vol Mode
- data_in
The volatility measure to classify, such as an ATR line, Bollinger band width, or any numeric series. With nothing connected, the node produces no signal.
Outputs
- signal — Signal. Activates on bars matching the selected Vol Mode. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The regime score, drawn on its own subchart.
Formulas
Percentile: score[t] = percentile rank of input[t] within the last (lookback) values, times 100 Mean: score[t] = input[t] / rolling mean of input over (lookback) Fixed: score[t] = input[t]
High Vol: signal[t] = 1 while score[t] >= High Threshold Low Vol: signal[t] = 1 while score[t] <= Low Threshold Expansion: signal[t] = 1 while score[t] > score[t-1] Contraction: signal[t] = 1 while score[t] < score[t-1] Extreme: signal[t] = 1 while score[t] >= High Threshold OR score[t] <= Low Threshold
Pivot Points
The Pivot Points node computes support and resistance levels from a prior period's open, high, low, and close, holding them constant across the current period. It emits a signal from price relative to one selected level.
Parameters
- Method
- Timeframe
- Level
Which computed level drives the signal. The available levels depend on the Method (for example P, R1 through R3 and S1 through S3 for Traditional; P, TC, BC for CPR).
- Trigger
- Direction
- Pivot Levels
How many R/S pairs to compute and plot. Clamped to the maximum the Method supports.
- Rounding
Decimal places the computed level values are rounded to.
Outputs
- signal — Signal. Activates per the Level, Direction, and Trigger selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The computed level lines drawn as price overlays. Each level (P, R1, S1, TC, BC, and so on for the Method) is available by name on the output handle.
Formulas
P = (high + low + close) / 3 (from the prior period) R1 = 2*P - low S1 = 2*P - high R2 = P + (high - low) S2 = P - (high - low) R3 = P + 2*(high - low) S3 = P - 2*(high - low)
Bullish: signal[t] = 1 when close[t] > level[t] AND close[t-1] <= level[t-1] Bearish: signal[t] = 1 when close[t] < level[t] AND close[t-1] >= level[t-1]
Support & Resistance
The Support & Resistance node detects price levels that have been touched repeatedly, ranks them by how many times price bounced off them, and emits a signal from price interacting with the strongest levels.
Parameters
- Trigger Type
- Min Bounces
Minimum number of separate touches a price level needs before it is kept as a level.
- Bounce Tolerance
How close, as a percent of the level price, a bar must come to count as a touch of that level.
- Lookback Period
Window of recent bars searched for the pivot highs and lows that seed candidate levels.
- Levels
Maximum number of levels to keep, taken in order of strength.
- Level Strength Threshold
Minimum strength (bounce count) a level must reach to be kept.
- Rounding
Decimal places the level prices are rounded to.
Outputs
- signal — Signal. Activates per the Trigger Type; Level Detection never activates. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The kept level lines drawn as price overlays, ordered by strength (level_1, level_2, and so on), each available by name on the output handle.
Formulas
strength = number of separate touches within Bounce Tolerance of the level A touch counts separately from the previous one once enough bars have passed between them. Levels are kept when strength >= Min Bounces and strength >= Level Strength Threshold, then ranked by strength.
Resistance level: signal[t] = 1 when close[t] > level AND close[t-1] <= level Support level: signal[t] = 1 when close[t] < level AND close[t-1] >= level
Swing Pivots
The Swing Pivots node detects swing highs and lows, where a bar's high or low is the most extreme within a window on both sides. It emits a signal once each pivot is confirmed.
Parameters
- Mode
- Window
Number of bars on each side of a pivot that must be lower (for a swing high) or higher (for a swing low) than the pivot bar.
- Confirm Bars
Extra bars to wait after the window closes before the pivot is confirmed. Added to the window delay so the signal carries no look-ahead.
Outputs
- signal — Signal. Activates on the bar a pivot is confirmed (Window plus Confirm Bars after the pivot bar). Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The confirmed pivot price, carried on the confirmation bar.
Formulas
Swing high at bar i: high[i] is strictly greater than every high within Window bars on each side Swing low at bar i: low[i] is strictly lower than every low within Window bars on each side
signal fires at bar i + Window + Confirm Bars, the earliest bar at which the pivot is known without using future data
ZigZag
The ZigZag node connects significant swing turns, filtering out moves smaller than a threshold. It draws a line between confirmed turns and emits a signal on the bar each turn is confirmed.
Parameters
- Threshold Mode
- Threshold Value
The size of move required to confirm a reversal: a percent in Percent mode, or an ATR multiplier in ATR mode.
- ATR Period
Lookback for the ATR used as the threshold in ATR mode. Ignored in Percent mode.
- Pivot Source
- Mode
Outputs
- signal — Signal. Activates on the bar a turn is confirmed (when price has reversed past the threshold), not on the pivot bar itself, so it carries no look-ahead. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The ZigZag line, interpolated between confirmed turns, drawn as a price overlay.
Formulas
Percent: threshold[t] = close[t] * Threshold Value / 100 ATR: threshold[t] = Threshold Value * ATR(ATR Period)
After a swing high, a low turn is confirmed once price rises from the running low by at least the threshold; after a swing low, a high turn is confirmed once price falls from the running high by at least the threshold. The chart marks the turn at the pivot bar; the signal fires on the confirmation bar.
Volume
The Volume node exposes trading volume in raw or moving-average-smoothed form and emits a signal when that volume moves past a threshold. Its values output can also feed other nodes that accept a numeric series.
Parameters
- Volume Type
- MA Type
- Period
Lookback in bars for the volume moving average. Only used when Volume Type is Smoothed.
- Threshold
The volume level the processed series is compared against to produce the signal.
- Trigger
- Direction
- data_in
If connected, the volume series is taken from the connected input. If unconnected, the ticker's bar volume is used.
Outputs
- signal — Signal. Activates per the Trigger and Direction selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The processed volume series, raw or smoothed. Any input that accepts a Series receives this line.
Formulas
Total: volume[t] Smoothed: SMA(volume, period) or EMA(volume, period)
Bullish: signal[t] = 1 when volume[t] > threshold AND volume[t-1] <= threshold Bearish: signal[t] = 1 when volume[t] < threshold AND volume[t-1] >= threshold
Bullish: signal[t] = 1 while volume[t] > threshold Bearish: signal[t] = 1 while volume[t] < threshold
Relative Volume
The Relative Volume (RVOL) node computes the ratio of current volume to its lookback baseline and emits a signal when that ratio reaches a high- or low-activity threshold.
Parameters
- Lookback Period
Number of bars used to compute the baseline average volume.
- MA Type
- Mode
- Activity Filter
- High Threshold
RVOL level for high-activity signals. A value of 1.5 means current volume is 150% of the baseline. Must be greater than the Low Threshold.
- Low Threshold
RVOL level for low-activity signals. A value of 0.5 means current volume is 50% of the baseline.
- Trigger
- data_in
If connected, the volume series is taken from the connected input. If unconnected, the ticker's bar volume is used.
Outputs
- signal — Signal. Activates per the Activity Filter and Trigger selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. Three lines are drawn: the RVOL ratio, the baseline, and the raw volume. Any input that accepts a Series receives the RVOL ratio.
Formulas
baseline = MA(volume, lookback) (Default mode) baseline = mean of volume at the same time of day over the last `lookback` days (ToD mode) RVOL[t] = volume[t] / baseline[t]
High: signal[t] = 1 when RVOL[t] >= high AND RVOL[t-1] < high Low: signal[t] = 1 when RVOL[t] <= low AND RVOL[t-1] > low
High: signal[t] = 1 while RVOL[t] >= high Low: signal[t] = 1 while RVOL[t] <= low
OBV
The OBV (On-Balance Volume) node accumulates volume as a running total, adding it on up bars and subtracting it on down bars. It signals from the OBV line crossing its moving average, or from the OBV line's direction.
Parameters
- MA Length
Lookback in bars for the moving average of OBV. When set to 0 the moving average is disabled and the signal comes from the OBV line's direction instead of an MA cross.
- MA Type
- Direction
- data_in
If connected, the connected series replaces close for the up/down direction test; volume still comes from the ticker's bars. If unconnected, close is used.
Outputs
- signal — Signal. Activates per the MA Length and Direction selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The OBV line, plus its moving average when MA Length is greater than 0. Any input that accepts a Series receives the OBV line by default.
Formulas
OBV[t] = OBV[t-1] + volume[t] when close[t] > close[t-1] OBV[t] = OBV[t-1] - volume[t] when close[t] < close[t-1] OBV[t] = OBV[t-1] when close[t] = close[t-1] (bar 0 is seeded with the first bar's volume)
Bullish: signal[t] = 1 when OBV[t] > MA[t] AND OBV[t-1] <= MA[t-1] Bearish: signal[t] = 1 when OBV[t] < MA[t] AND OBV[t-1] >= MA[t-1]
Bullish: signal[t] = 1 when OBV[t] > OBV[t-1] Bearish: signal[t] = 1 when OBV[t] < OBV[t-1]
MFI
The MFI (Money Flow Index) node is a volume-weighted oscillator bounded between 0 and 100. It weights typical-price moves by volume and signals from the result crossing or sitting beyond the oversold and overbought levels.
Parameters
- Period
Lookback in bars for summing positive and negative money flow.
- Oversold
Lower threshold. Must be less than Overbought.
- Overbought
Upper threshold. Must be greater than Oversold.
- Trigger
- Direction
- data_in
If connected, the connected series replaces the typical price as the price component; volume still comes from the ticker's bars. If unconnected, typical price (high + low + close) / 3 is used.
Outputs
- signal — Signal. Activates per the Trigger and Direction selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The MFI line, from 0 to 100. Any input that accepts a Series receives this line.
Formulas
typical price = (high + low + close) / 3 raw money flow = typical price * volume positive flow counts bars where typical price rose; negative flow where it fell money ratio = sum(positive flow, period) / sum(negative flow, period) MFI = 100 - 100 / (1 + money ratio)
Bullish: signal[t] = 1 when MFI[t] > oversold AND MFI[t-1] <= oversold Bearish: signal[t] = 1 when MFI[t] < overbought AND MFI[t-1] >= overbought
Bullish: signal[t] = 1 while MFI[t] < oversold Bearish: signal[t] = 1 while MFI[t] > overbought
CMF
The CMF (Chaikin Money Flow) node is a volume-weighted average of where price closes within its high-low range over a lookback window. It oscillates around zero and signals from crossing a threshold buffer around the zero line.
Parameters
- Period
Lookback in bars for summing money flow volume and volume.
- Threshold
Buffer around the zero line. Signals fire at plus and minus this value instead of exactly zero. A value of 0 makes it a pure zero-line crossover.
- Trigger
- Direction
Outputs
- signal — Signal. Activates per the Trigger and Direction selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The CMF line, oscillating between -1 and +1. Any input that accepts a Series receives this line.
Formulas
money flow multiplier (MFM) = (2 * close - low - high) / (high - low) money flow volume (MFV) = MFM * volume CMF = sum(MFV, period) / sum(volume, period) (bars where high = low contribute 0 to money flow)
Bullish: signal[t] = 1 when CMF[t] > +threshold AND CMF[t-1] <= +threshold Bearish: signal[t] = 1 when CMF[t] < -threshold AND CMF[t-1] >= -threshold
Bullish: signal[t] = 1 while CMF[t] > +threshold Bearish: signal[t] = 1 while CMF[t] < -threshold
Volume Profile
The Volume Profile node aggregates volume across price levels over a rolling window and emits the Point of Control and the Value Area boundaries as price overlay lines. It signals from price crossing the selected level.
Parameters
- Lookback
Number of bars in the rolling window aggregated into the profile, recomputed each bar.
- Rows
Number of price bins the window's range is divided into. More rows give finer price granularity.
- VA %
Percentage of total window volume that defines the Value Area, expanded outward from the Point of Control.
- Signal Level
- Trigger
- Direction
Outputs
- signal — Signal. Activates per the Signal Level, Trigger, and Direction selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. Three price-overlay lines: POC, VAH, and VAL. Any input that accepts a Series receives the POC by default; the line selector on the output handle lets you pick VAH or VAL.
Formulas
For each bar in the lookback window, its volume is spread evenly across the price bins its high-low range covers. POC = the bin with the most accumulated volume. The Value Area expands outward from the POC, each step adding the adjacent bin with more volume, until VA % of total volume is captured. VAH and VAL are the upper and lower edges of that area.
level = POC, VAH, or VAL per Signal Level Bullish: signal[t] = 1 when close[t] > level[t] AND close[t-1] <= level[t-1] Bearish: signal[t] = 1 when close[t] < level[t] AND close[t-1] >= level[t-1]
Bullish: signal[t] = 1 while close[t] > level[t] Bearish: signal[t] = 1 while close[t] < level[t]
VWAP
The VWAP (Volume Weighted Average Price) node computes the volume-weighted average of typical price over an anchor window. It signals from price crossing the VWAP line, or from the VWAP line crossing its moving average.
Parameters
- Anchor
- Window
Number of trailing bars in the rolling average. Only used when Anchor is Rolling.
- MA Length
Lookback in bars for a moving average of the VWAP line. When set to 0 the moving average is disabled and the signal comes from close crossing VWAP instead of a VWAP-vs-MA cross.
- MA Type
- Direction
- data_in
If connected, the connected series replaces typical price as the price component; volume still comes from the ticker's bars. If unconnected, typical price (high + low + close) / 3 is used.
Outputs
- signal — Signal. Activates per the MA Length and Direction selection. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The VWAP line, plus its moving average when MA Length is greater than 0. Any input that accepts a Series receives the VWAP line by default.
Formulas
typical price = (high + low + close) / 3 Session: VWAP = cumulative(tp * volume) / cumulative(volume), reset each day Rolling: VWAP = sum(tp * volume, window) / sum(volume, window) Anchored: VWAP = cumulative(tp * volume) / cumulative(volume) from the start
Bullish: signal[t] = 1 when close[t] > VWAP[t] AND close[t-1] <= VWAP[t-1] Bearish: signal[t] = 1 when close[t] < VWAP[t] AND close[t-1] >= VWAP[t-1]
Bullish: signal[t] = 1 when VWAP[t] > MA[t] AND VWAP[t-1] <= MA[t-1] Bearish: signal[t] = 1 when VWAP[t] < MA[t] AND VWAP[t-1] >= MA[t-1]
Price
The Price node emits a chosen price field (or a connected series) as a numeric series for downstream nodes, with an optional backward lag. Its signal activates on any bar where the series changes from the prior bar.
Parameters
- Price Source
- Lag / Shift
Number of bars to shift the series backward, so bar t carries the value from bar t minus Lag. Negative values are rejected because they would read future bars.
Outputs
- values — Series. The selected price series after any lag. Any input that accepts a Series receives this; the chart does not draw a separate overlay for it.
- signal — Signal. Activates on bars where the series differs from the prior bar (price moved up or down). Any input that accepts a Signal reads this and reacts on bars where it's active.
Formulas
HL2[t] = (high[t] + low[t]) / 2 HLC3[t] = (high[t] + low[t] + close[t]) / 3 OHL4[t] = (open[t] + high[t] + low[t] + close[t]) / 4
VWAP[t] = sum(close[0..t] * volume[0..t]) / sum(volume[0..t])
signal[t] = 1 when source[t] != source[t-1], else 0
Candlestick
The Candlestick node detects classic candlestick patterns from the bar's OHLC shape. Its signal activates on bars where any selected pattern is detected, after the optional confirmation window.
Parameters
- Patterns
One or more patterns to detect, grouped by structure: single-bar (Doji, Hammer, Inverted Hammer, Hanging Man, Shooting Star, Marubozu, Spinning Top), two-bar (Bullish/Bearish Engulfing, Piercing, Dark Cloud Cover, Harami, Harami Cross, Inside Bar, On Neck, In Neck, Separating Lines, Homing Pigeon), three-bar (Morning Star, Evening Star, Three Inside, Three Outside, Tri-Star, Abandoned Baby, Gap Side-by-Side White), and multi-bar (Three Line Strike, Breakaway). The signal activates when any selected pattern is detected on a bar.
- Confirm Bars
Bars of confirmation required after a pattern. With 0, the signal activates on the pattern bar. With N greater than 0, a bullish pattern is confirmed only if the close N bars later breaks above the highest high of the confirmation window (a bearish pattern, below the lowest low), and the signal is placed on that confirmation bar.
- Direction
Outputs
- signal — Signal. Activates on bars where a selected pattern is detected (and confirmed). Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. Pattern strength: the count of selected patterns detected on each bar.
Behavior
- Multiple patterns — when several patterns are selected, the signal activates if any one of them is detected on the bar.
- Direction classification — each pattern carries a fixed bullish or bearish classification; Direction filters which classifications can activate, it does not re-interpret a pattern.
Formulas
body[t] = abs(close[t] - open[t]) range[t] = high[t] - low[t] doji[t] = 1 when body[t] < 0.1 * range[t], else 0
confirmed[t+N] = pattern[t] AND close[t+N] > max(high[t+1 .. t+N])
Bars
The Bars node detects price-bar patterns defined by the relationship between a bar and its neighbors (ranges, gaps, and breakouts). Its signal activates on bars where any selected pattern is detected, after the optional confirmation window.
Parameters
- Patterns
One or more patterns to detect, grouped by structure: single-bar rejection or exhaustion (Pin Bar, Hammer, Inverted Hammer, Key Reversal Bar, Wide-Range Bar, NR4, NR7), inside/outside structure (Inside Bar, Inside Bar Inside Day, Outside Bar, Engulfing Bar), and multi-bar momentum or continuation (2-Bar Breakout, Inside-Inside Bar, 1-2-3 Pullback, NR7 + Wide-Range Bar, Breakaway Gap, Runaway Gap, Climax Bar, Volume Dry-Up). The signal activates when any selected pattern is detected on a bar.
- Confirm Bars
Bars of confirmation required after a pattern. With 0, the signal activates on the pattern bar. With N greater than 0, a bullish detection is confirmed only if the close N bars later breaks above the highest high of the confirmation window (a bearish detection, below the lowest low), and the signal is placed on that confirmation bar.
- Direction
Outputs
- signal — Signal. Activates on bars where a selected pattern is detected (and confirmed). Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. Pattern strength: the count of selected patterns detected on each bar.
Behavior
- Multiple patterns — when several patterns are selected, the signal activates if any one of them is detected on the bar.
- Direction classification — Hammer, Breakaway Gap, and Runaway Gap are bullish-only; Inverted Hammer is bearish-only; every other pattern activates in both directions.
Formulas
insideBar[t] = 1 when high[t] < high[t-1] AND low[t] > low[t-1], else 0
range[t] = high[t] - low[t] nr7[t] = 1 when range[t] == min(range[t-6 .. t]), else 0
Heikin Ashi
The Heikin Ashi node computes smoothed Heikin Ashi candles from the raw OHLC using a recursive formula, and activates a signal from the candle color (bullish when HA close is above HA open, bearish when below).
Parameters
- Direction
- Trigger
Outputs
- signal — Signal. Activates per Direction and Trigger. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The four Heikin Ashi lines (ha_open, ha_high, ha_low, ha_close). The chart draws them as a price overlay; an input that accepts a Series receives ha_close by default, and the line selector on the output handle picks any of the four.
Formulas
HA_Close[t] = (open[t] + high[t] + low[t] + close[t]) / 4 HA_Open[t] = (HA_Open[t-1] + HA_Close[t-1]) / 2 HA_High[t] = max(high[t], HA_Open[t], HA_Close[t]) HA_Low[t] = min(low[t], HA_Open[t], HA_Close[t]) First bar: HA_Open[0] = (open[0] + close[0]) / 2
State: signal[t] = 1 when HA_Close[t] > HA_Open[t] Cross: signal[t] = 1 when HA_Close[t] > HA_Open[t] AND HA_Close[t-1] < HA_Open[t-1]
Dividend
The Dividend node detects cash dividend payments on the strategy's stock, using the ex-dividend date from the data provider. Its signal activates on the ex-dividend bar, shiftable by an offset, and its values output carries the cash amount paid per share on the active bar. Stock only; crypto symbols carry no dividend data.
Parameters
- Direction
- Offset
Number of days between the ex-dividend date and the active bar. 0 activates on the ex-dividend bar itself, regardless of Direction. The ex-dividend date, and any offset target, each map to the first trading bar on or after that date.
Outputs
- signal — Signal. Activates on the bar matching the ex-dividend date shifted by the offset. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The dividend amount per share on the active (shifted) bar, 0 on every other bar. Any input that accepts a Series receives this.
Formulas
target[k] = ex_dividend_date[k] + Offset (Offset is negative for Days Before) signal[t] = 1 on the first bar with date >= target[k], else 0 values[t] = dividend_amount[k] on that active bar, else 0
Earnings Event
The Earnings Event node marks each fiscal reporting period for the strategy's stock, using the company's quarter-end date from the data provider. It keys off the fiscal quarter-end (the reporting period close), not the earnings announcement date, which the provider does not supply; a positive offset shifts the signal toward the usual announcement window a few weeks later. Stock only.
Parameters
- Direction
- Offset
Number of days between the quarter-end and the active bar. 0 activates on the quarter-end bar itself, regardless of Direction. The quarter-end, and any offset target, each map to the first trading bar on or after that date.
Outputs
- signal — Signal. Activates on the bar matching the quarter-end shifted by the offset. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. 1.0 on active bars, 0.0 on every other bar.
Formulas
target[k] = quarter_end[k] + Offset (Offset is negative for Days Before) signal[t] = 1 on the first bar with date >= target[k], else 0
Split Event
The Split Event node detects stock split events on the strategy's stock and can filter them by direction. Its signal activates on the split's effective bar, and its values output carries the split ratio. Stock only; crypto symbols carry no split data.
Parameters
- Split Type
Outputs
- signal — Signal. Activates on the effective bar of a split that passes the Split Type filter. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The split ratio on active bars (2.0 for a 2:1 forward split, 0.5 for a 1:2 reverse split), 1.0 on every other bar.
Formulas
ratio[t] = split factor on the split bar, else 1.0 All Splits: signal[t] = 1 when ratio[t] != 1.0 Forward: signal[t] = 1 when ratio[t] >= 2.0 Reverse: signal[t] = 1 when ratio[t] <= 0.5
Buy
The Buy node places a buy order on bars where its incoming signal is active.
Parameters
- Direction
- Amount Type
- Amount Value
The number consumed by the Amount Type formula. Percentage types accept 0.1 to 100. Dollar and share types accept any positive number.
- Order Type
- Limit Price, Stop Price, Trail Type, Trail Value
Each is required only when the chosen Order Type uses it. The node configuration panel shows and hides these fields as Order Type changes.
Inputs
- in0 — Signal. Accepts one wire from a Signal-emitting source.
Outputs
- signal — Signal. Activates on bars where the input signal is active. When activated, the strategy engine places the trade per the node's sizing and order configuration.
Signal timing
A trade fills at the next bar's open price, not the bar where the signal activates. Signals that activate on the last bar of the data range are dropped because there is no next bar to fill on. This matches real exchange behavior: an order placed after a bar closes can only fill at the next available open.
Chain aggregation
When multiple Buy signals activate on the same ticker without an intervening Sell, the engine merges them into a single position record. The combined quantity, total cost, and weighted-average entry price are tracked together. The position stays open until a Sell closes it, at which point realized profit and loss is computed against the aggregate entry.
Sell
The Sell node places a sell order on bars where its incoming signal is active.
Parameters
- Direction
- Amount Type
- Amount Value
The number consumed by the Amount Type formula. Percentage types accept 0.1 to 100. Dollar and share types accept any positive number.
- Order Type
- Limit Price, Stop Price, Trail Type, Trail Value
Each is required only when the chosen Order Type uses it. The node configuration panel shows and hides these fields as Order Type changes.
Inputs
- in0 — Signal. Accepts one wire from a Signal-emitting source.
Outputs
- signal — Signal. Activates on bars where the input signal is active. When activated, the strategy engine places the trade per the node's sizing and order configuration.
Signal timing
A trade fills at the next bar's open price, not the bar where the signal activates. Signals that activate on the last bar of the data range are dropped because there is no next bar to fill on. This matches real exchange behavior: an order placed after a bar closes can only fill at the next available open. If an Exit Long signal activates while the strategy's minimum holding period has not yet elapsed, the engine waits until the minimum is met before exiting.
Aggregate exit
If a long position has been built up via multiple chained Buy signals, a single Exit Long Sell at % of Position equal to 100 closes the entire aggregated position in one trade record. Realized profit and loss is computed against the weighted-average entry price across the full chain.
Wait
The Wait node gates its incoming signal by a timing rule and emits a Signal to downstream nodes. It either delays activation by a fixed number of bars or latches active once its input first becomes active.
Parameters
- Wait Type
- Periods
The number of bars N that the output stays inactive before activating. The node configuration panel shows this field only when Wait Type is Fixed Periods.
Inputs
- in0 — Signal. Accepts one wire from a Signal-emitting source. Read only in Until Input True mode; ignored in Fixed Periods mode.
Outputs
- signal — Signal. In Fixed Periods mode it activates on the bar at index N (the bars before it are inactive) and stays active through the end of the range. In Until Input True mode it activates on the first bar where the input is active and stays active afterward.
And
The And node combines its signal inputs and activates only on bars where every input is active at once. It has no parameters.
Inputs
- in0, in1
Two input handles, each accepting a Signal from another node. The node reads the active state of both on every bar.
Outputs
- signal — Signal. Activates on bars where both inputs are active, and is inactive on any bar where either input is inactive. Any input that accepts a Signal reads this and reacts on bars where it's active.
Formula
signal[t] = 1 when in0[t] = 1 AND in1[t] = 1, else 0
Or
The Or node combines its signal inputs and activates on bars where at least one input is active. It has no parameters.
Inputs
- in0, in1
Two input handles, each accepting a Signal from another node. The node reads the active state of both on every bar. A single wired input passes through unchanged.
Outputs
- signal — Signal. Activates on bars where either input is active, and is inactive only on bars where every input is inactive. Any input that accepts a Signal reads this and reacts on bars where it's active.
Formula
signal[t] = 1 when in0[t] = 1 OR in1[t] = 1, else 0
Split
The Split node is a fan-out: it takes one input and passes it through to two outputs unchanged, so two downstream nodes can consume the same payload independently. It has no parameters.
Inputs
- in0
A single input handle. It accepts whatever the connected source emits, a Signal or a Series, and carries that payload through without modifying it.
Outputs
- out0, out1 — the input payload, duplicated. Both outputs carry the same data as the input, unchanged. A downstream node reading a Signal sees it active on the same bars the input was active; a downstream node reading a Series receives the identical series. The two outputs are independent connection points for the one payload.
Relation
The Relation node compares two numeric inputs with a relational operator. Its signal activates on bars where the comparison holds.
Parameters
- Relation
Inputs
- in0 (A), in1 (B)
A is the left operand and B is the right operand of the comparison. Both must be wired. On any bar where either value is missing, the comparison is inactive.
Outputs
- signal — Signal. Activates on bars where the configured comparison between A and B holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
Formula
signal[t] = 1 when A[t] op B[t], else 0 where op is one of >, <, >=, <=, ==, !=
Sequence
The Sequence node detects an ordered pair of conditions. Its signal activates on bars where input B is active and input A was active within the last Candles bars, counting the current bar.
Parameters
- Candles
The length of the lookback window in bars. A counts as having occurred if it was active on any bar in the window ending at, and including, the current bar. With Candles set to 1, A and B must be active on the same bar.
Inputs
- in0 (A), in1 (B)
A is the trigger condition and B is the confirmation condition. Both must be wired. The node reads the active state of each on every bar.
Outputs
- signal — Signal. Activates on bars where B is active and A was active somewhere in the trailing Candles-bar window. Any input that accepts a Signal reads this and reacts on bars where it's active.
Formula
signal[t] = 1 when B[t] = 1 AND A was active on any bar in [t - Candles + 1, t], else 0
Transform
The Transform node applies one mathematical transformation to a numeric series. Transform Type selects the transformation; Period and a set of per-type parameters configure it.
Parameters
- Transform Type
- Period
The lookback window in bars. Used by SMA, EMA, WMA, Delta, Percent, ROC, Rolling Max, Rolling Min, Rolling Std, Z-Score, and Linear Regression.
- Alpha
The smoothing factor for EMA. When set, it overrides Period and the EMA weights the current bar by Alpha and the prior EMA by one minus Alpha. When left unset, EMA derives its smoothing from Period.
- Weight Scheme
- Custom Weights
A comma-separated list of weights, one per bar in the window. The list length must equal Period. The weights are normalized to sum to 1 before being applied.
- Offset
Shifts the series back by Offset bars before the rolling window is applied, so the aggregate covers bars ending Offset bars before the current one.
- Ddof
Delta degrees of freedom for the standard deviation. A value of 1 gives the sample standard deviation; 0 gives the population standard deviation.
- Multiplier
Scales the z-score before it is clipped to the range minus 10 to 10.
- Method
- Reset Window
The running total restarts every Reset Window bars. A value of 0 means the total never resets and accumulates over the whole series.
- Bars
The number of bars to shift the series. A positive value looks back, so the output at the current bar is the input from Bars bars earlier.
- Allow Negative
When true, Bars may be negative, shifting the series forward. When false, a negative Bars value is rejected.
- in0
If connected, the transform runs on the connected series. If unconnected, it runs on the close price of the strategy's ticker.
Outputs
- values — Series. The transformed series. The chart draws it as an overlay, and any input that accepts a Series receives it.
- signal — Signal. Activates on bars where the transform has produced a valid number, that is, once the lookback window has filled. Any input that accepts a Signal reads this and reacts on bars where it's active.
Formulas
SMA at bar t = (x[t-N+1] + x[t-N+2] + ... + x[t]) / N
alpha = 2 / (N + 1) EMA at bar t = alpha * x[t] + (1 - alpha) * EMA[t-1]
Delta at bar t = x[t] - x[t-N] Percent at bar t = (x[t] - x[t-N]) / x[t-N] * 100
z[t] = Multiplier * (x[t] - mean(x, N)[t]) / std(x, N, Ddof)[t] clipped to the range -10 to 10
Math
The Math node evaluates a free-text formula over its wired inputs and emits the result as a series. The formula references each input as input1 through input5 and may use a built-in library of math functions and constants.
Parameters
- Formula
The expression evaluated on every bar. It references inputs by name (input1 through input5), the arithmetic operators below, the function library, and the constants pi and e. Every input referenced in the formula must be wired, or the node reports an error.
- Input Count
How many input handles the node exposes. The handles map in order to input1 through input5 in the formula.
Inputs
- in0 through in4
One handle per input, mapped in order to input1 through input5 in the formula. The number of handles shown is set by Input Count.
Function library
The formula accepts these operators and functions, applied per bar:
- Operators
Addition, subtraction, multiplication, division, exponent, and modulo.
- Arithmetic
Rounding, sign, and remainder helpers.
- Exponential and logarithmic
Powers, roots, and logarithms. log is the natural logarithm.
- Trigonometric and hyperbolic
Angle functions and their inverses and hyperbolic forms.
- Comparison and selection
max and min take two operands per bar; clip(x, low, high) bounds a value; where(condition, a, b) selects a when the condition holds, otherwise b.
- Statistical
Reductions across a series.
- Constants and checks
Mathematical constants and validity checks.
Outputs
- values — Series. The result of the formula evaluated on each bar. The chart draws it as an overlay, and any input that accepts a Series receives it.
- signal — Signal. Activates on bars where the formula produces a valid number. Any input that accepts a Signal reads this and reacts on bars where it's active.
Numeric Value
The Numeric Value node emits a number as a series. In Value mode it emits a constant; in Percent mode it emits a percentage of a chosen source.
Parameters
- Value
In Value mode, the constant emitted on every bar. In Percent mode, the percentage applied to the selected source.
- Mode
- Percent Source
Inputs
- in0
Used only when Mode is Percent and Percent Source is Input. The node emits Value percent of this series. Ignored in all other configurations.
Outputs
- values — Series. The constant or computed number on each bar. Any input that accepts a Series receives it; a common use is the threshold operand of a Relation.
- signal — Signal. Active on bars where a valid value is present. Any input that accepts a Signal reads this and reacts on bars where it's active.
Capture
The Capture node stores the value of a data series on the bars a mask activates and holds that value until the next capture. The held value becomes available on the bar after the capture bar.
Parameters
- Mode
- Initial value
The value held before the first capture occurs. When left empty, no value is held until the first capture, and the output signal stays inactive until then.
- A
The mask. The node captures the data value on bars where this signal is active.
- data_in
The series whose value is captured. If unconnected, the close price of the strategy's ticker is captured.
Outputs
- signal — Signal. Active on every bar from the first captured value onward, while a value is being held. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The held value. Any input that accepts a Series receives the most recent captured value, carried forward until the next capture.
Availability
A captured value becomes available on the bar after the capture bar, not on the capture bar itself. Downstream nodes therefore read the value of the series as it was when the mask last activated, never the current bar's value at the moment of capture.
Schedule
The Schedule node activates its signal on bars that fall at a specific time of day (event mode) or inside a time-of-day window (range mode), restricted to the selected days of the week. Bar timestamps are converted to the configured timezone before matching.
Parameters
- Mode
- Timezone
The timezone the trigger and window times are interpreted in. Each bar's timestamp is converted to this zone before its time of day is matched.
- Days of week
The weekdays on which the signal may activate. Bars on unselected days never activate.
- Anchor time
- Manual time
The trigger time of day, used when Anchor time is Manual.
- Offset
Minutes added to (sign +) or subtracted from (sign −) the anchor time to produce the final trigger time.
- Start / End
The window bounds. Each is an anchor (market open, market close, or manual), a manual time, and a signed minute offset, resolved the same way as the event-mode trigger. A window whose start is later than its end wraps across midnight.
Outputs
- signal — Signal. Active on bars whose day of week is enabled and whose time of day matches the trigger (event mode) or falls inside the window (range mode). Any input that accepts a Signal reads this and reacts on bars where it's active.
Stop Loss
The Stop Loss node computes a stop price level a configurable distance from a reference price and activates its signal on the bar price crosses that level. It outputs the level and the cross signal; it does not place trades.
Parameters
- Stop type
- Stop value
The distance, in the unit set by Stop type: a percent for Percentage, a price amount for Fixed, an ATR multiple for ATR.
- ATR period
Lookback in bars for the Average True Range. Used only when Stop type is ATR.
- Direction
- data_in
The reference price the level is measured from, typically a captured entry price. If unconnected, the close price is used.
Outputs
- signal — Signal. Active on the bar price crosses the stop level. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The stop price level per bar. The chart draws this as a price overlay.
Formulas
Percentage: level = entry * (1 - value / 100) Fixed: level = entry - value ATR: level = entry - ATR(period) * value
Percentage: level = entry * (1 + value / 100) Fixed: level = entry + value ATR: level = entry + ATR(period) * value
ATR(period) = simple moving average of true range over period true range[t] = max(high[t] - low[t], |high[t] - close[t-1]|, |low[t] - close[t-1]|)
signal[t] = 1 when close[t] < level[t] AND close[t-1] >= level[t-1], else 0
signal[t] = 1 when close[t] > level[t] AND close[t-1] <= level[t-1], else 0
Profit Target
The Profit Target node computes a target price level a configurable distance from a reference price and activates its signal on the bar price crosses that level. It outputs the level and the cross signal; it does not place trades.
Parameters
- Target type
- Target value
The distance, in the unit set by Target type: a percent for Percentage, a price amount for Fixed, an ATR multiple for ATR.
- ATR period
Lookback in bars for the Average True Range. Used only when Target type is ATR.
- Direction
- data_in
The reference price the level is measured from, typically a captured entry price. If unconnected, the close price is used.
Outputs
- signal — Signal. Active on the bar price crosses the target level. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The target price level per bar. The chart draws this as a price overlay.
Formulas
Percentage: level = entry * (1 + value / 100) Fixed: level = entry + value ATR: level = entry + ATR(period) * value
Percentage: level = entry * (1 - value / 100) Fixed: level = entry - value ATR: level = entry - ATR(period) * value
ATR(period) = simple moving average of true range over period true range[t] = max(high[t] - low[t], |high[t] - close[t-1]|, |low[t] - close[t-1]|)
signal[t] = 1 when close[t] > level[t] AND close[t-1] <= level[t-1], else 0
signal[t] = 1 when close[t] < level[t] AND close[t-1] >= level[t-1], else 0
Trailing Stop
The Trailing Stop node computes a stop level that ratchets in the favorable direction and never loosens, and activates its signal on the bar price crosses it. It outputs the level and the cross signal; it does not place trades.
Parameters
- Trail type
- Trail value
The trailing distance, in the unit set by Trail type: a percent for Percentage, a price amount for Fixed, an ATR multiple for ATR.
- ATR period
Lookback in bars for the Average True Range. Used only when Trail type is ATR.
- Direction
Outputs
- signal — Signal. Active on the bar price crosses the trailing stop. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The trailing stop level per bar. The chart draws this as a price overlay.
Formulas
best_high[t] = running maximum of high up to bar t raw[t] = best_high[t] - distance (distance per Trail type, as in Stop Loss) level[t] = running maximum of raw up to bar t (only tightens, never loosens)
best_low[t] = running minimum of low up to bar t raw[t] = best_low[t] + distance level[t] = running minimum of raw up to bar t (only tightens, never loosens)
signal[t] = 1 when close[t] < level[t] AND close[t-1] >= level[t-1], else 0
signal[t] = 1 when close[t] > level[t] AND close[t-1] <= level[t-1], else 0
Divergence
The Divergence node compares swing points in two connected series and activates when the most recent matching pair of swings moves in opposite directions. It detects regular divergence (opposing extremes) and hidden divergence (the continuation variant).
Parameters
- Pivot left
Bars to the left of a candidate swing that must be lower (for a swing high) or higher (for a swing low) to confirm it.
- Pivot right
Bars to the right of a candidate swing that must confirm it. A confirmed swing cannot produce a signal until this many bars have passed, so this also sets the confirmation delay.
- Max bars
The largest bar distance allowed between the two compared swing points. Pairs farther apart than this are not compared.
- Divergence type
- Direction
- in0
Series A, typically price.
- in1
Series B, typically an oscillator such as RSI or MACD.
Outputs
- signal — Signal. Activates on the confirmation bar (Pivot right bars after the swing) when a divergence is found. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The divergence kind on each active bar: regular bullish, regular bearish, hidden bullish, or hidden bearish.
Divergence cases
Regular: A makes a lower low AND B makes a higher low Hidden: A makes a higher low AND B makes a lower low
Regular: A makes a higher high AND B makes a lower high Hidden: A makes a lower high AND B makes a higher high
Direction Filter
The Direction Filter node passes an input signal through only on the bars where a separate direction series matches the selected sign, gating the signal by market direction.
Parameters
- Filter direction
- in0
The signal to filter. The output can only be active on bars where this is active.
- in1
The direction series. Positive values mark bullish bars, negative values mark bearish bars. Connect any directional series whose sign carries the direction.
Outputs
- signal — Signal. The input signal restricted to bars where the direction series matches Filter direction. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The direction series, passed through for downstream use.
Formulas
signal[t] = 1 when input[t] is active AND direction[t] > 0, else 0
signal[t] = 1 when input[t] is active AND direction[t] < 0, else 0
Crossover
The Crossover node compares two connected series and activates either on the bar one crosses the other (cross mode) or on every bar one stays above or below the other (state mode).
Parameters
- Mode
- Direction
- in0
Series A — the first series in the comparison (for example a price or a fast line). Defaults to close when unconnected.
- in1
Series B — the second series in the comparison (for example a band level or a slow line). Defaults to close when unconnected.
Outputs
- signal — Signal. Active per the configured Mode and Direction. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The difference series A minus B, available for downstream use.
Formulas
bullish[t] = 1 when A[t] > B[t] AND A[t-1] <= B[t-1], else 0 bearish[t] = 1 when A[t] < B[t] AND A[t-1] >= B[t-1], else 0
bullish[t] = 1 when A[t] > B[t], else 0 bearish[t] = 1 when A[t] < B[t], else 0
Portfolio Value
The Portfolio Value node compares the strategy's current portfolio equity against a target, in dollars or as a percentage of starting capital. Each ticker in a backtest runs its own isolated portfolio, so the equity is that ticker's portfolio only.
Parameters
- Mode
- Comparison
- Target Value
The dollar amount (Dollars mode) or percentage of starting cash (Percent mode) the equity is compared against.
- data_in
If connected, the comparison and the value output use the connected series instead of the portfolio's computed equity.
Outputs
- signal — Signal. Activates on bars where the configured comparison holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The portfolio equity in dollars on each bar (or the connected data_in series when wired).
Formulas
equity[t] = cash[t] + position_quantity[t] * close[t] - margin_debt[t]
target = (Target Value / 100) * starting_cash
Portfolio state evaluation
The node reads the portfolio's live state during trade execution rather than from precomputed price data. On each bar the equity reflects every fill that has already executed on that bar (fills happen at the bar's open), with the open position valued at that bar's close — the same valuation the equity curve records.
Because the output depends on live portfolio state, strategies that include this node cannot be exported to Python or Pine Script. The export dialog flags them before any code is generated.
Drawdown
The Drawdown node tracks the strategy's portfolio equity over a rolling lookback window and compares its decline from the window peak against a target percentage. Each ticker in a backtest runs its own isolated portfolio, so the drawdown is that ticker's equity drawdown.
Parameters
- Lookback Period
The size of the rolling window the peak is measured within, in the selected unit.
- Lookback Unit
- Trigger On
- Comparison Type
- Target Percentage
The drawdown percentage the selected metric is compared against. Drawdown is always expressed as a positive percentage below the peak.
- data_in
If connected, the drawdown is computed on the connected series instead of portfolio equity.
Outputs
- signal — Signal. Activates on bars where the configured comparison holds. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The current drawdown percentage on each bar.
Formulas
drawdown[t] = (window_peak - equity[t]) / window_peak * 100
equity[t] = cash[t] + position_quantity[t] * close[t] - margin_debt[t]
Portfolio state evaluation
The node reads the portfolio's live state during trade execution rather than from precomputed price data. On each bar the equity reflects every fill that has already executed on that bar, with the open position valued at that bar's close. When the window peak is not positive there is no valid peak to measure from and the drawdown reports as zero.
Because the output depends on live portfolio state, strategies that include this node cannot be exported to Python or Pine Script. The export dialog flags them before any code is generated.
Exposure
The Exposure node outputs the strategy portfolio's position exposure as a percentage of portfolio equity, for a selected metric. Each ticker in a backtest runs its own isolated portfolio holding at most one position, so the exposure reflects that ticker's position only.
Parameters
- Metric to Output
Outputs
- signal — Signal. Always active; the node is a value source, and conditions are built by comparing its value downstream. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The selected exposure metric in percent on each bar. A leveraged position can exceed 100.
Formulas
exposure[t] = position_value[t] / equity[t] * 100 where position_value is signed for Net, clamped to one side for Long/Short, absolute for Gross
Portfolio state evaluation
The node reads the portfolio's live state during trade execution rather than from precomputed price data. On each bar the position and equity reflect every fill that has already executed on that bar, valued at that bar's close. When equity is not positive there is no valid base to measure against and the exposure reports as zero.
Because the output depends on live portfolio state, strategies that include this node cannot be exported to Python or Pine Script. The export dialog flags them before any code is generated.
Position Count
The Position Count node outputs the number of open positions in the strategy's portfolio for the current ticker, filtered by direction. Each ticker in a backtest runs its own isolated portfolio, which holds at most one open position at a time, so the count is 0 or 1.
Parameters
- Direction
Outputs
- signal — Signal. Activates on bars where an open position matches the selected Direction. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The position count for the selected Direction on each bar: 0 while no matching position is open, 1 while one is.
Portfolio state evaluation
The node reads the portfolio's live state during trade execution rather than from precomputed price data. On each bar the count reflects every fill that has already executed on that bar (fills happen at the bar's open), so a position opened at the current bar's open is counted on that same bar. The count covers only the current ticker's portfolio; a multi-ticker strategy evaluates each ticker independently.
Because the output depends on live portfolio state, strategies that include this node cannot be exported to Python or Pine Script. The export dialog flags them before any code is generated.
Cash Balance
The Cash Balance node outputs a cash metric of the strategy's portfolio for the current ticker: total cash, cash available after the global reserve, or a reserve amount computed from a configurable percentage. Each ticker in a backtest runs its own isolated portfolio, so the value reflects that ticker's portfolio only.
Parameters
- Output Metric
- Reserve (%)
The percentage of current portfolio equity reported by the Reserved Amount metric. Only used when Output Metric is Reserved Amount.
- reserve_pct_in
If connected, the connected series value replaces the Reserve (%) setting on each bar.
Outputs
- signal — Signal. Always active; the node is a value source, and conditions are built by comparing its value downstream. Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The selected cash metric in dollars on each bar.
Portfolio state evaluation
The node reads the portfolio's live state during trade execution rather than from precomputed price data. On each bar the value reflects every fill that has already executed on that bar (fills happen at the bar's open), and equity-based amounts value the open position at that bar's close.
Because the output depends on live portfolio state, strategies that include this node cannot be exported to Python or Pine Script. The export dialog flags them before any code is generated.
Risk Per Trade
The Risk Per Trade node computes a risk-based position size from live portfolio equity and a connected volatility series (typically ATR). Each ticker in a backtest runs its own isolated portfolio, so the equity in the calculation is that ticker's portfolio.
Parameters
- Max Risk Pct
The percentage of current portfolio equity that defines the risk budget for one trade.
- ATR Multiplier
Factor applied to the connected volatility value to define the stop distance used in the size calculation. Wider stop distance produces a smaller size.
- Value per Price Point
The monetary value of one full price point. One for most stocks; contract or pip value for other instruments.
- volatility_in
The volatility series the stop distance is derived from, typically an ATR node's values. A strategy using this node without the wire fails before execution starts.
Outputs
- signal — Signal. Activates on bars where a positive size is computable (the volatility input has warmed up and equity is positive). Any input that accepts a Signal reads this and reacts on bars where it's active.
- values — Series. The computed position size in shares or contracts on each bar; zero while no valid size is computable.
Formulas
position_size[t] = (equity[t] * max_risk_pct / 100) / (volatility[t] * atr_multiplier * value_per_price_point)
Portfolio state evaluation
The node reads the portfolio's live state during trade execution rather than from precomputed price data. On each bar the equity reflects every fill that has already executed on that bar, with the open position valued at that bar's close. Buy and Sell nodes size trades from their own configuration; this node's output is read through value comparisons, not as an order quantity.
Because the output depends on live portfolio state, strategies that include this node cannot be exported to Python or Pine Script. The export dialog flags them before any code is generated.
Charts
Overview
After running a backtest, Backtest Labs generates a suite of interactive charts and visualizations that break down your strategy's performance from multiple angles. This section documents each chart individually, covering how to read the data and the calculations behind it.
- Ticker selector
Switches between tickers when the strategy ran on more than one. Each ticker has its own per-ticker results, and the selected ticker drives every chart in the suite. Multi-ticker strategies do not combine positions across tickers.
Price Chart
The Price Chart shows candlestick price action for one ticker in the backtest, with indicator overlays, executed trade markers, and synchronized volume.
Panels and overlays
- Price candles
One candle per bar at the strategy's execution interval, showing open, high, low, and close. Candle color reflects whether the bar closed above or below its open and follows the active chart theme.
- Indicator overlays
Indicator nodes whose output is plotted on price (moving averages, Bollinger Bands, Donchian Channels, VWAP, and similar band or line indicators) draw directly on top of the candles using the node's color.
- Indicator subpanels
Indicator nodes whose output is not a price overlay (RSI, MACD, ATR, volume-based oscillators) appear in their own subpanels beneath the price panel. All subpanels share the price panel's time axis.
- Trade markers
Every executed entry and exit places a marker on the bar where the trade filled. Long entries and short covers render as upward markers; short entries and long exits render as downward markers. Hovering a marker shows the trade's direction, fill price, size, and realized profit and loss for closed positions.
- Volume
Bar chart of executed-interval volume rendered as an underlay in the same panel as the candles, not a separate panel beneath. Bars are colored by the matching candle's direction.
Returns Analysis
The Returns Analysis view summarizes how the portfolio grew over the backtest. It pairs a strip of headline performance metrics with three charts: the equity curve, returns grouped by calendar period, and the distribution of per-bar returns.
Panels
- Equity Curve
Full-width line of the portfolio's cumulative result across the backtest. Benchmarks overlay as their own lines for comparison, and dividend markers appear on the curve when the ticker paid dividends. Hovering reports the value at that bar in a status bar beneath the chart.
- Periodic Returns
Bar chart with one bar per calendar period, each bar the portfolio's return over that period. The W / M / Q / Y toggle switches the grouping between weekly, monthly, quarterly, and yearly. The panel also reports the share of periods that were positive.
- Returns Distribution
Histogram that bins per-bar returns by size, showing how often returns of each magnitude occurred. Benchmarks overlay their own distribution for comparison.
Performance metrics
- Total Return
Cumulative percentage gain or loss from the start to the end of the backtest, before annualization.
- CAGR
Compound annual growth rate, the smoothed annualized return as if the portfolio grew at a steady rate each year.
- Ann. Volatility
Standard deviation of returns scaled to a yearly figure.
- Sharpe Ratio
Excess return over the risk-free rate per unit of total volatility. The risk-free rate used is shown beneath the value.
- Sortino Ratio
Excess return over the risk-free rate per unit of downside volatility only.
- Calmar Ratio
Annualized return divided by maximum drawdown.
- Skewness
Asymmetry of the returns distribution. Positive values lean toward larger gains, negative toward larger losses.
- Kurtosis
Tail weight of the returns distribution relative to a normal distribution. Higher values mean more frequent extreme returns.
Drawdown Analysis
The Drawdown Analysis view shows how far and how long the portfolio fell below its prior equity peaks. It pairs a strip of drawdown metrics with three charts: the underwater curve over time, the worst drawdown episodes, and the distribution of drawdown depths.
Panels
- Underwater Chart
Full-width plot of drawdown depth over time: at each bar, how far below the running equity peak the portfolio sits, as a percentage. The line is at zero whenever equity makes a new high and dips negative through each decline. Benchmarks overlay their own underwater curves, and hovering reports the depth at that bar in a status bar beneath the chart.
- Worst Drawdowns
The largest drawdown episodes ranked by depth, so the handful of most severe peak-to-trough declines can be read at a glance.
- Drawdown Distribution
Histogram that bins drawdown depths by size, showing how often declines of each magnitude occurred. Benchmarks overlay their own distribution for comparison.
Drawdown metrics
- Max Drawdown
The largest peak-to-trough decline over the whole backtest.
- P95 Depth
95th percentile of drawdown depth; 95% of drawdowns were shallower than this.
- Avg Depth
Mean drawdown depth across the bars spent below a prior peak.
- Tail Average
Average of the worst 5% of drawdowns (the drawdown expected shortfall).
- Time Underwater
Percentage of all bars spent below the previous equity peak.
- Current
Drawdown at the end of the backtest. Zero means it ended at or near an equity high.
- Longest
The longest single stretch spent below a prior peak before recovering, in calendar days (or hours/bars for intraday).
- Recovery Factor
Total net profit divided by maximum drawdown.
- Period Count
Number of distinct underwater periods (peak-to-recovery cycles).
- Ulcer Index
Root mean square of drawdowns, combining their depth and duration into one figure.
Trade Distribution
The Trade Distribution view breaks the backtest down to the level of individual round-trip trades. It is organized into five tabs: headline trade quality, the spread of outcomes, a per-trade blotter, when trades happen, and what they cost to execute.
Overview tab
Headline trade-quality vitals, the geometry of wins versus losses, and a chronological view of every trade.
- Win Rate
Donut of winning versus losing trades, with the win rate and trade count at the center.
- Net P&L
Cumulative realized profit and loss across trades in sequence, as an area sparkline.
- Win/Loss Comparison
Diverging bars comparing winners and losers across six points of their size distribution: smallest, 25th percentile, median, average, 75th percentile, and largest.
- MAE/MFE Pain Map
Scatter of each closed trade by its worst unrealized loss (MAE) against its largest unrealized gain (MFE), sized by profit and loss and colored by outcome.
- Trade Rhythm
One bar per closed trade in chronological order, colored by win or loss with opacity scaled to size, shown alongside max win streak, max loss streak, and average duration.
The vitals scorecard reports:
- Profit Factor
Gross profit divided by gross loss across closed trades.
- Expectancy
Average profit or loss per trade.
- Payoff Ratio
Average winning trade divided by average losing trade.
- SQN Score
System Quality Number (Van Tharp), shown once there are at least 30 trades.
- Trade Frequency
How often trades occur on average over the period.
- Closed Trades
Count of completed round-trip trades.
- Dividend Events and Div. Income
Number of dividend payouts received and total dividend income, shown when the ticker paid dividends.
Distribution tab
The spread of per-trade outcomes, viewable as dollar profit and loss, percent return, or R-multiple, and filterable to winners or losers.
- Histogram
Trade count binned by outcome size, on a linear or logarithmic count axis.
- Cumulative Distribution
Cumulative share of trades against outcome size, with the median marked.
- Q-Q Plot
Observed trade quantiles against the quantiles of a normal distribution, with a reference line for a perfect match.
The scorecard reports:
- Trades
Count of trades in the current distribution after filtering.
- Mean
Average of the selected outcome metric.
- Median
Middle value of the selected outcome metric.
- Std Dev
Standard deviation of the selected outcome metric.
- 5th %ile
Fifth-percentile (worst) value of the metric.
- 95th %ile
95th-percentile (best) value of the metric.
Trades tab
A blotter of every closed trade, viewable ungrouped per trade or grouped into trade chains.
- Ungrouped blotter
One row per trade with its ID, chain, action, outcome, timestamp, quantity, price, profit and loss, return percent, commission, slippage, MAE, MFE, R-multiple, and duration.
- Grouped chains
Each trade chain rolled up with its outcome, first entry, last exit, leg count, duration, total profit and loss, MAE, and average R, expandable to the individual legs.
Timing tab
When trades occur and how long they are held. The layout adapts to intraday or end-of-day strategies, and values can be shown as R-multiple or profit and loss.
- Hour × Day Performance
Intraday strategies: heatmap of average performance by hour of day against day of week.
- Session Performance
Intraday strategies: average performance by trading session (pre-market, open hour, midday, power hour, after hours, or crypto sessions) as horizontal bars.
- Day of Week Performance
End-of-day strategies: average performance by weekday as horizontal bars.
- Monthly Performance
End-of-day strategies: average performance by month as vertical bars.
- Duration vs Payoff
Scatter of each trade's holding duration against its R-multiple or profit and loss.
- Holding Period Distribution
Trade count binned by holding-period length.
The scorecard reports:
- Best Hour and Worst Hour
Intraday strategies: hours of day with the strongest and weakest average performance.
- Best Day and Worst Day
Weekdays with the strongest and weakest average performance.
- Median Hold
Median holding duration across closed trades.
- Hold Consistency
Coefficient of variation of holding durations, where lower is more consistent.
- Avg Winner Hold and Avg Loser Hold
End-of-day strategies: average holding duration of winning and of losing trades.
Execution tab
The per-trade cost of execution and how it eroded performance.
- Cost Drag
Gross return and net return over time, with the cost drag shaded between them.
- Cost Waterfall
Gross profit stepped down through commission and slippage to net, as a waterfall.
- Capacity
Trade count binned by trade size as a percent of average daily volume, with a cumulative-share overlay.
- Periodic Costs
Commission and slippage per period as stacked bars, with a cost-in-basis-points efficiency line. The period (hourly through yearly) is selectable.
The scorecard reports:
- All-In Cost
Average execution cost in basis points, commission and slippage combined.
- Total Costs
Total commission and slippage paid across the backtest.
- Cost % P&L
Share of gross profit and loss consumed by execution costs.
- Turnover
Average monthly portfolio turnover rate.
- Median %ADV
Median trade size as a percent of average daily volume (24h volume for crypto).
- P95 %ADV
95th-percentile trade size as a percent of average daily volume (24h volume for crypto).
Rolling Metrics
The Rolling Metrics view shows how the strategy's risk-adjusted performance changes across the backtest, recomputing each metric over a rolling window of bars so the value at each point reflects only the recent window rather than the whole run. It is split into two tabs: standalone performance metrics, and metrics measured against a selected benchmark.
Performance tab
Standalone risk-adjusted metrics, each as a rolling line chart. Every chart overlays a line per selected benchmark for comparison.
- Sharpe Ratio
Rolling line of excess return over the risk-free rate divided by volatility.
- Sortino Ratio
Rolling line of excess return divided by downside volatility only, ignoring upside swings.
- Calmar Ratio
Rolling line of annualized return divided by the maximum drawdown within the window.
- Volatility
Rolling line of the annualized standard deviation of returns, in percent.
The scorecard reports:
- Sharpe
Current (latest) rolling Sharpe ratio.
- Sortino
Current rolling Sortino ratio.
- Calmar
Current rolling Calmar ratio.
- Volatility
Current annualized rolling volatility.
- Tail Ratio
Ratio of extreme gains to extreme losses, the 95th percentile of returns over the 5th percentile.
- Med. Sharpe
Median rolling Sharpe ratio across the backtest.
- Med. Sortino
Median rolling Sortino ratio across the backtest.
- Med. Calmar
Median rolling Calmar ratio across the backtest.
- P95 Vol
95th-percentile rolling volatility.
- Skewness
Asymmetry of the return distribution. Positive leans toward occasional large gains, negative toward occasional large losses.
Benchmark tab
Metrics measured against each selected benchmark, each as a rolling line chart. This tab is available only when the backtest includes one or more benchmark tickers.
- Alpha
Rolling line of return beyond what the benchmark's risk exposure alone would predict, drawn with a 95% confidence band.
- Beta
Rolling line of the sensitivity of strategy returns to benchmark moves, where 1.0 tracks the benchmark one-for-one, drawn with a 95% confidence band.
- Correlation
Correlation between strategy and benchmark returns, ranging from -1 to +1. Viewable as a line over time or as a scatter of paired returns with a regression fit.
- Tracking Error
Rolling line of the annualized standard deviation of the return difference between the strategy and the benchmark.
- Information Ratio
Rolling line of alpha divided by tracking error, the excess return earned per unit of active risk.
The scorecard reports:
- Beta
Current rolling beta against the benchmark.
- R-squared
Fraction of strategy return variance explained by benchmark moves, from 0 to 1.
- Correlation
Current rolling correlation with the benchmark.
- Track. Error
Current annualized tracking error.
- Info Ratio
Current rolling information ratio.
- Alpha
Current annualized alpha.
- Batting Avg
Percentage of periods in which the strategy return exceeded the benchmark return.
- Up Capture
Share of the benchmark's gains the strategy captured during the benchmark's up periods.
- Down Capture
Share of the benchmark's losses the strategy absorbed during the benchmark's down periods.
- % IR > 0
Percentage of rolling periods with a positive information ratio.
Calendar Returns
The Calendar Returns view breaks the backtest down by calendar time, coloring each day by its return. It pairs a per-year heatmap and a month-by-month detail grid with a strip of calendar-based summary metrics.
Panels
- Year Overview
Heatmap of a single year, one cell per day colored by that day's return. Cells lay out either as a months-by-days grid or as a weekday-by-week grid, and the axis labels carry each month's or weekday's running total. The header shows the year and its total, days that had trades are marked, and on stock calendars weekend cells are dimmed.
- Month Detail
A calendar grid of a single month, one cell per trading day showing the day's return, its trade count, and a secondary profit-and-loss or percentage figure; days with no position held read "No Shares Held". When benchmarks are included, each day cell also carries that day's return for each benchmark. A row of per-weekday totals sits above the grid, and a trailing column holds each week's total.
The month header shows the month's total return, and when the month had trades, a summary strip beside it: trade count, win rate, the best and worst day, and the count of green versus red days.
Display modes
- Value
Returns are shown either as percentages or as dollar profit and loss.
- Layout
The year heatmap lays out by day (months by days 1 to 31) or by week (weekday by week). Stock calendars span Monday to Friday; crypto calendars span all seven days.
- Color
Positive days shade green and negative days red, scaled symmetrically around zero up to a configurable percentage ceiling for each side.
Metrics
- Best Day
The single highest-return day over the backtest, with its date.
- Worst Day
The single lowest-return day over the backtest, with its date.
- Avg Daily
Mean return per trading day across the whole backtest.
- Win/Loss Days
Count of positive versus negative days, with the resulting day win rate.
- Max Loss Streak
Longest run of consecutive losing closed trades.
- Max Win Streak
Longest run of consecutive winning closed trades.
- Prof. Months
Number of months with a positive cumulative return, out of the total months.
- Avg Monthly
Mean return per month across all months in the backtest.
Exposure Analysis
The Exposure Analysis view shows how much of the portfolio's equity was deployed over the backtest, broken into long, short, net, and gross exposure plus a leverage multiplier. It pairs a strip of exposure metrics with charts of leverage, exposure composition, net and gross exposure, and the distribution of exposure levels.
Series
- Long
Long-position exposure as a percent of portfolio equity.
- Short
Short-position exposure as a percent of portfolio equity.
- Net Exposure
Directional bias, long exposure minus short exposure, as a signed percent of equity.
- Gross Exposure
Total capital at risk, long exposure plus short exposure, as a percent of equity.
- Leverage
Total market exposure as a multiple of equity. Values above 1.0x mean combined long and short exposure exceeds equity.
Panels
- Leverage
Step line of the leverage multiplier over time, with a dashed reference line at 2x.
- Exposure Composition
Mirrored area chart with long exposure plotted as a positive area above zero and short exposure as a negative area below zero, each in percent of equity.
- Net & Gross Exposure
Overlaid area chart of net exposure and gross exposure over time, in percent of equity, with a dashed reference line at zero.
- Distribution
Histogram of how often the portfolio sat at each exposure level, binning either net exposure or leverage, with a line marking the mean. Bins cover the currently visible time window.
Metrics
- Time Invested
Percentage of bars that held any long or short exposure.
- Avg When Active
Average gross exposure across only the bars that held a position.
- Avg Net
Average net exposure across all bars, the typical directional bias.
- Avg Leverage
Average leverage multiplier across all bars.
- Exposure Periods
Number of distinct contiguous runs of bars that held exposure.
- Avg Period
Average number of bars per exposure period.
- Max Long
Highest long exposure reached at any bar.
- Max Short
Highest short exposure reached at any bar.
- Max Leverage
Highest leverage multiplier reached at any bar.
- Net Volatility
Standard deviation of net exposure, how much the directional bias varied.
Aggregation
The series can be aggregated to a coarser calendar interval than the strategy's native interval, and the metrics recompute at the selected aggregation level. When portfolio equity was zero or negative on some bars, exposure for those bars is shown as 0 and a notice appears above the charts.
Multi-Chart
The Multi-Chart view is a grid that displays several result charts at once for side-by-side comparison. Each panel renders one visualization drawn from the full catalog below, for a chosen strategy or benchmark ticker, and the time-series panels share one zoom slider and a synchronized crosshair.
Layout
- Panel grid
Panels arrange in one of four layouts: two, three, or four stacked rows, or a two-by-two grid. A single zoom slider spans the full width beneath the panels.
- Synchronized time axis
Time-series panels are linked: zooming or panning one, or moving the shared slider, scrolls every linked panel to the same time window, and a crosshair tracks the same timestamp across them. Panels that are not time series, such as period bars, histograms, and heatmaps, do not link to the shared axis.
Value
- Price (Line + Events)
The asset's price over time as a line, with trade and corporate-event markers.
- Equity Curve
The portfolio's account value over time.
- Cumulative Returns
The strategy's compounded return over time.
- Net P&L
Cumulative dollar profit and loss over time.
Returns
- Daily Returns
Per-bar return as a time-series bar chart.
- Log Returns
Per-bar logarithmic return as a line.
- Weekly Returns
Return aggregated by week as period bars.
- Monthly Returns
Return aggregated by month as period bars.
- Yearly Returns
Return aggregated by year as period bars.
- Calendar Returns
Per-day returns laid out as a calendar barcode.
- Returns Distribution
Histogram of how often returns of each size occurred.
- Returns Heatmap
Returns laid out as a colored heatmap grid.
Risk Metrics
- Rolling Sharpe
Sharpe ratio over a rolling window.
- Rolling Sortino
Sortino ratio over a rolling window.
- Rolling Volatility
Annualized volatility over a rolling window.
- Rolling Max Drawdown
Maximum drawdown over a rolling window.
- Rolling Calmar
Calmar ratio over a rolling window.
- Tracking Error
Annualized standard deviation of the strategy-minus-benchmark return, over time.
- Information Ratio
Alpha divided by tracking error, over time.
- Rolling Beta
Sensitivity of strategy returns to a benchmark over a rolling window.
- Rolling Correlation
Correlation between strategy and benchmark returns over a rolling window.
- Rolling Alpha
Return beyond the benchmark's predicted contribution over a rolling window.
- Active Risk
Active risk against a benchmark, shown as tracking error or information ratio.
Oscillator-type indicators used in the strategy (such as RSI, MACD, CCI, ATR, and DMI/ADX) can also appear here, each in its own panel.
Drawdown
- Drawdown
Underwater equity decline from prior peaks, as a filled area.
- Drawdown Periodic
Drawdown aggregated into daily, weekly, monthly, or yearly periods as bars.
- Drawdown Distribution
Histogram of drawdown magnitudes.
Exposure
- Exposure Composition
Long and short exposure over time as mirrored areas.
- Net & Gross Exposure
Net and gross exposure over time as areas.
- Leverage
Leverage multiplier over time as a line.
- Exposure Distribution
Histogram of exposure levels.
- Exposure Heatmap
Exposure laid out as a colored heatmap.
Trade Analysis
- Trade Distribution
Histogram of per-trade outcomes, as dollar P&L, percent return, or R-multiple.
- Holding Period Distribution
Histogram of how long trades were held.
- Trade P&L Timeline
Each trade's profit and loss plotted as a point along time.
- Trade Rhythm
Heatmap of trade activity by time pattern.
- Trade Timeline
Heatmap of trades along the time axis.
- Trade Costs
Cumulative commission and slippage as stacked bars.
- Volume
Traded volume per bar as bars.
Volume-scale indicators used in the strategy (such as OBV, relative volume, and VWAP difference) can also appear here, each in its own panel.
Validations
The Validations category carries no built-in visualization and is available only when the run has validation data; validation results are shown in the dedicated Validations view.
Validations
The Validations view presents the results of the validation tests that ran with the backtest, one tab per method. The view appears only when a backtest was run with validations enabled, and a method's tab carries results only when that test produced them. How each test is computed is covered in the Validation Engine documentation; the sections below describe what each tab displays.
Monte Carlo
Ranks the actual result against many simulated runs built by resampling the strategy's trades.
- Final Equity
Histogram of final equity across all simulations, with a marker on the actual result and the percentile it falls at.
- Max Drawdown
Histogram of maximum drawdown across all simulations, with a marker on the actual result and its percentile.
- Equity Confidence Bands
Simulated equity paths drawn as nested percentile bands (5th to 95th, 10th to 90th, and 25th to 75th) around the median path, with the actual equity curve overlaid.
The scorecard reports:
- Equity Rank
Percentile where the actual final equity ranks among the simulations.
- DD Rank
Percentile where the actual maximum drawdown ranks among the simulations.
- Final Equity
The backtest's ending equity, with its percent return.
- Max Drawdown
The backtest's largest peak-to-trough decline.
- Trades
Number of trades resampled, the sample size.
- Confidence
Reliability rating of the result: high, medium, or low.
- Expected Eq
Median final equity across the simulations.
- 95% CI Low and 95% CI High
Lower and upper bounds of the 95% confidence interval for final equity.
- Expected DD
Median maximum drawdown across the simulations.
- Worst-Case DD
Fifth-percentile (worst) maximum drawdown across the simulations.
- Risk of Ruin
Estimated probability of exceeding a large drawdown.
- Worst Streak
Longest losing streak seen across the simulations.
- Typical Streak
Median losing streak across the simulations.
Rolling Window
Splits the backtest into sequential windows and evaluates each one independently.
- Window Returns
One bar per window showing that window's return, with a line marking the average across windows.
- Multi-Metric Comparison
One line per window across eight axes (return, Sharpe, max drawdown, win rate, profit factor, average trade, payoff, and trade count) to compare every window on every metric at once.
- Window Equity Curves
Each window's equity curve normalized to percent return and aligned by trading day, overlaid for comparison.
The scorecard reports:
- Consistency
Number of profitable windows out of the total, with the percentage.
- Confidence
Reliability rating: high, medium, or low.
- Avg Return
Average return per window.
- Variability
Standard deviation of window returns.
- Best Window
Highest single-window return.
- Worst Window
Lowest single-window return.
- Trend
Direction of change in returns across the windows, from improving to degrading.
Hold-Out
Compares an in-sample segment of the backtest against a held-out out-of-sample segment.
- Win Rate
In-sample versus out-of-sample win rate as stacked bars.
- Max Drawdown
Out-of-sample maximum drawdown on a bullet chart with low, moderate, and high risk zones and an in-sample reference marker.
- Total Return
In-sample versus out-of-sample total return as side-by-side bars.
- CAGR
In-sample versus out-of-sample compound annual growth rate as side-by-side bars.
- Trades
A donut splitting closed trades into in-sample and out-of-sample, with the total at the center.
- In-Sample vs Out-of-Sample Equity
Both equity curves rebased to a common 100% start, plotted over percent of period elapsed.
The scorecard reports:
- Risk Level
Overall hold-out risk inferred from how far out-of-sample fell short of in-sample.
- Confidence
Reliability rating: high, medium, or low.
- Avg Degradation
Average drop from in-sample to out-of-sample performance.
- IS Sharpe
In-sample Sharpe ratio.
- OOS Sharpe
Out-of-sample Sharpe ratio.
- CAGR Diff
Out-of-sample CAGR minus in-sample CAGR.
Sensitivity
Varies the strategy's parameters around their set values and measures the effect on results.
- Sensitivity Heatmap
Grid of parameters against variation levels, each cell colored by the change in Sharpe ratio, green for improvement and red for degradation.
- Sharpe Impact
Bidirectional bars ranking parameters by how far varying each one moves the Sharpe ratio up or down.
- Sensitivity Curves
Sharpe ratio plotted against percent variation for each parameter, with a baseline reference line.
- 3D Parameter Surface
A surface of Sharpe ratio over the two most sensitive parameters.
- Stability Band
The baseline equity curve with a shaded band between its 10th and 90th percentile across the variations.
The scorecard reports:
- Stability
How consistent the Sharpe ratio stays across the variations, where 100% means no impact.
- Sharpe Range
Lowest to highest Sharpe ratio across the variations.
- Best Varied
Best variation result relative to the baseline.
- Baseline Sharpe
The Sharpe ratio at the strategy's set parameters.
- Avg Varied
Average Sharpe ratio across the variations.
- Most Sensitive
The parameter with the largest impact, with its impact percentage.
- DD Range
Lowest to highest maximum drawdown across the variations.
- Worst Case DD
Deepest maximum drawdown across the variations.
- DSR
Deflated Sharpe Ratio, the Sharpe ratio adjusted for the number of variations tested.
Robustness
Re-runs the strategy with entry and exit fills delayed by one to three bars.
- Trade Impact
Per-trade profit-and-loss impact under each delay scenario, grouped by one, two, and three bars of delay.
- Multi-Metric Comparison
One line per run across eight axes (Sharpe, return, CAGR, max drawdown, degradation, trades, win rate, and profit factor), with the no-delay baseline emphasized.
- Equity Curves
The baseline equity curve overlaid with each delayed run, the best and worst highlighted.
The scorecard reports:
- Tolerance
How consistent the Sharpe ratio stays under delay, where 100% means no impact.
- Baseline Sharpe
The Sharpe ratio with no delay.
- Avg Delayed
Average Sharpe ratio across the delayed runs.
- Worst Case
The weakest delayed run.
- Best Case
The strongest delayed run.
- Entry Sens.
Impact of delaying entry fills.
- Exit Sens.
Impact of delaying exit fills.
- Delay Impact
Delay effect relative to the average holding time.
Cost Stress
Multiplies the strategy's trading costs across several stress levels.
- Metric Degradation Heatmap
Five metrics (profit change, Sharpe, average trade P&L, profit factor, and max drawdown) against stress levels, each cell colored by how well the metric survives.
- Profit Erosion
Profit plotted against the cost multiplier, with the breakeven multiplier marked where profit crosses zero.
- Profit %Δ
Percent change in profit at 1x, 2x, and 3x cost, with a survival-threshold line.
- Sharpe
Sharpe ratio at 1x, 2x, and 3x cost, with a survival-threshold line.
- Avg Trade P&L
Average trade profit and loss at 1x, 2x, and 3x cost.
- Profit Factor
Profit factor at 1x, 2x, and 3x cost, with a survival-threshold line.
- Resilience
Resilience score at 1x, 2x, and 3x cost.
- Equity Curves Under Stress
Equity curves at baseline, 2x, and 3x cost overlaid.
The scorecard reports:
- Breakeven
The cost multiplier at which profit crosses zero.
- Baseline
Profit at unmodified cost.
- Profit @ 2x
Profit at twice the cost.
- Sharpe @ 2x
Sharpe ratio at twice the cost.
- Max DD @ 2x
Maximum drawdown at twice the cost.
- Degradation
Performance lost per added unit of cost.
- Survival
Count of key metrics still passing their thresholds at twice the cost.
- Profit @ 3x
Profit at three times the cost.
- Confidence
Reliability rating: high, medium, or low.
Execution Engine
Overview
The execution engine is the core of Backtest Labs. When you hit execute, it takes your node-based strategy, resolves the graph of connections into an execution order, computes every indicator, evaluates your conditions, and simulates trades against historical market data with realistic cost modeling. This section covers each stage of that pipeline in detail, from how the graph is resolved to how trades are executed and positions are managed.
Graph Resolution
When you execute a strategy, the engine processes your node graphonce for every bar of data in your backtest range. On each bar, it runs through your entire graph in the order determined by how you've connected your nodes. If an EMA feeds into a Crossover node, the EMA always calculates first so the Crossover has fresh data to work with. The engine figures out this ordering automatically from your connections.
Every node runs on every bar, regardless of whether a trade signal is produced. This is how the engine ensures that indicator values, conditions, and signals are always up to date.
When you select multiple tickers, the engine runs your entire strategy graph independently on each ticker's data. Tickers do not share state or interact with each other during execution.
Data Pipeline
Backtest Labs sources stock data from Tiingo and cryptocurrency data from Binance. Both provide standard OHLCV (Open, High, Low, Close, Volume) data, which is what every indicator and chart in the platform operates on.
Available timeframes vary by asset class. Stocks support 1-minute through 12-hour intraday intervals as well as daily, and follow regular US market hours. Crypto supports the same interval range but trades 24/7, which means significantly more data bars per day at shorter intervals.
Price adjustments are applied automatically. Stock prices are adjusted for historical splits so that indicators and charts reflect actual trading conditions rather than raw unadjusted prices. Dividends are tracked separately rather than being folded into the price, which allows dividend analysis and DRIP reinvestment to work correctly. Crypto assets do not have corporate actions, so no adjustments are needed.
Trade Execution
When a Buy or Sell node receives a signal from its connected conditions, it evaluates whether or not to fire. If a node has multiple inputs,all conditions must be true simultaneously for the signal to trigger.
Trades fill at the next bar's open price, not at the bar where the signal fires. This matches how real brokers work: when your conditions trigger at bar close, you can't actually execute at that close because it's already happened. Your order fills at the next available price, which is the following bar's open. Signals that fire on the last bar of the data range are dropped since there is no next bar to fill on.
The platform supports both long and short trading. Buy nodes can open a long position or cover an existing short. Sell nodes can exit a long position or open a new short. Each node's direction is configured in its parameters.
Order types include market, limit, stop, stop-limit, and trailing stop. These are configured directly on the Buy and Sell nodes and determine how the fill price is evaluated relative to the next bar's open.
When multiple buy signals fire consecutively on the same ticker without an intervening sell, those buys are aggregated into a single position. The engine tracks the combined entry cost, total quantity, and weighted average entry price across all entries. The position stays open until a sell signal closes it, at which point the full realized P&L is calculated against the aggregate entry.
Holding periods can enforce minimum and maximum trade durations. A minimum holding period prevents a position from being closed too early, even if a sell signal fires. A maximum holding period forces a position to close after a set number of bars, regardless of signals. Forced closes from max holding periods also execute at the next bar's open for consistency.
As covered in Graph Resolution, each ticker operates with its own independent portfolio. Cash, positions, and trade history are completely isolated between tickers.
Cost Modeling
Every trade in the backtest has commission and slippage applied to simulate realistic execution costs. These are deducted automatically and reflected in your trade log, P&L calculations, and performance metrics.
Slippage adjusts the fill price itself. When you buy, slippage pushes your fill price higher than the market price. When you sell, it pushes your fill price lower. The execution price you see in the trade log already has slippage baked in. This means your realized P&L accounts for the true cost of getting in and out of a position, not just the theoretical market price.
Volume-based slippage scales with how large your trade is relative to the bar's actual volume. A trade that represents 10% of the bar's volume will experience more slippage than one that represents 1%. This models real market impact since larger orders move the market more. If you're testing strategies with large position sizes on low-volume stocks, this is where you'll see the biggest difference between theoretical and realistic results.
Commission is deducted from your cash balance separately from the fill price. The engine enforces minimum and maximum commission bounds per trade regardless of which commission model you use, so very small trades still incur a minimum cost and very large trades are capped.
Dividends & Corporate Actions
The engine automatically processes stock splits and dividends during backtest execution. These are not triggered by your strategy's nodes. They happen based on the actual historical corporate action data for the ticker you're testing.
When a stock split occurs, the engine adjusts your position's share count and average entry price to reflect the split. A 2-for-1 split doubles your shares and halves your entry price. Your P&L remains accurate because both sides of the equation are adjusted. This happens automatically on the bar where the split historically occurred.
When a dividend is paid, the engine either adds the cash directly to your portfolio or reinvests it depending on whether DRIP is enabled. With DRIP on, dividend cash is used to purchase additional shares at the current price, and those shares are added to your existing position. With DRIP off, the dividend is deposited as cash. Either way, dividend events appear in your trade history as separate entries from your signal-driven trades, which means they are reflected in your total return and equity curve.
Dividends are credited on the ex-dividend date at that bar's price. Real brokers deposit dividend cash on the payment date, typically two to six weeks later, and execute DRIP purchases around that date. The engine reinvests immediately on the ex-dividend bar instead, which matches how total-return indexes are calculated and keeps results independent of payment schedules that vary by company and broker.
Eligibility follows the record-date convention: only shares held before the ex-dividend bar's open receive the dividend. A position opened on the ex-dividend bar does not collect that dividend, and a position sold at the ex-dividend bar's open still does, paid as cash.
Validation Engine
The validation engine runs after your main backtest completes, using its results to stress-test your strategy from multiple angles. Each validation method re-runs or resamples your strategy in a different way to answer a specific question about its reliability.
Monte Carlo takes the actual trades from your backtest and randomly resamples them with replacement (the same trade can be drawn more than once, and others not at all) across thousands of simulations. This produces a spread of possible equity curves, summarized as confidence bands, a drawdown distribution, and risk-of-ruin probabilities at drawdown levels from 10% to 50%. It answers the question: how much of your performance is a durable edge versus luck, and how severe could the drawdowns realistically get?
Hold-Out Validation splits your data range into an in-sample period and an out-of-sample period, then runs your strategy on both independently. If performance is significantly stronger on the in-sample data than the out-of-sample data, the strategy may be overfit to the specific conditions it was tested on. Performance is compared across Sharpe, CAGR, return, win rate, and max drawdown, and the average out-of-sample degradation drives a low, medium, or high risk rating.
Rolling Window divides the full date range into sequential windows and runs your strategy independently on each one. This reveals whether performance is consistent across different market conditions or concentrated in a specific time period. It uses 3 to 8 windows (rolling or non-overlapping), and the consistency score is the share of windows that finished profitable.
Cost Stress progressively increases transaction costs beyond your configured levels and re-runs the backtest at each step. Commission and slippage are scaled from 1x up to 3x across six steps to find the breakeven point where the strategy stops being profitable, showing how sensitive your profitability is to cost assumptions.
Execution Robustness delays your trade signals and re-runs the backtest for each delay. It applies positive delays of 1 to 3 bars only (simulating latency, never acting earlier than the signal) across 10 configurations covering entry-only, exit-only, and both delayed together. This tests whether your strategy still works if you are consistently a bar or two late on entries and exits.
Parameter Sensitivity automatically discovers all tunable numeric parameters across your strategy's nodes, varies each one independently, and re-runs the backtest for each variation. Parameters are ranked by how much they affect performance, scored from the coefficient of variation across each parameter's variations, and the two most sensitive parameters from different nodes are automatically selected for the interaction heatmap. This tests whether your results depend on very specific parameter choices or remain stable across a range of values; strategies that collapse with small parameter changes are likely fragile.
Code Export
Any strategy can be exported as runnable code in two targets: Python andPine Script. An export reproduces the strategy's signal logic so it can run outside Backtest Labs.
The Python export generates a generate_signals() function, built on TA-Lib, that returns the strategy's buy and sell signals for a bar series you provide. The Pine Script export generates a TradingView indicator that plots buy and sell markers and exposes them as alerts.
Portfolio nodes cannot be exported. Nodes that read live portfolio state (Portfolio Value, Cash Balance, Drawdown, Exposure, Position Count, and Risk Per Trade) depend on the running portfolio that Backtest Labs maintains during a backtest. Standalone Python and charting platforms such as TradingView have no equivalent, so a strategy that uses any of these nodes cannot be exported. The builder flags this and asks you to remove the portfolio node before exporting.
Indicator math is based on TA-Lib, the industry-standard reference library the platform itself uses to compute every indicator. Because the Python export is also TA-Lib-based, it reproduces the platform's indicator values to floating-point tolerance: the signals it produces are the same signals you saw on the platform.
Pine Script matches in nearly all cases, since TradingView's built-in ta.* functions implement the same standard math. A few indicators cannot match exactly, and the export labels these in-line. ATR, MACD, and Supertrend seed their Wilder and EMA averages one bar earlier in Pine than in TA-Lib, so values differ by a tiny, decaying amount over roughly the first period bars, then converge to identical values.Volume Profile needs tick or lower-timeframe data that Pine does not expose to a charting indicator, so its Point of Control and value-area levels are approximated and will differ from Backtest Labs. The Python export reproduces the full histogram exactly.
Exports are signal logic, not execution. A signal activates on the bar its condition is met, computed from that bar's close, and the export emits the signal on that bar. The exports describe when a signal fired, not when a simulated trade was filled.
Execution belongs to your own system. A bar's close is known only after the bar completes, so the earliest an order can fill is the following bar's open. When you wire an export into your broker, automation, or notifications, that system places the order on the next bar. That is the realistic one-bar delay. The exports therefore do notshift the signal forward; shifting it would push your real order a further bar out. Backtest Labs applies this same one-bar fill internally when it simulates trades and draws the equity curve, which is why a Backtest Labs trade marker sits one bar after the signal that triggered it.
For Pine alerts, set the alert to Once Per Bar Close so it triggers on the confirmed bar rather than intrabar on the still-forming live bar.