Confirmation Candles Indicator For ThinkorSwim

Hi @SEPTrader!
Thank you for the detailed question. In order to get the WL column to work, I had to omit a few of the studies. Otherwise the code is too complex for ToS to run. Although the Confirmation Level is slightly different between the WL and the actual indicator, you will find the indications on the WL column to still be extremely similar to the OB/OS indications that you see on your chart. Another thing to note is that when the column reads equal to or greater than 7, it generally indicates a green candle on the chart and numbers below 7 are generally red candles. I am really glad you are enjoying the indicators! Happy trading!
@Christopher84
Just curious, what does colors represent in this watch list column?

Also, do you have any pro versions of your indicators?
 
Last edited:
@s1111 @Christopher84 @MerryDay @Trader Raider

Folks,
I am not sure what am I doing wrong :)
After installing the indicator (see chart and studies config below),

The "time line" is way off from the current trading hours
- see chart image showing current time in upper left vs the chart time on the bottom and indicator cut-off

8Hvc9UJ.jpg
jzEHSLd.jpg
 

Attachments

  • 8Hvc9UJ.jpg
    8Hvc9UJ.jpg
    803.2 KB · Views: 205
Last edited:
@s1111 @Christopher84 @MerryDay @Trader Raider

Folks,
I am not sure what am I doing wrong :)
After installing the indicator (see chart and studies config below),

The "time line" is way off from the current trading hours
- see chart image showing current time in upper left vs the chart time on the bottom and indicator cut-off

8Hvc9UJ.jpg
jzEHSLd.jpg
Lol. Looks like you have your time set up wrong. On the top of the chart where you see oct,25, and time, click on it and set to localized time. Somehow you have localized and eastern time mixed up?
 

Attachments

  • 8Hvc9UJ.jpg
    8Hvc9UJ.jpg
    803.2 KB · Views: 149
Lol. Looks like you have your time set up wrong. On the top of the chart where you see oct,25, and time, click on it and set to localized time. Somehow you have localized and eastern time mixed up?
@s1111 Many Thanks for your help
I end-up reconfiguring my charts, starting from "default" (the time is set to local)
looks good now
I left only C3 and B4 configuring on the chart
 
@s1111 Many Thanks for your help
I end-up reconfiguring my charts, starting from "default" (the time is set to local)
looks good now
I left only C3 and B4 configuring on the chart
@DeepThinker . My pleasure, glad I could be help. Remember less is more, more is chaos . As I'm slowly learning to trade I have less and less script on my chart. My chart used to look like 4th of July fireworks which was a big disaster and distraction. Keep it simple and clean. Best of luck 👍
 
Hi Chris, pleased to meet you. I came across this indicator from a friend who is in the states and can use TOS, but I am in Canada and we're not able to set up TOS accounts. Is there a modification of this script that I can put onto trading view or Interactive Brokers by chance? Thank you
 
Hi Everyone!
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 15 indicators of trend within this indicator. You can choose how many of the 15 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.

***Please note that I will always post the newest version of these indicators on page 1 of this thread. I am always happy to answer questions for those who are trying to utilize these indicators. However, I ask that you review my post below explaining the various aspects of the indicators. I'll do my best to continue to elaborate to help everyone.

wx6WYDq.png

IATXQlV.png


Code:
#
#Confirmation Candles V.10
#Created 04/15/2021 by Christopher84
#Select the level of agreement among the 15 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.
#Changed 05/12/2021 to V.9  - dialed in studies to give stronger signals. Removed reversal buy and sell signals with OB/OS signals. Included OB/OS clouds to indicate favorable zones to buy or take profit. Clouds can also indicate nearterm reversals. Cleaned up code.
#Changed 05/20/2021 to V.10 - Removed Pivot Study and replaced with CIP. Reworked Labels to reflect mean reversion Look to Buy/Look to Sell conditions. Removed Mean Reversion Label. Added new label to show the Confirmation_Level and color coded it to show OB/OS conditions.

#Keltner Channel
declare upper;
def displace = 0;
def factorK = 2.0;
def 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;
def BulgeLengthPrice = 75;
def SqueezeLengthPrice = 75;
def BulgeLengthPrice2 = 20;
def 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 IntermResistance = Highest(price, BulgeLengthPrice);
IntermResistance.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
plot IntermSupport = Lowest(price, SqueezeLengthPrice);
IntermSupport.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);

plot NearTResistance = Highest(price, BulgeLengthPrice2);
NearTResistance.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
NearTResistance.SetStyle(Curve.SHORT_DASH);
plot NearTSupport = Lowest(price, SqueezeLengthPrice2);
NearTSupport.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
NearTSupport.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) or (NearT >= MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];

def condition5 = CIP_UP;

#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 (AvgExp2[2] <= AvgExp2);

#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 = 20;#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.25;
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 = 13;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0);

#Projection Oscillator
def ProjectionOsc_length = 30;#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);# or ((PROSC[1] < PROSC) and PROSC > 40);
def conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = 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_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

#Keltner #2
input showCloud = yes;
def factorK2 = 3.25;
def lengthK2 = 20;

def shiftK2 = factorK2 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK2);
def averageK2 = MovingAverage(averageType, price, lengthK2);
def AvgK2 = averageK2[-displace];
def Upper_BandK2 = averageK2[-displace] + shiftK2[-displace];
def Lower_BandK2 = averageK2[-displace] - shiftK2[-displace];

def condition_BandRevDn = (Upper_BandS > Upper_BandK2);
def condition_BandRevUp = (Lower_BandS < Lower_BandK2);

AddCloud(if showCloud and condition_BandRevUp then Lower_BandK2 else Double.NaN, Lower_BandS, Color.LIGHT_GREEN, color.CURRENT);
AddCloud(if showCloud and condition_BandRevDn then Upper_BandS else Double.NaN, Upper_BandK2, Color.LIGHT_Red, Color.CURRENT);

#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 Consensus_Line = OB_Level - OS_Level;
def Zero_Line = 0;
def Super_OB = 4;
def Super_OS = -3;

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

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Consensus_Line < Super_OB and Consensus_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);

plot OB_Signal = Upper_BandS crosses above IntermResistance;
OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OB_Signal.SetLineWeight(3);
OB_Signal.SetDefaultColor(Color.RED);

plot OS_Signal = (condition_BandRevUP) and (Lower_BandS crosses below IntermSupport);
OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OS_Signal.SetLineWeight(3);
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
def lengthBB = 10;
def Num_Dev_DnBB = -0.8;
def 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;

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);

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
AddLabel(yes, "Look_To_Buy", if (ConditionK2 and (Agreement_Level < Confirmation_Factor)) then Color.GREEN else Color.GRAY);
AddLabel(yes, "Look_To_Sell", if (ConditionK3 and (Agreement_Level > Confirmation_Factor)) 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 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);

AddLabel(yes, "Confirmation_Level = " + round(Agreement_Level,1), if ((Agreement_Level >= 12) and (Consensus_Line >= 4)) then Color.RED else if ((Agreement_Level <= 3) and (Consensus_Line <= -3)) then Color.Green else color.Gray);

Here is the Confirmation Candles lower study.
Code:
#Confirmation Candles Lower V.10
#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.
#Changed 05/12/2021 to V.9  - dialed in studies to give stronger signals.
#Changed 05/20/2021 to V.10 - Removed Pivot Study and replaced with CIP.

#Keltner Channel
declare lower;
def displace = 0;
def factorK = 2.0;
def lengthK = 20;
def 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) or (NearT >= MidLine);
def conditionFOB = Intermed > FOB;
def conditionFOS = Intermed < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;

#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 (AvgExp2[2] <= AvgExp2);

#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 = 20;#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.25;
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 = 13;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0);

#Projection Oscillator
def ProjectionOsc_length = 30;#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;

Agreement_Level.AssignValueColor(
if Agreement_Level > Agreement_Level[1] and Agreement_Level >= Confirmation_Factor then Color.LIGHT_GREEN
else if Agreement_Level < Agreement_Level[1] and Agreement_Level >= Confirmation_Factor then Color.LIGHT_GREEN
else 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 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);

(Confirmation Consensus Candles) C3 v5

This is a new candle painting indicator C3, 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 C3 utilizes both positive and negative factors of price movement and weighs them against each other to derive the Consensus Level. 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.
nOD1krz.png

5QygBoC.png

wPdK4Ht.png

Code:
# (Consensus Confirmation Candles) C3 v6
#
# 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.
#
# v2   - 05/11/2021 - dialed in studies to give stronger signals. Removed reversal buy and sell signals with
#                     OB/OS signals. Included OB/OS clouds to indicate favorable zones to buy or take profit.
#                     Clouds can also indicate nearterm reversals. Cleaned up code.
# v3   - 05/20/2021 - Removed Pivot Study and replaced with CIP. Reworked Labels to reflect mean reversion Look
#                     to Buy/Look to Sell conditions. Removed Mean Reversion Label. Added new label to show the
#                     Confirmation_Level and color coded it to show OB/OS conditions.
# BETA - 05/21/2021 - (barbaros) Consensus Level filter set to above 4 and below -4
# v4   - 05/24/2021 - Consensus Level filter changed to above 6 and below -6
# BETA - 05/29/2021 - (barbaros) Bug fixes
# v5   - 06/01/2021 - Consolidated labels. Added new squeeze condition based on NearTSupport and NearTResistance.
# v5   - 06/04/2021 - Included Ichimoku cloud.
# v6   - 06/09/2021 - Added Arrows using Confirmation_Factor

#Keltner Channel
declare upper;
def displace = 0;
def factorK = 2.0;
def lengthK = 20;
def price = close;
input averageType = AverageType.SIMPLE;
def trueRangeAverageType = AverageType.SIMPLE;
def BulgeLengthPrice = 75;
def SqueezeLengthPrice = 75;
def BulgeLengthPrice2 = 20;
def SqueezeLengthPrice2 = 20;
def BulgeLengthPrice3 = 12;
def SqueezeLengthPrice3 = 12;

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 conditionK1UP = price >= Upper_BandK;
def conditionK2UP = (Upper_BandK[1] < Upper_BandK) and (Lower_BandK[1] < Lower_BandK);
def conditionK3DN = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);
def conditionK4DN = price < Lower_BandK;
def BandwidthK = (Upper_BandK - Lower_BandK) / AvgK * 100;

plot IntermResistance = Highest(price, BulgeLengthPrice);
IntermResistance.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
plot IntermSupport = Lowest(price, SqueezeLengthPrice);
IntermSupport.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);

plot NearTResistance = Highest(price, BulgeLengthPrice2);
NearTResistance.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
NearTResistance.SetStyle(Curve.SHORT_DASH);
plot NearTSupport = Lowest(price, SqueezeLengthPrice2);
NearTSupport.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
NearTSupport.SetStyle(Curve.SHORT_DASH);

def NearTResistance1 = Highest(price, BulgeLengthPrice3);
def NearTSupport1 = Lowest(price, SqueezeLengthPrice3);

#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) or (NearT >= MidLine);
def condition4D = (Intermed[1] > Intermed) or (NearT < MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;
def condition5D = CIP_DOWN;

#EMA_1
def EMA_length = 8;
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 (AvgExp2[2] <= AvgExp);
def condition7D = (price < AvgExp2) and (AvgExp2[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 = 20;#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.25;
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 = 13;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0);
def condition13D = (KVOH < 0);

#Projection Oscillator
def ProjectionOsc_length = 30;#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;
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_LevelOB = 10;
def Agreement_LevelOS = -10;

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

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

def Consensus_Level = Agreement_Level - Agreement_LevelD;

def UP = Consensus_Level >= 6;
def DOWN = Consensus_Level < -6;

def priceColor = if UP then 1
                 else if DOWN then -1
                 else priceColor[1];

AssignPriceColor(if coloredCandlesOn and priceColor == 1 then Color.LIGHT_GREEN else if coloredCandlesOn and priceColor == -1 then Color.RED else Color.CURRENT);

#Additional Signals
#Keltner #2
input showCloud = yes;
def factorK2 = 3.25;
def lengthK2 = 20;

def shiftK2 = factorK2 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK2);
def averageK2 = MovingAverage(averageType, price, lengthK2);
def AvgK2 = averageK2[-displace];
def Upper_BandK2 = averageK2[-displace] + shiftK2[-displace];
def Lower_BandK2 = averageK2[-displace] - shiftK2[-displace];
def condition_BandRevDn = (Upper_BandS > Upper_BandK2);
def condition_BandRevUp = (Lower_BandS < Lower_BandK2);

AddCloud(if showCloud and condition_BandRevUp then Lower_BandK2 else Double.NaN,  Lower_BandS,  Color.LIGHT_GREEN,  Color.CURRENT);
AddCloud(if showCloud and condition_BandRevDn then Upper_BandS else Double.NaN,  Upper_BandK2,  Color.LIGHT_RED,  Color.CURRENT);

#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 Consensus_Line = OB_Level - OS_Level;
def Zero_Line = 0;
def Super_OB = 4;
def Super_OS = -4;

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

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Consensus_Line < Super_OB and Consensus_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);

plot OB_Signal = Upper_BandS crosses above IntermResistance;
OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OB_Signal.SetLineWeight(3);
OB_Signal.SetDefaultColor(Color.RED);

plot OS_Signal = (condition_BandRevUp) and (Lower_BandS crosses below IntermSupport);
OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OS_Signal.SetLineWeight(3);
OS_Signal.SetDefaultColor(Color.GREEN);

#Squeeze Alert
def BandwidthC3 = (NearTResistance1 - NearTSupport1);
def IntermResistance2 = Highest(BandwidthC3,BulgeLengthPrice);
def IntermSupport2 = Lowest(BandwidthC3, SqueezeLengthPrice);
def sqzTrigger = BandwidthC3 <= IntermSupport2;
def sqzLevel = if !sqzTrigger[1] and sqzTrigger then hl2
               else if !sqzTrigger then Double.NaN
               else sqzLevel[1];

plot Squeeze_Alert = sqzLevel;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.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);

#Bollinger_Bands2
def lengthBB = 10;
def Num_Dev_DnBB = -0.8;
def 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;

input tenkan_period = 9;
input kijun_period = 26;
input show_Ichimoku_Cloud = yes;

def Tenkan = (Highest(high, tenkan_period) + Lowest(low, tenkan_period)) / 2;
def Kijun = (Highest(high, kijun_period) + Lowest(low, kijun_period)) / 2;
def "Span A" = (Tenkan[kijun_period] + Kijun[kijun_period]) / 2;
def "Span B" = (Highest(high[kijun_period], 2 * kijun_period) + Lowest(low[kijun_period], 2 * kijun_period)) / 2;
def Chikou = close[-kijun_period];

AddCloud(if show_Ichimoku_Cloud and "Span A" then "Span A" else Double.NaN, "Span B",  Color.WHITE,  Color.GRAY);
#AddCloud("Span A", "Span B", color.WHITE, color.GRAY);

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
def conditionLTB = (ConditionK2UP and (Consensus_Level < 0));
def conditionLTS = (ConditionK3DN and (Consensus_Level > 0));
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));
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));
def MomentumUP = Consensus_Level[1] < Consensus_Level;
def MomentumDOWN = Consensus_Level[1] > Consensus_Level;
def Squeeze_Signal = !isNaN(Squeeze_Alert);
def conditionOB = (Consensus_Level >= 12) and (Consensus_Line >= 4);
def conditionOS = (Consensus_Level <= -12) and (Consensus_Line <= -3);

AddLabel(yes, if conditionLTB then "BULLISH_LOOK_To_BUY" else if conditionLTS then "BEARISH_LOOK_TO_SELL" else if conditionK2UP then "TREND_BULLISH" else if conditionK3DN then "TREND_BEARISH" else "TREND_CONSOLIDATION", if conditionLTB then Color.GREEN else if conditionLTS then Color.Red else if conditionK2UP then Color.WHITE else if conditionK3DN then Color.DARK_GRAY else Color.GRAY);

AddLabel(yes, if conditionBD then "BREAKDOWN" else if conditionBO then "BREAKOUT" else "NO_BREAK", if conditionBD then Color.RED else if conditionBO then Color.Green else Color.Gray);

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

AddLabel(yes, if MomentumUP then "Consensus_Increasing = " + round(Consensus_Level,1) else if MomentumUP or MomentumDOWN and conditionOB then "Consensus_OVERBOUGHT = " + round(Consensus_Level,1) else if MomentumDOWN then  "Consensus_Decreasing = " + round(Consensus_Level,1) else if MomentumUP or MomentumDOWN and conditionOS then "Consensus_OVERSOLD = " + round(Consensus_Level,1)else "Consensus = " + round(Consensus_Level,1), if conditionOB then Color.RED else if conditionOS then Color.Green else color.GRAY);

For those of you that trade FOREX or the SPX, here is a modified version that will function on those instruments.
Code:
# (Consensus Confirmation Candles) C3 v5 FOREX & SPX Compatible
#
# 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.
#
# v2   - 05/11/2021 - dialed in studies to give stronger signals. Removed reversal buy and sell signals with
#                     OB/OS signals. Included OB/OS clouds to indicate favorable zones to buy or take profit.
#                     Clouds can also indicate nearterm reversals. Cleaned up code.
# v3   - 05/20/2021 - Removed Pivot Study and replaced with CIP. Reworked Labels to reflect mean reversion Look
#                     to Buy/Look to Sell conditions. Removed Mean Reversion Label. Added new label to show the
#                     Confirmation_Level and color coded it to show OB/OS conditions.
# BETA - 05/21/2021 - (barbaros) Consensus Level filter set to above 4 and below -4
# v4   - 05/24/2021 - Consensus Level filter changed to above 6 and below -6
# BETA - 05/29/2021 - (barbaros) Bug fixes
# v5   - 06/01/2021 - Consolidated labels. Added new squeeze condition based on NearTSupport and NearTResistance.
# BETA - 06/02/2021 - Modified study set to be compatable with FOREX and SPX.
# v6   - 06/09/2021 - Modified to include Confirmation Arrows
#Keltner Channel
declare upper;
def displace = 0;
def factorK = 2.0;
def lengthK = 20;
def price = close;
input averageType = AverageType.SIMPLE;
def trueRangeAverageType = AverageType.SIMPLE;
def BulgeLengthK = 250;
def SqueezeLengthK = 250;
def BulgeLengthK2 = 150;
def SqueezeLengthK2 = 150;
def BulgeLengthPrice = 75;
def SqueezeLengthPrice = 75;
def BulgeLengthPrice2 = 20;
def SqueezeLengthPrice2 = 20;
def BulgeLengthPrice3 = 12;
def SqueezeLengthPrice3 = 12;

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 conditionK1UP = price >= Upper_BandK;
def conditionK2UP = (Upper_BandK[1] < Upper_BandK) and (Lower_BandK[1] < Lower_BandK);
def conditionK3DN = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);
def conditionK4DN = price < Lower_BandK;

def BandwidthK = (Upper_BandK - Lower_BandK) / AvgK * 100;
def BandwidthKS = (Bandwidthk[2]+ Bandwidthk[1] + BandwidthK) / 3;
def BulgeK = Highest(BandwidthKS, BulgeLengthK);
def SqueezeK = Lowest(BandwidthKS, SqueezeLengthK);
def BulgeK2 = Highest(BandwidthKS, BulgeLengthK2);
def SqueezeK2 = Lowest(BandwidthKS, SqueezeLengthK2);
def condition_Keltner_Squeeze = BandwidthKS <= SqueezeK;

plot IntermResistance = Highest(price, BulgeLengthPrice);
IntermResistance.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
plot IntermSupport = Lowest(price, SqueezeLengthPrice);
IntermSupport.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);

plot NearTResistance = Highest(price, BulgeLengthPrice2);
NearTResistance.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
NearTResistance.SetStyle(Curve.SHORT_DASH);
plot NearTSupport = Lowest(price, SqueezeLengthPrice2);
NearTSupport.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
NearTSupport.SetStyle(Curve.SHORT_DASH);

def NearTResistance1 = Highest(price, BulgeLengthPrice3);
def NearTSupport1 = Lowest(price, SqueezeLengthPrice3);

#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) or (NearT >= MidLine);
def condition4D = (Intermed[1] > Intermed) or (NearT < MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;
def condition5D = CIP_DOWN;

#EMA_1
def EMA_length = 8;
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 (AvgExp2[2] <= AvgExp);
def condition7D = (price < AvgExp2) and (AvgExp2[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 = 20;#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.25;
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 = 13;
#def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
#def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
#def condition13 = (KVOH > 0);
#def condition13D = (KVOH < 0);

#Projection Oscillator
def ProjectionOsc_length = 30;#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;
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_LevelOB = 10;
def Agreement_LevelOS = -10;

def Agreement_Level = condition1 + condition2 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition14 + conditionK1UP + conditionK2UP;

def Agreement_LevelD = condition1D + condition2D + condition4D + condition5D + condition6D + condition7D + condition8D + condition9D + condition10D + condition11D + condition12D + condition14D + conditionK3DN + conditionK4DN;

def Consensus_Level = Agreement_Level - Agreement_LevelD;

def UP = Consensus_Level >= 4;
def DOWN = Consensus_Level < -4;

def priceColor = if UP then 1
                 else if DOWN then -1
                 else priceColor[1];

AssignPriceColor(if coloredCandlesOn and priceColor == 1 then Color.LIGHT_GREEN else if coloredCandlesOn and priceColor == -1 then Color.RED else Color.CURRENT);

#Additional Signals
#Keltner #2
input showCloud = yes;
def factorK2 = 3.25;
def lengthK2 = 20;

def shiftK2 = factorK2 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK2);
def averageK2 = MovingAverage(averageType, price, lengthK2);
def AvgK2 = averageK2[-displace];
def Upper_BandK2 = averageK2[-displace] + shiftK2[-displace];
def Lower_BandK2 = averageK2[-displace] - shiftK2[-displace];
def condition_BandRevDn = (Upper_BandS > Upper_BandK2);
def condition_BandRevUp = (Lower_BandS < Lower_BandK2);

AddCloud(if showCloud and condition_BandRevUp then Lower_BandK2 else Double.NaN,  Lower_BandS,  Color.LIGHT_GREEN,  Color.CURRENT);
AddCloud(if showCloud and condition_BandRevDn then Upper_BandS else Double.NaN,  Upper_BandK2,  Color.LIGHT_RED,  Color.CURRENT);

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

def Consensus_Line = OB_Level - OS_Level;
def Zero_Line = 0;
def Super_OB = 4;
def Super_OS = -4;

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

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Consensus_Line < Super_OB and Consensus_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);

plot OB_Signal = Upper_BandS crosses above IntermResistance;
OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OB_Signal.SetLineWeight(3);
OB_Signal.SetDefaultColor(Color.RED);

plot OS_Signal = (condition_BandRevUp) and (Lower_BandS crosses below IntermSupport);
OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OS_Signal.SetLineWeight(3);
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);

