UPDATED CODE 4/7 - to clean it up a little bit
I wanted a quick visual for stacked moving averages with the ability to look at either exponential or simple and modify timeframes. I only went out as far as an hour for options because I usually only scalp or intraday. Added in the ability to select another symbol so I can see QQQ and SPY at the same time. You can select 3 moving averages
mod note:
I wanted a quick visual for stacked moving averages with the ability to look at either exponential or simple and modify timeframes. I only went out as far as an hour for options because I usually only scalp or intraday. Added in the ability to select another symbol so I can see QQQ and SPY at the same time. You can select 3 moving averages
mod note:
| Use Case | Purpose | Operational Behavior |
|---|---|---|
| Higher‑Timeframe Trend Confirmation | Ensure 15m setups align with 30m and 1h structure | Trade only when 4 of 6 or more timeframes show the same MA stack direction |
| Trade Filtering | Avoid low‑probability or countertrend trades | Mixed colors or fewer than 4 aligned timeframes signal no‑trade conditions |
| Trend Continuation Timing | Enter pullbacks or continuation setups with structural support | Use new bull or bear alignment alerts as confirmation of synchronized trend |
| Reversal Trap Avoidance | Prevent premature fading of trends | A reversal is valid only when multiple timeframes flip together, not when a single TF changes |
| Multi‑Timeframe Compression | See 1m through 1h structure without opening multiple charts | TF1–TF6 grid provides a full trend map in one lower pane |
| Novice Trader Guidance | Provide a simple go or no‑go system | Green alignment for long bias, red alignment for short bias, yellow or mixed means stand down |
Code:
# =========================================================
# 6-TF MA STACK ALIGNMENT
# COMPRESSED + DEFAULTS TO CURRENT CHART SYMBOL
# REACTS TO CURRENT CHART TF LIKE PRIOR VERSION
# STACK STATE = MA ORDER ONLY
# FIXED: ENUM TIMEFRAME MAPPING
# =========================================================
declare lower;
input useCustomSymbol = no;
input customSymbol = "SPY";
input averageType = {default Exponential, Simple};
input fastMA = 5;
input midMA = 13;
input slowMA = 21;
input candleColorMode = {default Off, FullAlignment, TF1, TF2, TF3, TF4, TF5, TF6};
input tf1 = {default M1, M2, M3, M4, M5, M10, M15, M20, M30, H1};
input tf2 = {default M2, M1, M3, M4, M5, M10, M15, M20, M30, H1};
input tf3 = {default M3, M1, M2, M4, M5, M10, M15, M20, M30, H1};
input tf4 = {default M4, M1, M2, M3, M5, M10, M15, M20, M30, H1};
input tf5 = {default M5, M1, M2, M3, M4, M10, M15, M20, M30, H1};
input tf6 = {default M10, M1, M2, M3, M4, M5, M15, M20, M30, H1};
input minAlignment = 4;
input showAlert = yes;
input showLabels = yes;
input labelSize = FontSize.SMALL;
input labelLocation = Location.TOP_LEFT;
def useChartSymbol = !useCustomSymbol;
# =========================================================
# STACK STATE
# 1 = fast > mid > slow
# -1 = fast < mid < slow
# 0 = mixed / not stacked
# =========================================================
script stackState {
input c = close;
input f = 5;
input m = 13;
input s = 21;
input avgType = {default Exponential, Simple};
def fastLine;
def midLine;
def slowLine;
if avgType == avgType.Exponential then {
fastLine = ExpAverage(c, f);
midLine = ExpAverage(c, m);
slowLine = ExpAverage(c, s);
} else {
fastLine = Average(c, f);
midLine = Average(c, m);
slowLine = Average(c, s);
}
plot state =
if IsNaN(c) then 0
else if fastLine > midLine and midLine > slowLine then 1
else if fastLine < midLine and midLine < slowLine then -1
else 0;
}
# =========================================================
# ENUM -> AGGREGATION
# FIXED: map enum directly instead of numeric index
# =========================================================
script tfToAgg {
input tf = {default M1, M2, M3, M4, M5, M10, M15, M20, M30, H1};
plot agg =
if tf == tf.M1 then AggregationPeriod.MIN
else if tf == tf.M2 then AggregationPeriod.TWO_MIN
else if tf == tf.M3 then AggregationPeriod.THREE_MIN
else if tf == tf.M4 then AggregationPeriod.FOUR_MIN
else if tf == tf.M5 then AggregationPeriod.FIVE_MIN
else if tf == tf.M10 then AggregationPeriod.TEN_MIN
else if tf == tf.M15 then AggregationPeriod.FIFTEEN_MIN
else if tf == tf.M20 then AggregationPeriod.TWENTY_MIN
else if tf == tf.M30 then AggregationPeriod.THIRTY_MIN
else AggregationPeriod.HOUR;
}
script tfToMinutes {
input tf = {default M1, M2, M3, M4, M5, M10, M15, M20, M30, H1};
plot mins =
if tf == tf.M1 then 1
else if tf == tf.M2 then 2
else if tf == tf.M3 then 3
else if tf == tf.M4 then 4
else if tf == tf.M5 then 5
else if tf == tf.M10 then 10
else if tf == tf.M15 then 15
else if tf == tf.M20 then 20
else if tf == tf.M30 then 30
else 60;
}
def agg1 = tfToAgg(tf1);
def agg2 = tfToAgg(tf2);
def agg3 = tfToAgg(tf3);
def agg4 = tfToAgg(tf4);
def agg5 = tfToAgg(tf5);
def agg6 = tfToAgg(tf6);
def tf1Min = tfToMinutes(tf1);
def tf2Min = tfToMinutes(tf2);
def tf3Min = tfToMinutes(tf3);
def tf4Min = tfToMinutes(tf4);
def tf5Min = tfToMinutes(tf5);
def tf6Min = tfToMinutes(tf6);
# =========================================================
# ACTIVE / REACTIVE LOGIC
# Only allow TF row when chart aggregation is <= selected TF
# =========================================================
def active1 = GetAggregationPeriod() <= agg1;
def active2 = GetAggregationPeriod() <= agg2;
def active3 = GetAggregationPeriod() <= agg3;
def active4 = GetAggregationPeriod() <= agg4;
def active5 = GetAggregationPeriod() <= agg5;
def active6 = GetAggregationPeriod() <= agg6;
# =========================================================
# TIMEFRAME CLOSES
# =========================================================
def c1 =
if !active1 then Double.NaN
else if useChartSymbol then close(period = agg1)
else close(symbol = customSymbol, period = agg1);
def c2 =
if !active2 then Double.NaN
else if useChartSymbol then close(period = agg2)
else close(symbol = customSymbol, period = agg2);
def c3 =
if !active3 then Double.NaN
else if useChartSymbol then close(period = agg3)
else close(symbol = customSymbol, period = agg3);
def c4 =
if !active4 then Double.NaN
else if useChartSymbol then close(period = agg4)
else close(symbol = customSymbol, period = agg4);
def c5 =
if !active5 then Double.NaN
else if useChartSymbol then close(period = agg5)
else close(symbol = customSymbol, period = agg5);
def c6 =
if !active6 then Double.NaN
else if useChartSymbol then close(period = agg6)
else close(symbol = customSymbol, period = agg6);
# =========================================================
# STATES
# inactive = 99 so rows can be grayed out
# =========================================================
def s1raw = stackState(c1, fastMA, midMA, slowMA, averageType);
def s2raw = stackState(c2, fastMA, midMA, slowMA, averageType);
def s3raw = stackState(c3, fastMA, midMA, slowMA, averageType);
def s4raw = stackState(c4, fastMA, midMA, slowMA, averageType);
def s5raw = stackState(c5, fastMA, midMA, slowMA, averageType);
def s6raw = stackState(c6, fastMA, midMA, slowMA, averageType);
def s1 = if active1 then s1raw else 99;
def s2 = if active2 then s2raw else 99;
def s3 = if active3 then s3raw else 99;
def s4 = if active4 then s4raw else 99;
def s5 = if active5 then s5raw else 99;
def s6 = if active6 then s6raw else 99;
# =========================================================
# ALIGNMENT
# =========================================================
def bullCount = (s1 == 1) + (s2 == 1) + (s3 == 1) + (s4 == 1) + (s5 == 1) + (s6 == 1);
def bearCount = (s1 == -1) + (s2 == -1) + (s3 == -1) + (s4 == -1) + (s5 == -1) + (s6 == -1);
def bullAlign = bullCount >= minAlignment;
def bearAlign = bearCount >= minAlignment;
def newBull = bullAlign and !bullAlign[1];
def newBear = bearAlign and !bearAlign[1];
# =========================================================
# ALERTS
# =========================================================
Alert(showAlert and newBull, "BULL ALIGNMENT (" + bullCount + "/6)", Alert.BAR, Sound.Ding);
Alert(showAlert and newBear, "BEAR ALIGNMENT (" + bearCount + "/6)", Alert.BAR, Sound.Ding);
# =========================================================
# CANDLE COLOR
# =========================================================
def candleState =
if candleColorMode == candleColorMode.FullAlignment then
if bullAlign then 1 else if bearAlign then -1 else 0
else if candleColorMode == candleColorMode.TF1 then if s1 == 99 then 0 else s1
else if candleColorMode == candleColorMode.TF2 then if s2 == 99 then 0 else s2
else if candleColorMode == candleColorMode.TF3 then if s3 == 99 then 0 else s3
else if candleColorMode == candleColorMode.TF4 then if s4 == 99 then 0 else s4
else if candleColorMode == candleColorMode.TF5 then if s5 == 99 then 0 else s5
else if candleColorMode == candleColorMode.TF6 then if s6 == 99 then 0 else s6
else 0;
AssignPriceColor(
if candleColorMode == candleColorMode.Off then Color.CURRENT
else if candleState == 1 then Color.GREEN
else if candleState == -1 then Color.RED
else Color.CURRENT
);
# =========================================================
# GRID
# =========================================================
def realBar = !IsNaN(close) and !IsNaN(close[1]);
plot r6 = if realBar then 6 else Double.NaN;
plot r5 = if realBar then 5 else Double.NaN;
plot r4 = if realBar then 4 else Double.NaN;
plot r3 = if realBar then 3 else Double.NaN;
plot r2 = if realBar then 2 else Double.NaN;
plot r1 = if realBar then 1 else Double.NaN;
r6.SetPaintingStrategy(PaintingStrategy.POINTS);
r5.SetPaintingStrategy(PaintingStrategy.POINTS);
r4.SetPaintingStrategy(PaintingStrategy.POINTS);
r3.SetPaintingStrategy(PaintingStrategy.POINTS);
r2.SetPaintingStrategy(PaintingStrategy.POINTS);
r1.SetPaintingStrategy(PaintingStrategy.POINTS);
r6.SetLineWeight(5);
r5.SetLineWeight(5);
r4.SetLineWeight(5);
r3.SetLineWeight(5);
r2.SetLineWeight(5);
r1.SetLineWeight(5);
r6.AssignValueColor(if s6 == 99 then Color.GRAY else if s6 == 1 then Color.GREEN else if s6 == -1 then Color.RED else Color.YELLOW);
r5.AssignValueColor(if s5 == 99 then Color.GRAY else if s5 == 1 then Color.GREEN else if s5 == -1 then Color.RED else Color.YELLOW);
r4.AssignValueColor(if s4 == 99 then Color.GRAY else if s4 == 1 then Color.GREEN else if s4 == -1 then Color.RED else Color.YELLOW);
r3.AssignValueColor(if s3 == 99 then Color.GRAY else if s3 == 1 then Color.GREEN else if s3 == -1 then Color.RED else Color.YELLOW);
r2.AssignValueColor(if s2 == 99 then Color.GRAY else if s2 == 1 then Color.GREEN else if s2 == -1 then Color.RED else Color.YELLOW);
r1.AssignValueColor(if s1 == 99 then Color.GRAY else if s1 == 1 then Color.GREEN else if s1 == -1 then Color.RED else Color.YELLOW);
# =========================================================
# ANCHORS
# =========================================================
plot upperAnchor = 7;
plot lowerAnchor = 0;
upperAnchor.Hide();
lowerAnchor.Hide();
# =========================================================
# LABELS
# =========================================================
AddLabel(showLabels,
"SYM " + (if useChartSymbol then GetSymbol() else customSymbol),
Color.WHITE,
labelLocation, labelSize);
AddLabel(showLabels,
if averageType == averageType.Exponential then "EXP" else "SMA",
Color.WHITE,
labelLocation, labelSize);
AddLabel(showLabels,
if candleColorMode == candleColorMode.Off then "Candle: Off"
else if candleColorMode == candleColorMode.FullAlignment then "Candle: Align"
else if candleColorMode == candleColorMode.TF1 then "Candle: TF1"
else if candleColorMode == candleColorMode.TF2 then "Candle: TF2"
else if candleColorMode == candleColorMode.TF3 then "Candle: TF3"
else if candleColorMode == candleColorMode.TF4 then "Candle: TF4"
else if candleColorMode == candleColorMode.TF5 then "Candle: TF5"
else "Candle: TF6",
Color.WHITE,
labelLocation, labelSize);
AddLabel(showLabels,
"TF6 " + (if tf6Min == 60 then "1H" else tf6Min + "M"),
if s6 == 99 then Color.GRAY else if s6 == 1 then Color.GREEN else if s6 == -1 then Color.RED else Color.YELLOW,
labelLocation, labelSize);
AddLabel(showLabels,
"TF5 " + (if tf5Min == 60 then "1H" else tf5Min + "M"),
if s5 == 99 then Color.GRAY else if s5 == 1 then Color.GREEN else if s5 == -1 then Color.RED else Color.YELLOW,
labelLocation, labelSize);
AddLabel(showLabels,
"TF4 " + (if tf4Min == 60 then "1H" else tf4Min + "M"),
if s4 == 99 then Color.GRAY else if s4 == 1 then Color.GREEN else if s4 == -1 then Color.RED else Color.YELLOW,
labelLocation, labelSize);
AddLabel(showLabels,
"TF3 " + (if tf3Min == 60 then "1H" else tf3Min + "M"),
if s3 == 99 then Color.GRAY else if s3 == 1 then Color.GREEN else if s3 == -1 then Color.RED else Color.YELLOW,
labelLocation, labelSize);
AddLabel(showLabels,
"TF2 " + (if tf2Min == 60 then "1H" else tf2Min + "M"),
if s2 == 99 then Color.GRAY else if s2 == 1 then Color.GREEN else if s2 == -1 then Color.RED else Color.YELLOW,
labelLocation, labelSize);
AddLabel(showLabels,
"TF1 " + (if tf1Min == 60 then "1H" else tf1Min + "M"),
if s1 == 99 then Color.GRAY else if s1 == 1 then Color.GREEN else if s1 == -1 then Color.RED else Color.YELLOW,
labelLocation, labelSize);
AddLabel(showLabels,
if bullAlign then "BULL " + bullCount + "/6"
else if bearAlign then "BEAR " + bearCount + "/6"
else "MIXED",
if bullAlign then Color.GREEN else if bearAlign then Color.RED else Color.GRAY,
labelLocation, labelSize);
Attachments
Last edited by a moderator: