Confirmation Candles Indicator For ThinkorSwim

Hello Christopher84!

Thank you so much for your swift reply. Yes your right its to do with appearance settings and has been changed now.

The confirmation factor is set to 3 ( as per your V.7) on the first page. Is that the best setting or how shall we tweak it to adjust the entries? I mean 3 is the number of factors it has to be ticked or checked before giving entry signal ?
That's right. I have found that confirmation levels between 3-7 tend to have the best results. It just depends on your risk tolerance and how many entry/exit signals you want to navigate.
 
Is there a factor to adjust the reversal signals ? There are many appearing at the time of bullish trend which makes the trader exit the trade earlier than usual. Or, is there some sequence behind this reversal ?
 

Example

Please see attached for your reference.
The green signals are "look to buy" the red signals are "look to sell". In your image, you will notice that the red reversal was triggered in a zone that price quickly came back to (on the red candle). That zone would have allowed you to potentially sell into strength and repurchase at a lower price. Remember, the reversal signals are not by any means perfect and I will have an updated version later today which should perform better. If you don't want to see them the easiest thing to do is to turn off the plots for the reversals. That way you can use the candles to make the decisions for entry or exit without the additional noise produced by the reversal signals.
 
Thank you very much. Looking forward to the updated edition :) Can you please advise about squeeze alert ? Why does it appear and what does it indicate ?
 
Thank you very much. Looking forward to the updated edition :) Can you please advise about squeeze alert ? Why does it appear and what does it indicate ?
Hi diamondhands,
The squeeze alert is to let you know that the price is in a squeeze condition. This typically happens prior to a larger price movement. When grouped with the other indicators determining direction it can give traders insights on how to be on the right side of these larger movements.
 
Hi Everyone!
Confirmation Candles V.8 is now available on the main page of this thread. Overall I think its really starting to perform well. I have added some new features. Now there are support and resistance lines which are colored to give insight on directionality as well as give more context to the buy/sell signals. As I'm sure many of you know, when signals occur near to or at support or resistance they are far more potent. I hope you all like the changes! Looking forward to feedback.

WXd1oo6.png
 
Hi Everyone!
Confirmation Candles V.8 is now available on the main page of this thread. Overall I think its really starting to perform well. I have added some new features. Now there are support and resistance lines which are colored to give insight on directionality as well as give more context to the buy/sell signals. As I'm sure many of you know, when signals occur near to or at support or resistance they are far more potent. I hope you all like the changes! Looking forward to feedback.

WXd1oo6.png
you know I'll be checking this out....great work!
 
Hi Everyone!
Confirmation Candles V.8 is now available on the main page of this thread. Overall I think its really starting to perform well. I have added some new features. Now there are support and resistance lines which are colored to give insight on directionality as well as give more context to the buy/sell signals. As I'm sure many of you know, when signals occur near to or at support or resistance they are far more potent. I hope you all like the changes! Looking forward to feedback.

WXd1oo6.png
Would you be able to go into a bit of detail regarding the new lines on the price action? Things like Squeeze Price, Bulge Price, Reversal Prices 1, 2, 3? I have an idea of what they're for just was hoping for some interpretation on the above chart. Thanks very much!
 
Would you be able to go into a bit of detail regarding the new lines on the price action? Things like Squeeze Price, Bulge Price, Reversal Prices 1, 2, 3? I have an idea of what they're for just was hoping for some interpretation on the above chart. Thanks very much!
Hey Splinter!
Let me try to shed some light on all of this. The squeeze price is the lowest value over the specified period (squeeze price length). The bulge price is the highest value over the specified period (bulge price length). These help to give support and resistance levels as well as show directionality. The reversal buy/sell signals are based on individual conditions. They utilize changes in volatility and their relationship with OB/OS conditions to help anticipate possible price reversals. They are meant to give context and insight to the trader and are more significant when seen on support(squeeze price) or resistance (bulge price) lines. The color of the squeeze and bulge lines tells the trader how to look at potential trades. When the lines are green and the channel is sloping upward, look to buy red candles(buy weakness in a strong trend) near support and sell into resistance. When the lines are red and sloping downward, look to sell green candles. This is a mean reversion zone (labeled MR in the image). Price is unlikely to make major upward movements until the channel reverts to an upward slope. In the image below, you can see the sell opportunities while the channel is downward and red, and the buy opportunities when the channel is sloping upward and green. There's a nice chain of reversal sell red points right along resistance at the top of the chart. These were the alert to the trader that price was overheating and about to turn down. The "R's" on the chart are showing the channels during trend reversals. I am in the process of cleaning up the code a bit to help it be a bit more clear. I really appreciate you trying this out, asking questions and providing feedback. Also, I wanted to let you know that I released two new indicators today with a different take on the Confirmation Candles. I suspect you might like them.
MFze0Q9.jpg
 
Hey Splinter!
Let me try to shed some light on all of this. The squeeze price is the lowest value over the specified period (squeeze price length). The bulge price is the highest value over the specified period (bulge price length). These help to give support and resistance levels as well as show directionality. The reversal buy/sell signals are based on individual conditions. They utilize changes in volatility and their relationship with OB/OS conditions to help anticipate possible price reversals. They are meant to give context and insight to the trader and are more significant when seen on support(squeeze price) or resistance (bulge price) lines. The color of the squeeze and bulge lines tells the trader how to look at potential trades. When the lines are green and the channel is sloping upward, look to buy red candles(buy weakness in a strong trend) near support and sell into resistance. When the lines are red and sloping downward, look to sell green candles. This is a mean reversion zone (labeled MR in the image). Price is unlikely to make major upward movements until the channel reverts to an upward slope. In the image below, you can see the sell opportunities while the channel is downward and red, and the buy opportunities when the channel is sloping upward and green. There's a nice chain of reversal sell red points right along resistance at the top of the chart. These were the alert to the trader that price was overheating and about to turn down. The "R's" on the chart are showing the channels during trend reversals. I am in the process of cleaning up the code a bit to help it be a bit more clear. I really appreciate you trying this out, asking questions and providing feedback. Also, I wanted to let you know that I released two new indicators today with a different take on the Confirmation Candles. I suspect you might like them.
MFze0Q9.jpg
Thank you for your in depth reply, I'll be sure to chk out your other indicators!
 
I have been working on an Idea I am calling confirmation candles. I often times find myself trying to find agreement among the numerous indicators that I use to help guide my decisions. Unfortunately, a lot of the time this creates indicator overload and analysis paralysis. So I have included 13 indicators of trend within this indicator. You can choose how many of the 13 indicators have to be in agreement in order to confirm the trend. I may have gone a bit overboard here, however it makes it adaptable to individual risk tolerance and trading style. Checkout the image below. If anyone likes this idea/indicator, I am happy to share the script.

7ItcupI.png

tOhnko8.png


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

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

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

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

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

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

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

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

def condition1 = Value[1] <= Value;

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

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

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


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

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

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

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


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

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

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

def condition5 = !IsNaN(PivL);

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

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

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

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

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

def condition8 = Osc >= ZeroLine;

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

def condition9 = Periods > 0;

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

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


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

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


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

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

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

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

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


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

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

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

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

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

#Additional Signals

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

CC: Confirmation Consensus

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

kaMjEs7.png


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

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


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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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


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

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

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

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

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


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

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

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

def Consensus_Level = Agreement_Level - Agreement_LevelD;

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

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

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

#Additional Signals

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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


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

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

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

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

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


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

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

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

plot Consensus_Level = Agreement_Level - Agreement_LevelD;

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

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

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

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

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

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

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

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

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

7ItcupI.png

tOhnko8.png


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

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

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

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

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

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

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

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

def condition1 = Value[1] <= Value;

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

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

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


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

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

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

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


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

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

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

def condition5 = !IsNaN(PivL);

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

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

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

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

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

def condition8 = Osc >= ZeroLine;

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

def condition9 = Periods > 0;

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

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


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

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


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

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

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

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

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


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

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

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

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

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

#Additional Signals

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

CC: Confirmation Consensus

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

kaMjEs7.png


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

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


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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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


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

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

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

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

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


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

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

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

def Consensus_Level = Agreement_Level - Agreement_LevelD;

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

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

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

#Additional Signals

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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


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

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

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

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

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


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

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

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

plot Consensus_Level = Agreement_Level - Agreement_LevelD;

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

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

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

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

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

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

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

plot SqueezeCC2 = Lowest(Consensus_Level, SqueezeLengthCC2);
SqueezeCC2.AssignValueColor(if (conditionK2) then Color.GREEN else if (conditionK3) then Color.RED else Color.GRAY);
SqueezeCC2.SetStyle(Curve.SHORT_DASH);
Results from the strategy using CC Candles on the TSLA. Trading 1 share on the 1 Hour chart 180 days no shorting. 1 hour chart seems to be the sweet spot so far. Any thoughts?
cWIVrOe.png
 