def BandwidthC3 = (NearTResistance1 - NearTSupport1);

def IntermResistance2 = Highest(BandwidthC3,BulgeLengthPrice);
def IntermSupport2 = Lowest(BandwidthC3, SqueezeLengthPrice);
#def NearTResistance2 = Highest(BandwidthC3, BulgeLengthPrice2);
#def NearTSupport2 = Lowest(BandwidthC3, SqueezeLengthPrice2);

def sqzTrigger = BandwidthC3 <= IntermSupport2;
def sqzLevel = if !sqzTrigger[1] and sqzTrigger then hl2
               else if !sqzTrigger then Double.NaN
               else sqzLevel[1];

plot Squeeze_Alert = sqzLevel;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.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);
#Bollinger_Bands2
def lengthBB = 10;
def Num_Dev_DnBB = -0.8;
def 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;

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
def conditionLTB = (ConditionK2UP and (Consensus_Level < 0));
def conditionLTS = (ConditionK3DN and (Consensus_Level > 0));
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));
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));
def MomentumUP = Consensus_Level[1] < Consensus_Level;
def MomentumDOWN = Consensus_Level[1] > Consensus_Level;
def Squeeze_Signal = !isNaN(Squeeze_Alert);
def conditionOB = (Consensus_Level >= 12) and (Consensus_Line >= 4);
def conditionOS = (Consensus_Level <= -12) and (Consensus_Line <= -3);

AddLabel(yes, if conditionLTB then "BULLISH_LOOK_To_BUY" else if conditionLTS then "BEARISH_LOOK_TO_SELL" else if conditionK2UP then "TREND_BULLISH" else if conditionK3DN then "TREND_BEARISH" else "TREND_CONSOLIDATION", if conditionLTB then Color.GREEN else if conditionLTS then Color.Red else if conditionK2UP then Color.WHITE else if conditionK3DN then Color.DARK_GRAY else Color.GRAY);

AddLabel(yes, if conditionBD then "BREAKDOWN" else if conditionBO then "BREAKOUT" else "NO_BREAK", if conditionBD then Color.RED else if conditionBO then Color.Green else Color.Gray);

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

AddLabel(yes, if MomentumUP then "Consensus_Increasing = " + round(Consensus_Level,1) else if MomentumUP or MomentumDOWN and conditionOB then "Consensus_OVERBOUGHT = " + round(Consensus_Level,1) else if MomentumDOWN then  "Consensus_Decreasing = " + round(Consensus_Level,1) else if MomentumUP or MomentumDOWN and conditionOS then "Consensus_OVERSOLD = " + round(Consensus_Level,1)else "Consensus = " + round(Consensus_Level,1), if conditionOB then Color.RED else if conditionOS then Color.Green else color.GRAY);
Here's the lower study.
gWWYe5M.png

Code:
#CC Candles Lower V.2
#Created 04/28/2021 by Christopher84
#Modified to V.2 05/11/2021 - dialed in studies to give stronger signals. Included OB/OS Clouds and cleaned up code.
#Changed 05/20/2021 to V.3 - Removed Pivot Study and replaced with CIP.

#Keltner Channel
declare lower;
def displace = 0;
def factorK = 2.0;
def 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;
def BulgeLengthPrice = 75;
def SqueezeLengthPrice = 75;
def BulgeLengthPrice2 = 20;
def SqueezeLengthPrice2 = 20;
def BulgeLengthCC = 40;
def SqueezeLengthCC = 40;
def BulgeLengthCC2 = 8;
def 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);

#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) or (NearT >= MidLine);
def condition4D = (Intermed[1] > Intermed) or (NearT < MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);

def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;
def condition5D = CIP_DOWN;

#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 = 20;#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.25;
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 = 13;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0);
def condition13D = (KVOH < 0);

#Projection Oscillator
def ProjectionOsc_length = 30;#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;
def Confirmation_Factor = 0;
#Use for testing conditions individually. Remove # from line below and change Confirmation_Factor to 1.
#def Agreement_Level = condition1;
def Agreement_LevelOB = 10;
def Agreement_LevelOS = -10;

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;

AddCloud(Consensus_Level, Agreement_LevelOB, Color.LIGHT_RED, Color.CURRENT);
AddCloud(Consensus_Level, Agreement_LevelOS, Color.CURRENT, Color.LIGHT_GREEN);

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);

Here is a custom watchlist column for the Confirmation Candles. If you sort the column, it makes it easier to see OB/OS conditions. Especially when grouped with the Super OB/OS custom watchlist column which is also posted below.
oBocGCU.png

Code:
#Confirmation Level Watchlist developed 04/15/2021 by Christopher Wilson
#Select the level of agreement among the 15 indicators included.
#Changed 05/20/21 Included CIP.

#MACD with Price
declare lower;
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 FOB = 80;
def FOS = 20;
def upperLine = 110;

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

#Change in Price
def lengthCIP = 5;
def displace = 0;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;

#EMA_1
input EMA_length = 12;
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 (AvgExp2[2] <= AvgExp2);

#DMI Oscillator
input DMI_length = 5;
input averageType = AverageType.WILDERS;

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

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

def condition8 = Osc >= ZeroLine;

#Trend_Periods
input TP_fastLength = 3;
input TP_slowLength = 4;

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

def condition9 = Periods > 0;

#Polarized Fractal Efficiency
input PFE_length = 5;
input smoothingLength = 2.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 > 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 condition11 = PercentB > 50;

#STARC Bands
def ATR_length = 15;
def SMA_lengthS = 6;
def multiplier_factor = 1.25;
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);

#Projection Oscillator
def ProjectionOsc_length = 30;#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 condition13 = (PROSC > 50);

#Trend Confirmation
#Confirmation_Factor range 1-13.
input Confirmation_Factor = 7;
#Use for testing conditions individually.
#def Agreement_Level = condition1;
plot Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13;

def Sell_Alert = Agreement_Level >= 9;
def Buy_Alert = Agreement_Level <= 2 ;


def Factor_Line = Confirmation_Factor;

AssignBackgroundColor(if Sell_Alert then color.LIGHT_RED else if Buy_Alert then color.dark_green else color.black);

Here is the Super OB/OS custom watchlist column.
Code:
#Super_OB_OS_Lower
#Created by Christopher84 04/22/2021
#Modified 5/12/2021 Adjusted OB/OS levels.

declare lower;
def BulgeLength = 75;
def SqueezeLength = 75;
def BulgeLength2 = 8;
def SqueezeLength2 = 8;

#RSI
def price = close;
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 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 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 conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;

def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#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 conditionOB5 = PFE > UpperLevel;
def conditionOS5 = PFE < LowerLevel;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
def displace = 0;
def BBPB_length = 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 conditionOB6 = PercentB > BBPB_OB;
def conditionOS6 = PercentB < BBPB_OS;

#Projection Oscillator
def ProjectionOsc_length = 30;#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 conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = PROSC < PROSC_OS;

#OB/OS Calculation

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

plot Consensus_Line = OB_Level - OS_Level;

def Zero_Line = 0;
def Super_OB = 4;
def Super_OS = -3;

def OB = Consensus_Line >= Super_OB;
def OS = Consensus_Line <= Super_OS;

AssignBackgroundColor(if OB then color.light_red else if OS then color.dark_green else color.black);

For those of you that are intrested, here is the Super OB/OS lower indicator.
wea6B5x.png

gKaEnqX.png

Code:
#Super_OB_OS_Lower
#Created by Christopher84 04/22/2021
#Modified 5/12/2021 Included dynamic support and resistance. Adjusted OB/OS levels.

declare lower;
def BulgeLength = 75;
def SqueezeLength = 75;
def BulgeLength2 = 8;
def SqueezeLength2 = 8;

#RSI
def price = close;
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 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 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 conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;

def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#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 conditionOB5 = PFE > UpperLevel;
def conditionOS5 = PFE < LowerLevel;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
def displace = 0;
def BBPB_length = 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 conditionOB6 = PercentB > BBPB_OB;
def conditionOS6 = PercentB < BBPB_OS;

#Projection Oscillator
def ProjectionOsc_length = 30;#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 conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = PROSC < PROSC_OS;

#OB/OS Calculation

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

plot Consensus_Line = OB_Level - OS_Level;

def Zero_Line = 0;

plot Bulge = Highest(Consensus_Line, BulgeLength);
bulge.SetPaintingStrategy(PaintingStrategy.LINE);
bulge.SetLineWeight(1);
bulge.SetDefaultColor(Color.RED);

plot Squeeze = Lowest(Consensus_Line, SqueezeLength);
Squeeze.SetPaintingStrategy(PaintingStrategy.LINE);
Squeeze.SetLineWeight(1);
Squeeze.SetDefaultColor(Color.LIGHT_GREEN);

plot Bulge2 = Highest(Consensus_Line, BulgeLength2);
bulge2.SetPaintingStrategy(PaintingStrategy.LINE);
bulge2.SetStyle(Curve.SHORT_DASH);
bulge2.SetLineWeight(1);
bulge2.SetDefaultColor(Color.GRAY);

plot Squeeze2 = Lowest(Consensus_Line, SqueezeLength2);
Squeeze2.SetPaintingStrategy(PaintingStrategy.LINE);
Squeeze2.SetStyle(Curve.SHORT_DASH);
Squeeze2.SetLineWeight(1);
Squeeze2.SetDefaultColor(Color.GRAY);

input Super_OB = 4;
input Super_OS = -3;

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


AddCloud(Consensus_Line, Super_OB, Color.LIGHT_RED, Color.CURRENT);
AddCloud(Consensus_Line, Super_OS, Color.CURRENT, Color.LIGHT_GREEN);
Here is the Super_OB_OS_SPX_Version.
Code:
#Super_OB_OS_Lower_SPX
#Created by Christopher84 04/22/2021
#Modified 5/12/2021 Included dynamic support and resistance. Adjusted OB/OS levels.

declare lower;
def BulgeLength = 75;
def SqueezeLength = 75;
def BulgeLength2 = 8;
def SqueezeLength2 = 8;

#RSI
def price = close;
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 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 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 conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;

def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#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 conditionOB5 = PFE > UpperLevel;
def conditionOS5 = PFE < LowerLevel;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
def displace = 0;
def BBPB_length = 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 conditionOB6 = PercentB > BBPB_OB;
def conditionOS6 = PercentB < BBPB_OS;

#Projection Oscillator
def ProjectionOsc_length = 30;#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 conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = PROSC < PROSC_OS;

#OB/OS Calculation

def OB_Level = conditionOB1 + conditionOB3 + conditionOB4 + conditionOB5 + conditionOB6 + conditionOB7;
def OS_Level = conditionOS1 + conditionOS3 + conditionOS4 + conditionOS5 + conditionOS6 + conditionOS7;

plot Consensus_Line = OB_Level - OS_Level;

def Zero_Line = 0;

plot Bulge = Highest(Consensus_Line, BulgeLength);
bulge.SetPaintingStrategy(PaintingStrategy.LINE);
bulge.SetLineWeight(1);
bulge.SetDefaultColor(Color.RED);

plot Squeeze = Lowest(Consensus_Line, SqueezeLength);
Squeeze.SetPaintingStrategy(PaintingStrategy.LINE);
Squeeze.SetLineWeight(1);
Squeeze.SetDefaultColor(Color.LIGHT_GREEN);

plot Bulge2 = Highest(Consensus_Line, BulgeLength2);
bulge2.SetPaintingStrategy(PaintingStrategy.LINE);
bulge2.SetStyle(Curve.SHORT_DASH);
bulge2.SetLineWeight(1);
bulge2.SetDefaultColor(Color.GRAY);

plot Squeeze2 = Lowest(Consensus_Line, SqueezeLength2);
Squeeze2.SetPaintingStrategy(PaintingStrategy.LINE);
Squeeze2.SetStyle(Curve.SHORT_DASH);
Squeeze2.SetLineWeight(1);
Squeeze2.SetDefaultColor(Color.GRAY);

input Super_OB = 4;
input Super_OS = -4;

Consensus_Line.AssignValueColor(
if Consensus_Line > Consensus_Line[1] and Consensus_Line > Zero_Line then Color.GREEN
else if Consensus_Line < Consensus_Line[1] and Consensus_Line > Zero_Line then Color.GREEN
else if Consensus_Line < Consensus_Line[1] and Consensus_Line <= Zero_Line then Color.RED else
if Consensus_Line > Consensus_Line[1] and Consensus_Line <= Zero_Line then Color.RED
else Color.RED);

### Bar Color
input ColorCandlesON = no;

def UP = Consensus_Line > 2;
def DOWN = Consensus_Line < -2;

def PriceColor = if UP then 1
                 else if DOWN then -1
                 else PriceColor[1];

AssignPriceColor(
    if ColorCandlesOn and PriceColor == 1 then Color.GREEN
else if ColorCandlesOn and PriceColor == -1 then Color.RED
else Color.CURRENT
);

AddCloud(Consensus_Line, Super_OB, Color.LIGHT_RED, Color.CURRENT);
AddCloud(Consensus_Line, Super_OS, Color.CURRENT, Color.GREEN);

So last but not least, I have had several request to share my MTF Cloud Upper and Lower studies. So here they are!
aJLdasc.png

Code:
# MTF Moving Average Upper Created 05/01/2021 by Christopher84

declare upper;

input price = close;
input length = 10;
input agperiod1 = {"1 min", "2 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "4 hours", default "Day", "Week"};
input agperiod2 = {"1 min", "2 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "4 hours", "Day", default "Week"};

plot avg = ExpAverage(close(period = agperiod1), length);
def height = avg - avg[length];
avg.SetStyle(Curve.SHORT_DASH);
avg.SetLineWeight(1);

def UP = avg[1] < avg;
def DOWN = avg[1] > avg;
Avg.AssignValueColor(if UP then Color.LIGHT_GREEN else if DOWN then Color.RED else Color.YELLOW);

plot avg2 = ExpAverage(close(period = agperiod2), length);
def height2 = avg2 - avg2[length];
avg2.SetStyle(Curve.SHORT_DASH);
avg2.SetLineWeight(1);

def UP2 = avg2[1] < avg2;
def DOWN2 = avg2[1] > avg2;
Avg2.AssignValueColor(if UP2 then Color.LIGHT_GREEN else if DOWN2 then Color.RED else Color.YELLOW);

AddCloud(avg2, avg, Color.LIGHT_RED, Color.CURRENT);
AddCloud(avg, avg2, Color.LIGHT_GREEN, Color.CURRENT);
Here's the lower MTF Cloud study.
Code:
#MTF Moving Average Lower Created by Christopher84 05/01/2021

declare lower;
#Keltner Channel
def displace = 0;
def factorK = 2.0;
def lengthK = 20;
plot price = close;
input averageType = AverageType.SIMPLE;
def trueRangeAverageType = AverageType.SIMPLE;
def BulgeLengthK = 150;
def SqueezeLengthK = 150;
def BulgeLengthK2 = 40;
def SqueezeLengthK2 = 40;
def BulgeLengthPrice = 75;
def SqueezeLengthPrice = 75;
def BulgeLengthPrice2 = 20;
def SqueezeLengthPrice2 = 20;
def BulgeLengthCC = 40;
def SqueezeLengthCC = 40;
def BulgeLengthCC2 = 8;
def 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 IntermResistance = Highest(price, BulgeLengthPrice);
IntermResistance.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
plot IntermSupport = Lowest(price, SqueezeLengthPrice);
IntermSupport.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);

#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) or (NearT >= MidLine);
def condition4D = (Intermed[1] > Intermed) or (NearT < MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;
def condition5D = CIP_DOWN;

#EMA_1
def EMA_length = 8;
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 (AvgExp2[2] <= AvgExp);
def condition7D = (price < AvgExp2) and (AvgExp2[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 = 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.25;
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 = 13;
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 = 30;#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.
def coloredCandlesOn = no;
def Confirmation_Factor = 7;
#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 >= 6;

def DOWN = Consensus_Level < -6;


def priceColor = if UP then 1

                 else if DOWN then -1

                 else priceColor[1];

price.AssignValueColor(if priceColor == 1 then Color.LIGHT_GREEN else if priceColor == -1 then Color.RED else Color.CURRENT);

#EMA's
input length = 10;
input agperiod1 = {"1 min", "2 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "4 hours", default "Day", "Week"};
input agperiod2 = {"1 min", "2 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "4 hours", "Day", default "Week"};

plot avg1 = ExpAverage(close(period = agperiod1), length);
def height = avg - avg[length];
avg1.SetStyle(Curve.SHORT_DASH);
avg1.SetLineWeight(1);

def UP1 = avg1[1] < avg1;
def DOWN1 = avg1[1] > avg1;
Avg1.AssignValueColor(if UP1 then Color.LIGHT_GREEN else if DOWN1 then Color.RED else Color.YELLOW);

plot avg2 = ExpAverage(close(period = agperiod2), length);
def height2 = avg2 - avg2[length];
avg2.SetStyle(Curve.SHORT_DASH);
avg2.SetLineWeight(1);

def UP2 = avg2[1] < avg2;
def DOWN2 = avg2[1] > avg2;
Avg2.AssignValueColor(if UP2 then Color.LIGHT_GREEN else if DOWN2 then Color.RED else Color.YELLOW);

AddCloud(avg2, avg1, Color.LIGHT_RED, Color.CURRENT);
AddCloud(avg1, avg2, Color.LIGHT_GREEN, Color.CURRENT);

This is an MTF STARC. Looks great with the MTF MA Cloud for anyone that is interested.
zpf9ntR.png

Code:
#Created 05/26/2021 by Christopher84

declare weak_volume_dependency;

input price = close;
input ATR_length = 15;
input SMA_length = 6;
input displace = 0;
input multiplier_factor = 1.5;
input agperiod1 = {"1 min", "2 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "4 hours", default "Day", "Week"};
def open = open(period = agperiod1);
def high = high(period = agperiod1);
def low = low(period = agperiod1);
def close = close(period = agperiod1);

    def val = Average(close, SMA_length);

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

    plot Upper_Band = val[-displace] + multiplier_factor * average_true_range[-displace];
    def UP = Upper_Band[1] < Upper_Band;
    def DOWN =  Upper_Band[1] > Upper_Band;
    Upper_Band.AssignValueColor(if UP then Color.LIGHT_GREEN else if DOWN then Color.RED else Color.YELLOW);
    Upper_Band.SetStyle(Curve.SHORT_DASH);
    Upper_Band.SetLineWeight(2);

    plot Middle_Band = val[-displace];
    Middle_Band.SetStyle(Curve.SHORT_DASH);
    Middle_Band.SetLineWeight(2);
    Middle_Band.SetDefaultColor(Color.GRAY);

    plot Lower_Band = val[-displace] - multiplier_factor * average_true_range[-displace];
    def UP2 = Lower_Band[1] < Lower_Band;
    def DOWN2 =  Lower_Band[1] > Lower_Band;
    Lower_Band.AssignValueColor(if UP2 then Color.LIGHT_GREEN else if DOWN2 then Color.RED else Color.YELLOW);
    Lower_Band.SetStyle(Curve.SHORT_DASH);
    Lower_Band.SetLineWeight(2);
Hello
Hi Everyone!
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 15 indicators of trend within this indicator. You can choose how many of the 15 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.

***Please note that I will always post the newest version of these indicators on page 1 of this thread. I am always happy to answer questions for those who are trying to utilize these indicators. However, I ask that you review my post below explaining the various aspects of the indicators. I'll do my best to continue to elaborate to help everyone.

wx6WYDq.png

IATXQlV.png


Code:
#
#Confirmation Candles V.10
#Created 04/15/2021 by Christopher84
#Select the level of agreement among the 15 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.
#Changed 05/12/2021 to V.9  - dialed in studies to give stronger signals. Removed reversal buy and sell signals with OB/OS signals. Included OB/OS clouds to indicate favorable zones to buy or take profit. Clouds can also indicate nearterm reversals. Cleaned up code.
#Changed 05/20/2021 to V.10 - Removed Pivot Study and replaced with CIP. Reworked Labels to reflect mean reversion Look to Buy/Look to Sell conditions. Removed Mean Reversion Label. Added new label to show the Confirmation_Level and color coded it to show OB/OS conditions.

#Keltner Channel
declare upper;
def displace = 0;
def factorK = 2.0;
def 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;
def BulgeLengthPrice = 75;
def SqueezeLengthPrice = 75;
def BulgeLengthPrice2 = 20;
def 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 IntermResistance = Highest(price, BulgeLengthPrice);
IntermResistance.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
plot IntermSupport = Lowest(price, SqueezeLengthPrice);
IntermSupport.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);

plot NearTResistance = Highest(price, BulgeLengthPrice2);
NearTResistance.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
NearTResistance.SetStyle(Curve.SHORT_DASH);
plot NearTSupport = Lowest(price, SqueezeLengthPrice2);
NearTSupport.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
NearTSupport.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) or (NearT >= MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];

def condition5 = CIP_UP;

#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 (AvgExp2[2] <= AvgExp2);

#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 = 20;#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.25;
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 = 13;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0);

#Projection Oscillator
def ProjectionOsc_length = 30;#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);# or ((PROSC[1] < PROSC) and PROSC > 40);
def conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = 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_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

#Keltner #2
input showCloud = yes;
def factorK2 = 3.25;
def lengthK2 = 20;

def shiftK2 = factorK2 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK2);
def averageK2 = MovingAverage(averageType, price, lengthK2);
def AvgK2 = averageK2[-displace];
def Upper_BandK2 = averageK2[-displace] + shiftK2[-displace];
def Lower_BandK2 = averageK2[-displace] - shiftK2[-displace];

def condition_BandRevDn = (Upper_BandS > Upper_BandK2);
def condition_BandRevUp = (Lower_BandS < Lower_BandK2);

AddCloud(if showCloud and condition_BandRevUp then Lower_BandK2 else Double.NaN, Lower_BandS, Color.LIGHT_GREEN, color.CURRENT);
AddCloud(if showCloud and condition_BandRevDn then Upper_BandS else Double.NaN, Upper_BandK2, Color.LIGHT_Red, Color.CURRENT);

#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 Consensus_Line = OB_Level - OS_Level;
def Zero_Line = 0;
def Super_OB = 4;
def Super_OS = -3;

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

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Consensus_Line < Super_OB and Consensus_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);

plot OB_Signal = Upper_BandS crosses above IntermResistance;
OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OB_Signal.SetLineWeight(3);
OB_Signal.SetDefaultColor(Color.RED);

plot OS_Signal = (condition_BandRevUP) and (Lower_BandS crosses below IntermSupport);
OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OS_Signal.SetLineWeight(3);
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
def lengthBB = 10;
def Num_Dev_DnBB = -0.8;
def 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;

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);

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
AddLabel(yes, "Look_To_Buy", if (ConditionK2 and (Agreement_Level < Confirmation_Factor)) then Color.GREEN else Color.GRAY);
AddLabel(yes, "Look_To_Sell", if (ConditionK3 and (Agreement_Level > Confirmation_Factor)) 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 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);

AddLabel(yes, "Confirmation_Level = " + round(Agreement_Level,1), if ((Agreement_Level >= 12) and (Consensus_Line >= 4)) then Color.RED else if ((Agreement_Level <= 3) and (Consensus_Line <= -3)) then Color.Green else color.Gray);

Here is the Confirmation Candles lower study.
Code:
#Confirmation Candles Lower V.10
#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.
#Changed 05/12/2021 to V.9  - dialed in studies to give stronger signals.
#Changed 05/20/2021 to V.10 - Removed Pivot Study and replaced with CIP.

#Keltner Channel
declare lower;
def displace = 0;
def factorK = 2.0;
def lengthK = 20;
def 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) or (NearT >= MidLine);
def conditionFOB = Intermed > FOB;
def conditionFOS = Intermed < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;

#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 (AvgExp2[2] <= AvgExp2);

#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 = 20;#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.25;
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 = 13;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0);

#Projection Oscillator
def ProjectionOsc_length = 30;#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;

Agreement_Level.AssignValueColor(
if Agreement_Level > Agreement_Level[1] and Agreement_Level >= Confirmation_Factor then Color.LIGHT_GREEN
else if Agreement_Level < Agreement_Level[1] and Agreement_Level >= Confirmation_Factor then Color.LIGHT_GREEN
else 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 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);

(Confirmation Consensus Candles) C3 v5

This is a new candle painting indicator C3, 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 C3 utilizes both positive and negative factors of price movement and weighs them against each other to derive the Consensus Level. 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.
nOD1krz.png

5QygBoC.png

wPdK4Ht.png

Code:
# (Consensus Confirmation Candles) C3 v6
#
# 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.
#
# v2   - 05/11/2021 - dialed in studies to give stronger signals. Removed reversal buy and sell signals with
#                     OB/OS signals. Included OB/OS clouds to indicate favorable zones to buy or take profit.
#                     Clouds can also indicate nearterm reversals. Cleaned up code.
# v3   - 05/20/2021 - Removed Pivot Study and replaced with CIP. Reworked Labels to reflect mean reversion Look
#                     to Buy/Look to Sell conditions. Removed Mean Reversion Label. Added new label to show the
#                     Confirmation_Level and color coded it to show OB/OS conditions.
# BETA - 05/21/2021 - (barbaros) Consensus Level filter set to above 4 and below -4
# v4   - 05/24/2021 - Consensus Level filter changed to above 6 and below -6
# BETA - 05/29/2021 - (barbaros) Bug fixes
# v5   - 06/01/2021 - Consolidated labels. Added new squeeze condition based on NearTSupport and NearTResistance.
# v5   - 06/04/2021 - Included Ichimoku cloud.
# v6   - 06/09/2021 - Added Arrows using Confirmation_Factor

#Keltner Channel
declare upper;
def displace = 0;
def factorK = 2.0;
def lengthK = 20;
def price = close;
input averageType = AverageType.SIMPLE;
def trueRangeAverageType = AverageType.SIMPLE;
def BulgeLengthPrice = 75;
def SqueezeLengthPrice = 75;
def BulgeLengthPrice2 = 20;
def SqueezeLengthPrice2 = 20;
def BulgeLengthPrice3 = 12;
def SqueezeLengthPrice3 = 12;

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 conditionK1UP = price >= Upper_BandK;
def conditionK2UP = (Upper_BandK[1] < Upper_BandK) and (Lower_BandK[1] < Lower_BandK);
def conditionK3DN = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);
def conditionK4DN = price < Lower_BandK;
def BandwidthK = (Upper_BandK - Lower_BandK) / AvgK * 100;

plot IntermResistance = Highest(price, BulgeLengthPrice);
IntermResistance.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
plot IntermSupport = Lowest(price, SqueezeLengthPrice);
IntermSupport.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);

plot NearTResistance = Highest(price, BulgeLengthPrice2);
NearTResistance.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
NearTResistance.SetStyle(Curve.SHORT_DASH);
plot NearTSupport = Lowest(price, SqueezeLengthPrice2);
NearTSupport.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
NearTSupport.SetStyle(Curve.SHORT_DASH);

def NearTResistance1 = Highest(price, BulgeLengthPrice3);
def NearTSupport1 = Lowest(price, SqueezeLengthPrice3);

#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) or (NearT >= MidLine);
def condition4D = (Intermed[1] > Intermed) or (NearT < MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;
def condition5D = CIP_DOWN;

#EMA_1
def EMA_length = 8;
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 (AvgExp2[2] <= AvgExp);
def condition7D = (price < AvgExp2) and (AvgExp2[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 = 20;#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.25;
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 = 13;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0);
def condition13D = (KVOH < 0);

#Projection Oscillator
def ProjectionOsc_length = 30;#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;
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_LevelOB = 10;
def Agreement_LevelOS = -10;

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

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

def Consensus_Level = Agreement_Level - Agreement_LevelD;

def UP = Consensus_Level >= 6;
def DOWN = Consensus_Level < -6;

def priceColor = if UP then 1
                 else if DOWN then -1
                 else priceColor[1];

AssignPriceColor(if coloredCandlesOn and priceColor == 1 then Color.LIGHT_GREEN else if coloredCandlesOn and priceColor == -1 then Color.RED else Color.CURRENT);

#Additional Signals
#Keltner #2
input showCloud = yes;
def factorK2 = 3.25;
def lengthK2 = 20;

def shiftK2 = factorK2 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK2);
def averageK2 = MovingAverage(averageType, price, lengthK2);
def AvgK2 = averageK2[-displace];
def Upper_BandK2 = averageK2[-displace] + shiftK2[-displace];
def Lower_BandK2 = averageK2[-displace] - shiftK2[-displace];
def condition_BandRevDn = (Upper_BandS > Upper_BandK2);
def condition_BandRevUp = (Lower_BandS < Lower_BandK2);

AddCloud(if showCloud and condition_BandRevUp then Lower_BandK2 else Double.NaN,  Lower_BandS,  Color.LIGHT_GREEN,  Color.CURRENT);
AddCloud(if showCloud and condition_BandRevDn then Upper_BandS else Double.NaN,  Upper_BandK2,  Color.LIGHT_RED,  Color.CURRENT);

#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 Consensus_Line = OB_Level - OS_Level;
def Zero_Line = 0;
def Super_OB = 4;
def Super_OS = -4;

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

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Consensus_Line < Super_OB and Consensus_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);

plot OB_Signal = Upper_BandS crosses above IntermResistance;
OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OB_Signal.SetLineWeight(3);
OB_Signal.SetDefaultColor(Color.RED);

plot OS_Signal = (condition_BandRevUp) and (Lower_BandS crosses below IntermSupport);
OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OS_Signal.SetLineWeight(3);
OS_Signal.SetDefaultColor(Color.GREEN);

#Squeeze Alert
def BandwidthC3 = (NearTResistance1 - NearTSupport1);
def IntermResistance2 = Highest(BandwidthC3,BulgeLengthPrice);
def IntermSupport2 = Lowest(BandwidthC3, SqueezeLengthPrice);
def sqzTrigger = BandwidthC3 <= IntermSupport2;
def sqzLevel = if !sqzTrigger[1] and sqzTrigger then hl2
               else if !sqzTrigger then Double.NaN
               else sqzLevel[1];

plot Squeeze_Alert = sqzLevel;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.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);

#Bollinger_Bands2
def lengthBB = 10;
def Num_Dev_DnBB = -0.8;
def 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;

input tenkan_period = 9;
input kijun_period = 26;
input show_Ichimoku_Cloud = yes;

def Tenkan = (Highest(high, tenkan_period) + Lowest(low, tenkan_period)) / 2;
def Kijun = (Highest(high, kijun_period) + Lowest(low, kijun_period)) / 2;
def "Span A" = (Tenkan[kijun_period] + Kijun[kijun_period]) / 2;
def "Span B" = (Highest(high[kijun_period], 2 * kijun_period) + Lowest(low[kijun_period], 2 * kijun_period)) / 2;
def Chikou = close[-kijun_period];

AddCloud(if show_Ichimoku_Cloud and "Span A" then "Span A" else Double.NaN, "Span B",  Color.WHITE,  Color.GRAY);
#AddCloud("Span A", "Span B", color.WHITE, color.GRAY);

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
def conditionLTB = (ConditionK2UP and (Consensus_Level < 0));
def conditionLTS = (ConditionK3DN and (Consensus_Level > 0));
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));
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));
def MomentumUP = Consensus_Level[1] < Consensus_Level;
def MomentumDOWN = Consensus_Level[1] > Consensus_Level;
def Squeeze_Signal = !isNaN(Squeeze_Alert);
def conditionOB = (Consensus_Level >= 12) and (Consensus_Line >= 4);
def conditionOS = (Consensus_Level <= -12) and (Consensus_Line <= -3);

AddLabel(yes, if conditionLTB then "BULLISH_LOOK_To_BUY" else if conditionLTS then "BEARISH_LOOK_TO_SELL" else if conditionK2UP then "TREND_BULLISH" else if conditionK3DN then "TREND_BEARISH" else "TREND_CONSOLIDATION", if conditionLTB then Color.GREEN else if conditionLTS then Color.Red else if conditionK2UP then Color.WHITE else if conditionK3DN then Color.DARK_GRAY else Color.GRAY);

