TradingView indicator guides

MACD VXI Pine Script: SMA Signal, Cross Dots and Background States

MACD VXI combines an EMA price difference with an SMA signal, crossover dots and a two-color background. The background shows a current relationship; a dot records a strict crossing event. Those are not equivalent at equality, and neither establishes a trade outcome.

Inspect the Pine Script

Five outputs from one calculation

M = EMA(close,13) − EMA(close,21). S = SMA(M,8). H = M − S. The dot value is S when ta.cross(S,M) is true and otherwise na. The binary output is 1 when S ≥ M and 0 otherwise. With valid values, the background is red for H ≤ 0 and green for H > 0.

The signal is an SMA of MACD, unlike the EMA-based signal in the conventional ta.macd example. The pink line plots M, blue plots S, purple columns plot H, and orange dots are located at the current S value. A dot marks the bar on which sampled values changed order; it is not an interpolated exact intersection point.

TradingView’s MACD reference distinguishes main, signal and histogram values. This page describes the supplied VXI implementation without assigning an unverified origin or expansion to its name.

A background flip need not coincide with a dot

The background includes equality in its red state. The crossing test requires the current difference to be strictly positive or negative, with the previous difference on the opposite side or equal to zero. Arriving at equality can change the background without a dot; leaving equality can produce a dot without changing that background.

To check this with exact arithmetic, start with a long zero MACD history, then use M values 8, 8/7 and 0. The SMA length is 8:

BarMSHBackgroundDot
A817GreenYes, at 1
B8/78/70RedNo
C08/7−8/7RedYes, at 8/7

This tests the signal-and-state stage with synthetic MACD inputs, not a claimed price backtest. Floating-point implementations need a deliberate equality policy if approximations to the fractions are used. Do not silently replace the code’s strict comparisons with an undocumented tolerance.

Warmup and live updates are separate issues

On uninterrupted valid data, SMA(8) first becomes available after eight MACD observations. Before then, S is unavailable. Pine v6 comparisons involving na are false, so the raw helper’s S ≥ M test falls back to output 0. The example below explicitly suppresses background color until both values are valid; it does not display that fallback as an established green state.

The formulas and dots still update on the open bar. There is no barstate.isconfirmed gate: a dot can appear and disappear, and the background can change before close. TradingView’s repainting documentation explains this distinction. A fixed historical dataset produces deterministic values, but changes to history, adjustments or the data feed can also change a recalculation. No blanket non-repainting claim follows just from using ta.ema or ta.cross.

SMA versus EMA: compare the same input

For a signal input that has been zero for a long time and then has a single value of 1, SMA(8) initially becomes 1/8 = 0.125. EMA(8) initially becomes 2/9 ≈ 0.222222. The SMA keeps that impulse contribution for eight observations and then drops it; the EMA contribution decays recursively. This is a response difference, not proof that one removes more false signals.

Nor is every part of 13/21/8 faster than 12/26/9. The fast EMA coefficient at length 13 is 1/7, smaller than 2/13 at length 12. The slow length and signal method also change. Compare actual outputs rather than assigning the entire variant a universal lead or crossover frequency.

A background is not a price level or an order

Green can occur while M is negative: for M = −1 and S = −2, H = +1. Red can occur while M is positive: M = 1 and S = 2 gives H = −1. The background is therefore not a test of which price EMA is higher. The zero line refers to a difference, not a tradable price at which to place a stop.

A price stop must reference a price level, such as an explicitly defined entry or prior price extreme, with a distance in price units. An instruction to place a stop on the other side of the oscillator’s zero line does not define an executable order. Likewise, a filter within a percentage of zero needs a nonzero reference scale; ten percent of zero is still zero.

If a strategy waits for the next bar’s closing background, that information is not available at that bar’s open. Specify decision time and order-fill assumptions before evaluating such a rule.

What this example implements

The script fixes close and 13/21/8 on the chart timeframe. It has no settings inputs, alerts, automated divergence detection, higher-timeframe requests or strategy orders. Background transparency is 80 on Pine’s 0–100 scale: this controls opacity, not the fraction of the pane covered. Purple histogram columns keep one color; their sign and size must be read from their values.

Named plotting arguments make the source’s color, linewidth and style choices explicit. The warmup gate affects only the background. Any adaptation that changes the source, signal average or confirmation policy should document that difference and compare the resulting series before use.

Pine Script v6: implementation and limits

The final source includes all five outputs, named plot arguments and a valid-data gate for the background. Its 13/21/8 calculation remains fixed and its plots and dots remain live. Syntax validation does not establish trading performance.

Pine Script v6
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// (c) Pineify

//@version=6
indicator(title="MACD VXI Indicator", overlay=false, max_labels_count=500)

p_ta_macd_vxi(fastLength, slowLength, signalLength) =>
    source = close
    fastMA = ta.ema(source, fastLength)
    slowMA = ta.ema(source, slowLength)
    macd = fastMA - slowMA
    signal = ta.sma(macd, signalLength)
    hist = macd - signal
    crossDot = ta.cross(signal, macd) ? signal : na
    outputSignal = signal >= macd ? 1 : 0
    [macd, signal, hist, crossDot, outputSignal]

[p_ind_1_macd, p_ind_1_signal, p_ind_1_histogram, p_ind_1_crossDot, p_ind_1_outputSignal] = p_ta_macd_vxi(13, 21, 8)
hline(0, "MACD VXI - Zero Line", color.new(#787B86, 50))
plot(p_ind_1_histogram, title="MACD VXI - Histogram", color=color.rgb(156, 39, 176), linewidth=1, style=plot.style_columns)
plot(p_ind_1_macd, "MACD VXI - MACD", color.rgb(233, 30, 99, 0), 1)
plot(p_ind_1_signal, "MACD VXI - Signal", color.rgb(33, 150, 243, 0), 2)
plot(p_ind_1_crossDot, title="MACD VXI - Cross", color=color.rgb(255, 152, 0), linewidth=4, style=plot.style_circles)
ready = not na(p_ind_1_macd) and not na(p_ind_1_signal)
bgcolor(ready ? (p_ind_1_outputSignal > 0 ? color.new(color.rgb(244, 67, 54), 80) : color.new(color.rgb(76, 175, 80), 80)) : na)
Existing indicator chart preview
Existing visual preview. Verify exact values against the source; the image is not a performance result.

Specify a checkable adaptation in Pineify

Ask Pine Script AI Coding Agent for explicit length inputs, a chosen equality policy and separate confirmed-bar alerts for background transitions and strict crosses. Compare those events with the synthetic sequence, then inspect any order logic independently.

Open Pine Script AI Coding Agent

Educational indicator analysis. No measured trading performance is established here. Syntax validation does not prove formula equivalence, execution assumptions or profitability.

Implementation questions

No. Green means MACD is above its signal when both are valid. Both can still be negative.

The valid background is red. Merely arriving at equality does not satisfy a strict crossing event.

No. A transition from positive histogram to zero changes green to red without a cross. Moving from equality to negative histogram can then produce a dot while remaining red.

No. The script has no close-confirmation gate. Dots and the background can change during the current bar.

The SMA signal needs enough valid observations. Suppression prevents an unavailable comparison’s fallback value from appearing as a meaningful green state.

The oscillator zero is a difference of averages, not an asset price. A trading rule needs an explicit price-based order and timing model.