Last edited:
Hey Splinter!
Let me try to shed some light on all of this. The squeeze price is the lowest value over the specified period (squeeze price length). The bulge price is the highest value over the specified period (bulge price length). These help to give support and resistance levels as well as show directionality. The reversal buy/sell signals are based on individual conditions. They utilize changes in volatility and their relationship with OB/OS conditions to help anticipate possible price reversals. They are meant to give context and insight to the trader and are more significant when seen on support(squeeze price) or resistance (bulge price) lines. The color of the squeeze and bulge lines tells the trader how to look at potential trades. When the lines are green and the channel is sloping upward, look to buy red candles(buy weakness in a strong trend) near support and sell into resistance. When the lines are red and sloping downward, look to sell green candles. This is a mean reversion zone (labeled MR in the image). Price is unlikely to make major upward movements until the channel reverts to an upward slope. In the image below, you can see the sell opportunities while the channel is downward and red, and the buy opportunities when the channel is sloping upward and green. There's a nice chain of reversal sell red points right along resistance at the top of the chart. These were the alert to the trader that price was overheating and about to turn down. The "R's" on the chart are showing the channels during trend reversals. I am in the process of cleaning up the code a bit to help it be a bit more clear. I really appreciate you trying this out, asking questions and providing feedback. Also, I wanted to let you know that I released two new indicators today with a different take on the Confirmation Candles. I suspect you might like them.
MFze0Q9.jpg
Now that I had a chance to study your reply more closely I just want to confirm.

1. So in a sense the dotted line represents almost a bollinger band type of effect except better in that they are color coded to dictate trend direction and areas of support/resistance. So if the dotted line is green denoting an upward trend and a red candle hits it, it could be a possible long scenario (buying a pullback off as it bounces off support). And vice versa for a downward trend?

2. Still not quite clear on "mean reversion". Is it basically a failed reversal in a channel? In which case price would head back towards the middle of the channel?

3. Lastly the solid lines represent possible buy/sell opportunities as the line changes color. I'm thinking that these solid lines also represent support and resistance areas as well once price hits them and leaves?

Thank you for taking the time to answer my questions, its greatly appreciated!
 
hello my name is Eddie and I would like to know what to put in the scanner of thinkorswim to get the long signals thank you
 
Now that I had a chance to study your reply more closely I just want to confirm.

1. So in a sense the dotted line represents almost a bollinger band type of effect except better in that they are color coded to dictate trend direction and areas of support/resistance. So if the dotted line is green denoting an upward trend and a red candle hits it, it could be a possible long scenario (buying a pullback off as it bounces off support). And vice versa for a downward trend?

2. Still not quite clear on "mean reversion". Is it basically a failed reversal in a channel? In which case price would head back towards the middle of the channel?

3. Lastly the solid lines represent possible buy/sell opportunities as the line changes color. I'm thinking that these solid lines also represent support and resistance areas as well once price hits them and leaves?

Thank you for taking the time to answer my questions, its greatly appreciated!
1. The dotted lines and the solid lines both act as support and resistance. They do reflect volatility like the Bollinger Bands, but the way they are calculated is very different. The color of the lines is determined by the orientation of the Keltner channels. "So if the dotted line is green denoting an upward trend and a red candle hits it, it could be a possible long scenario (buying a pullback off as it bounces off support). And vice versa for a downward trend?" Yep that's right.

2. Yes. Its not so much of a failed breakout as it is a return back toward the average once price gets over extended (up or down). These generally represent good opportunities for buying or selling (depending on the channel direction).

3. The solid lines and the dotted lines both represent support and resistance. The main difference is the length of time they use. The dotted lines are using a 20 period length whereas the solid lines are using a 75 period length. The longer the period length the stronger the support/resistance. Look at it as near term vs longer term support/resistance.

Hope this helps! I am always happy to answer questions. Thanks for putting this indicator to good use and trying to understand my thought process.
 
hello my name is Eddie and I would like to know what to put in the scanner of thinkorswim to get the long signals thank you
Hi Eddie!
Here's the code to scan for a cross above OS on the Super OB/OS indicator. I think you might find it useful. The code for the Confirmation Candles is too complex in its current form to be used in scans.

Code:
#Super_OB_OS_Lower
#Created by Christopher84 04/22/2021

declare lower;