AddLabel(yes, if conditionBD then "BREAKDOWN" else if conditionBO then "BREAKOUT" else "NO_BREAK", if conditionBD then Color.RED else if conditionBO then Color.Green else Color.Gray);

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

AddLabel(yes, if MomentumUP then "Consensus_Increasing = " + round(Consensus_Level,1) else if MomentumUP or MomentumDOWN and conditionOB then "Consensus_OVERBOUGHT = " + round(Consensus_Level,1) else if MomentumDOWN then  "Consensus_Decreasing = " + round(Consensus_Level,1) else if MomentumUP or MomentumDOWN and conditionOS then "Consensus_OVERSOLD = " + round(Consensus_Level,1)else "Consensus = " + round(Consensus_Level,1), if conditionOB then Color.RED else if conditionOS then Color.Green else color.GRAY);

For those of you that trade FOREX or the SPX, here is a modified version that will function on those instruments.
Code:
# (Consensus Confirmation Candles) C3 v5 FOREX & SPX Compatible
#
# 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.
#
# v2   - 05/11/2021 - dialed in studies to give stronger signals. Removed reversal buy and sell signals with
#                     OB/OS signals. Included OB/OS clouds to indicate favorable zones to buy or take profit.
#                     Clouds can also indicate nearterm reversals. Cleaned up code.
# v3   - 05/20/2021 - Removed Pivot Study and replaced with CIP. Reworked Labels to reflect mean reversion Look
#                     to Buy/Look to Sell conditions. Removed Mean Reversion Label. Added new label to show the
#                     Confirmation_Level and color coded it to show OB/OS conditions.
# BETA - 05/21/2021 - (barbaros) Consensus Level filter set to above 4 and below -4
# v4   - 05/24/2021 - Consensus Level filter changed to above 6 and below -6
# BETA - 05/29/2021 - (barbaros) Bug fixes
# v5   - 06/01/2021 - Consolidated labels. Added new squeeze condition based on NearTSupport and NearTResistance.
# BETA - 06/02/2021 - Modified study set to be compatable with FOREX and SPX.
# v6   - 06/09/2021 - Modified to include Confirmation Arrows
#Keltner Channel
declare upper;
def displace = 0;
def factorK = 2.0;
def lengthK = 20;
def price = close;
input averageType = AverageType.SIMPLE;
def trueRangeAverageType = AverageType.SIMPLE;
def BulgeLengthK = 250;
def SqueezeLengthK = 250;
def BulgeLengthK2 = 150;
def SqueezeLengthK2 = 150;
def BulgeLengthPrice = 75;
def SqueezeLengthPrice = 75;
def BulgeLengthPrice2 = 20;
def SqueezeLengthPrice2 = 20;
def BulgeLengthPrice3 = 12;
def SqueezeLengthPrice3 = 12;

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 conditionK1UP = price >= Upper_BandK;
def conditionK2UP = (Upper_BandK[1] < Upper_BandK) and (Lower_BandK[1] < Lower_BandK);
def conditionK3DN = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);
def conditionK4DN = price < Lower_BandK;

def BandwidthK = (Upper_BandK - Lower_BandK) / AvgK * 100;
def BandwidthKS = (Bandwidthk[2]+ Bandwidthk[1] + BandwidthK) / 3;
def BulgeK = Highest(BandwidthKS, BulgeLengthK);
def SqueezeK = Lowest(BandwidthKS, SqueezeLengthK);
def BulgeK2 = Highest(BandwidthKS, BulgeLengthK2);
def SqueezeK2 = Lowest(BandwidthKS, SqueezeLengthK2);
def condition_Keltner_Squeeze = BandwidthKS <= SqueezeK;

plot IntermResistance = Highest(price, BulgeLengthPrice);
IntermResistance.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
plot IntermSupport = Lowest(price, SqueezeLengthPrice);
IntermSupport.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);

plot NearTResistance = Highest(price, BulgeLengthPrice2);
NearTResistance.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
NearTResistance.SetStyle(Curve.SHORT_DASH);
plot NearTSupport = Lowest(price, SqueezeLengthPrice2);
NearTSupport.AssignValueColor(if (conditionK2UP) then Color.GREEN else if (conditionK3DN) then Color.RED else Color.GRAY);
NearTSupport.SetStyle(Curve.SHORT_DASH);

def NearTResistance1 = Highest(price, BulgeLengthPrice3);
def NearTSupport1 = Lowest(price, SqueezeLengthPrice3);

#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) or (NearT >= MidLine);
def condition4D = (Intermed[1] > Intermed) or (NearT < MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;
def condition5D = CIP_DOWN;

#EMA_1
def EMA_length = 8;
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 (AvgExp2[2] <= AvgExp);
def condition7D = (price < AvgExp2) and (AvgExp2[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 = 20;#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.25;
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 = 13;
#def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
#def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
#def condition13 = (KVOH > 0);
#def condition13D = (KVOH < 0);

#Projection Oscillator
def ProjectionOsc_length = 30;#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;
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_LevelOB = 10;
def Agreement_LevelOS = -10;

def Agreement_Level = condition1 + condition2 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition14 + conditionK1UP + conditionK2UP;

def Agreement_LevelD = condition1D + condition2D + condition4D + condition5D + condition6D + condition7D + condition8D + condition9D + condition10D + condition11D + condition12D + condition14D + conditionK3DN + conditionK4DN;

def Consensus_Level = Agreement_Level - Agreement_LevelD;

def UP = Consensus_Level >= 4;
def DOWN = Consensus_Level < -4;

def priceColor = if UP then 1
                 else if DOWN then -1
                 else priceColor[1];

AssignPriceColor(if coloredCandlesOn and priceColor == 1 then Color.LIGHT_GREEN else if coloredCandlesOn and priceColor == -1 then Color.RED else Color.CURRENT);

#Additional Signals
#Keltner #2
input showCloud = yes;
def factorK2 = 3.25;
def lengthK2 = 20;

def shiftK2 = factorK2 * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), lengthK2);
def averageK2 = MovingAverage(averageType, price, lengthK2);
def AvgK2 = averageK2[-displace];
def Upper_BandK2 = averageK2[-displace] + shiftK2[-displace];
def Lower_BandK2 = averageK2[-displace] - shiftK2[-displace];
def condition_BandRevDn = (Upper_BandS > Upper_BandK2);
def condition_BandRevUp = (Lower_BandS < Lower_BandK2);

AddCloud(if showCloud and condition_BandRevUp then Lower_BandK2 else Double.NaN,  Lower_BandS,  Color.LIGHT_GREEN,  Color.CURRENT);
AddCloud(if showCloud and condition_BandRevDn then Upper_BandS else Double.NaN,  Upper_BandK2,  Color.LIGHT_RED,  Color.CURRENT);

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

def Consensus_Line = OB_Level - OS_Level;
def Zero_Line = 0;
def Super_OB = 4;
def Super_OS = -4;

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

def OS_Buy = UP_OS;
def OB_Sell = DOWN_OB;
def neutral = Consensus_Line < Super_OB and Consensus_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);

plot OB_Signal = Upper_BandS crosses above IntermResistance;
OB_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OB_Signal.SetLineWeight(3);
OB_Signal.SetDefaultColor(Color.RED);

plot OS_Signal = (condition_BandRevUp) and (Lower_BandS crosses below IntermSupport);
OS_Signal.SetPaintingStrategy(PaintingStrategy.BOOLEAN_POINTS);
OS_Signal.SetLineWeight(3);
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);

def BandwidthC3 = (NearTResistance1 - NearTSupport1);

def IntermResistance2 = Highest(BandwidthC3,BulgeLengthPrice);
def IntermSupport2 = Lowest(BandwidthC3, SqueezeLengthPrice);
#def NearTResistance2 = Highest(BandwidthC3, BulgeLengthPrice2);
#def NearTSupport2 = Lowest(BandwidthC3, SqueezeLengthPrice2);

def sqzTrigger = BandwidthC3 <= IntermSupport2;
def sqzLevel = if !sqzTrigger[1] and sqzTrigger then hl2
               else if !sqzTrigger then Double.NaN
               else sqzLevel[1];

plot Squeeze_Alert = sqzLevel;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.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);
#Bollinger_Bands2
def lengthBB = 10;
def Num_Dev_DnBB = -0.8;
def 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;

#Labels
def Buy = UP_OS;
def Sell = DOWN_OB;
def conditionLTB = (ConditionK2UP and (Consensus_Level < 0));
def conditionLTS = (ConditionK3DN and (Consensus_Level > 0));
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));
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));
def MomentumUP = Consensus_Level[1] < Consensus_Level;
def MomentumDOWN = Consensus_Level[1] > Consensus_Level;
def Squeeze_Signal = !isNaN(Squeeze_Alert);
def conditionOB = (Consensus_Level >= 12) and (Consensus_Line >= 4);
def conditionOS = (Consensus_Level <= -12) and (Consensus_Line <= -3);

AddLabel(yes, if conditionLTB then "BULLISH_LOOK_To_BUY" else if conditionLTS then "BEARISH_LOOK_TO_SELL" else if conditionK2UP then "TREND_BULLISH" else if conditionK3DN then "TREND_BEARISH" else "TREND_CONSOLIDATION", if conditionLTB then Color.GREEN else if conditionLTS then Color.Red else if conditionK2UP then Color.WHITE else if conditionK3DN then Color.DARK_GRAY else Color.GRAY);

AddLabel(yes, if conditionBD then "BREAKDOWN" else if conditionBO then "BREAKOUT" else "NO_BREAK", if conditionBD then Color.RED else if conditionBO then Color.Green else Color.Gray);

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

AddLabel(yes, if MomentumUP then "Consensus_Increasing = " + round(Consensus_Level,1) else if MomentumUP or MomentumDOWN and conditionOB then "Consensus_OVERBOUGHT = " + round(Consensus_Level,1) else if MomentumDOWN then  "Consensus_Decreasing = " + round(Consensus_Level,1) else if MomentumUP or MomentumDOWN and conditionOS then "Consensus_OVERSOLD = " + round(Consensus_Level,1)else "Consensus = " + round(Consensus_Level,1), if conditionOB then Color.RED else if conditionOS then Color.Green else color.GRAY);
Here's the lower study.
gWWYe5M.png

Code:
#CC Candles Lower V.2
#Created 04/28/2021 by Christopher84
#Modified to V.2 05/11/2021 - dialed in studies to give stronger signals. Included OB/OS Clouds and cleaned up code.
#Changed 05/20/2021 to V.3 - Removed Pivot Study and replaced with CIP.

#Keltner Channel
declare lower;
def displace = 0;
def factorK = 2.0;
def 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;
def BulgeLengthPrice = 75;
def SqueezeLengthPrice = 75;
def BulgeLengthPrice2 = 20;
def SqueezeLengthPrice2 = 20;
def BulgeLengthCC = 40;
def SqueezeLengthCC = 40;
def BulgeLengthCC2 = 8;
def 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);

#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) or (NearT >= MidLine);
def condition4D = (Intermed[1] > Intermed) or (NearT < MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);

def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;
def condition5D = CIP_DOWN;

#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 = 20;#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.25;
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 = 13;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0);
def condition13D = (KVOH < 0);

