Articles ·

Indicators and rules: values you can check against TA-Lib and TradingView

A strategy is only as honest as the numbers it decides on. Metrand computes every indicator in the same engine for backtests, paper runs and live runs, and computes it the way the reference libraries traders already trust do, so you can check a value bar by bar.

How averages start

An exponential average needs a first value to start from. Metrand starts every one of them the way TA-Lib and TradingView do: the first value is the plain average of the first period bars, and the average is empty until then.

This applies to EMA, RMA (Wilder's average), DEMA, TEMA, MACD (all three of its averages), PPO, TSI, RSI, ATR and NATR. ATR's first true range is the bar's high minus its low.

Starting from the first price instead — which many engines do — produces values on the second bar that no reference library would show, and signals from them: an EMA(5)/EMA(20) crossover could fire before the slow average existed.

An EMA(5) on twelve bars of illustrative prices: started from the first price it has values from bar 1; started like TA-Lib it is empty until bar 5, where it is the average of bars 1 to 5, and the two converge afterwards.
Illustrative values. Started from the first price, an EMA(5) already has a value on bar 2. Started like TA-Lib, it is empty until bar 5, where it is the average of the first five bars.

Other details that match TradingView:

A period that cannot mean anything is refused rather than silently changed: RSI, HMA, standard deviation, z-score, %B, linear-regression slope and historical volatility need a period of at least 2.

What "empty" means

An indicator that has not seen enough bars yet has no value. Empty means unknown, not false, and the rules built on it keep that meaning:

Rule Result
a comparison (gt, lt, compare, in_range …) of an empty value empty
rule.not of an empty value empty
rule.all false as soon as one input is false; true when all are true; otherwise empty
rule.any true as soon as one input is true; false when all are false; otherwise empty
rule.cross_up / rule.cross_down empty on the first bar both lines exist — there is no earlier bar to cross from
an entry whose gate is empty holds
Tables of rule.all and rule.any for two inputs and rule.not for one, each input true, false or empty: all is false whenever an input is false, any is true whenever an input is true, and every other combination with an empty input is empty.
Empty stays empty unless one input settles the answer: a false input makes all false, a true input makes any true.

So not(any(...)) does not fire while its inputs are still warming up, and a crossover that happened before the slow average existed is never reported as a fresh signal.

Comparing two values

Ladders of orders

A grid or martingale ladder emits several orders at once. A risk or execution node shapes a single order, so a ladder wired through one would be dropped without a trace; such a graph is refused when you save it, with a message that says why. A ladder can pass through decision.exit, which replaces it with one close when the exit condition fires. A long ladder whose deepest rung would sit at or below a zero price is refused too. Ladder sizes are computed relative to the largest rung, so even a 120-rung doubling ladder splits its total exactly instead of overflowing.

How much history a strategy needs

Each strategy's warm-up is derived from its graph:

The chain close, RSI(14), EMA(10) and its warm-up as one bar of 100: 70 bars for the RSI, 5 × 14, then 30 for the EMA, 3 × 10.
An EMA(10) of an RSI(14): five periods of 14 for Wilder’s RSI, then three periods of 10 for the EMA.

Backtests and live runs warm up on at least this much history before the first decision — see A backtest warms up the way a live run does.