#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 = 5;#Typically 20
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;
def BBPB_OB = 100;
def BBPB_OS = 0;
def upperBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).UpperBand;
def lowerBand = BollingerBands(price, displace, BBPB_length, Num_Dev_Dn, Num_Dev_up, BBPB_averageType).LowerBand;
def PercentB = (price - lowerBand) / (upperBand - lowerBand) * 100;
def HalfLine = 50;
def UnitLine = 100;

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

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

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

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

PLOT OSX = Concensus_Line crosses above Super_OS;
 
1. The dotted lines and the solid lines both act as support and resistance. They do reflect volatility like the Bollinger Bands, but the way they are calculated is very different. The color of the lines is determined by the orientation of the Keltner channels. "So if the dotted line is green denoting an upward trend and a red candle hits it, it could be a possible long scenario (buying a pullback off as it bounces off support). And vice versa for a downward trend?" Yep that's right.

2. Yes. Its not so much of a failed breakout as it is a return back toward the average once price gets over extended (up or down). These generally represent good opportunities for buying or selling (depending on the channel direction).

3. The solid lines and the dotted lines both represent support and resistance. The main difference is the length of time they use. The dotted lines are using a 20 period length whereas the solid lines are using a 75 period length. The longer the period length the stronger the support/resistance. Look at it as near term vs longer term support/resistance.

Hope this helps! I am always happy to answer questions. Thanks for putting this indicator to good use and trying to understand my thought process.
Thanks very much, greatly appreciated!
 
results look pretty good. what parameters ar you using for b/s/? these?

def Buy = UP_OS;
def Sell = DOWN_OB;

i'll have to try to duplicate the strategy myself and see what i think.

how do you get all those stats? that's a motherlode!

keep up the great work. i've taken your code and done what you see in the pic below. in the lower most study window, i've done away with everything but the buy suggestion and added vertical lines and price for when it triggers. the white dashed lines. meanwhile, in the price window, i'm using it as a filter for my favorite mean-reversion indicator, which shows up as purple arrows while yours are the white ones.

if i took a purple trade and didn't get a white confirmation within 3 bars, it's time to get out. better bet would be to wait until both fire but by then a lot of what makes mean reversion work is done. see how that first purple arrow isn't confirmed? get out! see how the second one is, in the very next bar? yay!

anyway, thanks for this. i think it's going to be muy useful.


Jmd39VV.png


by the way, the vertical lines in the upper chart reflect my indicator firing, along w/ the price at which it did so. the diff between buying right then and waiting a day is pretty substantial, sometimes for better, others for worse.
 
Last edited:
results look pretty good. what parameters ar you using for b/s/? these?

def Buy = UP_OS;
def Sell = DOWN_OB;

i'll have to try to duplicate the strategy myself and see what i think.

how do you get all those stats? that's a motherlode!

keep up the great work. i've taken your code and done what you see in the pic below. in the lower most study window, i've done away with everything but the buy suggestion and added vertical lines and price for when it triggers. the white dashed lines. meanwhile, in the price window, i'm using it as a filter for my favorite mean-reversion indicator, which shows up as purple arrows while yours are the white ones.

if i took a purple trade and didn't get a white confirmation within 3 bars, it's time to get out. better bet would be to wait until both fire but by then a lot of what makes mean reversion work is done. see how that first purple arrow isn't confirmed? get out! see how the second one is, in the very next bar? yay!

anyway, thanks for this. i think it's going to be muy useful.


Jmd39VV.png


by the way, the vertical lines in the upper chart reflect my indicator firing, along w/ the price at which it did so. the diff between buying right then and waiting a day is pretty substantial, sometimes for better, others for worse.
Hi floydddd,
Most of what I have incorporated into the study is from my own observations and staring at charts way too long. I am curious which version of the indicator you are currently using?
For the Confirmation Candles, the b/s signals are coded:
def UP = Agreement_Level >= Confirmation_Factor;
def DOWN = Agreement_Level <= Confirmation_Factor;
*Note that you can adjust the confirmation level on the confirmation candles which may result with a better fit to your strategy.

For the CC Candles the b/s signals are coded:
def UP = Consensus_Level >= 0;
def DOWN = Consensus_Level < 0;
*Note that the CC Candles utilize a static consensus level either above or below 0. Its a little slower on entry signals but gives tighter exit signals.

One additional note, if you haven't tried CC Candles Lower indicator, I believe it could be an excellent fit with your mean reversion strategy. In the image below, you can see how the lower indicator is being rejected from the dynamic resistance dotted line right when price is reverting.

yNuL7Hq.png
 

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
359 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