#Projection Oscillator
def ProjectionOsc_length = 30;#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;
def Confirmation_Factor = 0;
#Use for testing conditions individually. Remove # from line below and change Confirmation_Factor to 1.
#def Agreement_Level = condition1;
def Agreement_LevelOB = 10;
def Agreement_LevelOS = -10;

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;

AddCloud(Consensus_Level, Agreement_LevelOB, Color.LIGHT_RED, Color.CURRENT);
AddCloud(Consensus_Level, Agreement_LevelOS, Color.CURRENT, Color.LIGHT_GREEN);

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);

Here is a custom watchlist column for the Confirmation Candles. If you sort the column, it makes it easier to see OB/OS conditions. Especially when grouped with the Super OB/OS custom watchlist column which is also posted below.
oBocGCU.png

Code:
#Confirmation Level Watchlist developed 04/15/2021 by Christopher Wilson
#Select the level of agreement among the 15 indicators included.
#Changed 05/20/21 Included CIP.

#MACD with Price
declare lower;
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 FOB = 80;
def FOS = 20;
def upperLine = 110;

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

#Change in Price
def lengthCIP = 5;
def displace = 0;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;

#EMA_1
input EMA_length = 12;
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 (AvgExp2[2] <= AvgExp2);

#DMI Oscillator
input DMI_length = 5;
input averageType = AverageType.WILDERS;

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

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

def condition8 = Osc >= ZeroLine;

#Trend_Periods
input TP_fastLength = 3;
input TP_slowLength = 4;

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

def condition9 = Periods > 0;

#Polarized Fractal Efficiency
input PFE_length = 5;
input smoothingLength = 2.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 > 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 condition11 = PercentB > 50;

#STARC Bands
def ATR_length = 15;
def SMA_lengthS = 6;
def multiplier_factor = 1.25;
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);

#Projection Oscillator
def ProjectionOsc_length = 30;#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 condition13 = (PROSC > 50);

#Trend Confirmation
#Confirmation_Factor range 1-13.
input Confirmation_Factor = 7;
#Use for testing conditions individually.
#def Agreement_Level = condition1;
plot Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13;

def Sell_Alert = Agreement_Level >= 9;
def Buy_Alert = Agreement_Level <= 2 ;


def Factor_Line = Confirmation_Factor;

AssignBackgroundColor(if Sell_Alert then color.LIGHT_RED else if Buy_Alert then color.dark_green else color.black);

Here is the Super OB/OS custom watchlist column.
Code:
#Super_OB_OS_Lower
#Created by Christopher84 04/22/2021
#Modified 5/12/2021 Adjusted OB/OS levels.

declare lower;
def BulgeLength = 75;
def SqueezeLength = 75;
def BulgeLength2 = 8;
def SqueezeLength2 = 8;

#RSI
def price = close;
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 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 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 conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;

def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#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 conditionOB5 = PFE > UpperLevel;
def conditionOS5 = PFE < LowerLevel;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
def displace = 0;
def BBPB_length = 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 conditionOB6 = PercentB > BBPB_OB;
def conditionOS6 = PercentB < BBPB_OS;

#Projection Oscillator
def ProjectionOsc_length = 30;#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 conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = PROSC < PROSC_OS;

#OB/OS Calculation

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

plot Consensus_Line = OB_Level - OS_Level;

def Zero_Line = 0;
def Super_OB = 4;
def Super_OS = -3;

def OB = Consensus_Line >= Super_OB;
def OS = Consensus_Line <= Super_OS;

AssignBackgroundColor(if OB then color.light_red else if OS then color.dark_green else color.black);

For those of you that are intrested, here is the Super OB/OS lower indicator.
wea6B5x.png

gKaEnqX.png

Code:
#Super_OB_OS_Lower
#Created by Christopher84 04/22/2021
#Modified 5/12/2021 Included dynamic support and resistance. Adjusted OB/OS levels.

declare lower;
def BulgeLength = 75;
def SqueezeLength = 75;
def BulgeLength2 = 8;
def SqueezeLength2 = 8;

#RSI
def price = close;
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 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 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 conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;

def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#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 conditionOB5 = PFE > UpperLevel;
def conditionOS5 = PFE < LowerLevel;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
def displace = 0;
def BBPB_length = 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 conditionOB6 = PercentB > BBPB_OB;
def conditionOS6 = PercentB < BBPB_OS;

#Projection Oscillator
def ProjectionOsc_length = 30;#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 conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = PROSC < PROSC_OS;

#OB/OS Calculation

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

plot Consensus_Line = OB_Level - OS_Level;

def Zero_Line = 0;

plot Bulge = Highest(Consensus_Line, BulgeLength);
bulge.SetPaintingStrategy(PaintingStrategy.LINE);
bulge.SetLineWeight(1);
bulge.SetDefaultColor(Color.RED);

plot Squeeze = Lowest(Consensus_Line, SqueezeLength);
Squeeze.SetPaintingStrategy(PaintingStrategy.LINE);
Squeeze.SetLineWeight(1);
Squeeze.SetDefaultColor(Color.LIGHT_GREEN);

plot Bulge2 = Highest(Consensus_Line, BulgeLength2);
bulge2.SetPaintingStrategy(PaintingStrategy.LINE);
bulge2.SetStyle(Curve.SHORT_DASH);
bulge2.SetLineWeight(1);
bulge2.SetDefaultColor(Color.GRAY);

plot Squeeze2 = Lowest(Consensus_Line, SqueezeLength2);
Squeeze2.SetPaintingStrategy(PaintingStrategy.LINE);
Squeeze2.SetStyle(Curve.SHORT_DASH);
Squeeze2.SetLineWeight(1);
Squeeze2.SetDefaultColor(Color.GRAY);

input Super_OB = 4;
input Super_OS = -3;

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


AddCloud(Consensus_Line, Super_OB, Color.LIGHT_RED, Color.CURRENT);
AddCloud(Consensus_Line, Super_OS, Color.CURRENT, Color.LIGHT_GREEN);
Here is the Super_OB_OS_SPX_Version.
Code:
#Super_OB_OS_Lower_SPX
#Created by Christopher84 04/22/2021
#Modified 5/12/2021 Included dynamic support and resistance. Adjusted OB/OS levels.

declare lower;
def BulgeLength = 75;
def SqueezeLength = 75;
def BulgeLength2 = 8;
def SqueezeLength2 = 8;

#RSI
def price = close;
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 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 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 conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;

def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#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 conditionOB5 = PFE > UpperLevel;
def conditionOS5 = PFE < LowerLevel;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
def displace = 0;
def BBPB_length = 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 conditionOB6 = PercentB > BBPB_OB;
def conditionOS6 = PercentB < BBPB_OS;

#Projection Oscillator
def ProjectionOsc_length = 30;#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 conditionOB7 = PROSC > PROSC_OB;
def conditionOS7 = PROSC < PROSC_OS;

#OB/OS Calculation

def OB_Level = conditionOB1 + conditionOB3 + conditionOB4 + conditionOB5 + conditionOB6 + conditionOB7;
def OS_Level = conditionOS1 + conditionOS3 + conditionOS4 + conditionOS5 + conditionOS6 + conditionOS7;

plot Consensus_Line = OB_Level - OS_Level;

def Zero_Line = 0;

plot Bulge = Highest(Consensus_Line, BulgeLength);
bulge.SetPaintingStrategy(PaintingStrategy.LINE);
bulge.SetLineWeight(1);
bulge.SetDefaultColor(Color.RED);

plot Squeeze = Lowest(Consensus_Line, SqueezeLength);
Squeeze.SetPaintingStrategy(PaintingStrategy.LINE);
Squeeze.SetLineWeight(1);
Squeeze.SetDefaultColor(Color.LIGHT_GREEN);

plot Bulge2 = Highest(Consensus_Line, BulgeLength2);
bulge2.SetPaintingStrategy(PaintingStrategy.LINE);
bulge2.SetStyle(Curve.SHORT_DASH);
bulge2.SetLineWeight(1);
bulge2.SetDefaultColor(Color.GRAY);

plot Squeeze2 = Lowest(Consensus_Line, SqueezeLength2);
Squeeze2.SetPaintingStrategy(PaintingStrategy.LINE);
Squeeze2.SetStyle(Curve.SHORT_DASH);
Squeeze2.SetLineWeight(1);
Squeeze2.SetDefaultColor(Color.GRAY);

input Super_OB = 4;
input Super_OS = -4;

Consensus_Line.AssignValueColor(
if Consensus_Line > Consensus_Line[1] and Consensus_Line > Zero_Line then Color.GREEN
else if Consensus_Line < Consensus_Line[1] and Consensus_Line > Zero_Line then Color.GREEN
else if Consensus_Line < Consensus_Line[1] and Consensus_Line <= Zero_Line then Color.RED else
if Consensus_Line > Consensus_Line[1] and Consensus_Line <= Zero_Line then Color.RED
else Color.RED);

### Bar Color
input ColorCandlesON = no;

def UP = Consensus_Line > 2;
def DOWN = Consensus_Line < -2;

def PriceColor = if UP then 1
                 else if DOWN then -1
                 else PriceColor[1];

AssignPriceColor(
    if ColorCandlesOn and PriceColor == 1 then Color.GREEN
else if ColorCandlesOn and PriceColor == -1 then Color.RED
else Color.CURRENT
);

AddCloud(Consensus_Line, Super_OB, Color.LIGHT_RED, Color.CURRENT);
AddCloud(Consensus_Line, Super_OS, Color.CURRENT, Color.GREEN);

So last but not least, I have had several request to share my MTF Cloud Upper and Lower studies. So here they are!
aJLdasc.png

Code:
# MTF Moving Average Upper Created 05/01/2021 by Christopher84

declare upper;

