Confirmation Candles Indicator for ThinkorSwim

Christopher84

Active member
VIP
I have been working on an Idea I am calling confirmation candles. I often times find myself trying to find agreement among the numerous indicators that I use to help guide my decisions. Unfortunately, a lot of the time this creates indicator overload and analysis paralysis. So I have included 13 indicators of trend within this indicator. You can choose how many of the 13 indicators have to be in agreement in order to confirm the trend. I may have gone a bit overboard here, however it makes it adaptable to individual risk tolerance and trading style. Checkout the image below. If anyone likes this idea/indicator, I am happy to share the script.

7ItcupI.png

tOhnko8.png


Code:
#
#Confirmation Candles V.8
#Created 04/15/2021 by Christopher84
#Select the level of agreement among the 14 indicators included.
#Changed 04/19/2021 to V.3 - Removed ChaikinOsc and replaced with STARCBands. Added squeeze alert.
#Changed 04/20/2021 to V.4 - Added Keltner Channel, Labels, and Buy and Sell Zones. Mean Reversion and Breakout Labels added. Reversal_Alert points added.
#Changed 4/22/2021 to V.5 - Removed Buy/Sell clouds. Created new reversal alert buy(gray points) and take profit (red points). Increase factorK.
#Changed 4/23/2021 to V.6 - Refined reversal signals. Fully integrated Super_OB_OS indicator. Fixed candles going yellow if colored_candles is off.
#Changed 4/26/2021 to V.7 - Refined reversal signals and included Keltner Bandwidth. Adjusted Keltner Channel levels.
#Changed 4/27/2021 to V.8 - Improved reversal signals and included support and resistance zones.

#Keltner Channel
declare upper;
def displace = 0;
input factorK = 2.0;
input lengthK = 20;
def price = close;
input averageType = AverageType.SIMPLE;
def trueRangeAverageType = AverageType.SIMPLE;
def BulgeLengthK = 150;
def SqueezeLengthK = 150;
def BulgeLengthK2 = 40;
def SqueezeLengthK2 = 40;
input BulgeLengthPrice = 75;
input SqueezeLengthPrice = 75;
input BulgeLengthPrice2 = 20;
input SqueezeLengthPrice2 = 20;

def shift = factorK * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK);
def averageK = MovingAverage(averageType, price, lengthK);
def AvgK = averageK[-displace];
def Upper_BandK = averageK[-displace] + shift[-displace];
def Lower_BandK = averageK[-displace] - shift[-displace];

def conditionK1 = price >= Upper_BandK;
def conditionK2 = (Upper_BandK[1] < Upper_BandK) and (Lower_BandK[1] < Lower_BandK);
def conditionK2L = (Upper_BandK[2] < Upper_BandK[1]) and (Lower_BandK[2] < Lower_BandK[1]);
def conditionK3L = (Upper_BandK[3] < Upper_BandK[2]) and (Lower_BandK[3] < Lower_BandK[2]);
def conditionK3 = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);
def BandwidthK = (Upper_BandK - Lower_BandK) / AvgK * 100;
def condition_BWKUP = BandwidthK[1] < BandwidthK;
def condition_BWKDOWN = BandwidthK[1] > BandwidthK;
def BulgeK = Highest(BandwidthK, BulgeLengthK);
def SqueezeK = Lowest(BandwidthK, SqueezeLengthK);
def BulgeK2 = Highest(BandwidthK, BulgeLengthK2);
def SqueezeK2 = Lowest(BandwidthK, SqueezeLengthK2);

plot BulgePrice = Highest(price, BulgeLengthPrice);
BulgePrice.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
plot SqueezePrice = Lowest(price, SqueezeLengthPrice);
SqueezePrice.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);

plot BulgePrice2 = Highest(price, BulgeLengthPrice2);
BulgePrice2.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
BulgePrice2.SetStyle(Curve.SHORT_DASH);
plot SqueezePrice2 = Lowest(price, SqueezeLengthPrice2);
SqueezePrice2.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
SqueezePrice2.SetStyle(Curve.SHORT_DASH);

#MACD with Price
def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input MACD_AverageType = {SMA, default EMA};
def MACDLevel = 0.0;

def fastEMA = ExpAverage(price, fastLength);
def slowEMA = ExpAverage(price, slowLength);
def Value;
def Avg;
switch (MACD_AverageType) {
case SMA:
    Value = Average(price, fastLength) - Average(price, slowLength);
    Avg = Average(Value, MACDLength);
case EMA:
    Value = fastEMA - slowEMA;
    Avg = ExpAverage(Value, MACDLength);
}
def Diff = Value - Avg;
def Level = MACDLevel;

def condition1 = Value[1] <= Value;

#RSI
def RSI_length = 14;
def RSI_AverageType = AverageType.WILDERS;
def RSI_OB = 70;
def RSI_OS = 30;

def NetChgAvg = MovingAverage(RSI_AverageType, price - price[1], RSI_length);
def TotChgAvg = MovingAverage(RSI_AverageType, AbsValue(price - price[1]), RSI_length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);

def condition2 = (RSI[3] < RSI) is true or (RSI >= 80) is true;
def conditionOB1 = RSI > RSI_OB;
def conditionOS1 = RSI < RSI_OS;


#MFI
def MFI_Length = 14;
def MFIover_Sold = 20;
def MFIover_Bought = 80;
def movingAvgLength = 1;
def MoneyFlowIndex = Average(MoneyFlow(high, close, low, volume, MFI_Length), movingAvgLength);
def MFIOverBought = MFIover_Bought;
def MFIOverSold = MFIover_Sold;

def condition3 = (MoneyFlowIndex[2] < MoneyFlowIndex) is true or (MoneyFlowIndex > 85) is true;
def conditionOB2 = MoneyFlowIndex > MFIover_Bought;
def conditionOS2 = MoneyFlowIndex < MFIover_Sold;

#Forecast
def na = Double.NaN;
def MidLine = 50;
def Momentum = MarketForecast().Momentum;
def NearT =  MarketForecast().NearTerm;
def Intermed = MarketForecast().Intermediate;
def FOB = 80;
def FOS = 20;
def upperLine = 110;

def condition4 = (Intermed[1] <= Intermed) and (NearT >= MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;


#Pivot Signals
def n = 20;
def ticks = 2.0;
def bnOK = BarNumber() > n;
def isHigher = fold i = 1 to n + 1 with p = 1 while p do high > GetValue(high, -i);
def HH = if bnOK and isHigher and high == Highest(high, n) then high else Double.NaN;
def isLower = fold j = 1 to n + 1 with q = 1 while q do low < GetValue(low, -j);
def LL = if bnOK and isLower and low == Lowest(low, n) then low else Double.NaN;
def PivH = if HH > 0 then HH else Double.NaN;
def PivL = if LL > 0 then LL else Double.NaN;

def UpPivotLow = !IsNaN(PivL);
#UpPivotLow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#UpPivotLow.SetLineWeight(4);
#UpPivotLow.SetDefaultColor(Color.GREEN);

def DownPivotHigh = !IsNaN(PivH);
#DownPivotHigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#DownPivotHigh.SetLineWeight(4);
#DownPivotHigh.SetDefaultColor(Color.RED);

def condition5 = !IsNaN(PivL);

#EMA_1
def EMA_length = 12;
def AvgExp = ExpAverage(price[-displace], EMA_length);

def condition6 = (price >= AvgExp) and (AvgExp[2] <= AvgExp);

#EMA_2
def EMA_2length = 20;
def displace2 = 0;
def AvgExp2 = ExpAverage(price[-displace2], EMA_2length);

def condition7 = (price >= AvgExp2) and (AvgExp[2] <= AvgExp);

#DMI Oscillator
def DMI_length = 5;#Typically set to 10
input DMI_averageType = AverageType.WILDERS;
def diPlus = DMI(DMI_length, DMI_averageType)."DI+";
def diMinus = DMI(DMI_length, DMI_averageType)."DI-";
def Osc = diPlus - diMinus;
def Hist = Osc;
def ZeroLine = 0;

def condition8 = Osc >= ZeroLine;

#Trend_Periods
def TP_fastLength = 3;#Typically 7
def TP_slowLength = 4;#Typically 15
def Periods = Sign(ExpAverage(close, TP_fastLength) - ExpAverage(close, TP_slowLength));

def condition9 = Periods > 0;

#Polarized Fractal Efficiency
def PFE_length = 5;#Typically 10
def smoothingLength = 2.5;#Typically 5
def PFE_diff = close - close[PFE_length - 1];
def val = 100 * Sqrt(Sqr(PFE_diff) + Sqr(PFE_length)) / Sum(Sqrt(1 + Sqr(close - close[1])), PFE_length - 1);
def PFE = ExpAverage(if PFE_diff > 0 then val else -val, smoothingLength);
def UpperLevel = 50;
def LowerLevel = -50;

def condition10 = PFE > 0;
def conditionOB5 = PFE > UpperLevel;
def conditionOS5 = PFE < LowerLevel;


#Bollinger Bands PercentB
input BBPB_averageType = AverageType.SIMPLE;
def BBPB_length = 5;#Typically 20
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;
def BBPB_OB = 100;
def BBPB_OS = 0;
def upperBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).LowerBand;
def PercentB = (price - lowerBand) / (upperBand - lowerBand) * 100;
def HalfLine = 50;
def UnitLine = 100;

def condition11 = PercentB > HalfLine;
def conditionOB6 = PercentB > BBPB_OB;
def conditionOS6 = PercentB < BBPB_OS;


#STARC Bands
def ATR_length = 15;
def SMA_lengthS = 6;
def multiplier_factor = 1.5;
def valS = Average(price, SMA_lengthS);
def average_true_range = Average(TrueRange(high, close, low), length = ATR_length);
def Upper_BandS = valS[-displace] + multiplier_factor * average_true_range[-displace];
def Middle_BandS = valS[-displace];
def Lower_BandS = valS[-displace] - multiplier_factor * average_true_range[-displace];

def condition12 = (Upper_BandS[1] <= Upper_BandS) and (Lower_BandS[1] <= Lower_BandS);

#Klinger Histogram
def Klinger_Length = 8;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0) and (KVOsc[1] <= KVOsc);

#Projection Oscillator
def ProjectionOsc_length = 9;#Typically 10
def MaxBound = HighestWeighted(high, ProjectionOsc_length, LinearRegressionSlope(price = high, length = ProjectionOsc_length));
def MinBound = LowestWeighted(low, ProjectionOsc_length, LinearRegressionSlope(price = low, length = ProjectionOsc_length));
def ProjectionOsc_diff = MaxBound - MinBound;
def PROSC = if ProjectionOsc_diff != 0 then 100 * (close - MinBound) / ProjectionOsc_diff else 0;
def PROSC_OB = 80;
def PROSC_OS = 20;

def condition14 = PROSC > 50;
def conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = PROSC < PROSC_OS;


#Trend Confirmation Calculator
#Confirmation_Factor range 1-15.
input coloredCandlesOn = yes;
input Confirmation_Factor = 3;
#Use for testing conditions individually. Remove # from line below and change Confirmation_Factor to 1.
#def Agreement_Level = condition1;
def Agreement_LevelOB = 12;
def Agreement_LevelOS = 3;

def Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13 + condition14 + conditionK1 + conditionK2;

def conditionChannel1 = Upper_BandK > price;
def conditionChannel2 = Lower_BandK < price;

def UP = Agreement_Level >= Confirmation_Factor;
def DOWN = Agreement_Level <= Confirmation_Factor;

AssignPriceColor(if coloredCandlesOn and UP then Color.LIGHT_GREEN else if coloredCandlesOn and DOWN then Color.RED else Color.CURRENT);

#Additional Signals

#Super_OB/OS Signal
def OB_Level = conditionOB1 + conditionOB2 + conditionOB3 + conditionOB4 + conditionOB5 + conditionOB6 + conditionOB7;
def OS_Level = conditionOS1 + conditionOS2 + conditionOS3 + conditionOS4 + conditionOS5 + conditionOS6 + conditionOS7;

def Concensus_Line = OB_Level - OS_Level;
def Zero_Line = 0;
def Super_OB = 4;
def Super_OS = -2;

def DOWN_OB = (Agreement_Level > Agreement_LevelOB) and (Concensus_Line > Super_OB);
def UP_OS = (Agreement_Level < Agreement_LevelOS) and (Concensus_Line < Super_OS);

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Concensus_Line < Super_OB and Concensus_Line > Super_OS;

#AddVerticalLine (OS_Buy and !OS_Buy[1], close, Color.GREEN, Curve.SHORT_DASH);
#AddVerticalLine (Neutral and !neutral[1], close, Color.Gray, Curve.SHORT_DASH);
#AddVerticalLine (OB_Sell and OB_Sell and !OB_Sell[1], close, Color.RED, Curve.SHORT_DASH);

def Buy_Opportnity = if OS_Buy then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
#AddCloud(Buy_Opportnity, Neutral, Color.LIGHT_GREEN, Color.LIGHT_RED);
def Sell_Opportnity = if OB_Sell then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
#AddCloud(Sell_Opportnity, Neutral, Color.LIGHT_RED, Color.LIGHT_RED);

def OB_Signal = price crosses below Upper_BandK;
#OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#OB_Signal.SetLineWeight(1);
#OB_Signal.SetDefaultColor(Color.RED);

def OS_Signal = price crosses above Lower_BandK;
#OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#OS_Signal.SetLineWeight(1);
#OS_Signal.SetDefaultColor(Color.GREEN);

#Squeeze Alert
def length = 20;
def BulgeLength = 150;
def SqueezeLength = 150;
def upperBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_up, averageType).UpperBand;
def lowerBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_up, averageType).LowerBand;
def midLineBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_up, averageType).MidLine;
def Bandwidth = (upperBandBB - lowerBandBB) / midLineBB * 100;
def Bulge = Highest(Bandwidth, BulgeLength);
def Squeeze = Lowest(Bandwidth, SqueezeLength);

plot Squeeze_Alert = Bandwidth <= Squeeze;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Squeeze_Alert.SetLineWeight(3);
Squeeze_Alert.SetDefaultColor(Color.YELLOW);

#Trend Signals
#Bollinger_Bands2
input lengthBB = 10;
input Num_Dev_DnBB = -0.8;
input Num_Dev_upBB = 0.8;

def price1 = open;
def sDev = StDev(data = price[-displace], length = lengthBB);
def MidLineBB2 = MovingAverage(averageType, data = price[-displace], length = lengthBB);
def LowerBandBB2 = MidLineBB2 + Num_Dev_DnBB * sDev;
def UpperBandBB2 = MidLineBB2 + Num_Dev_upBB * sDev;


def condition_Slope_RevUP = ((Agreement_Level[1] < Agreement_Level) or (Agreement_Level[2] >= Agreement_Level[1])) or ((Concensus_Line[1] < Concensus_Line) and (Concensus_Line[2] >= Concensus_Line[1]));
def condition_Slope_RevDOWN = ((Agreement_Level[1] > Agreement_Level) and (Agreement_Level[2] <= Agreement_Level[1])) or ((Concensus_Line[1] > Concensus_Line) and (Concensus_Line[2] <= Concensus_Line[1]));
def condition_Flat = (Agreement_Level[2] == Agreement_Level[1]) or (Concensus_Line[2] == Concensus_Line[1]);
def condition_Flat2 = ((Agreement_Level[1] == Agreement_Level) and (Concensus_Line[1] == Concensus_Line));
def condition_Flat3 = ((Agreement_Level[1] == Agreement_Level) or (Concensus_Line[1] == Concensus_Line));
def condition_OB = ((Agreement_Level >= 12) or (Concensus_Line >= 2));# and (price > Upper_BandK));
def condition_OS = ((Agreement_Level <= 2) or (Concensus_Line <= -2));# and (price < lower_BandK)
def condition_AC_SlopeDOWN = (Agreement_Level[1] > Agreement_Level) or (Concensus_Line[1] > Concensus_Line);
def condition_AC_SlopeUP = (Agreement_Level[1] < Agreement_Level) or (Concensus_Line[1] < Concensus_Line);

plot UPConfirmSignal = Agreement_Level crosses above Confirmation_Factor;
UPConfirmSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
UPConfirmSignal.SetLineWeight(1);
UPConfirmSignal.SetDefaultColor(Color.GREEN);

plot DOWNConfirmSignal = Agreement_Level crosses below Confirmation_Factor;
DOWNConfirmSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
DOWNConfirmSignal.SetLineWeight(1);
DOWNConfirmSignal.SetDefaultColor(Color.RED);

plot Reversal_Buy_1 = (BandwidthK crosses below BulgeK2) and (condition_OS);
Reversal_Buy_1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Buy_1.SetLineWeight(3);
Reversal_Buy_1.SetDefaultColor(Color.GREEN);

plot Reversal_Buy2 = (BandwidthK crosses above SqueezeK) and (condition_OS);
#((Agreement_Level < 2) and Concensus_Line < 0) and condition_Slope_RevUP and conditionK2 and condition_BWKDOWN;
Reversal_Buy2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Buy2.SetLineWeight(3);
Reversal_Buy2.SetDefaultColor(Color.GREEN);

plot Reversal_Buy_3 = (BandwidthK == BulgeK) and (Concensus_Line < 0) and condition_AC_SlopeUP;
Reversal_Buy_3.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Buy_3.SetLineWeight(3);
Reversal_Buy_3.SetDefaultColor(Color.GREEN);

plot Reversal_Sell_1 = ((Agreement_Level crosses below 10) and (Concensus_Line crosses below Super_OB) and (price > Middle_BandS));
Reversal_Sell_1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Sell_1.SetLineWeight(3);
Reversal_Sell_1.SetDefaultColor(Color.RED);

plot Reversal_Sell_2 = (BandwidthK crosses below BulgeK2) and (Concensus_Line >= 0) and (Agreement_Level >= 5) and (condition_Flat3 or condition_AC_SlopeDOWN);
Reversal_Sell_2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Sell_2.SetLineWeight(3);
Reversal_Sell_2.SetDefaultColor(Color.RED);

plot Reversal_Sell_3 = (BandwidthK == SqueezeK) and condition_OB;
Reversal_Sell_3.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Sell_3.SetLineWeight(3);
Reversal_Sell_3.SetDefaultColor(Color.RED);

#plot Reversal_MeanReversion = conditionK3 and (price > UpperBandBB2);
#Reversal_MeanReversion.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
#Reversal_MeanReversion.SetLineWeight(3);
#Reversal_MeanReversion.SetDefaultColor(Color.RED);

def condition_Reversal_CA_Buy = (Agreement_Level < 1) and (Agreement_Level[1] <= Agreement_Level);
def condition_Reversal_SOS_Buy = (Concensus_Line < -2) and (Concensus_Line[1] <= Concensus_Line);
#plot Reversal_Buy = (condition_Reversal_CA_Buy) or (condition_Reversal_SOS_Buy);
#Reversal_Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
#Reversal_Buy.SetLineWeight(1);
#Reversal_Buy.SetDefaultColor(Color.LIGHT_GRAY);

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
AddLabel(yes, "Look_To_Buy", if Buy then Color.GREEN else Color.GRAY);
AddLabel(yes, "Look_To_Sell", if Sell then Color.RED else Color.GRAY);

def MomentumUP = Agreement_Level[1] < Agreement_Level;
def MomentumDOWN = Agreement_Level[1] > Agreement_Level;
AddLabel(yes, "Increasing Momentum", if MomentumUP then Color.GREEN else Color.GRAY);
AddLabel(yes, "Decreasing Momentum", if MomentumDOWN then Color.RED else Color.GRAY);

def conditionMR = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);
AddLabel(yes, "MEAN REVERSION", if conditionMR then Color.RED else Color.GRAY);

def conditionBO = ((Upper_BandS[1] < Upper_BandS) and (Lower_BandS[1] < Lower_BandS)) and ((Upper_BandK[1] < Upper_BandK) and (Lower_BandK[1] < Lower_BandK));
AddLabel(yes, "BREAKOUT", if conditionBO then Color.GREEN else Color.GRAY);

def conditionBD = ((Upper_BandS[1] > Upper_BandS) and (Lower_BandS[1] > Lower_BandS) and (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK));
AddLabel(yes, "BREAKDOWN", if conditionBD then Color.RED else Color.GRAY);

def Squeeze_Signal = Squeeze_Alert;
AddLabel(yes, "SQUEEZE ALERT", if Squeeze_Signal then Color.YELLOW else Color.GRAY);

CC: Confirmation Consensus

This is a new candle painting indicator CC Candles (Confirmation Consensus), that I have adapted from the original Confirmation Candles. The main difference between the two indicators is that Confirmation Candles confirms only positive factors for upward price movement, and CC Candles utilizes both positive and negative factors of price movement and weighs them against each other to derive the Consensus Level being above 0(up) or below 0 (down). There is a histagram style lower study that goes with it. Check it out! Big thanks to everyone trying out my work and giving feedback.

kaMjEs7.png


Code:
#(Consensus Confirmation) CC Candles V.1
#Created 04/28/2021 by Christopher84
#Based off of the Confirmation Candles Study. Main difference is that CC Candles weigh factors of positive and negative price movement to create the Consensus_Level. The Consensus_Level is considered positive if above zero and negative if below zero.

#Keltner Channel
declare upper;
def displace = 0;
input factorK = 2.0;
input lengthK = 20;
def price = close;
input averageType = AverageType.SIMPLE;
def trueRangeAverageType = AverageType.SIMPLE;
def BulgeLengthK = 150;
def SqueezeLengthK = 150;
def BulgeLengthK2 = 40;
def SqueezeLengthK2 = 40;
input BulgeLengthPrice = 75;
input SqueezeLengthPrice = 75;
input BulgeLengthPrice2 = 20;
input SqueezeLengthPrice2 = 20;


def shift = factorK * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK);
def averageK = MovingAverage(averageType, price, lengthK);
def AvgK = averageK[-displace];
def Upper_BandK = averageK[-displace] + shift[-displace];
def Lower_BandK = averageK[-displace] - shift[-displace];

def conditionK1 = price >= Upper_BandK;
def conditionK2 = (Upper_BandK[1] < Upper_BandK) and (Lower_BandK[1] < Lower_BandK);
def conditionK3D = price < Lower_BandK;
def conditionK4D = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);

def conditionK2L = (Upper_BandK[2] < Upper_BandK[1]) and (Lower_BandK[2] < Lower_BandK[1]);
def conditionK3L = (Upper_BandK[3] < Upper_BandK[2]) and (Lower_BandK[3] < Lower_BandK[2]);
def conditionK3 = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);

def BandwidthK = (Upper_BandK - Lower_BandK) / AvgK * 100;
def condition_BWKUP = BandwidthK[1] < BandwidthK;
def condition_BWKDOWN = BandwidthK[1] > BandwidthK;
def BulgeK = Highest(BandwidthK, BulgeLengthK);
def SqueezeK = Lowest(BandwidthK, SqueezeLengthK);
def BulgeK2 = Highest(BandwidthK, BulgeLengthK2);
def SqueezeK2 = Lowest(BandwidthK, SqueezeLengthK2);

plot BulgePrice = Highest(price, BulgeLengthPrice);
BulgePrice.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
plot SqueezePrice = Lowest(price, SqueezeLengthPrice);
SqueezePrice.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);

plot BulgePrice2 = Highest(price, BulgeLengthPrice2);
BulgePrice2.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
BulgePrice2.SetStyle(Curve.SHORT_DASH);
plot SqueezePrice2 = Lowest(price, SqueezeLengthPrice2);
SqueezePrice2.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
SqueezePrice2.SetStyle(Curve.SHORT_DASH);

#MACD with Price
def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input MACD_AverageType = {SMA, default EMA};
def MACDLevel = 0.0;

def fastEMA = ExpAverage(price, fastLength);
def slowEMA = ExpAverage(price, slowLength);
def Value;
def Avg;
switch (MACD_AverageType) {
case SMA:
    Value = Average(price, fastLength) - Average(price, slowLength);
    Avg = Average(Value, MACDLength);
case EMA:
    Value = fastEMA - slowEMA;
    Avg = ExpAverage(Value, MACDLength);
}
def Diff = Value - Avg;
def Level = MACDLevel;

def condition1 = Value[1] <= Value;
def condition1D = Value[1] > Value;

#RSI
def RSI_length = 14;
def RSI_AverageType = AverageType.WILDERS;
def RSI_OB = 70;
def RSI_OS = 30;

def NetChgAvg = MovingAverage(RSI_AverageType, price - price[1], RSI_length);
def TotChgAvg = MovingAverage(RSI_AverageType, AbsValue(price - price[1]), RSI_length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);

def condition2 = (RSI[3] < RSI) is true or (RSI >= 80) is true;
def condition2D = (RSI[3] > RSI) is true or (RSI < 20) is true;
def conditionOB1 = RSI > RSI_OB;
def conditionOS1 = RSI < RSI_OS;


#MFI
def MFI_Length = 14;
def MFIover_Sold = 20;
def MFIover_Bought = 80;
def movingAvgLength = 1;
def MoneyFlowIndex = Average(MoneyFlow(high, close, low, volume, MFI_Length), movingAvgLength);
def MFIOverBought = MFIover_Bought;
def MFIOverSold = MFIover_Sold;

def condition3 = (MoneyFlowIndex[2] < MoneyFlowIndex) is true or (MoneyFlowIndex > 85) is true;
def condition3D = (MoneyFlowIndex[2] > MoneyFlowIndex) is true or (MoneyFlowIndex < 20) is true;
def conditionOB2 = MoneyFlowIndex > MFIover_Bought;
def conditionOS2 = MoneyFlowIndex < MFIover_Sold;

#Forecast
def na = Double.NaN;
def MidLine = 50;
def Momentum = MarketForecast().Momentum;
def NearT =  MarketForecast().NearTerm;
def Intermed = MarketForecast().Intermediate;
def FOB = 80;
def FOS = 20;
def upperLine = 110;

def condition4 = (Intermed[1] <= Intermed) and (NearT >= MidLine);
def condition4D = (Intermed[1] > Intermed) and (NearT < MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;


#Pivot Signals
def n = 20;
def ticks = 2.0;
def bnOK = BarNumber() > n;
def isHigher = fold i = 1 to n + 1 with p = 1 while p do high > GetValue(high, -i);
def HH = if bnOK and isHigher and high == Highest(high, n) then high else Double.NaN;
def isLower = fold j = 1 to n + 1 with q = 1 while q do low < GetValue(low, -j);
def LL = if bnOK and isLower and low == Lowest(low, n) then low else Double.NaN;
def PivH = if HH > 0 then HH else Double.NaN;
def PivL = if LL > 0 then LL else Double.NaN;

def UpPivotLow = !IsNaN(PivL);
#UpPivotLow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#UpPivotLow.SetLineWeight(4);
#UpPivotLow.SetDefaultColor(Color.GREEN);

def DownPivotHigh = !IsNaN(PivH);
#DownPivotHigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#DownPivotHigh.SetLineWeight(4);
#DownPivotHigh.SetDefaultColor(Color.RED);

def condition5 = !IsNaN(PivL);
def condition5D = !IsNaN(PivH);

#EMA_1
def EMA_length = 12;
def AvgExp = ExpAverage(price[-displace], EMA_length);

def condition6 = (price >= AvgExp) and (AvgExp[2] <= AvgExp);
def condition6D = (price < AvgExp) and (AvgExp[2] > AvgExp);

#EMA_2
def EMA_2length = 20;
def displace2 = 0;
def AvgExp2 = ExpAverage(price[-displace2], EMA_2length);

def condition7 = (price >= AvgExp2) and (AvgExp[2] <= AvgExp);
def condition7D = (price < AvgExp2) and (AvgExp[2] > AvgExp);

#DMI Oscillator
def DMI_length = 5;#Typically set to 10
input DMI_averageType = AverageType.WILDERS;
def diPlus = DMI(DMI_length, DMI_averageType)."DI+";
def diMinus = DMI(DMI_length, DMI_averageType)."DI-";
def Osc = diPlus - diMinus;
def Hist = Osc;
def ZeroLine = 0;

def condition8 = Osc >= ZeroLine;
def condition8D = Osc < ZeroLine;

#Trend_Periods
def TP_fastLength = 3;#Typically 7
def TP_slowLength = 4;#Typically 15
def Periods = Sign(ExpAverage(close, TP_fastLength) - ExpAverage(close, TP_slowLength));

def condition9 = Periods > 0;
def condition9D = Periods < 0;

#Polarized Fractal Efficiency
def PFE_length = 5;#Typically 10
def smoothingLength = 2.5;#Typically 5
def PFE_diff = close - close[PFE_length - 1];
def val = 100 * Sqrt(Sqr(PFE_diff) + Sqr(PFE_length)) / Sum(Sqrt(1 + Sqr(close - close[1])), PFE_length - 1);
def PFE = ExpAverage(if PFE_diff > 0 then val else -val, smoothingLength);
def UpperLevel = 50;
def LowerLevel = -50;

def condition10 = PFE > 0;
def condition10D = PFE < 0;
def conditionOB5 = PFE > UpperLevel;
def conditionOS5 = PFE < LowerLevel;


#Bollinger Bands PercentB
input BBPB_averageType = AverageType.SIMPLE;
def BBPB_length = 5;#Typically 20
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;
def BBPB_OB = 100;
def BBPB_OS = 0;
def upperBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).LowerBand;
def PercentB = (price - lowerBand) / (upperBand - lowerBand) * 100;
def HalfLine = 50;
def UnitLine = 100;

def condition11 = PercentB > HalfLine;
def condition11D = PercentB < HalfLine;
def conditionOB6 = PercentB > BBPB_OB;
def conditionOS6 = PercentB < BBPB_OS;


#STARC Bands
def ATR_length = 15;
def SMA_lengthS = 6;
def multiplier_factor = 1.5;
def valS = Average(price, SMA_lengthS);
def average_true_range = Average(TrueRange(high, close, low), length = ATR_length);
def Upper_BandS = valS[-displace] + multiplier_factor * average_true_range[-displace];
def Middle_BandS = valS[-displace];
def Lower_BandS = valS[-displace] - multiplier_factor * average_true_range[-displace];

def condition12 = (Upper_BandS[1] <= Upper_BandS) and (Lower_BandS[1] <= Lower_BandS);
def condition12D = (Upper_BandS[1] > Upper_BandS) and (Lower_BandS[1] > Lower_BandS);

#Klinger Histogram
def Klinger_Length = 8;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0) and (KVOsc[1] <= KVOsc);
def condition13D = (KVOH < 0) and (KVOsc[1] > KVOsc);

#Projection Oscillator
def ProjectionOsc_length = 9;#Typically 10
def MaxBound = HighestWeighted(high, ProjectionOsc_length, LinearRegressionSlope(price = high, length = ProjectionOsc_length));
def MinBound = LowestWeighted(low, ProjectionOsc_length, LinearRegressionSlope(price = low, length = ProjectionOsc_length));
def ProjectionOsc_diff = MaxBound - MinBound;
def PROSC = if ProjectionOsc_diff != 0 then 100 * (close - MinBound) / ProjectionOsc_diff else 0;
def PROSC_OB = 80;
def PROSC_OS = 20;

