Trying something new. Please test it out. Need help since it's my very first custom indicator.
Code:
# ═══════════════════════════════════════════════════════════════════
# Volume-Validated Trend Color (VVTC) — 5-Minute Edition
# ═══════════════════════════════════════════════════════════════════
declare upper;
# ═══════════════════════════════════════════════════════════════════
# INPUTS
# ═══════════════════════════════════════════════════════════════════
input trendMaLen = 21;
input fastMaLen = 8;
input volLookback = 15;
input volMultiplier = 1.3;
input volStrongMult = 2.0;
input atrLen = 10;
input momentumLen = 5;
input showLabels = yes;
input useVwap = yes;
input strictMode = yes;
# ═══════════════════════════════════════════════════════════════════
# MOVING AVERAGES
# ═══════════════════════════════════════════════════════════════════
def trendMA = ExpAverage(close, trendMaLen);
def fastMA = ExpAverage(close, fastMaLen);
def trendSlope = trendMA - trendMA[2];
def fastSlope = fastMA - fastMA[1];
# ═══════════════════════════════════════════════════════════════════
# VWAP — using built-in to avoid recursive def issues
# ═══════════════════════════════════════════════════════════════════
def isNewDay = GetDay() != GetDay()[1];
def cumVolPrice = if isNewDay then close * volume
else cumVolPrice[1] + close * volume;
def cumVol = if isNewDay then volume
else cumVol[1] + volume;
def vwapLine = if !useVwap then close
else if cumVol > 0 then cumVolPrice / cumVol
else close;
def aboveVwap = close > vwapLine;
def belowVwap = close < vwapLine;
# ═══════════════════════════════════════════════════════════════════
# VOLUME
# ═══════════════════════════════════════════════════════════════════
def avgVol = Average(volume, volLookback);
def volRatio = if avgVol != 0 then volume / avgVol else 1;
def isSigVol = volRatio >= volMultiplier;
def isStrongVol = volRatio >= volStrongMult;
def isNormalVol = volRatio >= 1.0;
def recentSigVol = isSigVol or isSigVol[1] or isSigVol[2];
def recentStrongVol = isStrongVol or isStrongVol[1] or isStrongVol[2];
# ═══════════════════════════════════════════════════════════════════
# MOMENTUM
# ═══════════════════════════════════════════════════════════════════
def atrVal = ATR(atrLen);
def safeATR = if atrVal > 0 then atrVal else 0.0001;
def momentum = close - close[momentumLen];
def momStrength = AbsValue(momentum) / safeATR;
def strongMom = momStrength > 1.2;
def weakMom = momStrength < 0.4;
def bullMom = momentum > 0;
def bearMom = momentum < 0;
# ═══════════════════════════════════════════════════════════════════
# CANDLE BODY
# ═══════════════════════════════════════════════════════════════════
def bullCandle = close > open;
def bearCandle = close < open;
def candleRange = high - low;
def bodySize = AbsValue(close - open);
def bodyRatio = if candleRange != 0 then bodySize / candleRange else 0;
def strongCandle = bodyRatio > 0.5;
# ═══════════════════════════════════════════════════════════════════
# TREND CONDITIONS
# Price must be on correct side of both MAs,
# MAs must be aligned, slopes must agree,
# and VWAP must confirm (if enabled)
# ═══════════════════════════════════════════════════════════════════
def priceAboveBoth = close > trendMA and close > fastMA;
def priceBelowBoth = close < trendMA and close < fastMA;
def masAlignedBull = fastMA > trendMA;
def masAlignedBear = fastMA < trendMA;
def slopesBull = trendSlope > 0 and fastSlope > 0;
def slopesBear = trendSlope < 0 and fastSlope < 0;
def vwapBull = if useVwap then aboveVwap else 1;
def vwapBear = if useVwap then belowVwap else 1;
def rawBull = priceAboveBoth and masAlignedBull and slopesBull and vwapBull;
def rawBear = priceBelowBoth and masAlignedBear and slopesBear and vwapBear;
# ═══════════════════════════════════════════════════════════════════
# VOLUME VALIDATED TREND
# ═══════════════════════════════════════════════════════════════════
def volConfirmedBull = rawBull and recentSigVol and !weakMom and bullMom;
def volConfirmedBear = rawBear and recentSigVol and !weakMom and bearMom;
# ═══════════════════════════════════════════════════════════════════
# TREND STATE — persistent, sticky
# ═══════════════════════════════════════════════════════════════════
def trendState =
if volConfirmedBull then 1
else if volConfirmedBear then -1
else trendState[1];
def inBull = trendState == 1;
def inBear = trendState == -1;
def inNeutral = trendState == 0;
def newBullTrend = inBull and trendState[1] != 1;
def newBearTrend = inBear and trendState[1] != -1;
# ═══════════════════════════════════════════════════════════════════
# STRICT MODE — candle direction must agree with trend
# ═══════════════════════════════════════════════════════════════════
def candleAgrees = (inBull and bullCandle) or (inBear and bearCandle);
def candleOpposes = (inBull and bearCandle) or (inBear and bullCandle);
def showFull = if strictMode then candleAgrees else 1;
def showDim = if strictMode then candleOpposes else 0;
# ═══════════════════════════════════════════════════════════════════
# CANDLE COLOR
# ═══════════════════════════════════════════════════════════════════
AssignPriceColor(
if inBull and showFull and recentStrongVol and strongMom
then CreateColor(0, 255, 255) # Cyan - max bull
else if inBull and showFull and recentStrongVol
then CreateColor(0, 230, 130) # Light green - strong vol
else if inBull and showFull and recentSigVol
then CreateColor(0, 190, 90) # Green - sig vol
else if inBull and showFull
then CreateColor(0, 140, 55) # Dark green - low vol
else if inBull and showDim
then CreateColor(40, 80, 60) # Muted - pullback in uptrend
else if inBear and showFull and recentStrongVol and strongMom
then CreateColor(255, 0, 255) # Magenta - max bear
else if inBear and showFull and recentStrongVol
then CreateColor(230, 0, 80) # Bright red - strong vol
else if inBear and showFull and recentSigVol
then CreateColor(190, 0, 55) # Red - sig vol
else if inBear and showFull
then CreateColor(140, 0, 35) # Dark red - low vol
else if inBear and showDim
then CreateColor(80, 40, 50) # Muted - bounce in downtrend
else CreateColor(100, 100, 100) # Gray - no trend
);
# ═══════════════════════════════════════════════════════════════════
# MA + VWAP PLOTS
# ═══════════════════════════════════════════════════════════════════
plot TrendMAPlot = trendMA;
TrendMAPlot.SetLineWeight(2);
TrendMAPlot.AssignValueColor(
if inBull then CreateColor(0, 200, 100)
else if inBear then CreateColor(200, 0, 60)
else Color.GRAY
);
plot FastMAPlot = fastMA;
FastMAPlot.SetLineWeight(1);
FastMAPlot.SetStyle(Curve.SHORT_DASH);
FastMAPlot.AssignValueColor(
if inBull then CreateColor(0, 255, 150)
else if inBear then CreateColor(255, 80, 80)
else Color.DARK_GRAY
);
plot VwapPlot = if useVwap then vwapLine else Double.NaN;
VwapPlot.SetDefaultColor(CreateColor(255, 200, 0));
VwapPlot.SetLineWeight(2);
# ═══════════════════════════════════════════════════════════════════
# EMA CLOUD
# ═══════════════════════════════════════════════════════════════════
AddCloud(
if inBull then fastMA else Double.NaN,
if inBull then trendMA else Double.NaN,
CreateColor(0, 50, 25), CreateColor(0, 50, 25)
);
AddCloud(
if inBear then fastMA else Double.NaN,
if inBear then trendMA else Double.NaN,
CreateColor(50, 0, 15), CreateColor(50, 0, 15)
);
# ═══════════════════════════════════════════════════════════════════
# TREND CHANGE ARROWS
# ═══════════════════════════════════════════════════════════════════
plot BullArrow = if newBullTrend then low else Double.NaN;
BullArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
BullArrow.SetDefaultColor(CreateColor(0, 255, 255));
BullArrow.SetLineWeight(4);
plot BearArrow = if newBearTrend then high else Double.NaN;
BearArrow.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
BearArrow.SetDefaultColor(CreateColor(255, 0, 255));
BearArrow.SetLineWeight(4);
# ═══════════════════════════════════════════════════════════════════
# LABELS
# ═══════════════════════════════════════════════════════════════════
AddLabel(showLabels,
"Trend: " + (if inBull then "BULL" else if inBear then "BEAR" else "NEUTRAL"),
if inBull then CreateColor(0, 230, 100)
else if inBear then CreateColor(230, 0, 60)
else Color.GRAY
);
AddLabel(showLabels,
"Vol: " + Round(volRatio, 1) + "x " +
(if isStrongVol then "STRONG" else if isSigVol then "SIG" else "WEAK"),
if isStrongVol then CreateColor(0, 255, 255)
else if isSigVol then CreateColor(0, 200, 100)
else Color.GRAY
);
AddLabel(showLabels and useVwap,
"VWAP: " + (if aboveVwap then "ABOVE" else "BELOW"),
if aboveVwap then CreateColor(0, 200, 100)
else CreateColor(200, 0, 60)
);
AddLabel(showLabels,
"Mom: " + Round(momStrength, 2) +
(if strongMom then " STRONG" else if weakMom then " WEAK" else " MOD"),
if strongMom then CreateColor(0, 230, 120)
else if weakMom then Color.GRAY
else Color.WHITE
);
Last edited by a moderator: