# GHLA_SuperTrend_CCI_High_Low_Activator_Oscillator
#By CANDO13579
#STDEV zones by Chewie76
#Oscillator Range Analysis Labels by Antwerks
declare lower;
declare real_size;
input ghlaPeriod = 10;
input stPeriod = 14;
input stShiftTicks = 20.0;
input useFilter = yes;
def minTick = TickSize();
def shift = stShiftTicks * minTick;
# -----------------------------
# GHLA Logic
# -----------------------------
def ghlaAvgH = Average(high, ghlaPeriod);
def ghlaAvgL = Average(low, ghlaPeriod);
def sw = if close > ghlaAvgH then 1
else if close < ghlaAvgL then -1
else 0;
def ghlaDir = CompoundValue(1, if sw != 0 then sw else ghlaDir[1], 0);
def ghlaLevel = if ghlaDir < 0 then ghlaAvgH else ghlaAvgL;
# -----------------------------
# Custom CCI using Typical Price
# -----------------------------
def tp = (high + low + close) / 3;
def tpSMA = Average(tp, stPeriod);
def meanDev = Average(AbsValue(tp - tpSMA), stPeriod);
def cciValue = if meanDev == 0 then 0 else (tp - tpSMA) / (0.015 * meanDev);
# -----------------------------
# SuperTrend State Machine
# -----------------------------
# stFlag: 1=long, -1=short
rec stFlag = if IsNaN(stFlag[1]) then if cciValue >= 0 then 1 else -1
else if cciValue > 0 and stFlag[1] <= 0 then 1
else if cciValue < 0 and stFlag[1] >= 0 then -1
else stFlag[1];
rec st = if IsNaN(st[1]) then if cciValue >= 0 then low - shift else high + shift
else
if cciValue > 0 and stFlag[1] <= 0 then low - shift
else if cciValue < 0 and stFlag[1] >= 0 then high + shift
else
if stFlag > 0 and (low - shift) > st[1] then low - shift
else if stFlag < 0 and (high + shift) < st[1] then high + shift
else
if useFilter and stFlag > 0 and st[1] < st[1] and (close < open or high < high[1]) then st[1]
else if useFilter and stFlag < 0 and st[1] > st[1] and (close > open or low > low[1]) then st[1]
else st[1];
# -----------------------------
# signals
# -----------------------------
def notNaST = !IsNaN(st);
def upSignal = notNaST and close > st and close > ghlaLevel;
def downSignal = notNaST and close < st and close < ghlaLevel;
def neutralSignal = notNaST and !upSignal and !downSignal;
# -----------------------------
# Output (centered)
# -----------------------------
def signalCenter = 0;
plot Sig = signalCenter;
Sig.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
Sig.SetLineWeight(4);
Sig.AssignValueColor(
if upSignal then Color.GREEN
else if downSignal then Color.RED
else Color.LIGHT_GRAY
);
# Boundary reference lines
# -----------------------------
plot UpperLine = 1;
UpperLine.SetDefaultColor(Color.DARK_GRAY);
UpperLine.SetStyle(Curve.SHORT_DASH);
plot LowerLine = -1;
LowerLine.SetDefaultColor(Color.DARK_GRAY);
LowerLine.SetStyle(Curve.SHORT_DASH);
# Gann High/Low Activator Oscillator
input activatorPeriod = 14;
# Calculate simple moving averages
def avgHigh = Average(high, activatorPeriod);
def avgLow = Average(low, activatorPeriod);
# Determine state
def bullState = close > avgHigh;
def bearState = close < avgLow;
# Track the last valid state
def lastState = CompoundValue(1,
if bullState then 1
else if bearState then -1
else lastState[1],
0);
def avgRange = avgHigh - avgLow;
def oscillator =
if avgRange != 0 then
if lastState == 1 then (close - avgLow) / avgRange
else if lastState == -1 then (close - avgHigh) / avgRange
else 0.5
else 0.5;
# Plot oscillator
plot GannOsc = oscillator;
GannOsc.SetLineWeight(2);
GannOsc.AssignValueColor(
if lastState == 1 then CreateColor(0, 255, 0) # Green
else if lastState == -1 then CreateColor(255, 165, 0) # Orange
else Color.GRAY
);
# Plot midline
plot MidLine = 0.5;
MidLine.SetDefaultColor(Color.LIGHT_GRAY);
MidLine.SetStyle(Curve.SHORT_DASH);
# 2 Standard Deviation Full
input deviations = 2.0;
input deviations2 = 2.5;
input fullRange = yes;
input length = 300;
def regression;
def stdDeviation;
if (fullRange) {
regression = InertiaAll(GannOsc);
stdDeviation = StDevAll(GannOsc);
} else {
regression = InertiaAll(GannOsc, length);
stdDeviation = StDevAll(GannOsc, length);
}
plot UpperLine1 = regression + deviations * stdDeviation;
#plot MiddleLine = regression;
plot LowerLine1 = regression - deviations * stdDeviation;
UpperLine1.SetDefaultColor(Color.RED);
LowerLine1.SetDefaultColor(Color.GREEN);
UpperLine1.SetLineWeight(1);
LowerLine1.SetLineWeight(1);
UpperLine1.HideBubble();
UpperLine1.HideTitle();
LowerLine1.HideBubble();
LowerLine1.HideTitle();
plot UpperLine2 = regression + deviations2 * stdDeviation;
plot LowerLine2 = regression - deviations2 * stdDeviation;
UpperLine2.SetDefaultColor(Color.RED);
LowerLine2.SetDefaultColor(Color.GREEN);
UpperLine2.SetLineWeight(1);
LowerLine2.SetLineWeight(1);
UpperLine2.HideBubble();
UpperLine2.HideTitle();
LowerLine2.HideBubble();
LowerLine2.HideTitle();
AddCloud(UpperLine2, UpperLine1, Color.RED, Color.CURRENT);
AddCloud(LowerLine1, LowerLine2, Color.GREEN, Color.CURRENT);
# === Oscillator Range Analysis ===
def isOverbought2 = GannOsc >= UpperLine2;
def isOverbought1 = GannOsc >= UpperLine1;
def isOversold2 = GannOsc <= LowerLine2;
def isOversold1 = GannOsc <= LowerLine1;
def oscZone =
if isOverbought2 then 2
else if isOverbought1 then 1
else if isOversold2 then -2
else if isOversold1 then -1
else 0;
def forecastSignal =
if upSignal and oscZone <= -1 then 1 # Strong Buy
else if downSignal and oscZone >= 1 then -1 # Strong Sell
else if upSignal then 2 # Buy Opportunity
else if downSignal then -2 # Sell Opportunity
else 0;
# === AddLabel Displays ===
AddLabel(yes,
if upSignal then "TREND: Bullish (UP)"
else if downSignal then "TREND: Bearish (DOWN)"
else "TREND: Neutral/Sideways",
if upSignal then Color.GREEN
else if downSignal then Color.RED
else Color.GRAY
);
AddLabel(yes,
"GANN STATE: " +
(if lastState == 1 then "Bull Zone"
else if lastState == -1 then "Bear Zone"
else "Neutral"),
if lastState == 1 then CreateColor(0, 255, 0)
else if lastState == -1 then CreateColor(255, 165, 0)
else Color.GRAY
);
AddLabel(yes,
"OSC Range: " +
(if oscZone == 2 then "Overbought (2σ)"
else if oscZone == 1 then "Overbought (1.5σ)"
else if oscZone == -1 then "Oversold (1.5σ)"
else if oscZone == -2 then "Oversold (2σ)"
else "In Range"),
if oscZone >= 1 then Color.RED
else if oscZone <= -1 then Color.GREEN
else Color.LIGHT_GRAY
);
AddLabel(yes,
"FORECAST: " +
(if forecastSignal == 1 then "Strong BUY Zone"
else if forecastSignal == -1 then "Strong SELL Zone"
else if forecastSignal == 2 then "Buying Opportunity"
else if forecastSignal == -2 then "Selling Opportunity"
else "Wait / Watch"),
if forecastSignal == 1 or forecastSignal == 2 then Color.GREEN
else if forecastSignal == -1 or forecastSignal == -2 then Color.RED
else Color.YELLOW
);