def condition14 = PROSC > 50;
def condition14D = PROSC < 50;
def conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = PROSC < PROSC_OS;


#Trend Confirmation Calculator
#Confirmation_Factor range 1-15.
input coloredCandlesOn = yes;
def Confirmation_Factor = 3;
#Use for testing conditions individually. Remove # from line below and change Confirmation_Factor to 1.
#def Agreement_Level = condition1;
def Agreement_LevelOB = 12;
def Agreement_LevelOS = 3;

def Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13 + condition14 + conditionK1 + conditionK2;

def Agreement_LevelD = (condition1D + condition2D + condition3D + condition4D + condition5D + condition6D + condition7D + condition8D + condition9D + condition10D + condition11D + condition12D + condition13D + condition14D + conditionK3D + conditionK4D);

def Consensus_Level = Agreement_Level - Agreement_LevelD;

def conditionChannel1 = Upper_BandK > price;
def conditionChannel2 = Lower_BandK < price;

def UP = Consensus_Level >= 0;
def DOWN = Consensus_Level < 0;

AssignPriceColor(if coloredCandlesOn and UP then Color.LIGHT_GREEN else if coloredCandlesOn and DOWN then Color.RED else Color.CURRENT);

#Additional Signals

#Super_OB/OS Signal
def OB_Level = conditionOB1 + conditionOB2 + conditionOB3 + conditionOB4 + conditionOB5 + conditionOB6 + conditionOB7;
def OS_Level = conditionOS1 + conditionOS2 + conditionOS3 + conditionOS4 + conditionOS5 + conditionOS6 + conditionOS7;

def Concensus_Line = OB_Level - OS_Level;
def Zero_Line = 0;
def Super_OB = 4;
def Super_OS = -2;

def DOWN_OB = (Agreement_Level > Agreement_LevelOB) and (Concensus_Line > Super_OB);
def UP_OS = (Agreement_Level < Agreement_LevelOS) and (Concensus_Line < Super_OS);

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Concensus_Line < Super_OB and Concensus_Line > Super_OS;

#AddVerticalLine (OS_Buy and !OS_Buy[1], close, Color.GREEN, Curve.SHORT_DASH);
#AddVerticalLine (Neutral and !neutral[1], close, Color.Gray, Curve.SHORT_DASH);
#AddVerticalLine (OB_Sell and OB_Sell and !OB_Sell[1], close, Color.RED, Curve.SHORT_DASH);

def Buy_Opportnity = if OS_Buy then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
#AddCloud(Buy_Opportnity, Neutral, Color.LIGHT_GREEN, Color.LIGHT_RED);
def Sell_Opportnity = if OB_Sell then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
#AddCloud(Sell_Opportnity, Neutral, Color.LIGHT_RED, Color.LIGHT_RED);

def OB_Signal = price crosses below Upper_BandK;
#OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#OB_Signal.SetLineWeight(1);
#OB_Signal.SetDefaultColor(Color.RED);

def OS_Signal = price crosses above Lower_BandK;
#OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#OS_Signal.SetLineWeight(1);
#OS_Signal.SetDefaultColor(Color.GREEN);

#Squeeze Alert
def length = 20;
def BulgeLength = 150;
def SqueezeLength = 150;
def upperBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_up, averageType).UpperBand;
def lowerBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_up, averageType).LowerBand;
def midLineBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_up, averageType).MidLine;
def Bandwidth = (upperBandBB - lowerBandBB) / midLineBB * 100;
def Bulge = Highest(Bandwidth, BulgeLength);
def Squeeze = Lowest(Bandwidth, SqueezeLength);

plot Squeeze_Alert = Bandwidth <= Squeeze;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Squeeze_Alert.SetLineWeight(3);
Squeeze_Alert.SetDefaultColor(Color.YELLOW);

#Trend Signals
#Bollinger_Bands2
input lengthBB = 10;
input Num_Dev_DnBB = -0.8;
input Num_Dev_upBB = 0.8;

def price1 = open;
def sDev = StDev(data = price[-displace], length = lengthBB);
def MidLineBB2 = MovingAverage(averageType, data = price[-displace], length = lengthBB);
def LowerBandBB2 = MidLineBB2 + Num_Dev_DnBB * sDev;
def UpperBandBB2 = MidLineBB2 + Num_Dev_upBB * sDev;


def condition_Slope_RevUP = ((Agreement_Level[1] < Agreement_Level) or (Agreement_Level[2] >= Agreement_Level[1])) or ((Concensus_Line[1] < Concensus_Line) and (Concensus_Line[2] >= Concensus_Line[1]));
def condition_Slope_RevDOWN = ((Agreement_Level[1] > Agreement_Level) and (Agreement_Level[2] <= Agreement_Level[1])) or ((Concensus_Line[1] > Concensus_Line) and (Concensus_Line[2] <= Concensus_Line[1]));
def condition_Flat = (Agreement_Level[2] == Agreement_Level[1]) or (Concensus_Line[2] == Concensus_Line[1]);
def condition_Flat2 = ((Agreement_Level[1] == Agreement_Level) and (Concensus_Line[1] == Concensus_Line));
def condition_Flat3 = ((Agreement_Level[1] == Agreement_Level) or (Concensus_Line[1] == Concensus_Line));
def condition_OB = ((Agreement_Level >= 12) or (Concensus_Line >= 2));# and (price > Upper_BandK));
def condition_OS = ((Agreement_Level <= 2) or (Concensus_Line <= -2));# and (price < lower_BandK)
def condition_AC_SlopeDOWN = (Agreement_Level[1] > Agreement_Level) or (Concensus_Line[1] > Concensus_Line);
def condition_AC_SlopeUP = (Agreement_Level[1] < Agreement_Level) or (Concensus_Line[1] < Concensus_Line);

plot UPConfirmSignal = Consensus_Level crosses above 0;
UPConfirmSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
UPConfirmSignal.SetLineWeight(1);
UPConfirmSignal.SetDefaultColor(Color.GREEN);

plot DOWNConfirmSignal = Consensus_Level crosses below 0;
DOWNConfirmSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
DOWNConfirmSignal.SetLineWeight(1);
DOWNConfirmSignal.SetDefaultColor(Color.RED);

plot Reversal_Buy_1 = (BandwidthK crosses below BulgeK2) and (condition_OS);
Reversal_Buy_1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Buy_1.SetLineWeight(3);
Reversal_Buy_1.SetDefaultColor(Color.GREEN);

plot Reversal_Buy2 = (BandwidthK crosses above SqueezeK) and (condition_OS);
#((Agreement_Level < 2) and Concensus_Line < 0) and condition_Slope_RevUP and conditionK2 and condition_BWKDOWN;
Reversal_Buy2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Buy2.SetLineWeight(3);
Reversal_Buy2.SetDefaultColor(Color.GREEN);

plot Reversal_Buy_3 = (BandwidthK == BulgeK) and (Concensus_Line < 0) and condition_AC_SlopeUP;
Reversal_Buy_3.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Buy_3.SetLineWeight(3);
Reversal_Buy_3.SetDefaultColor(Color.GREEN);

plot Reversal_Sell_1 = ((Agreement_Level crosses below 10) and (Concensus_Line crosses below Super_OB) and (price > Middle_BandS));
Reversal_Sell_1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Sell_1.SetLineWeight(3);
Reversal_Sell_1.SetDefaultColor(Color.RED);

plot Reversal_Sell_2 = (BandwidthK crosses below BulgeK2) and (Concensus_Line >= 0) and (Agreement_Level >= 5) and (condition_Flat3 or condition_AC_SlopeDOWN);
Reversal_Sell_2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Sell_2.SetLineWeight(3);
Reversal_Sell_2.SetDefaultColor(Color.RED);

plot Reversal_Sell_3 = (BandwidthK == SqueezeK) and condition_OB;
Reversal_Sell_3.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Sell_3.SetLineWeight(3);
Reversal_Sell_3.SetDefaultColor(Color.RED);

#plot Reversal_MeanReversion = conditionK3 and (price > UpperBandBB2);
#Reversal_MeanReversion.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
#Reversal_MeanReversion.SetLineWeight(3);
#Reversal_MeanReversion.SetDefaultColor(Color.RED);

def condition_Reversal_CA_Buy = (Agreement_Level < 1) and (Agreement_Level[1] <= Agreement_Level);
def condition_Reversal_SOS_Buy = (Concensus_Line < -2) and (Concensus_Line[1] <= Concensus_Line);
#plot Reversal_Buy = (condition_Reversal_CA_Buy) or (condition_Reversal_SOS_Buy);
#Reversal_Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
#Reversal_Buy.SetLineWeight(1);
#Reversal_Buy.SetDefaultColor(Color.LIGHT_GRAY);

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
AddLabel(yes, "Look_To_Buy", if Buy then Color.GREEN else Color.GRAY);
AddLabel(yes, "Look_To_Sell", if Sell then Color.RED else Color.GRAY);

def MomentumUP = Agreement_Level[1] < Agreement_Level;
def MomentumDOWN = Agreement_Level[1] > Agreement_Level;
AddLabel(yes, "Increasing Momentum", if MomentumUP then Color.GREEN else Color.GRAY);
AddLabel(yes, "Decreasing Momentum", if MomentumDOWN then Color.RED else Color.GRAY);

def conditionMR = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);
AddLabel(yes, "MEAN REVERSION", if conditionMR then Color.RED else Color.GRAY);

def conditionBO = ((Upper_BandS[1] < Upper_BandS) and (Lower_BandS[1] < Lower_BandS)) and ((Upper_BandK[1] < Upper_BandK) and (Lower_BandK[1] < Lower_BandK));
AddLabel(yes, "BREAKOUT", if conditionBO then Color.GREEN else Color.GRAY);

def conditionBD = ((Upper_BandS[1] > Upper_BandS) and (Lower_BandS[1] > Lower_BandS) and (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK));
AddLabel(yes, "BREAKDOWN", if conditionBD then Color.RED else Color.GRAY);

def Squeeze_Signal = Squeeze_Alert;
AddLabel(yes, "SQUEEZE ALERT", if Squeeze_Signal then Color.YELLOW else Color.GRAY);

Here's the lower study.
Code:
#CC Candles Lower V.1
#Created 04/28/2021 by Christopher84


#Keltner Channel
declare lower;
def displace = 0;
input factorK = 2.0;
input lengthK = 20;
def price = close;
input averageType = AverageType.SIMPLE;
def trueRangeAverageType = AverageType.SIMPLE;
def BulgeLengthK = 150;
def SqueezeLengthK = 150;
def BulgeLengthK2 = 40;
def SqueezeLengthK2 = 40;
input BulgeLengthPrice = 75;
input SqueezeLengthPrice = 75;
input BulgeLengthPrice2 = 20;
input SqueezeLengthPrice2 = 20;
input BulgeLengthCC = 40;
input SqueezeLengthCC = 40;
input BulgeLengthCC2 = 8;
input SqueezeLengthCC2 = 8;

def shift = factorK * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK);
def averageK = MovingAverage(averageType, price, lengthK);
def AvgK = averageK[-displace];
def Upper_BandK = averageK[-displace] + shift[-displace];
def Lower_BandK = averageK[-displace] - shift[-displace];

def conditionK1 = price >= Upper_BandK;
def conditionK2 = (Upper_BandK[1] < Upper_BandK) and (Lower_BandK[1] < Lower_BandK);
def conditionK3D = price < Lower_BandK;
def conditionK4D = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);

def conditionK2L = (Upper_BandK[2] < Upper_BandK[1]) and (Lower_BandK[2] < Lower_BandK[1]);
def conditionK3L = (Upper_BandK[3] < Upper_BandK[2]) and (Lower_BandK[3] < Lower_BandK[2]);
def conditionK3 = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);

def BandwidthK = (Upper_BandK - Lower_BandK) / AvgK * 100;
def condition_BWKUP = BandwidthK[1] < BandwidthK;
def condition_BWKDOWN = BandwidthK[1] > BandwidthK;
def BulgeK = Highest(BandwidthK, BulgeLengthK);
def SqueezeK = Lowest(BandwidthK, SqueezeLengthK);
def BulgeK2 = Highest(BandwidthK, BulgeLengthK2);
def SqueezeK2 = Lowest(BandwidthK, SqueezeLengthK2);

#plot BulgePrice = Highest(price, BulgeLengthPrice);
#BulgePrice.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
#plot SqueezePrice = Lowest(price, SqueezeLengthPrice);
#SqueezePrice.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);

#plot BulgePrice2 = Highest(price, BulgeLengthPrice2);
#BulgePrice2.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
#BulgePrice2.SetStyle(Curve.SHORT_DASH);
#plot SqueezePrice2 = Lowest(price, SqueezeLengthPrice2);
#SqueezePrice2.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
#SqueezePrice2.SetStyle(Curve.SHORT_DASH);

#MACD with Price
def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input MACD_AverageType = {SMA, default EMA};
def MACDLevel = 0.0;

def fastEMA = ExpAverage(price, fastLength);
def slowEMA = ExpAverage(price, slowLength);
def Value;
def Avg;
switch (MACD_AverageType) {
case SMA:
    Value = Average(price, fastLength) - Average(price, slowLength);
    Avg = Average(Value, MACDLength);
case EMA:
    Value = fastEMA - slowEMA;
    Avg = ExpAverage(Value, MACDLength);
}
def Diff = Value - Avg;
def Level = MACDLevel;

def condition1 = Value[1] <= Value;
def condition1D = Value[1] > Value;

#RSI
def RSI_length = 14;
def RSI_AverageType = AverageType.WILDERS;
def RSI_OB = 70;
def RSI_OS = 30;

def NetChgAvg = MovingAverage(RSI_AverageType, price - price[1], RSI_length);
def TotChgAvg = MovingAverage(RSI_AverageType, AbsValue(price - price[1]), RSI_length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);

def condition2 = (RSI[3] < RSI) is true or (RSI >= 80) is true;
def condition2D = (RSI[3] > RSI) is true or (RSI < 20) is true;
def conditionOB1 = RSI > RSI_OB;
def conditionOS1 = RSI < RSI_OS;


#MFI
def MFI_Length = 14;
def MFIover_Sold = 20;
def MFIover_Bought = 80;
def movingAvgLength = 1;
def MoneyFlowIndex = Average(MoneyFlow(high, close, low, volume, MFI_Length), movingAvgLength);
def MFIOverBought = MFIover_Bought;
def MFIOverSold = MFIover_Sold;

def condition3 = (MoneyFlowIndex[2] < MoneyFlowIndex) is true or (MoneyFlowIndex > 85) is true;
def condition3D = (MoneyFlowIndex[2] > MoneyFlowIndex) is true or (MoneyFlowIndex < 20) is true;
def conditionOB2 = MoneyFlowIndex > MFIover_Bought;
def conditionOS2 = MoneyFlowIndex < MFIover_Sold;

#Forecast
def na = Double.NaN;
def MidLine = 50;
def Momentum = MarketForecast().Momentum;
def NearT =  MarketForecast().NearTerm;
def Intermed = MarketForecast().Intermediate;
def FOB = 80;
def FOS = 20;
def upperLine = 110;

def condition4 = (Intermed[1] <= Intermed) and (NearT >= MidLine);
def condition4D = (Intermed[1] > Intermed) and (NearT < MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;


#Pivot Signals
def n = 20;
def ticks = 2.0;
def bnOK = BarNumber() > n;
def isHigher = fold i = 1 to n + 1 with p = 1 while p do high > GetValue(high, -i);
def HH = if bnOK and isHigher and high == Highest(high, n) then high else Double.NaN;
def isLower = fold j = 1 to n + 1 with q = 1 while q do low < GetValue(low, -j);
def LL = if bnOK and isLower and low == Lowest(low, n) then low else Double.NaN;
def PivH = if HH > 0 then HH else Double.NaN;
def PivL = if LL > 0 then LL else Double.NaN;

def UpPivotLow = !IsNaN(PivL);
#UpPivotLow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#UpPivotLow.SetLineWeight(4);
#UpPivotLow.SetDefaultColor(Color.GREEN);

def DownPivotHigh = !IsNaN(PivH);
#DownPivotHigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#DownPivotHigh.SetLineWeight(4);
#DownPivotHigh.SetDefaultColor(Color.RED);

def condition5 = !IsNaN(PivL);
def condition5D = !IsNaN(PivH);

#EMA_1
def EMA_length = 12;
def AvgExp = ExpAverage(price[-displace], EMA_length);

def condition6 = (price >= AvgExp) and (AvgExp[2] <= AvgExp);
def condition6D = (price < AvgExp) and (AvgExp[2] > AvgExp);

#EMA_2
def EMA_2length = 20;
def displace2 = 0;
def AvgExp2 = ExpAverage(price[-displace2], EMA_2length);

def condition7 = (price >= AvgExp2) and (AvgExp[2] <= AvgExp);
def condition7D = (price < AvgExp2) and (AvgExp[2] > AvgExp);

#DMI Oscillator
def DMI_length = 5;#Typically set to 10
input DMI_averageType = AverageType.WILDERS;
def diPlus = DMI(DMI_length, DMI_averageType)."DI+";
def diMinus = DMI(DMI_length, DMI_averageType)."DI-";
def Osc = diPlus - diMinus;
def Hist = Osc;
def ZeroLine = 0;

def condition8 = Osc >= ZeroLine;
def condition8D = Osc < ZeroLine;

#Trend_Periods
def TP_fastLength = 3;#Typically 7
def TP_slowLength = 4;#Typically 15
def Periods = Sign(ExpAverage(close, TP_fastLength) - ExpAverage(close, TP_slowLength));

def condition9 = Periods > 0;
def condition9D = Periods < 0;

#Polarized Fractal Efficiency
def PFE_length = 5;#Typically 10
def smoothingLength = 2.5;#Typically 5
def PFE_diff = close - close[PFE_length - 1];
def val = 100 * Sqrt(Sqr(PFE_diff) + Sqr(PFE_length)) / Sum(Sqrt(1 + Sqr(close - close[1])), PFE_length - 1);
def PFE = ExpAverage(if PFE_diff > 0 then val else -val, smoothingLength);
def UpperLevel = 50;
def LowerLevel = -50;

def condition10 = PFE > 0;
def condition10D = PFE < 0;
def conditionOB5 = PFE > UpperLevel;
def conditionOS5 = PFE < LowerLevel;


#Bollinger Bands PercentB
input BBPB_averageType = AverageType.SIMPLE;
def BBPB_length = 5;#Typically 20
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;
def BBPB_OB = 100;
def BBPB_OS = 0;
def upperBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).LowerBand;
def PercentB = (price - lowerBand) / (upperBand - lowerBand) * 100;
def HalfLine = 50;
def UnitLine = 100;

def condition11 = PercentB > HalfLine;
def condition11D = PercentB < HalfLine;
def conditionOB6 = PercentB > BBPB_OB;
def conditionOS6 = PercentB < BBPB_OS;


#STARC Bands
def ATR_length = 15;
def SMA_lengthS = 6;
def multiplier_factor = 1.5;
def valS = Average(price, SMA_lengthS);
def average_true_range = Average(TrueRange(high, close, low), length = ATR_length);
def Upper_BandS = valS[-displace] + multiplier_factor * average_true_range[-displace];
def Middle_BandS = valS[-displace];
def Lower_BandS = valS[-displace] - multiplier_factor * average_true_range[-displace];

def condition12 = (Upper_BandS[1] <= Upper_BandS) and (Lower_BandS[1] <= Lower_BandS);
def condition12D = (Upper_BandS[1] > Upper_BandS) and (Lower_BandS[1] > Lower_BandS);

#Klinger Histogram
def Klinger_Length = 8;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0) and (KVOsc[1] <= KVOsc);
def condition13D = (KVOH < 0) and (KVOsc[1] > KVOsc);

#Projection Oscillator
def ProjectionOsc_length = 9;#Typically 10
def MaxBound = HighestWeighted(high, ProjectionOsc_length, LinearRegressionSlope(price = high, length = ProjectionOsc_length));
def MinBound = LowestWeighted(low, ProjectionOsc_length, LinearRegressionSlope(price = low, length = ProjectionOsc_length));
def ProjectionOsc_diff = MaxBound - MinBound;
def PROSC = if ProjectionOsc_diff != 0 then 100 * (close - MinBound) / ProjectionOsc_diff else 0;
def PROSC_OB = 80;
def PROSC_OS = 20;

def condition14 = PROSC > 50;
def condition14D = PROSC < 50;
def conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = PROSC < PROSC_OS;


#Trend Confirmation Calculator
#Confirmation_Factor range 1-15.
input coloredCandlesOn = no;
input Confirmation_Factor = 3;
#Use for testing conditions individually. Remove # from line below and change Confirmation_Factor to 1.
#def Agreement_Level = condition1;
def Agreement_LevelOB = 12;
def Agreement_LevelOS = 3;

def Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13 + condition14 + conditionK1 + conditionK2;

def Agreement_LevelD = (condition1D + condition2D + condition3D + condition4D + condition5D + condition6D + condition7D + condition8D + condition9D + condition10D + condition11D + condition12D + condition13D + condition14D + conditionK3D + conditionK4D);

plot Consensus_Level = Agreement_Level - Agreement_LevelD;

def conditionChannel1 = Upper_BandK > price;
def conditionChannel2 = Lower_BandK < price;

def UP = Consensus_Level >= 0;
def DOWN = Consensus_Level < 0;

Consensus_Level.AssignValueColor(
if Consensus_Level > Consensus_Level[1] and Consensus_Level >= 0 then Color.LIGHT_GREEN
else if Consensus_Level < Consensus_Level[1] and Consensus_Level >= 0 then Color.LIGHT_GREEN
else if Consensus_Level < Consensus_Level[1] and Consensus_Level < 0 then Color.RED else
if Consensus_Level > Consensus_Level[1] and Consensus_Level < 0 then Color.RED
else Color.GRAY);

def Zero_Line = 0;
#Zero_Line.SetStyle(Curve.SHORT_DASH);
#Zero_Line.SetLineWeight(1);
#Zero_Line.SetDefaultColor(Color.Gray);

plot BulgeCC = Highest(Consensus_Level, BulgeLengthCC);
BulgeCC.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);

plot SqueezeCC = Lowest(Consensus_Level, SqueezeLengthCC);
SqueezeCC.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);

plot BulgeCC2 = Highest(Consensus_Level, BulgeLengthCC2);
BulgeCC2.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
BulgeCC2.SetStyle(Curve.SHORT_DASH);

plot SqueezeCC2 = Lowest(Consensus_Level, SqueezeLengthCC2);
SqueezeCC2.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
SqueezeCC2.SetStyle(Curve.SHORT_DASH);
 
Last edited by a moderator:

rad14733

Well-known member
VIP
Sure! Share link is below. Feedback is much appreciated.

https://tos.mx/vql512R

Could you please post the script code here rather than just providing a shared link because members shouldn't be required to install the code on the TOS platforms just to review the code... Then, if they want to install it, they can either Copy & Paste the code or use the Shared Link at their own discretion... The code should be posted whether or not shared link is provided as a form of proper forum etiquette...
 

sprahty

New member
VIP
it seems like the arrows repaint, but I wonder if we can modify the script so arrows plot at the given time, even if they're further out.
@BenTen would you maybe know how to do this?
 
Last edited:

Christopher84

Active member
VIP
Here is my most recent version of the Confirmation Candles. I was able to dial in the levels a bit more. I removed the ChaikinOsc and added a squeeze alert (yellow points). Check it out and let me know what you think.

Code:
#Confirmation Candles V.2 
#Created 04/15/2021 by Topher84
#Select the level of agreement among the 14 indicators included.
#Last changed 04/19/2021 to V.2 - Removed ChaikinOsc and replaced with STARCBands. Added squeeze alert.

#MACD with Price

declare upper;
def price = close;
def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input MACD_AverageType = {SMA, default EMA};
def MACDLevel = 0.0;

def fastEMA = ExpAverage(price, fastLength);
def slowEMA = ExpAverage(price, slowLength);
def Value;
def Avg;

switch (MACD_AverageType) {
case SMA:
    Value = Average(price, fastLength) - Average(price, slowLength);
    Avg = Average(Value, MACDLength);
case EMA:
    Value = fastEMA - slowEMA;
    Avg = ExpAverage(Value, MACDLength);}
def Diff = Value - Avg;
def Level = MACDLevel;

def condition1 = Value[1] <= Value;

#RSI

input RSI_length = 14;
input RSI_AverageType = AverageType.WILDERS;

def NetChgAvg = MovingAverage(RSI_AverageType, price - price[1], RSI_length);
def TotChgAvg = MovingAverage(RSI_AverageType, AbsValue(price - price[1]), RSI_length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);

def condition2 = (RSI[3] < RSI) is true or (RSI >= 80) is true;

#MFI

input MFI_Length = 14;
def MFIover_Sold = 20;
def MFIover_Bought = 80;
def movingAvgLength = 1;
def MoneyFlowIndex = Average(moneyflow(high, close, low, volume, MFI_Length), movingAvgLength);
def MFIOverBought = MFIover_Bought;
def MFIOverSold = MFIover_Sold;

def condition3 = (MoneyFlowIndex[2] < MoneyFlowIndex) is true or (MoneyFlowIndex > 85) is true;

#Forecast

def na = Double.NaN;
def MidLine = 50;
def Momentum = MarketForecast().Momentum;
def NearT =  MarketForecast().NearTerm;
def Intermed = MarketForecast().Intermediate;
def OB = 80;
def OS = 20;
def upperLine = 110;

def condition4 = (Intermed[1] <= Intermed) and (NearT >= MidLine);

#Pivot Signals
def n = 20;
def ticks = 2.0;
def bnOK = barNumber() > n;
def isHigher = fold i = 1 to n + 1 with p = 1 while p do high > GetValue(high, -i);
def HH = if bnOK and isHigher and high == Highest(high, n)then high else Double.NaN;
def isLower = fold j = 1 to n + 1 with q = 1 while q do low < GetValue(low, -j);
def LL = if bnOK and isLower and low == Lowest(low, n) then low else Double.NaN;
def PivH = if HH > 0 then HH else Double.NaN;
def PivL = if LL > 0 then LL else Double.NaN;

def UpPivotLow = !isNaN(PivL);
#UpPivotLow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#UpPivotLow.SetLineWeight(4);
#UpPivotLow.SetDefaultColor(Color.GREEN);

def DownPivotHigh = !isNaN(PivH);
#DownPivotHigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#DownPivotHigh.SetLineWeight(4);
#DownPivotHigh.SetDefaultColor(Color.RED);

def condition5 = !isNaN(PivL);

#EMA_1
input EMA_length = 12;
def displace = 0;
def AvgExp = ExpAverage(price[-displace], EMA_length);

def condition6 = (price >= AvgExp) and (AvgExp[2] <= AvgExp);

#EMA_2
input EMA_2length = 20;
def displace2 = 0;
def AvgExp2 = ExpAverage(price[-displace2], EMA_2length);

def condition7 = (price >= AvgExp2) and (AvgExp[2] <= AvgExp);

#DMI Oscillator
input DMI_length = 5;#Typically set to 10
input DMI_averageType = AverageType.WILDERS;

def diPlus = DMI(DMI_length, DMI_averageType)."DI+";
def diMinus = DMI(DMI_length, DMI_averageType)."DI-";

def Osc = diPlus - diMinus;
def Hist = Osc;
def ZeroLine = 0;

def condition8 = Osc >= zeroline;

#Trend_Periods

input TP_fastLength = 3;#Typically 7
input TP_slowLength = 4;#Typically 15

def Periods = sign(ExpAverage(close, TP_fastLength) - ExpAverage(close, TP_slowLength));

def condition9 = Periods > 0;

#Polarized Fractal Efficiency

input PFE_length = 5;#Typically 10
input smoothingLength = 2.5;#Typically 5

def PFE_diff = close - close[PFE_length - 1];
def val = 100 * Sqrt(Sqr(PFE_diff) + Sqr(PFE_length)) / sum(Sqrt(1 + Sqr(close - close[1])), PFE_length - 1);

def PFE = ExpAverage(if PFE_diff > 0 then val else -val, smoothingLength);
def UpperLevel = 50;
def LowerLevel = -50;

def condition10 = PFE > 0;

#Bollinger Bands PercentB

input BBPB_averageType = AverageType.Simple;
input BBPB_length = 5;#Typically 20
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;

def upperBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).LowerBand;

def PercentB = (price - lowerBand) / (upperBand - lowerBand) * 100;
def HalfLine = 50;
def UnitLine = 100;

def condition11 = PercentB > HalfLine;

#STARC Bands

input ATR_length = 15;
input SMA_lengthS = 6;
input multiplier_factor = 1.5;

def valS = Average(price, SMA_lengthS);

def average_true_range = Average(TrueRange(high, close, low), length = ATR_length);

def Upper_BandS = valS[-displace] + multiplier_factor * average_true_range[-displace];
#Upper_BandS.SetDefaultColor(GetColor(0));

def Middle_BandS = valS[-displace];
#Middle_BandS.SetDefaultColor(GetColor(1));

def Lower_BandS = valS[-displace] - multiplier_factor * average_true_range[-displace];
#Lower_BandS.SetDefaultColor(GetColor(0));

def condition12 = (Upper_BandS[1] <= Upper_BandS) and (Lower_BandS[1] <= Lower_BandS); 

#Klinger Histogram

input Klinger_Length = 8;

def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);

def condition13 = (KVOH > 0) and (KVOsc[1] <= KVOsc);

#Projection Oscillator

input ProjectionOsc_length = 9;#Typically 10

def MaxBound = HighestWeighted(high, ProjectionOsc_length, LinearRegressionSlope(price=high, length=ProjectionOsc_length));
def MinBound = LowestWeighted(low, ProjectionOsc_length, LinearRegressionSlope(price=low, length=ProjectionOsc_length));
def ProjectionOsc_diff = MaxBound - MinBound;
def PROSC = if ProjectionOsc_diff != 0 then 100 * (close - MinBound) / ProjectionOsc_diff else 0;

def condition14 = PROSC > 50;

#Trend Confirmation
#Confirmation_Factor range 1-14.

input Confirmation_Factor = 6;
#Use for testing conditions individually. Remove # from line below and change Confirmation_Factor to 1.
#def Agreement_Level = condition1; 
def Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13 + condition14;

input coloredCandlesOn = yes;
def UP = Agreement_Level >= Confirmation_Factor;
def DOWN = Agreement_Level < Confirmation_Factor;

AssignPriceColor(if coloredCandlesOn and UP then Color.LIGHT_GREEN else if coloredCandlesOn and DOWN then Color.RED else Color.YELLOW);

#Additional Signals

input averageType = AverageType.Simple;
input length = 20;
input BulgeLength = 150;
input SqueezeLength = 150;

def upperBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).UpperBand;
def lowerBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).LowerBand;
def midLineBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).MidLine;

def Bandwidth = (upperBandBB - lowerBandBB) / midLineBB * 100;
def Bulge = Highest(Bandwidth, BulgeLength);
def Squeeze = Lowest(Bandwidth, SqueezeLength);

plot Squeeze_Alert = bandwidth <= squeeze;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Squeeze_Alert.SetLineWeight(3);
Squeeze_Alert.SetDefaultColor(Color.YELLOW);

plot UPSignal = Agreement_Level crosses above Confirmation_Factor;
UPSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
UPSignal.SetLineWeight(1);
UPSignal.SetDefaultColor(Color.GREEN);

plot DOWNSignal = Agreement_Level crosses below Confirmation_Factor;
DOWNSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
DOWNSignal.SetLineWeight(1);
DOWNSIGNAL.SetDefaultColor(Color.RED);
 

Christopher84

Active member
VIP
Could you please post the script code here rather than just providing a shared link because members shouldn't be required to install the code on the TOS platforms just to review the code... Then, if they want to install it, they can either Copy & Paste the code or use the Shared Link at their own discretion... The code should be posted whether or not shared link is provided as a form of proper forum etiquette...
Thank you so much for your comment rad14733! As usual, I am completely blown away by your insightfulness...
 

Splinter

New member
VIP
I find your indicator very cool! I've checked it on a 3min of the /RTY and the signals look good. One thing I noticed are that when I opt out of painting the candles then all the candles turn yellow. Thank you for your hard work!
 
Last edited:

Christopher84

Active member
VIP
I find your indicator very cool! I've checked it on a 3min of the /RTY and the signals look good. One thing I noticed are that when I opt out of painting the candles then all the candles turn yellow. Thank you for your hard work!
Thank you for trying it out! I am continuing to refine this idea and really appreciate the feedback. I will be posting updates throughout the week. Stay tuned!
 

Christopher84

Active member
VIP
For those of you trying out the Confirmation Candles, here is version 4. OB and OS confirmation levels have now been included (white arrows and adjustable confirmation levels), as well as labels for "Look To Buy" "Look To Sell" zones (shaded green/red), Mean Reversion and Breakout. Magenta points are reversal alert. I have included a Keltner Channel as well, with an easily adjustable factorK. Looking forward to feedback. Enjoy!
pMybw5N.png

WbiZCum.png


Code:
#Confirmation Candles V.4
#Created 04/15/2021 by Topher84
#Select the level of agreement among the 14 indicators included.
#Changed 04/19/2021 to V.3 - Removed ChaikinOsc and replaced with STARCBands. Added squeeze alert.
#Changed 04/20/2021 to V.4 - Added Keltner Channel, Labels, and Buy and Sell Zones. Mean Reversion and Breakout Labels added. Reversal_Alert points added.

#Keltner Channel
declare upper;
def displace = 0;
input factorK = 2.0;
input lengthK = 20;
input price = close;
input averageType = AverageType.SIMPLE;
input trueRangeAverageType = AverageType.SIMPLE;

def shift = factorK * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK);
def averageK = MovingAverage(averageType, price, lengthK);
def AvgK = averageK[-displace];
def Upper_BandK = averageK[-displace] + shift[-displace];
def Lower_BandK = averageK[-displace] - shift[-displace];

def conditionKup = price >= Upper_BandK;
def conditionKdown = price <= Lower_BandK;

#MACD with Price
def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input MACD_AverageType = {SMA, default EMA};
def MACDLevel = 0.0;

def fastEMA = ExpAverage(price, fastLength);
def slowEMA = ExpAverage(price, slowLength);
def Value;
def Avg;
switch (MACD_AverageType) {
case SMA:
    Value = Average(price, fastLength) - Average(price, slowLength);
    Avg = Average(Value, MACDLength);
case EMA:
    Value = fastEMA - slowEMA;
    Avg = ExpAverage(Value, MACDLength);}
def Diff = Value - Avg;
def Level = MACDLevel;

def condition1 = Value[1] <= Value;

#RSI
def RSI_length = 14;
def RSI_AverageType = AverageType.WILDERS;
def RSI_OB = 70;
def RSI_OS = 30;

def NetChgAvg = MovingAverage(RSI_AverageType, price - price[1], RSI_length);
def TotChgAvg = MovingAverage(RSI_AverageType, AbsValue(price - price[1]), RSI_length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);

def condition2 = (RSI[3] < RSI) is true or (RSI >= 80) is true;
def conditionRSI_OB = RSI > RSI_OB;
def conditionRSI_OS = RSI < RSI_OS;

#MFI
def MFI_Length = 14;
def MFIover_Sold = 20;
def MFIover_Bought = 80;
def movingAvgLength = 1;
def MoneyFlowIndex = Average(moneyflow(high, close, low, volume, MFI_Length), movingAvgLength);
def MFIOverBought = MFIover_Bought;
def MFIOverSold = MFIover_Sold;

def condition3 = (MoneyFlowIndex[2] < MoneyFlowIndex) is true or (MoneyFlowIndex > 85) is true;
def conditionMFI_OB = MoneyFlowIndex > MFIover_Bought;
def conditionMFI_OS = MoneyFlowIndex < MFIover_Sold;

#Forecast
def na = Double.NaN;
def MidLine = 50;
def Momentum = MarketForecast().Momentum;
def NearT =  MarketForecast().NearTerm;
def Intermed = MarketForecast().Intermediate;
def FOB = 80;
def FOS = 20;
def upperLine = 110;

def condition4 = (Intermed[1] <= Intermed) and (NearT >= MidLine);
def conditionFOB = Intermed > FOB;
def conditionFOS = Intermed < FOS;

#Pivot Signals
def n = 20;
def ticks = 2.0;
def bnOK = barNumber() > n;
def isHigher = fold i = 1 to n + 1 with p = 1 while p do high > GetValue(high, -i);
def HH = if bnOK and isHigher and high == Highest(high, n)then high else Double.NaN;
def isLower = fold j = 1 to n + 1 with q = 1 while q do low < GetValue(low, -j);
def LL = if bnOK and isLower and low == Lowest(low, n) then low else Double.NaN;
def PivH = if HH > 0 then HH else Double.NaN;
def PivL = if LL > 0 then LL else Double.NaN;

def UpPivotLow = !isNaN(PivL);
#UpPivotLow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#UpPivotLow.SetLineWeight(4);
#UpPivotLow.SetDefaultColor(Color.GREEN);

def DownPivotHigh = !isNaN(PivH);
#DownPivotHigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#DownPivotHigh.SetLineWeight(4);
#DownPivotHigh.SetDefaultColor(Color.RED);

def condition5 = !isNaN(PivL);

#EMA_1
def EMA_length = 12;
def AvgExp = ExpAverage(price[-displace], EMA_length);

def condition6 = (price >= AvgExp) and (AvgExp[2] <= AvgExp);

#EMA_2
def EMA_2length = 20;
def displace2 = 0;
def AvgExp2 = ExpAverage(price[-displace2], EMA_2length);

def condition7 = (price >= AvgExp2) and (AvgExp[2] <= AvgExp);

#DMI Oscillator
def DMI_length = 5;#Typically set to 10
input DMI_averageType = AverageType.WILDERS;
def diPlus = DMI(DMI_length, DMI_averageType)."DI+";
def diMinus = DMI(DMI_length, DMI_averageType)."DI-";
def Osc = diPlus - diMinus;
def Hist = Osc;
def ZeroLine = 0;

def condition8 = Osc >= zeroline;

#Trend_Periods
def TP_fastLength = 3;#Typically 7
def TP_slowLength = 4;#Typically 15
def Periods = sign(ExpAverage(close, TP_fastLength) - ExpAverage(close, TP_slowLength));

def condition9 = Periods > 0;

#Polarized Fractal Efficiency
def PFE_length = 5;#Typically 10
def smoothingLength = 2.5;#Typically 5
def PFE_diff = close - close[PFE_length - 1];
def val = 100 * Sqrt(Sqr(PFE_diff) + Sqr(PFE_length)) / sum(Sqrt(1 + Sqr(close - close[1])), PFE_length - 1);
def PFE = ExpAverage(if PFE_diff > 0 then val else -val, smoothingLength);
def UpperLevel = 50;
def LowerLevel = -50;

def condition10 = PFE > 0;
def conditionPFE_OB = PFE > UpperLevel;
def conditionPFE_OS = PFE < LowerLevel;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
def BBPB_length = 5;#Typically 20
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;
def BBPB_OB = 100;
def BBPB_OS = 0;
def upperBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).LowerBand;
def PercentB = (price - lowerBand) / (upperBand - lowerBand) * 100;
def HalfLine = 50;
def UnitLine = 100;

def condition11 = PercentB > HalfLine;
def conditionBBPB_OB = PercentB > BBPB_OB;
def conditionBBPB_OS = PercentB < BBPB_OS;

#STARC Bands
def ATR_length = 15;
def SMA_lengthS = 6;
def multiplier_factor = 1.5;
def valS = Average(price, SMA_lengthS);
def average_true_range = Average(TrueRange(high, close, low), length = ATR_length);
def Upper_BandS = valS[-displace] + multiplier_factor * average_true_range[-displace];
def Middle_BandS = valS[-displace];
def Lower_BandS = valS[-displace] - multiplier_factor * average_true_range[-displace];

def condition12 = (Upper_BandS[1] <= Upper_BandS) and (Lower_BandS[1] <= Lower_BandS);

#Klinger Histogram
def Klinger_Length = 8;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0) and (KVOsc[1] <= KVOsc);

#Projection Oscillator
def ProjectionOsc_length = 9;#Typically 10
def MaxBound = HighestWeighted(high, ProjectionOsc_length, LinearRegressionSlope(price=high, length=ProjectionOsc_length));
def MinBound = LowestWeighted(low, ProjectionOsc_length, LinearRegressionSlope(price=low, length=ProjectionOsc_length));
def ProjectionOsc_diff = MaxBound - MinBound;
def PROSC = if ProjectionOsc_diff != 0 then 100 * (close - MinBound) / ProjectionOsc_diff else 0;
def PROSC_OB = 80;
def PROSC_OS = 20;

def condition14 = PROSC > 50;
def conditionPROSC_OB = PROSC > PROSC_OB;
def conditionPROSC_OS = PROSC < PROSC_OS;

#Trend Confirmation Calculator
#Confirmation_Factor range 1-15.
input coloredCandlesOn = yes;
input Confirmation_Factor = 7;
#Use for testing conditions individually. Remove # from line below and change Confirmation_Factor to 1.
#def Agreement_Level = condition1;
def Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13 + condition14 + conditionKup;

def conditionChannel1 = Upper_BandK > price;
def conditionChannel2 = Lower_BandK < price;

def UP = if conditionChannel1 and conditionChannel2 then Agreement_Level >= Confirmation_Factor else 0;
def DOWN = if conditionChannel1 and conditionChannel2 then Agreement_Level <= Confirmation_Factor else 0;

AssignPriceColor(if coloredCandlesOn and UP or conditionKup then Color.LIGHT_GREEN else if coloredCandlesOn and DOWN or conditionkdown then Color.RED else Color.YELLOW);

#Additional Signals

#OB/OS Signal
input Confirmation_OB = 4;
def Agreement_OB = conditionRSI_OB + conditionMFI_OB + conditionFOB + conditionPFE_OB + conditionBBPB_OB + conditionPROSC_OB;

input Confirmation_OS = 4;
def Agreement_OS = conditionRSI_OS + conditionMFI_OS + conditionFOS + conditionPFE_OS + conditionBBPB_OS + conditionPROSC_OS;

plot OB_Signal = Agreement_OB crosses below Confirmation_OB;
OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
OB_Signal.SetLineWeight(1);
OB_Signal.SetDefaultColor(Color.WHITE);

plot OS_Signal = Agreement_OS crosses below Confirmation_OS;
OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
OS_Signal.SetLineWeight(1);
OS_Signal.SetDefaultColor(Color.WHITE);

def DOWN_OB = Agreement_OB >= Confirmation_OB;
def UP_OS = Agreement_OS >= Confirmation_OS;

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Agreement_OB < Confirmation_OB and Agreement_OS < Confirmation_OS;

#AddVerticalLine (OS_Buy and !OS_Buy[1], close, Color.GREEN, Curve.SHORT_DASH);
#AddVerticalLine (Neutral and !neutral[1], close, Color.Gray, Curve.SHORT_DASH);
#AddVerticalLine (OB_Sell and OB_Sell and !OB_Sell[1], close, Color.RED, Curve.SHORT_DASH);

def Buy_Opportnity = if OS_Buy then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
AddCloud(Buy_Opportnity, Neutral, Color.LIGHT_GREEN, Color.LIGHT_RED);
def Sell_Opportnity = if OB_Sell then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
AddCloud(Sell_Opportnity, Neutral, Color.LIGHT_RED, Color.LIGHT_RED);

#Squeeze Alert
def length = 20;
def BulgeLength = 150;
def SqueezeLength = 150;
def upperBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).UpperBand;
def lowerBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).LowerBand;
def midLineBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).MidLine;
def Bandwidth = (upperBandBB - lowerBandBB) / midLineBB * 100;
def Bulge = Highest(Bandwidth, BulgeLength);
def Squeeze = Lowest(Bandwidth, SqueezeLength);

plot Squeeze_Alert = bandwidth <= squeeze;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Squeeze_Alert.SetLineWeight(3);
Squeeze_Alert.SetDefaultColor(Color.YELLOW);

#Trend Signals
plot UPSignal = Agreement_Level crosses above Confirmation_Factor;
UPSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
UPSignal.SetLineWeight(1);
UPSignal.SetDefaultColor(Color.GREEN);

plot DOWNSignal = Agreement_Level crosses below Confirmation_Factor;
DOWNSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
DOWNSignal.SetLineWeight(1);
DOWNSIGNAL.SetDefaultColor(Color.RED);

def conditionMR = (Upper_BandS[1] > Upper_BandS) and (Lower_BandS[1] > Lower_BandS);
plot Reversal_Alert = conditionMR and price>= Middle_BandS;
Reversal_Alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Alert.SetLineWeight(3);
Reversal_Alert.SetDefaultColor(Color.MAGENTA);

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
AddLabel(yes, "Look_To_Buy", if Buy then Color.GREEN else Color.GRAY);
AddLabel(yes, "Look_To_Sell", if Sell then Color.RED else Color.GRAY);

def MomentumUP = Agreement_Level[1] < Agreement_Level;
def MomentumDOWN = Agreement_Level[1] > Agreement_Level;
AddLabel(yes, "Increasing Momentum", if MomentumUP then Color.Green else Color.GRAY);
AddLabel(yes, "Decreasing Momentum", if MomentumDOWN then Color.RED else Color.GRAY);


AddLabel(yes, "MEAN REVERSION", if conditionMR then Color.RED else Color.GRAY);
def conditionBO = (Upper_BandS[1] < Upper_BandS) and (Lower_BandS[1] < Lower_BandS);
AddLabel(yes, "BREAKOUT", if conditionBO then Color.GREEN else Color.GRAY);

def Squeeze_Signal = Squeeze_Alert;
AddLabel(yes, "SQUEEZE ALERT", if Squeeze_Signal then Color.YELLOW else Color.GRAY);
 
Last edited by a moderator:

Christopher84

Active member
VIP
Here's the accompanying lower study.
cv1NrLa.png


Code:
#Confirmation Candles Lower V.3
#Created 04/15/2021 by Christopher84
#Select the level of agreement among the 14 indicators included.
#Last changed 04/20/2021 to V.3 - Removed ChaikinOsc and replaced with STARCBands. Adjusted levels to match upper study. Added OB/OS levels.