input price = close;
input length = 10;
input agperiod1 = {"1 min", "2 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "4 hours", default "Day", "Week"};
input agperiod2 = {"1 min", "2 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "4 hours", "Day", default "Week"};

plot avg = ExpAverage(close(period = agperiod1), length);
def height = avg - avg[length];
avg.SetStyle(Curve.SHORT_DASH);
avg.SetLineWeight(1);

def UP = avg[1] < avg;
def DOWN = avg[1] > avg;
Avg.AssignValueColor(if UP then Color.LIGHT_GREEN else if DOWN then Color.RED else Color.YELLOW);

plot avg2 = ExpAverage(close(period = agperiod2), length);
def height2 = avg2 - avg2[length];
avg2.SetStyle(Curve.SHORT_DASH);
avg2.SetLineWeight(1);

def UP2 = avg2[1] < avg2;
def DOWN2 = avg2[1] > avg2;
Avg2.AssignValueColor(if UP2 then Color.LIGHT_GREEN else if DOWN2 then Color.RED else Color.YELLOW);

AddCloud(avg2, avg, Color.LIGHT_RED, Color.CURRENT);
AddCloud(avg, avg2, Color.LIGHT_GREEN, Color.CURRENT);
Here's the lower MTF Cloud study.
Code:
#MTF Moving Average Lower Created by Christopher84 05/01/2021

declare lower;
#Keltner Channel
def displace = 0;
def factorK = 2.0;
def lengthK = 20;
plot price = close;
input averageType = AverageType.SIMPLE;
def trueRangeAverageType = AverageType.SIMPLE;
def BulgeLengthK = 150;
def SqueezeLengthK = 150;
def BulgeLengthK2 = 40;
def SqueezeLengthK2 = 40;
def BulgeLengthPrice = 75;
def SqueezeLengthPrice = 75;
def BulgeLengthPrice2 = 20;
def SqueezeLengthPrice2 = 20;
def BulgeLengthCC = 40;
def SqueezeLengthCC = 40;
def BulgeLengthCC2 = 8;
def 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 IntermResistance = Highest(price, BulgeLengthPrice);
IntermResistance.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
plot IntermSupport = Lowest(price, SqueezeLengthPrice);
IntermSupport.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);

#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) or (NearT >= MidLine);
def condition4D = (Intermed[1] > Intermed) or (NearT < MidLine);
def conditionOB3 = Intermed > FOB;
def conditionOS3 = Intermed < FOS;
def conditionOB4 = NearT > FOB;
def conditionOS4 = NearT < FOS;

#Change in Price
def lengthCIP = 5;
def CIP = (price - price[1]);
def AvgCIP = ExpAverage(CIP[-displace], lengthCIP);
def CIP_UP = AvgCIP > AvgCIP[1];
def CIP_DOWN = AvgCIP < AvgCIP[1];

def condition5 = CIP_UP;
def condition5D = CIP_DOWN;

#EMA_1
def EMA_length = 8;
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 (AvgExp2[2] <= AvgExp);
def condition7D = (price < AvgExp2) and (AvgExp2[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 = 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.25;
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 = 13;
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 = 30;#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.
def coloredCandlesOn = no;
def Confirmation_Factor = 7;
#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 >= 6;

def DOWN = Consensus_Level < -6;


def priceColor = if UP then 1

                 else if DOWN then -1

                 else priceColor[1];

price.AssignValueColor(if priceColor == 1 then Color.LIGHT_GREEN else if priceColor == -1 then Color.RED else Color.CURRENT);

#EMA's
input length = 10;
input agperiod1 = {"1 min", "2 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "4 hours", default "Day", "Week"};
input agperiod2 = {"1 min", "2 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "4 hours", "Day", default "Week"};

plot avg1 = ExpAverage(close(period = agperiod1), length);
def height = avg - avg[length];
avg1.SetStyle(Curve.SHORT_DASH);
avg1.SetLineWeight(1);

def UP1 = avg1[1] < avg1;
def DOWN1 = avg1[1] > avg1;
Avg1.AssignValueColor(if UP1 then Color.LIGHT_GREEN else if DOWN1 then Color.RED else Color.YELLOW);

plot avg2 = ExpAverage(close(period = agperiod2), length);
def height2 = avg2 - avg2[length];
avg2.SetStyle(Curve.SHORT_DASH);
avg2.SetLineWeight(1);

def UP2 = avg2[1] < avg2;
def DOWN2 = avg2[1] > avg2;
Avg2.AssignValueColor(if UP2 then Color.LIGHT_GREEN else if DOWN2 then Color.RED else Color.YELLOW);

AddCloud(avg2, avg1, Color.LIGHT_RED, Color.CURRENT);
AddCloud(avg1, avg2, Color.LIGHT_GREEN, Color.CURRENT);

This is an MTF STARC. Looks great with the MTF MA Cloud for anyone that is interested.
zpf9ntR.png

Code:
#Created 05/26/2021 by Christopher84

declare weak_volume_dependency;

input price = close;
input ATR_length = 15;
input SMA_length = 6;
input displace = 0;
input multiplier_factor = 1.5;
input agperiod1 = {"1 min", "2 min", "5 min", "10 min", "15 min", "30 min", "1 hour", "4 hours", default "Day", "Week"};
def open = open(period = agperiod1);
def high = high(period = agperiod1);
def low = low(period = agperiod1);
def close = close(period = agperiod1);

    def val = Average(close, SMA_length);

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

    plot Upper_Band = val[-displace] + multiplier_factor * average_true_range[-displace];
    def UP = Upper_Band[1] < Upper_Band;
    def DOWN =  Upper_Band[1] > Upper_Band;
    Upper_Band.AssignValueColor(if UP then Color.LIGHT_GREEN else if DOWN then Color.RED else Color.YELLOW);
    Upper_Band.SetStyle(Curve.SHORT_DASH);
    Upper_Band.SetLineWeight(2);

    plot Middle_Band = val[-displace];
    Middle_Band.SetStyle(Curve.SHORT_DASH);
    Middle_Band.SetLineWeight(2);
    Middle_Band.SetDefaultColor(Color.GRAY);

    plot Lower_Band = val[-displace] - multiplier_factor * average_true_range[-displace];
    def UP2 = Lower_Band[1] < Lower_Band;
    def DOWN2 =  Lower_Band[1] > Lower_Band;
    Lower_Band.AssignValueColor(if UP2 then Color.LIGHT_GREEN else if DOWN2 then Color.RED else Color.YELLOW);
    Lower_Band.SetStyle(Curve.SHORT_DASH);
    Lower_Band.SetLineWeight(2);
Great work @Christopher84! Pls can you share the code for the Confirm_Level custom column on the watchlist?
 
Sorry, as the resident noob here, using this primarily for trading stocks and options, which codes should I be putting into the TOS platform? Tyvm
 
Sorry, as the resident noob here, using this primarily for trading stocks and options, which codes should I be putting into the TOS platform? Tyvm
Always look in page 1 for up to date scripts.
There are two studies for upper chart
1.Confirmation Candles V.10
2.Consensus Confirmation Candles C3 v6
 
Always look in page 1 for up to date scripts.
There are two studies for upper chart
1.Confirmation Candles V.10
2.Consensus Confirmation Candles C3 v6
Did that, with thanks. Now that I've tooled around for a bit, I know how to create a watchlist script and an indicator script. I do have a question though, how come the numbers on the Chart and the Numbers on the Watchlist, are different?

Please see arrows. Thank you for assisting.

Just not sure why I can't drop a photo in here directly, and it won't upload my imgur link.
 
Did that, with thanks. Now that I've tooled around for a bit, I know how to create a watchlist script and an indicator script. I do have a question though, how come the numbers on the Chart and the Numbers on the Watchlist, are different?

Please see arrows. Thank you for assisting.

Just not sure why I can't drop a photo in here directly, and it won't upload my imgur link.
Hi @platinumestates,
In order to get a functioning WL column, a few studies have to be omitted from the Confirmation level calculation to avoid it being too complex for TOS. However, it still functions reasonably well and yields similar results for OB/OS levels. In general, if it reads 7 or higher, it is indicating a green candle on the actual chart. Hope this gives a bit of clarity. Happy trading!
 
Hi @platinumestates,
In order to get a functioning WL column, a few studies have to be omitted from the Confirmation level calculation to avoid it being too complex for TOS. However, it still functions reasonably well and yields similar results for OB/OS levels. In general, if it reads 7 or higher, it is indicating a green candle on the actual chart. Hope this gives a bit of clarity. Happy trading!
I am learning new setup, C3 (upper) and B4 (lower).
My goal is to create scanner based watchlist that will prompt me when the Upper and Lower recommendations are in agreement.
I am looking for a higher probability of entry or exit.

When created watchlist and added columns (see image below) from
a) Confirmation Candles : "ConfirmLevel", "OB/OS" (https://usethinkscript.com/threads/confirmation-candles-indicator-for-thinkorswim.6316/)
and
b) B4 indicator (https://usethinkscript.com/threads/balanced-bb-breakout.5708/) : "SQZ", "B4 Strategy"

The watchlist is showing consistent disagreement between Confirmation Candles and B4 indicator custom columns

I might be doing something wrong ?
I would appreciate the advice. Happy to get on the call or discord chat.

 
I am learning new setup, C3 (upper) and B4 (lower).
My goal is to create scanner based watchlist that will prompt me when the Upper and Lower recommendations are in agreement.
I am looking for a higher probability of entry or exit.

When created watchlist and added columns (see image below) from
a) Confirmation Candles : "ConfirmLevel", "OB/OS" (https://usethinkscript.com/threads/confirmation-candles-indicator-for-thinkorswim.6316/)
and
b) B4 indicator (https://usethinkscript.com/threads/balanced-bb-breakout.5708/) : "SQZ", "B4 Strategy"

The watchlist is showing consistent disagreement between Confirmation Candles and B4 indicator custom columns

I might be doing something wrong ?
I would appreciate the advice. Happy to get on the call or discord chat.

Hi @DeepThinker,
I’m not sure that you can definitively say that the columns are consistently in disagreement. Each of the columns are defining different conditions that are interpreted based on the strategy the trader is pursuing. For instance, B4 may have a sell condition while Confirmation and Super OB/OS are indicating an OS condition. These condition sets can certainly both be true and so could the inverse. It depends on your strategy on how this information is interpreted. If you are swinging from OS to OB zones, an OS indication could serve as your signal to start scaling in. However, in B4 an OS condition isn’t a signal to buy, so naturally it indicates “sell”. Both columns are depicting the information correctly. Hope that makes some sense.

Something I’ve been enjoying (for those of you that like to swing trade), is using the Confirmation WL column twice. One set on day and one set on month. I look for a monthly Confirmation Level of 7 or greater and an OS indication on the day Confirmation Level and Super OB/OS(also set to day). It has been doing an excellent job of picking up buying opportunities on strong trends especially when paired with strategies that help to scale into positions.
 
Last edited:
Hi @DeepThinker,
I’m not sure that you can definitively say that the columns are consistently in disagreement. Each of the columns are defining different conditions that are interpreted based on the strategy the trader is pursuing. For instance, B4 may have a sell condition while Confirmation and Super OB/OS are indicating an OS condition. These condition sets can certainly both be true and so could the inverse. It depends on your strategy on how this information is interpreted. If you are swinging from OS to OB zones, an OS indication could serve as your signal to start scaling in. However, in B4 an OS condition isn’t a signal to buy, so naturally it indicates “sell”. Both columns are depicting the information correctly. Hope that makes some sense.

Something I’ve been enjoying (for those of you that like to swing trade), is using the Confirmation WL column twice. One set on day and one set on month. I look for a monthly Confirmation Level of 7 or greater and an OS indication on the day Confirmation Level and Super OB/OS(also set to day). It has been doing an excellent job of picking up buying opportunities on strong trends especially when paired with strategies that help to scale into positions.
@Christopher84 Many thanks for your assistance,
I will test and compare observations further. Please let me know in case you offer training or plan to host another Q/A session for community members.
 
@Christopher84 I must thank you for this indicator. Probably the one I have found the most success with trading using 5 min candles. Using this indicator along with support/resistance levels and simple candle patterns have yielded a good win rate.

Good work.
 
@Christopher84 Hey, it looks amazing job you've done here. I'm quite struggling in translating this strategy with the entries/exits/target, especially with the dots and the clouds. Is there any detailed explanation or video. The video in this thread relates to different lower part. I really appreciate it. thanks a lot.
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
524 Online
Create Post

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top