Bars Since (barssince)

Bars Since turns a condition into a measure of elapsed time. It produces a counter expressed in candles that is 0 whenever the condition is true, then increases by 1 on each following candle for as long as the condition remains false. A new true occurrence immediately resets the counter to 0.

The value therefore shows how many candles have passed since the event described by the condition last occurred. Before its first occurrence in the available history, there is no earlier occurrence to count from, so the series remains NaN. Once the condition becomes true for the first time, the block starts producing numeric values and continues counting without limit until the next occurrence.

Block declaration

A strategy can contain multiple [[barssince]] blocks. Each block outputs one numeric series, exposed through the block id.

In [[barssince]], condition is an expression evaluated on each candle. It can use standard price series, outputs from indicators already defined in the strategy, and the variables those indicators expose.

condition follows the general expression syntax: operators, functions, reserved constants, and historical indexing. For the full reference, see Expressions and functions.

The [[barssince]] block does not expose a source parameter: the produced series depends directly on the condition expression.

[[barssince]] does not define a minimum history depth by itself. If you want the counter to account for events that happened before start_date, load earlier price data with price_history_start_date in [backtest]. This adds a warm-up period to the loaded price history without changing the actual backtest window.

[backtest]
symbol                   = "BINANCE:BTCUSDT"
timeframe                = "60"
start_date               = 2024-01-01
end_date                 = 2024-06-01
price_history_start_date = 2023-12-01

Examples

Minimal setup

This block counts the number of candles since the last green candle, defined here as close >= open.

[[barssince]]
id        = "bars_since_green"
condition = "close >= open"

Condition using history

This block counts the number of candles since the last time the current close was above the previous close.

[[barssince]]
id        = "bars_since_up_close"
condition = "close > close[1]"

Condition based on another indicator

This example first computes ATR, then counts how many candles have passed since the last candle whose body was greater than 75% of that ATR.

[[atr]]
id     = "atr14"
length = 14

[[barssince]]
id        = "bars_since_strong_body"
condition = "abs(close - open) > atr14 * 0.75"

Use in a condition

This example lets the strategy continue when the last green candle occurred three candles ago or less.

[[barssince]]
id        = "bars_since_green"
condition = "close >= open"

[[condition]]
id            = "recent_green_filter"
condition     = "bars_since_green <= 3"
next_block_id = "..."

Multi-market condition

This example counts the number of candles since the last green candle on BINANCE:ETHUSDT. The [[price]] blocks carry the market symbol; the [[barssince]] block simply combines their series in condition.

[[price]]
id     = "eth_open"
symbol = "BINANCE:ETHUSDT"
source = "open"

[[price]]
id     = "eth_close"
symbol = "BINANCE:ETHUSDT"
source = "close"

[[barssince]]
id        = "bars_since_eth_green"
condition = "eth_close >= eth_open"

Dedicated timeframe

This block evaluates the condition on a four-hour timeframe. The close >= open condition therefore uses candles from this timeframe (timeframe = "240"), and the produced series is aligned with the main timeframe when it is consumed elsewhere in the strategy. See the Exchanges, Symbols and Timeframes page for alignment rules between this timeframe and the main timeframe.

[[barssince]]
id        = "bars_since_green_4h"
timeframe = "240"
condition = "close >= open"

Parameters

ParameterDescription
id
 String
 Required
Unique identifier for the resulting series.
condition
 Expression
 Required
Expression evaluated on each candle to decide whether the counter should reset to 0.
The condition is true when it produces a defined non-zero value. 0 and NaN are treated as false.
Supported inputs: standard prices, ids of indicators already defined, variables exposed by those indicators (fast.length, fast.type, fast.symbol, fast.timeframe, etc.), numeric constants, and expression functions.
Accepted TOML types: string, integer, floating-point number.
Runtime backtest, portfolio, order, and trade variables are not available in this block.
timeframe
 String
 or Array
 Optional
Timeframe on which the condition is evaluated.
If omitted, computation uses the grid main timeframe defined in [backtest].
For accepted formats and alignment rules, see Exchanges, Symbols and Timeframes.

Note: symbol is not allowed on [[barssince]]. For multi-market logic, define upstream indicator sources with their own symbols, then combine those indicators in condition.

Available variables

The barssince block exposes one numeric series and the timeframe context field. These variables are exposed after the series has been computed and can be used downstream. They are not available inside the block condition itself.

Assume this configuration:

[[barssince]]
id        = "bars_since_green"
condition = "close >= open"

Then:

VariableDescription
bars_since_green or bars_since_green[0]
Decimal
Number of candles since the last time condition was true. The current value is 0 if the condition is true on the current candle.
bars_since_green[n]
Decimal
Counter value from n candles ago.
bars_since_green.timeframe
String
Timeframe effectively used by this block.

Notes

  • Until the condition has been true at least once in the available history, the series is NaN.
  • Numeric variables support arithmetic, comparisons, and logical operators.
  • Text variables are intended for equality/inequality checks only.
  • A condition cannot reference its own id (self-reference is forbidden).