#Keltner Channel
declare lower;
def displace = 0;
input factorK = 2.0;
input lengthK = 20;
input price = close;
input averageType = AverageType.SIMPLE;
input trueRangeAverageType = AverageType.SIMPLE;

def shift = factorK * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK);
def averageK = MovingAverage(averageType, price, lengthK);
def AvgK = averageK[-displace];
def Upper_BandK = averageK[-displace] + shift[-displace];
def Lower_BandK = averageK[-displace] - shift[-displace];

def conditionKup = price >= Upper_BandK;
def conditionKdown = price <= Lower_BandK;

#MACD with Price
def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input MACD_AverageType = {SMA, default EMA};
def MACDLevel = 0.0;

def fastEMA = ExpAverage(price, fastLength);
def slowEMA = ExpAverage(price, slowLength);
def Value;
def Avg;
switch (MACD_AverageType) {
case SMA:
Value = Average(price, fastLength) - Average(price, slowLength);
Avg = Average(Value, MACDLength);
case EMA:
Value = fastEMA - slowEMA;
Avg = ExpAverage(Value, MACDLength);}
def Diff = Value - Avg;
def Level = MACDLevel;

def condition1 = Value[1] <= Value;

#RSI
def RSI_length = 14;
def RSI_AverageType = AverageType.WILDERS;
def RSI_OB = 70;
def RSI_OS = 30;

def NetChgAvg = MovingAverage(RSI_AverageType, price - price[1], RSI_length);
def TotChgAvg = MovingAverage(RSI_AverageType, AbsValue(price - price[1]), RSI_length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);

def condition2 = (RSI[3] < RSI) is true or (RSI >= 80) is true;
def conditionRSI_OB = RSI > RSI_OB;
def conditionRSI_OS = RSI < RSI_OS;

#MFI
def MFI_Length = 14;
def MFIover_Sold = 20;
def MFIover_Bought = 80;
def movingAvgLength = 1;
def MoneyFlowIndex = Average(moneyflow(high, close, low, volume, MFI_Length), movingAvgLength);
def MFIOverBought = MFIover_Bought;
def MFIOverSold = MFIover_Sold;

def condition3 = (MoneyFlowIndex[2] < MoneyFlowIndex) is true or (MoneyFlowIndex > 85) is true;
def conditionMFI_OB = MoneyFlowIndex > MFIover_Bought;
def conditionMFI_OS = MoneyFlowIndex < MFIover_Sold;

#Forecast
def na = Double.NaN;
def MidLine = 50;
def Momentum = MarketForecast().Momentum;
def NearT = MarketForecast().NearTerm;
def Intermed = MarketForecast().Intermediate;
def FOB = 80;
def FOS = 20;
def upperLine = 110;

def condition4 = (Intermed[1] <= Intermed) and (NearT >= MidLine);
def conditionFOB = Intermed > FOB;
def conditionFOS = Intermed < FOS;

#Pivot Signals
def n = 20;
def ticks = 2.0;
def bnOK = barNumber() > n;
def isHigher = fold i = 1 to n + 1 with p = 1 while p do high > GetValue(high, -i);
def HH = if bnOK and isHigher and high == Highest(high, n)then high else Double.NaN;
def isLower = fold j = 1 to n + 1 with q = 1 while q do low < GetValue(low, -j);
def LL = if bnOK and isLower and low == Lowest(low, n) then low else Double.NaN;
def PivH = if HH > 0 then HH else Double.NaN;
def PivL = if LL > 0 then LL else Double.NaN;

def UpPivotLow = !isNaN(PivL);
#UpPivotLow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#UpPivotLow.SetLineWeight(4);
#UpPivotLow.SetDefaultColor(Color.GREEN);

def DownPivotHigh = !isNaN(PivH);
#DownPivotHigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#DownPivotHigh.SetLineWeight(4);
#DownPivotHigh.SetDefaultColor(Color.RED);

def condition5 = !isNaN(PivL);

#EMA_1
def EMA_length = 12;
def AvgExp = ExpAverage(price[-displace], EMA_length);

def condition6 = (price >= AvgExp) and (AvgExp[2] <= AvgExp);

#EMA_2
def EMA_2length = 20;
def displace2 = 0;
def AvgExp2 = ExpAverage(price[-displace2], EMA_2length);

def condition7 = (price >= AvgExp2) and (AvgExp[2] <= AvgExp);

#DMI Oscillator
def DMI_length = 5;#Typically set to 10
input DMI_averageType = AverageType.WILDERS;
def diPlus = DMI(DMI_length, DMI_averageType)."DI+";
def diMinus = DMI(DMI_length, DMI_averageType)."DI-";
def Osc = diPlus - diMinus;
def Hist = Osc;
def ZeroLine = 0;

def condition8 = Osc >= zeroline;

#Trend_Periods
def TP_fastLength = 3;#Typically 7
def TP_slowLength = 4;#Typically 15
def Periods = sign(ExpAverage(close, TP_fastLength) - ExpAverage(close, TP_slowLength));

def condition9 = Periods > 0;

#Polarized Fractal Efficiency
def PFE_length = 5;#Typically 10
def smoothingLength = 2.5;#Typically 5
def PFE_diff = close - close[PFE_length - 1];
def val = 100 * Sqrt(Sqr(PFE_diff) + Sqr(PFE_length)) / sum(Sqrt(1 + Sqr(close - close[1])), PFE_length - 1);
def PFE = ExpAverage(if PFE_diff > 0 then val else -val, smoothingLength);
def UpperLevel = 50;
def LowerLevel = -50;

def condition10 = PFE > 0;
def conditionPFE_OB = PFE > UpperLevel;
def conditionPFE_OS = PFE < LowerLevel;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
def BBPB_length = 5;#Typically 20
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;
def BBPB_OB = 100;
def BBPB_OS = 0;
def upperBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).LowerBand;
def PercentB = (price - lowerBand) / (upperBand - lowerBand) * 100;
def HalfLine = 50;
def UnitLine = 100;

def condition11 = PercentB > HalfLine;
def conditionBBPB_OB = PercentB > BBPB_OB;
def conditionBBPB_OS = PercentB < BBPB_OS;

#STARC Bands
def ATR_length = 15;
def SMA_lengthS = 6;
def multiplier_factor = 1.5;
def valS = Average(price, SMA_lengthS);
def average_true_range = Average(TrueRange(high, close, low), length = ATR_length);
def Upper_BandS = valS[-displace] + multiplier_factor * average_true_range[-displace];
def Middle_BandS = valS[-displace];
def Lower_BandS = valS[-displace] - multiplier_factor * average_true_range[-displace];

def condition12 = (Upper_BandS[1] <= Upper_BandS) and (Lower_BandS[1] <= Lower_BandS);

#Klinger Histogram
def Klinger_Length = 8;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0) and (KVOsc[1] <= KVOsc);

#Projection Oscillator
def ProjectionOsc_length = 9;#Typically 10
def MaxBound = HighestWeighted(high, ProjectionOsc_length, LinearRegressionSlope(price=high, length=ProjectionOsc_length));
def MinBound = LowestWeighted(low, ProjectionOsc_length, LinearRegressionSlope(price=low, length=ProjectionOsc_length));
def ProjectionOsc_diff = MaxBound - MinBound;
def PROSC = if ProjectionOsc_diff != 0 then 100 * (close - MinBound) / ProjectionOsc_diff else 0;
def PROSC_OB = 80;
def PROSC_OS = 20;

def condition14 = PROSC > 50;
def conditionPROSC_OB = PROSC > PROSC_OB;
def conditionPROSC_OS = PROSC < PROSC_OS;

#Trend Confirmation Calculator
#Confirmation_Factor range 1-15.
input Confirmation_Factor = 7;
#Use for testing conditions individually. Remove # from line below and change Confirmation_Factor to 1.
#def Agreement_Level = condition1;
plot Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13 + condition14 + conditionKup;

def conditionChannel1 = Upper_BandK > price;
def conditionChannel2 = Lower_BandK < price;

Agreement_Level.AssignValueColor(
if Agreement_Level > Agreement_Level[1] and Agreement_Level >= Confirmation_Factor then Color.RED
else if Agreement_Level < Agreement_Level[1] and Agreement_Level >= Confirmation_Factor then Color.DARK_RED
else if Agreement_Level < Agreement_Level[1] and Agreement_Level < Confirmation_Factor then Color.GREEN else
if Agreement_Level > Agreement_Level[1] and Agreement_Level < Confirmation_Factor then Color.DARK_GREEN
else Color.GRAY);

plot Factor_Line = Confirmation_Factor;
Factor_Line.SetStyle(Curve.SHORT_DASH);
Factor_Line.SetLineWeight(1);
Factor_Line.SetDefaultColor(Color.Gray);

plot OB_Level = 12;
OB_Level.SetPaintingStrategy(PaintingStrategy.LINE);
OB_Level.SetLineWeight(1);
OB_Level.SetDefaultColor(Color.RED);

plot OS_Level = 3;
OS_Level.SetPaintingStrategy(PaintingStrategy.LINE);
OS_Level.SetLineWeight(1);
OS_Level.SetDefaultColor(Color.LIGHT_GREEN);


AddCloud(Agreement_Level, OB_Level, Color.RED, Color.CURRENT);
AddCloud(Agreement_Level, OS_Level, Color.CURRENT, Color.LIGHT_GREEN);
 
Last edited:

Eddie

New member
I have been working on an Idea I am calling confirmation candles. I often times find myself trying to find agreement among the numerous indicators that I use to help guide my decisions. Unfortunately, a lot of the time this creates indicator overload and analysis paralysis. So I have included 13 indicators of trend within this indicator. You can choose how many of the 13 indicators have to be in agreement in order to confirm the trend. I may have gone a bit overboard here, however it makes it adaptable to individual risk tolerance and trading style. Checkout the image below. If anyone likes this idea/indicator, I am happy to share the script.

7ItcupI.png

tOhnko8.png


Code:
#Confirmation Candles developed 04/15/2021 by Christopher Wilson
#Select the level of agreement among the 13 indicators included.

#MACD with Price

declare upper;
def price = close;
def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input MACD_AverageType = {SMA, default EMA};
def MACDLevel = 0.0;

def fastEMA = ExpAverage(price, fastLength);
def slowEMA = ExpAverage(price, slowLength);
def Value;
def Avg;

switch (MACD_AverageType) {
case SMA:
    Value = Average(price, fastLength) - Average(price, slowLength);
    Avg = Average(Value, MACDLength);
case EMA:
    Value = fastEMA - slowEMA;
    Avg = ExpAverage(Value, MACDLength);}
def Diff = Value - Avg;
def Level = MACDLevel;

def condition1 = Value >= MACDLevel;

#RSI

input RSI_length = 14;
input RSI_AverageType = AverageType.WILDERS;

def NetChgAvg = MovingAverage(RSI_AverageType, price - price[1], RSI_length);
def TotChgAvg = MovingAverage(RSI_AverageType, AbsValue(price - price[1]), RSI_length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);

def condition2 = RSI >= 50;

#MFI

input MFI_Length = 14;
def MFIover_Sold = 20;
def MFIover_Bought = 80;
def movingAvgLength = 1;
def MoneyFlowIndex = Average(moneyflow(high, close, low, volume, MFI_Length), movingAvgLength);
def MFIOverBought = MFIover_Bought;
def MFIOverSold = MFIover_Sold;

def condition3 = MoneyFlowIndex > 50;

#Intermediate Forecast

def na = Double.NaN;
def MidLine = 50;
def Momentum = MarketForecast().Momentum;
def NearT =  MarketForecast().NearTerm;
def Intermed = MarketForecast().Intermediate;
def OB = 80;
def OS = 20;
def upperLine = 110;

def condition4 = Intermed[3] <= Intermed;

#Nearterm Forecast

def condition5 = NearT >= MidLine;

#VWAP_Pivot Signals
def n = 20;
def ticks = 2.0;
def bnOK = barNumber() > n;
def isHigher = fold i = 1 to n + 1 with p = 1 while p do high > GetValue(high, -i);
def HH = if bnOK and isHigher and high == Highest(high, n)then high else Double.NaN;
def isLower = fold j = 1 to n + 1 with q = 1 while q do low < GetValue(low, -j);
def LL = if bnOK and isLower and low == Lowest(low, n) then low else Double.NaN;
def PivH = if HH > 0 then HH else Double.NaN;
def PivL = if LL > 0 then LL else Double.NaN;

plot UpPivotLow = !isNaN(PivL);
UpPivotLow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
UpPivotLow.SetLineWeight(3);
UpPivotLow.SetDefaultColor(Color.GREEN);

plot DownPivotHigh = !isNaN(PivH);
DownPivotHigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
DownPivotHigh.SetLineWeight(3);
DownPivotHigh.SetDefaultColor(Color.RED);

def condition6 = !isNaN(PivL);

#EMA_1
input EMA_length = 20;
def displace = 0;
def AvgExp = ExpAverage(price[-displace], EMA_length);

def condition7 = price >= AvgExp;

#EMA_2
input EMA_2length = 50;
def displace2 = 0;
def AvgExp2 = ExpAverage(price[-displace2], EMA_2length);

def condition8 = price >= AvgExp2;

#DMI Oscillator
input DMI_length = 10;
input DMI_averageType = AverageType.WILDERS;

def diPlus = DMI(DMI_length, DMI_averageType)."DI+";
def diMinus = DMI(DMI_length, DMI_averageType)."DI-";

def Osc = diPlus - diMinus;
def Hist = Osc;
def ZeroLine = 0;

def condition9 = Osc > ZeroLine;

#Trend_Periods

input TP_fastLength = 7;
input TP_slowLength = 15;

def Periods = sign(ExpAverage(close, TP_fastLength) - ExpAverage(close, TP_slowLength));

def condition10 = Periods > 0;

#Polarized Fractal Efficiency

input PFE_length = 10;
input smoothingLength = 5;

def PFE_diff = close - close[PFE_length - 1];
def val = 100 * Sqrt(Sqr(PFE_diff) + Sqr(PFE_length)) / sum(Sqrt(1 + Sqr(close - close[1])), PFE_length - 1);

def PFE = ExpAverage(if PFE_diff > 0 then val else -val, smoothingLength);
def UpperLevel = 50;
def LowerLevel = -50;

def condition11 = PFE > ZERoLine;

#Bollinger Bands PercentB

input BBPB_averageType = AverageType.Simple;
input BBPB_length = 20;
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;

def upperBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).LowerBand;

def PercentB = (price - lowerBand) / (upperBand - lowerBand) * 100;
def HalfLine = 50;
def UnitLine = 100;

def condition12 = PercentB > 50;

#Chaikin Oscillator

input ChaikinOsc_longLength = 10;
input ChaikinOsc_shortLength = 3;

def accDist = AccDist();
def COSC = ExpAverage(accDist, ChaikinOsc_shortLength) - ExpAverage(accDist, ChaikinOsc_longLength);

def condition13 = COSC > zeroline;

#Trend Confirmation
#Confirmation_Factor range 1-13.

input Confirmation_Factor = 6;
#Use for testing conditions individually. Remove # from line below and chang Confirmation_Factor to 1.
#def Agreement_Level = condition1;
def Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13;

input coloredCandlesOn = yes;
def UP = Agreement_Level >= Confirmation_Factor;
def DOWN = Agreement_Level < Confirmation_Factor;

AssignPriceColor(if coloredCandlesOn and UP then Color.LIGHT_GREEN else if coloredCandlesOn and DOWN then Color.RED else Color.YELLOW);

#Additional Signals

plot UPSignal = Agreement_Level crosses above Confirmation_Factor;
UPSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
UPSignal.SetLineWeight(1);
UPSignal.SetDefaultColor(Color.green);

plot DOWNSignal = Agreement_Level crosses below Confirmation_Factor;
DOWNSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
DOWNSignal.SetLineWeight(1);
DOWNSIGNAL.SetDefaultColor(Color.red);
Thank you Christopher..I copied and paste the code, and i changed (in inputs options) confirmation factor to 13. Today was watching the whole day /NQ chart (I like to trade 5min chart) and no signals were shown. I logged in back at around 4:30 pm and I see one red arrow at 9:40 and one green at 11:30. Should I not change to 13 and leave confirmation code at 7?
 

Christopher84

Active member
VIP
Thank you Christopher..I copied and paste the code, and i changed (in inputs options) confirmation factor to 13. Today was watching the whole day /NQ chart (I like to trade 5min chart) and no signals were shown. I logged in back at around 4:30 pm and I see one red arrow at 9:40 and one green at 11:30. Should I not change to 13 and leave confirmation code at 7?
Hi Eddie! Thanks for trying this out. Typically I would suggest using confirmation level between 4-8. When you look at the lower study you can see why that may be. When you have agreement levels over 12, it seems to indicate a potential OB condition and when the agreement level is less than 3, it seems to indicate a potential OS condition. Let me know if this helps. Thanks again!
 

Christopher84

Active member
VIP
Hi Everyone! Here is Confirmation Candles V.5. Added new reversal signals. Reversal buy (gray points), reversal sell (red points). They seem to be pretty decent (will not repaint once the candle is closed). Looking forward to feedback.

qaMkvWE.png


Code:
#Confirmation Candles V.5
#Created 04/15/2021 by Christopher84
#Select the level of agreement among the 14 indicators included.
#Changed 04/19/2021 to V.3 - Removed ChaikinOsc and replaced with STARCBands. Added squeeze alert.
#Changed 04/20/2021 to V.4 - Added Keltner Channel, Labels, and Buy and Sell Zones. Mean Reversion and Breakout Labels added. Reversal_Alert points added.
#Changed 4/22/2021 to V.4 - Removed Buy/Sell clouds. Created new reversal alert buy(gray points) and take profit (red points). Increase factorK.

#Keltner Channel
declare upper;
def displace = 0;
input factorK = 6.5;
input lengthK = 20;
input price = close;
input averageType = AverageType.SIMPLE;
input trueRangeAverageType = AverageType.SIMPLE;

def shift = factorK * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK);
def averageK = MovingAverage(averageType, price, lengthK);
def AvgK = averageK[-displace];
def Upper_BandK = averageK[-displace] + shift[-displace];
def Lower_BandK = averageK[-displace] - shift[-displace];

def conditionKup = price >= Upper_BandK;
def conditionKdown = price <= Lower_BandK;

#MACD with Price
def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input MACD_AverageType = {SMA, default EMA};
def MACDLevel = 0.0;

def fastEMA = ExpAverage(price, fastLength);
def slowEMA = ExpAverage(price, slowLength);
def Value;
def Avg;
switch (MACD_AverageType) {
case SMA:
    Value = Average(price, fastLength) - Average(price, slowLength);
    Avg = Average(Value, MACDLength);
case EMA:
    Value = fastEMA - slowEMA;
    Avg = ExpAverage(Value, MACDLength);}
def Diff = Value - Avg;
def Level = MACDLevel;

def condition1 = Value[1] <= Value;

#RSI
def RSI_length = 14;
def RSI_AverageType = AverageType.WILDERS;
def RSI_OB = 70;
def RSI_OS = 30;

def NetChgAvg = MovingAverage(RSI_AverageType, price - price[1], RSI_length);
def TotChgAvg = MovingAverage(RSI_AverageType, AbsValue(price - price[1]), RSI_length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);

def condition2 = (RSI[3] < RSI) is true or (RSI >= 80) is true;
def conditionRSI_OB = RSI > RSI_OB;
def conditionRSI_OS = RSI < RSI_OS;

#MFI
def MFI_Length = 14;
def MFIover_Sold = 20;
def MFIover_Bought = 80;
def movingAvgLength = 1;
def MoneyFlowIndex = Average(moneyflow(high, close, low, volume, MFI_Length), movingAvgLength);
def MFIOverBought = MFIover_Bought;
def MFIOverSold = MFIover_Sold;

def condition3 = (MoneyFlowIndex[2] < MoneyFlowIndex) is true or (MoneyFlowIndex > 85) is true;
def conditionMFI_OB = MoneyFlowIndex > MFIover_Bought;
def conditionMFI_OS = MoneyFlowIndex < MFIover_Sold;

#Forecast
def na = Double.NaN;
def MidLine = 50;
def Momentum = MarketForecast().Momentum;
def NearT =  MarketForecast().NearTerm;
def Intermed = MarketForecast().Intermediate;
def FOB = 80;
def FOS = 20;
def upperLine = 110;

def condition4 = (Intermed[1] <= Intermed) and (NearT >= MidLine);
def conditionFOB = Intermed > FOB;
def conditionFOS = Intermed < FOS;

#Pivot Signals
def n = 20;
def ticks = 2.0;
def bnOK = barNumber() > n;
def isHigher = fold i = 1 to n + 1 with p = 1 while p do high > GetValue(high, -i);
def HH = if bnOK and isHigher and high == Highest(high, n)then high else Double.NaN;
def isLower = fold j = 1 to n + 1 with q = 1 while q do low < GetValue(low, -j);
def LL = if bnOK and isLower and low == Lowest(low, n) then low else Double.NaN;
def PivH = if HH > 0 then HH else Double.NaN;
def PivL = if LL > 0 then LL else Double.NaN;

def UpPivotLow = !isNaN(PivL);
#UpPivotLow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#UpPivotLow.SetLineWeight(4);
#UpPivotLow.SetDefaultColor(Color.GREEN);

def DownPivotHigh = !isNaN(PivH);
#DownPivotHigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#DownPivotHigh.SetLineWeight(4);
#DownPivotHigh.SetDefaultColor(Color.RED);

def condition5 = !isNaN(PivL);

#EMA_1
def EMA_length = 12;
def AvgExp = ExpAverage(price[-displace], EMA_length);

def condition6 = (price >= AvgExp) and (AvgExp[2] <= AvgExp);

#EMA_2
def EMA_2length = 20;
def displace2 = 0;
def AvgExp2 = ExpAverage(price[-displace2], EMA_2length);

def condition7 = (price >= AvgExp2) and (AvgExp[2] <= AvgExp);

#DMI Oscillator
def DMI_length = 5;#Typically set to 10
input DMI_averageType = AverageType.WILDERS;
def diPlus = DMI(DMI_length, DMI_averageType)."DI+";
def diMinus = DMI(DMI_length, DMI_averageType)."DI-";
def Osc = diPlus - diMinus;
def Hist = Osc;
def ZeroLine = 0;

def condition8 = Osc >= zeroline;

#Trend_Periods
def TP_fastLength = 3;#Typically 7
def TP_slowLength = 4;#Typically 15
def Periods = sign(ExpAverage(close, TP_fastLength) - ExpAverage(close, TP_slowLength));

def condition9 = Periods > 0;

#Polarized Fractal Efficiency
def PFE_length = 5;#Typically 10
def smoothingLength = 2.5;#Typically 5
def PFE_diff = close - close[PFE_length - 1];
def val = 100 * Sqrt(Sqr(PFE_diff) + Sqr(PFE_length)) / sum(Sqrt(1 + Sqr(close - close[1])), PFE_length - 1);
def PFE = ExpAverage(if PFE_diff > 0 then val else -val, smoothingLength);
def UpperLevel = 50;
def LowerLevel = -50;

def condition10 = PFE > 0;
def conditionPFE_OB = PFE > UpperLevel;
def conditionPFE_OS = PFE < LowerLevel;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
def BBPB_length = 5;#Typically 20
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;
def BBPB_OB = 100;
def BBPB_OS = 0;
def upperBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).LowerBand;
def PercentB = (price - lowerBand) / (upperBand - lowerBand) * 100;
def HalfLine = 50;
def UnitLine = 100;

def condition11 = PercentB > HalfLine;
def conditionBBPB_OB = PercentB > BBPB_OB;
def conditionBBPB_OS = PercentB < BBPB_OS;

#STARC Bands
def ATR_length = 15;
def SMA_lengthS = 6;
def multiplier_factor = 1.5;
def valS = Average(price, SMA_lengthS);
def average_true_range = Average(TrueRange(high, close, low), length = ATR_length);
def Upper_BandS = valS[-displace] + multiplier_factor * average_true_range[-displace];
def Middle_BandS = valS[-displace];
def Lower_BandS = valS[-displace] - multiplier_factor * average_true_range[-displace];

def condition12 = (Upper_BandS[1] <= Upper_BandS) and (Lower_BandS[1] <= Lower_BandS);

#Klinger Histogram
def Klinger_Length = 8;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0) and (KVOsc[1] <= KVOsc);

#Projection Oscillator
def ProjectionOsc_length = 9;#Typically 10
def MaxBound = HighestWeighted(high, ProjectionOsc_length, LinearRegressionSlope(price=high, length=ProjectionOsc_length));
def MinBound = LowestWeighted(low, ProjectionOsc_length, LinearRegressionSlope(price=low, length=ProjectionOsc_length));
def ProjectionOsc_diff = MaxBound - MinBound;
def PROSC = if ProjectionOsc_diff != 0 then 100 * (close - MinBound) / ProjectionOsc_diff else 0;
def PROSC_OB = 80;
def PROSC_OS = 20;

def condition14 = PROSC > 50;
def conditionPROSC_OB = PROSC > PROSC_OB;
def conditionPROSC_OS = PROSC < PROSC_OS;

#Trend Confirmation Calculator
#Confirmation_Factor range 1-15.
input coloredCandlesOn = yes;
input Confirmation_Factor = 3;
#Use for testing conditions individually. Remove # from line below and change Confirmation_Factor to 1.
#def Agreement_Level = condition1;
def Agreement_LevelOB = 12;
def Agreement_LevelOS = 3;

def Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13 + condition14 + conditionKup;

def conditionChannel1 = Upper_BandK > price;
def conditionChannel2 = Lower_BandK < price;

def UP = if conditionChannel1 and conditionChannel2 then Agreement_Level >= Confirmation_Factor else 0;
def DOWN = if conditionChannel1 and conditionChannel2 then Agreement_Level <= Confirmation_Factor else 0;

AssignPriceColor(if coloredCandlesOn and UP or conditionKup then Color.LIGHT_GREEN else if coloredCandlesOn and DOWN or conditionkdown then Color.RED else Color.YELLOW);

#Additional Signals

#OB/OS Signal
input Confirmation_OB = 2;
def Agreement_OB = conditionRSI_OB + conditionMFI_OB + conditionFOB + conditionPFE_OB + conditionBBPB_OB + conditionPROSC_OB;

input Confirmation_OS = 2;
def Agreement_OS = conditionRSI_OS + conditionMFI_OS + conditionFOS + conditionPFE_OS + conditionBBPB_OS + conditionPROSC_OS;

def DOWN_OB = (Agreement_Level > Agreement_LevelOB) and (Agreement_OB > Confirmation_OB);
def UP_OS = (Agreement_Level < Agreement_LevelOS) and (Agreement_OS > Confirmation_OS);

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Agreement_OB < Confirmation_OB and Agreement_OS < Confirmation_OS;

#AddVerticalLine (OS_Buy and !OS_Buy[1], close, Color.GREEN, Curve.SHORT_DASH);
#AddVerticalLine (Neutral and !neutral[1], close, Color.Gray, Curve.SHORT_DASH);
#AddVerticalLine (OB_Sell and OB_Sell and !OB_Sell[1], close, Color.RED, Curve.SHORT_DASH);

def Buy_Opportnity = if OS_Buy then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
#AddCloud(Buy_Opportnity, Neutral, Color.LIGHT_GREEN, Color.LIGHT_RED);
def Sell_Opportnity = if OB_Sell then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
#AddCloud(Sell_Opportnity, Neutral, Color.LIGHT_RED, Color.LIGHT_RED);

plot OB_Signal = price crosses below Upper_BandK;#(Agreement_OB crosses below Agreement_OS) or (Agreement_OB crosses below 5);
OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
OB_Signal.SetLineWeight(1);
OB_Signal.SetDefaultColor(Color.RED);

plot OS_Signal = price crosses above Lower_BandK;#(Agreement_OB crosses above Agreement_OS);
OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
OS_Signal.SetLineWeight(1);
OS_Signal.SetDefaultColor(Color.GREEN);

#Squeeze Alert
def length = 20;
def BulgeLength = 150;
def SqueezeLength = 150;
def upperBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).UpperBand;
def lowerBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).LowerBand;
def midLineBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).MidLine;
def Bandwidth = (upperBandBB - lowerBandBB) / midLineBB * 100;
def Bulge = Highest(Bandwidth, BulgeLength);
def Squeeze = Lowest(Bandwidth, SqueezeLength);

plot Squeeze_Alert = bandwidth <= squeeze;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Squeeze_Alert.SetLineWeight(3);
Squeeze_Alert.SetDefaultColor(Color.YELLOW);

#Trend Signals
plot UPConfirmSignal = Agreement_Level crosses above Confirmation_Factor;
UPConfirmSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
UPConfirmSignal.SetLineWeight(1);
UPConfirmSignal.SetDefaultColor(Color.GREEN);

plot DOWNConfirmSignal = Agreement_Level crosses below Confirmation_Factor;
DOWNConfirmSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
DOWNConfirmSignal.SetLineWeight(1);
DOWNConfirmSignal.SetDefaultColor(Color.RED);

plot Reversal_Alert1 = (Agreement_Level crosses below 13);
Reversal_Alert1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
Reversal_Alert1.SetLineWeight(1);
Reversal_Alert1.SetDefaultColor(Color.RED);

plot Reversal_Alert2 =(Agreement_Level crosses above 2);
Reversal_Alert2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
Reversal_Alert2.SetLineWeight(1);
Reversal_Alert2.SetDefaultColor(Color.GREEN);

plot Reversal_Buy = (Agreement_Level < 1) and (Agreement_Level[1] <= Agreement_Level);#conditionMR and price>= Middle_BandS;
Reversal_Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Buy.SetLineWeight(1);
Reversal_Buy.SetDefaultColor(Color.LIGHT_GRAY);

plot Reversal_Sell = (Agreement_Level > 12) and (Agreement_Level[1] >= Agreement_Level);#conditionMR and price>= Middle_BandS;
Reversal_Sell.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Sell.SetLineWeight(1);
Reversal_Sell.SetDefaultColor(Color.LIGHT_RED);

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
AddLabel(yes, "Look_To_Buy", if Buy then Color.GREEN else Color.GRAY);
AddLabel(yes, "Look_To_Sell", if Sell then Color.RED else Color.GRAY);

def MomentumUP = Agreement_Level[1] < Agreement_Level;
def MomentumDOWN = Agreement_Level[1] > Agreement_Level;
AddLabel(yes, "Increasing Momentum", if MomentumUP then Color.Green else Color.GRAY);
AddLabel(yes, "Decreasing Momentum", if MomentumDOWN then Color.RED else Color.GRAY);

def conditionMR = (Upper_BandS[1] > Upper_BandS) and (Lower_BandS[1] > Lower_BandS);
AddLabel(yes, "MEAN REVERSION", if conditionMR then Color.RED else Color.GRAY);
def conditionBO = (Upper_BandS[1] < Upper_BandS) and (Lower_BandS[1] < Lower_BandS);
AddLabel(yes, "BREAKOUT", if conditionBO then Color.GREEN else Color.GRAY);

def Squeeze_Signal = Squeeze_Alert;
AddLabel(yes, "SQUEEZE ALERT", if Squeeze_Signal then Color.YELLOW else Color.GRAY);
 

rfb

Member
Hi Everyone! Here is Confirmation Candles V.5. Added new reversal signals. Reversal buy (gray points), reversal sell (red points). They seem to be pretty decent (will not repaint once the candle is closed). Looking forward to feedback.
qaMkvWE.png


#Confirmation Candles V.5
#Created 04/15/2021 by Christopher84
#Select the level of agreement among the 14 indicators included.
#Changed 04/19/2021 to V.3 - Removed ChaikinOsc and replaced with STARCBands. Added squeeze alert.
#Changed 04/20/2021 to V.4 - Added Keltner Channel, Labels, and Buy and Sell Zones. Mean Reversion and Breakout Labels added. Reversal_Alert points added.
#Changed 4/22/2021 to V.4 - Removed Buy/Sell clouds. Created new reversal alert buy(gray points) and take profit (red points). Increase factorK.

#Keltner Channel
declare upper;
def displace = 0;
input factorK = 6.5;
input lengthK = 20;
input price = close;
input averageType = AverageType.SIMPLE;
input trueRangeAverageType = AverageType.SIMPLE;

def shift = factorK * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK);
def averageK = MovingAverage(averageType, price, lengthK);
def AvgK = averageK[-displace];
def Upper_BandK = averageK[-displace] + shift[-displace];
def Lower_BandK = averageK[-displace] - shift[-displace];

def conditionKup = price >= Upper_BandK;
def conditionKdown = price <= Lower_BandK;

#MACD with Price
def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input MACD_AverageType = {SMA, default EMA};
def MACDLevel = 0.0;

def fastEMA = ExpAverage(price, fastLength);
def slowEMA = ExpAverage(price, slowLength);
def Value;
def Avg;
switch (MACD_AverageType) {
case SMA:
Value = Average(price, fastLength) - Average(price, slowLength);
Avg = Average(Value, MACDLength);
case EMA:
Value = fastEMA - slowEMA;
Avg = ExpAverage(Value, MACDLength);}
def Diff = Value - Avg;
def Level = MACDLevel;

def condition1 = Value[1] <= Value;

#RSI
def RSI_length = 14;
def RSI_AverageType = AverageType.WILDERS;
def RSI_OB = 70;
def RSI_OS = 30;

def NetChgAvg = MovingAverage(RSI_AverageType, price - price[1], RSI_length);
def TotChgAvg = MovingAverage(RSI_AverageType, AbsValue(price - price[1]), RSI_length);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);

def condition2 = (RSI[3] < RSI) is true or (RSI >= 80) is true;
def conditionRSI_OB = RSI > RSI_OB;
def conditionRSI_OS = RSI < RSI_OS;

#MFI
def MFI_Length = 14;
def MFIover_Sold = 20;
def MFIover_Bought = 80;
def movingAvgLength = 1;
def MoneyFlowIndex = Average(moneyflow(high, close, low, volume, MFI_Length), movingAvgLength);
def MFIOverBought = MFIover_Bought;
def MFIOverSold = MFIover_Sold;

def condition3 = (MoneyFlowIndex[2] < MoneyFlowIndex) is true or (MoneyFlowIndex > 85) is true;
def conditionMFI_OB = MoneyFlowIndex > MFIover_Bought;
def conditionMFI_OS = MoneyFlowIndex < MFIover_Sold;

#Forecast
def na = Double.NaN;
def MidLine = 50;
def Momentum = MarketForecast().Momentum;
def NearT = MarketForecast().NearTerm;
def Intermed = MarketForecast().Intermediate;
def FOB = 80;
def FOS = 20;
def upperLine = 110;

def condition4 = (Intermed[1] <= Intermed) and (NearT >= MidLine);
def conditionFOB = Intermed > FOB;
def conditionFOS = Intermed < FOS;

#Pivot Signals
def n = 20;
def ticks = 2.0;
def bnOK = barNumber() > n;
def isHigher = fold i = 1 to n + 1 with p = 1 while p do high > GetValue(high, -i);
def HH = if bnOK and isHigher and high == Highest(high, n)then high else Double.NaN;
def isLower = fold j = 1 to n + 1 with q = 1 while q do low < GetValue(low, -j);
def LL = if bnOK and isLower and low == Lowest(low, n) then low else Double.NaN;
def PivH = if HH > 0 then HH else Double.NaN;
def PivL = if LL > 0 then LL else Double.NaN;

def UpPivotLow = !isNaN(PivL);
#UpPivotLow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#UpPivotLow.SetLineWeight(4);
#UpPivotLow.SetDefaultColor(Color.GREEN);

def DownPivotHigh = !isNaN(PivH);
#DownPivotHigh.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#DownPivotHigh.SetLineWeight(4);
#DownPivotHigh.SetDefaultColor(Color.RED);

def condition5 = !isNaN(PivL);

#EMA_1
def EMA_length = 12;
def AvgExp = ExpAverage(price[-displace], EMA_length);

def condition6 = (price >= AvgExp) and (AvgExp[2] <= AvgExp);

#EMA_2
def EMA_2length = 20;
def displace2 = 0;
def AvgExp2 = ExpAverage(price[-displace2], EMA_2length);

def condition7 = (price >= AvgExp2) and (AvgExp[2] <= AvgExp);

#DMI Oscillator
def DMI_length = 5;#Typically set to 10
input DMI_averageType = AverageType.WILDERS;
def diPlus = DMI(DMI_length, DMI_averageType)."DI+";
def diMinus = DMI(DMI_length, DMI_averageType)."DI-";
def Osc = diPlus - diMinus;
def Hist = Osc;
def ZeroLine = 0;

def condition8 = Osc >= zeroline;

#Trend_Periods
def TP_fastLength = 3;#Typically 7
def TP_slowLength = 4;#Typically 15
def Periods = sign(ExpAverage(close, TP_fastLength) - ExpAverage(close, TP_slowLength));

def condition9 = Periods > 0;

#Polarized Fractal Efficiency
def PFE_length = 5;#Typically 10
def smoothingLength = 2.5;#Typically 5
def PFE_diff = close - close[PFE_length - 1];
def val = 100 * Sqrt(Sqr(PFE_diff) + Sqr(PFE_length)) / sum(Sqrt(1 + Sqr(close - close[1])), PFE_length - 1);
def PFE = ExpAverage(if PFE_diff > 0 then val else -val, smoothingLength);
def UpperLevel = 50;
def LowerLevel = -50;

def condition10 = PFE > 0;
def conditionPFE_OB = PFE > UpperLevel;
def conditionPFE_OS = PFE < LowerLevel;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
def BBPB_length = 5;#Typically 20
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;
def BBPB_OB = 100;
def BBPB_OS = 0;
def upperBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).LowerBand;
def PercentB = (price - lowerBand) / (upperBand - lowerBand) * 100;
def HalfLine = 50;
def UnitLine = 100;

def condition11 = PercentB > HalfLine;
def conditionBBPB_OB = PercentB > BBPB_OB;
def conditionBBPB_OS = PercentB < BBPB_OS;

#STARC Bands
def ATR_length = 15;
def SMA_lengthS = 6;
def multiplier_factor = 1.5;
def valS = Average(price, SMA_lengthS);
def average_true_range = Average(TrueRange(high, close, low), length = ATR_length);
def Upper_BandS = valS[-displace] + multiplier_factor * average_true_range[-displace];
def Middle_BandS = valS[-displace];
def Lower_BandS = valS[-displace] - multiplier_factor * average_true_range[-displace];

def condition12 = (Upper_BandS[1] <= Upper_BandS) and (Lower_BandS[1] <= Lower_BandS);

#Klinger Histogram
def Klinger_Length = 8;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0) and (KVOsc[1] <= KVOsc);

#Projection Oscillator
def ProjectionOsc_length = 9;#Typically 10
def MaxBound = HighestWeighted(high, ProjectionOsc_length, LinearRegressionSlope(price=high, length=ProjectionOsc_length));
def MinBound = LowestWeighted(low, ProjectionOsc_length, LinearRegressionSlope(price=low, length=ProjectionOsc_length));
def ProjectionOsc_diff = MaxBound - MinBound;
def PROSC = if ProjectionOsc_diff != 0 then 100 * (close - MinBound) / ProjectionOsc_diff else 0;
def PROSC_OB = 80;
def PROSC_OS = 20;

def condition14 = PROSC > 50;
def conditionPROSC_OB = PROSC > PROSC_OB;
def conditionPROSC_OS = PROSC < PROSC_OS;

#Trend Confirmation Calculator
#Confirmation_Factor range 1-15.
input coloredCandlesOn = yes;
input Confirmation_Factor = 3;
#Use for testing conditions individually. Remove # from line below and change Confirmation_Factor to 1.
#def Agreement_Level = condition1;
def Agreement_LevelOB = 12;
def Agreement_LevelOS = 3;

def Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13 + condition14 + conditionKup;

def conditionChannel1 = Upper_BandK > price;
def conditionChannel2 = Lower_BandK < price;

def UP = if conditionChannel1 and conditionChannel2 then Agreement_Level >= Confirmation_Factor else 0;
def DOWN = if conditionChannel1 and conditionChannel2 then Agreement_Level <= Confirmation_Factor else 0;

AssignPriceColor(if coloredCandlesOn and UP or conditionKup then Color.LIGHT_GREEN else if coloredCandlesOn and DOWN or conditionkdown then Color.RED else Color.YELLOW);

#Additional Signals

#OB/OS Signal
input Confirmation_OB = 2;
def Agreement_OB = conditionRSI_OB + conditionMFI_OB + conditionFOB + conditionPFE_OB + conditionBBPB_OB + conditionPROSC_OB;

input Confirmation_OS = 2;
def Agreement_OS = conditionRSI_OS + conditionMFI_OS + conditionFOS + conditionPFE_OS + conditionBBPB_OS + conditionPROSC_OS;

def DOWN_OB = (Agreement_Level > Agreement_LevelOB) and (Agreement_OB > Confirmation_OB);
def UP_OS = (Agreement_Level < Agreement_LevelOS) and (Agreement_OS > Confirmation_OS);

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Agreement_OB < Confirmation_OB and Agreement_OS < Confirmation_OS;

#AddVerticalLine (OS_Buy and !OS_Buy[1], close, Color.GREEN, Curve.SHORT_DASH);
#AddVerticalLine (Neutral and !neutral[1], close, Color.Gray, Curve.SHORT_DASH);
#AddVerticalLine (OB_Sell and OB_Sell and !OB_Sell[1], close, Color.RED, Curve.SHORT_DASH);

def Buy_Opportnity = if OS_Buy then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
#AddCloud(Buy_Opportnity, Neutral, Color.LIGHT_GREEN, Color.LIGHT_RED);
def Sell_Opportnity = if OB_Sell then Double.POSITIVE_INFINITY else Double.NEGATIVE_INFINITY;
#AddCloud(Sell_Opportnity, Neutral, Color.LIGHT_RED, Color.LIGHT_RED);

plot OB_Signal = price crosses below Upper_BandK;#(Agreement_OB crosses below Agreement_OS) or (Agreement_OB crosses below 5);
OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
OB_Signal.SetLineWeight(1);
OB_Signal.SetDefaultColor(Color.RED);

plot OS_Signal = price crosses above Lower_BandK;#(Agreement_OB crosses above Agreement_OS);
OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
OS_Signal.SetLineWeight(1);
OS_Signal.SetDefaultColor(Color.GREEN);

#Squeeze Alert
def length = 20;
def BulgeLength = 150;
def SqueezeLength = 150;
def upperBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).UpperBand;
def lowerBandBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).LowerBand;
def midLineBB = BollingerBands(price, displace, length, Num_Dev_Dn, Num_Dev_Up, averageType).MidLine;
def Bandwidth = (upperBandBB - lowerBandBB) / midLineBB * 100;
def Bulge = Highest(Bandwidth, BulgeLength);
def Squeeze = Lowest(Bandwidth, SqueezeLength);

plot Squeeze_Alert = bandwidth <= squeeze;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Squeeze_Alert.SetLineWeight(3);
Squeeze_Alert.SetDefaultColor(Color.YELLOW);

#Trend Signals
plot UPConfirmSignal = Agreement_Level crosses above Confirmation_Factor;
UPConfirmSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
UPConfirmSignal.SetLineWeight(1);
UPConfirmSignal.SetDefaultColor(Color.GREEN);

plot DOWNConfirmSignal = Agreement_Level crosses below Confirmation_Factor;
DOWNConfirmSignal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
DOWNConfirmSignal.SetLineWeight(1);
DOWNConfirmSignal.SetDefaultColor(Color.RED);

plot Reversal_Alert1 = (Agreement_Level crosses below 13);
Reversal_Alert1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
Reversal_Alert1.SetLineWeight(1);
Reversal_Alert1.SetDefaultColor(Color.RED);

plot Reversal_Alert2 =(Agreement_Level crosses above 2);
Reversal_Alert2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
Reversal_Alert2.SetLineWeight(1);
Reversal_Alert2.SetDefaultColor(Color.GREEN);

plot Reversal_Buy = (Agreement_Level < 1) and (Agreement_Level[1] <= Agreement_Level);#conditionMR and price>= Middle_BandS;
Reversal_Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Buy.SetLineWeight(1);
Reversal_Buy.SetDefaultColor(Color.LIGHT_GRAY);

plot Reversal_Sell = (Agreement_Level > 12) and (Agreement_Level[1] >= Agreement_Level);#conditionMR and price>= Middle_BandS;
Reversal_Sell.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
Reversal_Sell.SetLineWeight(1);
Reversal_Sell.SetDefaultColor(Color.LIGHT_RED);

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
AddLabel(yes, "Look_To_Buy", if Buy then Color.GREEN else Color.GRAY);
AddLabel(yes, "Look_To_Sell", if Sell then Color.RED else Color.GRAY);

def MomentumUP = Agreement_Level[1] < Agreement_Level;
def MomentumDOWN = Agreement_Level[1] > Agreement_Level;
AddLabel(yes, "Increasing Momentum", if MomentumUP then Color.Green else Color.GRAY);
AddLabel(yes, "Decreasing Momentum", if MomentumDOWN then Color.RED else Color.GRAY);

def conditionMR = (Upper_BandS[1] > Upper_BandS) and (Lower_BandS[1] > Lower_BandS);
AddLabel(yes, "MEAN REVERSION", if conditionMR then Color.RED else Color.GRAY);
def conditionBO = (Upper_BandS[1] < Upper_BandS) and (Lower_BandS[1] < Lower_BandS);
AddLabel(yes, "BREAKOUT", if conditionBO then Color.GREEN else Color.GRAY);

def Squeeze_Signal = Squeeze_Alert;
AddLabel(yes, "SQUEEZE ALERT", if Squeeze_Signal then Color.YELLOW else Color.GRAY);
Hi Christopher. Happened to come across this study and found it very interesting. Can you confirm if this will work on the SPX index? I wasn't able to see any indications using SPX. Thank you for your efforts and what looks to be a great tool for the toolbox!
 

Christopher84

Active member
VIP
Hi Christopher. Happened to come across this study and found it very interesting. Can you confirm if this will work on the SPX index? I wasn't able to see any indications using SPX. Thank you for your efforts and what looks to be a great tool for the toolbox!
Hi rfb! The candles will still paint correctly for SPX, however, the signals and lower study will not show unfortunately. Thank you for trying it out and for your feedback!
 

Similar threads

Top