Confirmation Candles Indicator For ThinkorSwim

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

I wish I'd been following this since the beginning. I am wondering if there is ANYTHING in the 129 pages of replys that indicates which code I should be using? on page 1 there are many variations. Any documents that lay out exactly what it is I'm looking at, and looking for? I've only been trading SPY for 12 months, and just started /MES and /ES. tbh I do OK with some MAs and an Ichimoku overlay but am always interested in trying something new.
 
On the EMAD lower indicator, is there a way to put an up or down arrow on upper chart based on the the line crossing the 0 line?
I use it for my strategy.
 
I wish I'd been following this since the beginning. I am wondering if there is ANYTHING in the 129 pages of replys that indicates which code I should be using? on page 1 there are many variations. Any documents that lay out exactly what it is I'm looking at, and looking for? I've only been trading SPY for 12 months, and just started /MES and /ES. tbh I do OK with some MAs and an Ichimoku overlay but am always interested in trying something new.
Well unfortunately no one can tell you which code to use. You just have to use trial and error to find what you like and what you dont. My suggestion would be use the EMAD lower for sure if you do not like too much going on with the upper.
 
Heres a version that has a second aggregation per @Christopher84 use of the strategy (Disclaimer This version is subject to repaint - the original study is not).

C3_Max_TS_X2
  1. The 2 aggregation default is hourly (can be changed in settings)
  2. The 2nd aggregation (magenta) arrows show anytime the signal is true on that TF
    • in the case that the 2nd and current aggregation plot on the same bar - the higher aggregation signal will be shown
  3. The current chart aggregation signal (cyan) will plot if each of the following conditions is true:
  • if current aggregation signal is sell
    • Current aggregation sell signal is true
    • 2nd aggregation sell signal bar number is greater than the 2nd aggregation buy signal bar number (in other words the most recent 2nd aggregation signal is the same as the current aggregation signal)
    • 2nd aggregation signal is before the current aggregation signal
And vis versa for the buy signal.

* The labels are only for the current aggregation signal only (the calculation is still accounting for all signals from the original code as it its near pointless to have them calculate the filtered indication as it is subject to repaint * (I will likely add the 2nd aggregation labels as well if someone requires it)

And vis versa for the buy signal.


Of course it is not necessary when one can simply put one chart next to the other but oh well here it is:

Study share link: http://tos.mx/ULmKI0M

uHI4qrT.png


Code:
#####################################################
#C3_Max_TS_X2 HODL added 2nd aggregation
#####################################################

#####################################################
#C3_Max_TS Created Created by Christopher84 5/23/2023
#####################################################



#####################################################
#TS Strategy_V9 Created by Christopher84 08/10/2021
#####################################################
input Agperiod2 = {"1 min", "2 min", "3 min", "5 min", "10 min", "15 min", "30 min",default "1 hour", "2 hours", "4 hours", "Day", "Week", "Month"};

input trailType = {default modified, unmodified};
input ATRPeriod = 5;
input ATRFactor = 3.1;
input firstTrade = {default long, short};
input averageType = AverageType.SIMPLE;
input price = close;
input coloredCandlesOn = yes;
input LabelsOn = no;
input trailType2 = {default modified2, unmodified2};
input ATRPeriod2 = 11;
input ATRFactor2 = 2.2;
input firstTrade2 = {default long2, short2};
input averageType2 = AverageType.SIMPLE;

input OpenTime2 = 0930;


input CloseTime2 = 1600;


Assert(ATRFactor > 0, "'atr factor' must be positive: " + ATRFactor);

def HiLo = Min(high - low, 1.5 * Average(high - low, ATRPeriod));
def HRef = if low <= high[1]
    then high - close[1]
    else (high - close[1]) - 0.5 * (low - high[1]);
def LRef = if high >= low[1]
    then close[1] - low
    else (close[1] - low) - 0.5 * (low[1] - high);

def trueRange;
switch (trailType) {
case modified:
    trueRange = Max(HiLo, Max(HRef, LRef));
case unmodified:
    trueRange = TrueRange(high, close, low);
}
def loss = ATRFactor * MovingAverage(averageType, trueRange, ATRPeriod);

def state = {default init, long, short};
def trail;
switch (state[1]) {
case init:
    if (!IsNaN(loss)) {
        switch (firstTrade) {
        case long:
            state = state.long;
            trail =  close - loss;
        case short:
            state = state.short;
            trail = close + loss;
    }
    } else {
        state = state.init;
        trail = Double.NaN;
    }
case long:
    if (close > trail[1]) {
        state = state.long;
        trail = Max(trail[1], close - loss);
    } else {
        state = state.short;
        trail = close + loss;
    }
case short:
    if (close < trail[1]) {
        state = state.short;
        trail = Min(trail[1], close + loss);
    } else {
        state = state.long;
        trail =  close - loss;
    }
}

def TrailingStop = trail;
def LongEnter = (price crosses above TrailingStop);
def LongExit = (price crosses below TrailingStop);

AddOrder(OrderType.BUY_AUTO, condition = LongEnter, price = open[-1], 1, tickcolor = GetColor(1), arrowcolor = Color.LIME);
AddOrder(OrderType.SELL_AUTO, condition = LongExit, price = open[-1], 1, tickcolor = GetColor(2), arrowcolor = Color.LIME);

def upsignal = (price crosses above TrailingStop);

def downsignal = (price crosses below TrailingStop);


def high2 = high(period = agperiod2);
def low2 =low(period = agperiod2);
def close2 = close(period = agperiod2);

def price_V92 = close2;

Assert(ATRFactor2 > 0, "'atr factor' must be positive: " + ATRFactor2);

def HiLo2 = Min(high2 - low2, 1.5 * Average(high2 - low2, ATRPeriod2));
def HRef2 = if low2 <= high2[1]
    then high2 - close2[1]
    else (high2 - close2[1]) - 0.5 * (low2 - high2[1]);
def LRef2 = if high2 >= low2[1]
    then close2[1] - low2
    else (close2[1] - low2) - 0.5 * (low2[1] - high2);

def trueRange2;
switch (trailType2) {
    case modified2:
        trueRange2 = Max(HiLo2, Max(HRef2, LRef2));
    case unmodified2:
        trueRange2 = TrueRange(high2, close2, low2);
}
def loss2 = ATRFactor2 * MovingAverage(averageType2, trueRange2, ATRPeriod2);

def state2 = {default init2, long2, short2};
def trail2;
switch (state2[1]) {
    case init2:
        if (!IsNaN(loss2)) {
            switch (firstTrade2) {
                case long2:
                    state2 = state2.long2;
                    trail2 = close2 - loss2;
                case short2:
                    state2 = state2.short2;
                    trail2 = close2 + loss2;
            }
        } else {
            state2 = state2.init2;
            trail2 = Double.NaN;
        }
    case long2:
        if (close2 > trail2[1]) {
            state2 = state2.long2;
            trail2 = Max(trail2[1], close2 - loss2);
        } else {
            state2 = state2.short2;
            trail2 = close2 + loss2;
        }
    case short2:
        if (close2 < trail2[1]) {
            state2 = state2.short2;
            trail2 = Min(trail2[1], close2 + loss2);
        } else {
            state2 = state2.long2;
            trail2 = close2 - loss2;
        }
}

def TrailingStop2 = trail2;
def LongEnter2 = (price_v92 crosses above TrailingStop2);
def LongExit2 = (price_v92 crosses below TrailingStop2) ;

def upsignal2 = (price_V92 crosses above TrailingStop2);
def downsignal2 = (price_v92 crosses below TrailingStop2);
###------------------------------------------------------------------------------------------
# Profit and Loss Labels
#
# Fill in the 0>0 in the Create Signals section below to match your buy and sell signal conditions
#
# When using large amounts of hisorical data, P/L may take time to calculate
###------------------------------------------------------------------------------------------

input showSignals = yes; #hint showSignals: show buy and sell arrows
input LongTrades = yes; #hint LongTrades: perform long trades
input ShortTrades = yes; #hint ShortTrades: perform short trades
input showLabels  = yes; #hint showLabels: show PL labels at top
input showBubbles = no; #hint showBubbles: show PL bubbles at close of trade
input useStops = no;     #hint useStops: use stop orders
input useAlerts = no;    #hint useAlerts: use alerts on signals
input tradeDaytimeOnly = no; #hint tradeDaytimeOnly: (IntraDay Only) Only perform trades during hours stated
input OpenTime = 0930; #hint OpenTime: Opening time of market
input CloseTime = 1600; #hint CloseTime: Closing time of market

input showSignals2 = yes; #hint showSignals2: show buy and sell arrows
input LongTrades2 = yes; #hint LongTrades2: perform long trades
input ShortTrades2 = yes; #hint ShortTrades2: perform short trades
input showLabels2 = yes; #hint showLabels2: show PL labels at top
input showBubbles2 = no; #hint showBubbles2: show PL bubbles at close of trade
input useStops2 = no; #hint useStops2: use stop orders
input useAlerts2 = no; #hint useAlerts2: use alerts on signals

def Begin = SecondsFromTime(OpenTime);
def End = SecondsTillTime(CloseTime);
# Only use market hours when using intraday timeframe
def isIntraDay = if GetAggregationPeriod() > 14400000 or GetAggregationPeriod() == 0 then 0 else 1;
def MarketOpen = if !tradeDaytimeOnly or !isIntraDay then 1 else if tradeDaytimeOnly and isIntraDay and Begin > 0 and End > 0 then 1 else 0;



def Begin2 = SecondsFromTime(OpenTime2);
def End2 = SecondsTillTime(CloseTime2);

# Only use market hours when using intraday timeframe
input tradeDaytimeOnly2 = no; #hint tradeDaytimeOnly: (IntraDay Only) Only perform trades during hours stated

def isIntraDay2 = if GetAggregationPeriod() > 14400000 or GetAggregationPeriod() == 0 then 0 else 1;
def MarketOpen2 = if !tradeDaytimeOnly2 or !isIntraDay2 then 1 else if tradeDaytimeOnly2 and isIntraDay2 and Begin2 > 0 and End2 > 0 then 1 else 0;
###----------------------------


###------------------------------------------------------------------------------------------

######################################################
##  Create Signals -
##  FILL IN THIS SECTION
##      replace 0>0 with your conditions for signals
######################################################

def PLBuySignal = if  MarketOpen and (upsignal) then 1 else 0 ; # insert condition to create long position in place of the 0>0
def PLSellSignal =  if MarketOpen and (downsignal) then 1 else 0; # insert condition to create short position in place of the 0>0

def PLBuyStop  = if !useStops then 0 else if  (0 > 0) then 1 else 0  ; # insert condition to stop in place of the 0<0
def PLSellStop = if !useStops then 0 else if (0 > 0) then 1 else 0  ; # insert condition to stop in place of the 0>0

def PLMktStop = if MarketOpen[-1] == 0 then 1 else 0; # If tradeDaytimeOnly is set, then stop at end of day


#######################################
##  Maintain the position of trades
#######################################

def CurrentPosition;  # holds whether flat = 0 long = 1 short = -1

if (BarNumber() == 1) or IsNaN(CurrentPosition[1]) {
    CurrentPosition = 0;
} else {
    if CurrentPosition[1] == 0 {            # FLAT
        if (PLBuySignal and LongTrades) {
            CurrentPosition = 1;
        } else if (PLSellSignal and ShortTrades) {
            CurrentPosition = -1;
        } else {
            CurrentPosition = CurrentPosition[1];
        }
    } else if CurrentPosition[1] == 1 {      # LONG
        if (PLSellSignal and ShortTrades) {
            CurrentPosition = -1;
        } else if ((PLBuyStop and useStops) or PLMktStop or (PLSellSignal and ShortTrades == 0)) {
            CurrentPosition = 0;
        } else {
            CurrentPosition = CurrentPosition[1];
        }
    } else if CurrentPosition[1] == -1 {     # SHORT
        if (PLBuySignal and LongTrades) {
            CurrentPosition = 1;
        } else if ((PLSellStop and useStops) or PLMktStop or (PLBuySignal and LongTrades == 0)) {
            CurrentPosition = 0;
        } else {
            CurrentPosition = CurrentPosition[1];
        }
    } else {
        CurrentPosition = CurrentPosition[1];
    }
}

######################################################

def PLBuySignal2 = if MarketOpen2 and (Upsignal2) then 1 else 0 ; # insert condition to create long position in place of the 0>0
def PLSellSignal2 = if MarketOpen2 and (downsignal2) then 1 else 0; # insert condition to create short position in place of the 0>0
def PLBuyStop2 = if !useStops2 then 0 else if (0 > 0) then 1 else 0 ; # insert condition to stop in place of the 0<0
def PLSellStop2 = if !useStops2 then 0 else if (0 > 0) then 1 else 0  ; # insert condition to stop in place of the 0>0
def PLMktStop2 = if MarketOpen2[-1] == 0 then 1 else 0; # If tradeDaytimeOnly is set, then stop at end of day





def CurrentPosition2;  # holds whether flat = 0 long = 1 short = -1

if (BarNumber() == 1) or IsNaN(CurrentPosition2[1]) {
    CurrentPosition2 = 0;
} else {
    if CurrentPosition2[1] == 0 {            # FLAT
        if (PLBuySignal2 and LongTrades2) {
            CurrentPosition2 = 1;
        } else if (PLSellSignal2 and ShortTrades2) {
            CurrentPosition2 = -1;
        } else {
            CurrentPosition2 = CurrentPosition2[1];
        }
    } else if CurrentPosition2[1] == 1 {      # LONG
        if (PLSellSignal2 and ShortTrades2) {
            CurrentPosition2 = -1;
        } else if ((PLBuyStop2 and useStops2) or PLMktStop2 or (PLSellSignal2 and ShortTrades2 == 0)) {
            CurrentPosition2 = 0;
        } else {
            CurrentPosition2 = CurrentPosition2[1];
        }
    } else if CurrentPosition2[1] == -1 {     # SHORT
        if (PLBuySignal2 and LongTrades2) {
            CurrentPosition2 = 1;
        } else if ((PLSellStop2 and useStops2) or PLMktStop2 or (PLBuySignal2 and LongTrades2 == 0)) {
            CurrentPosition2 = 0;
        } else {
            CurrentPosition2 = CurrentPosition2[1];
        }
    } else {
        CurrentPosition2 = CurrentPosition2[1];
    }
}


def isLong2  = if CurrentPosition2 == 1 then 1 else 0;
def isShort2 = if CurrentPosition2 == -1 then 1 else 0;
def isFlat2  = if CurrentPosition2 == 0 then 1 else 0;

def bn = barnumber();

def isLong  = if CurrentPosition == 1 then 1 else 0;
def isShort = if CurrentPosition == -1 then 1 else 0;
def isFlat  = if CurrentPosition == 0 then 1 else 0;

def BuySig_1 = if (((isShort[1] and LongTrades) or (isFlat[1] and LongTrades)) and PLBuySignal and showSignals) then 1 else 0;
def BuySig_1_bn = if Buysig_1 then bn else BuySig_1_bn[1];

def BuySig_2 = if (((isShort2[1] and LongTrades2) or (isFlat2[1] and LongTrades2)) and PLBuySignal2 and showSignals2) then 1 else 0;
def BuySig_2_bn = if Buysig_2 then bn else BuySig_2_bn[1];

def SellSig_1 = if (((isLong[1] and ShortTrades) or (isFlat[1] and ShortTrades)) and PLSellSignal and showSignals) then 1 else 0;
def SellSig_1_bn = if SellSig_1 then bn else SellSig_1_bn[1];


def SellSig_2 = if (((isLong2[1] and ShortTrades2) or (isFlat2[1] and ShortTrades2)) and PLSellSignal2 and showSignals2)then 1 else 0;
def SellSig_2_bn = if SellSig_2 then bn else SellSig_2_bn[1];

def Sell_1_2 = if SellSig_1 and SellSig_2 then 1 else 0;
def Buy_1_2 = if buySig_1 and buySig_2 then 1 else 0;

def Hide_Sell = if SellSig_1 and (SellSig_2_bn <= SellSig_1_bn)and (SellSig_2_bn > BuySig_2_bn) then 1 else 0;
def Hide_Buy = if buySig_1 and (buySig_2_bn <= buySig_1_bn) and (buySig_2_bn > SellSig_2_bn) then 1 else 0;

# If not already long and get a PLBuySignal
#Plot BuySig = if (!isLong[1] and PLBuySignal and showSignals and LongTrades) then 1 else 0;
plot BuySig = if BuySig_1 and !buy_1_2 and Hide_Buy then 1 else 0;
BuySig.AssignValueColor(Color.CYAN);
BuySig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
BuySig.SetLineWeight(1);

Alert(BuySig and useAlerts, "Buy Signal", Alert.BAR, Sound.Ding);
Alert(BuySig and useAlerts, "Buy Signal", Alert.BAR, Sound.Ding);

plot BuySig2 = if BuySig_2 then 1 else 0;
BuySig2.AssignValueColor(Color.magenta);
BuySig2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
BuySig2.SetLineWeight(1);

Alert(BuySig2 and useAlerts, "Buy Signal", Alert.BAR, Sound.Ding);
Alert(BuySig2 and useAlerts, "Buy Signal", Alert.BAR, Sound.Ding);

plot SellSig = if SellSig_1 and !Sell_1_2 and Hide_Sell then 1 else 0;
SellSig.AssignValueColor(Color.CYAN);
SellSig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
SellSig.SetLineWeight(1);

Alert(SellSig and useAlerts, "Sell Signal", Alert.BAR, Sound.Ding);
Alert(SellSig and useAlerts, "Sell Signal", Alert.BAR, Sound.Ding);
# If not already short and get a PLSellSignal
plot SellSig2 = if SellSig_2 then 1 else 0;
SellSig2.AssignValueColor(Color.magenta);
SellSig2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
SellSig2.SetLineWeight(1);

Alert(SellSig2 and useAlerts, "Sell Signal", Alert.BAR, Sound.Ding);
Alert(SellSig2 and useAlerts, "Sell Signal", Alert.BAR, Sound.Ding);



# If long and get a PLBuyStop
plot BuyStpSig = if (PLBuyStop and isLong[1] and showSignals and useStops) or (isLong[1] and PLMktStop) or (isLong[1] and PLSellSignal and !ShortTrades) then 1 else 0;
BuyStpSig.AssignValueColor(Color.LIGHT_GRAY);
BuyStpSig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
BuyStpSig.SetLineWeight(3);

Alert(BuyStpSig and useAlerts, "Buy Stop Signal", Alert.BAR, Sound.Ding);
Alert(BuyStpSig and useAlerts, "Buy Stop Signal", Alert.BAR, Sound.Ding);


# If short and get a PLSellStop
plot SellStpSig = if (PLSellStop and isShort[1] and showSignals and useStops) or (isShort[1] and PLMktStop) or (isShort[1] and PLBuySignal and !LongTrades) then 1 else 0;
SellStpSig.AssignValueColor(Color.LIGHT_GRAY);
SellStpSig.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
SellStpSig.SetLineWeight(3);

Alert(SellStpSig and useAlerts, "Sell Stop Signal", Alert.BAR, Sound.Ding);
Alert(SellStpSig and useAlerts, "Sell Stop Signal", Alert.BAR, Sound.Ding);


#######################################
##  Orders
#######################################



def isOrder = if ((isFlat[1] and (BuySig_1 and LongTrades) or (SellSig_1 and ShortTrades)) or (isLong[1] and BuyStpSig or (SellSig_1 and ShortTrades)) or (isShort[1] and SellStpSig or (BuySig_1 and LongTrades))) then 1 else 0 ;

# If there is an order, then the price is the next day's close
def orderPrice = if (isOrder and ((BuySig_1 and LongTrades) or (SellSig_1 and ShortTrades))) then close else orderPrice[1];

def orderCount = CompoundValue(1, if IsNaN(isOrder) or BarNumber() == 1 then 0 else if (BuySig_1 or SellSig_1) then orderCount[1] + 1 else orderCount[1], 0);


#######################################
##  Price and Profit
#######################################

def profitLoss;

if (!isOrder or orderPrice[1] == 0) {
    profitLoss = 0;
} else if ((isOrder and isLong[1]) and (SellSig_1 or BuyStpSig)) {
    profitLoss = close - orderPrice[1];
} else if ((isOrder and isShort[1]) and (BuySig_1 or SellStpSig)) {
    profitLoss = orderPrice[1] - close;
} else {
    profitLoss = 0;
}

# Total Profit or Loss
def profitLossSum = CompoundValue(1, if IsNaN(isOrder) or BarNumber() == 1 then 0 else if isOrder then profitLossSum[1] + profitLoss else profitLossSum[1], 0);

# How many trades won or lost
def profitWinners = CompoundValue(1, if IsNaN(profitWinners[1]) or BarNumber() == 1 then 0 else if isOrder and profitLoss > 0 then profitWinners[1] + 1 else profitWinners[1], 0);
def profitLosers = CompoundValue(1, if IsNaN(profitLosers[1]) or BarNumber() == 1 then 0 else if isOrder and profitLoss < 0 then profitLosers[1] + 1 else profitLosers[1], 0);
def profitPush = CompoundValue(1, if IsNaN(profitPush[1]) or BarNumber() == 1 then 0 else if isOrder and profitLoss == 0 then profitPush[1] + 1 else profitPush[1], 0);

# Current Open Trade Profit or Loss
def TradePL = if isLong then Round(((close - orderPrice) / TickSize()) * TickValue()) else if isShort then Round(((orderPrice - close) / TickSize()) * TickValue()) else 0;

# Convert to actual dollars based on Tick Value for bubbles
def dollarProfitLoss = if orderPrice[1] == 0 or IsNaN(orderPrice[1]) then 0 else Round((profitLoss / TickSize()) * TickValue());

# Closed Orders dollar P/L
def dollarPLSum = Round((profitLossSum / TickSize()) * TickValue());

# Split profits or losses by long and short trades
def profitLong = CompoundValue(1, if IsNaN(profitLong[1]) or BarNumber() == 1 then 0 else if isOrder and isLong[1] then profitLong[1] + dollarProfitLoss else profitLong[1], 0);
def profitShort = CompoundValue(1, if IsNaN(profitShort[1]) or BarNumber() == 1 then 0 else if isOrder and isShort[1] then profitShort[1] + dollarProfitLoss else profitShort[1], 0);
def countLong = CompoundValue(1, if IsNaN(countLong[1]) or BarNumber() == 1 then 0 else if isOrder and isLong[1] then countLong[1] + 1 else countLong[1], 0);
def countShort = CompoundValue(1, if IsNaN(countShort[1]) or BarNumber() == 1 then 0 else if isOrder and isShort[1] then countShort[1] + 1 else countShort[1], 0);

# What was the biggest winning and losing trade
def biggestWin = CompoundValue(1, if IsNaN(biggestWin[1]) or BarNumber() == 1 then 0 else if isOrder and (dollarProfitLoss > 0) and (dollarProfitLoss > biggestWin[1]) then dollarProfitLoss else biggestWin[1], 0);
def biggestLoss = CompoundValue(1, if IsNaN(biggestLoss[1]) or BarNumber() == 1 then 0 else if isOrder and (dollarProfitLoss < 0) and (dollarProfitLoss < biggestLoss[1]) then dollarProfitLoss else biggestLoss[1], 0);

def ClosedTradeCount = if (isLong or isShort) then orderCount - 1 else orderCount;
def OpenTrades = if (isLong or isShort) then 1 else 0;

# What percent were winners
def PCTWin = if (OpenTrades and (TradePL < 0)) then Round((profitWinners / (ClosedTradeCount + 1)) * 100, 2)
else if (OpenTrades and (TradePL > 0)) then Round(((profitWinners + 1) / (ClosedTradeCount + 1)) * 100, 2) else Round(((profitWinners) / (ClosedTradeCount)) * 100, 2) ;

# Average trade
def avgTrade = if (OpenTrades and (TradePL < 0)) then Round(((dollarPLSum - TradePL) / (ClosedTradeCount + 1)), 2)
else if (OpenTrades and (TradePL > 0)) then Round(((dollarPLSum + TradePL) / (ClosedTradeCount + 1)), 2) else Round(((dollarPLSum) / (ClosedTradeCount)), 2) ;


#######################################
##  Create Labels
#######################################


AddLabel(showLabels and isIntraDay, if MarketOpen then "Market Open" else "Market Closed", Color.WHITE);
AddLabel(showLabels, GetSymbol() + " Tick Size: " + TickSize() + " Value: " + TickValue(), Color.WHITE);
AddLabel(showLabels and (LongTrades and ShortTrades), "Long+Short Trades", Color.WHITE);
AddLabel(showLabels and (LongTrades and !ShortTrades), "Long Trades Only", Color.WHITE);
AddLabel(showLabels and (!LongTrades and ShortTrades), "Short Trades Only", Color.WHITE);
AddLabel(showLabels, "Closed Orders: " + ClosedTradeCount + " P/L: " + AsDollars(dollarPLSum), if dollarPLSum > 0 then Color.GREEN else if dollarPLSum < 0 then Color.RED else Color.GRAY);
AddLabel(if !IsNaN(orderPrice) and showLabels then 1 else 0, "Closed+Open P/L: " + AsDollars(TradePL + dollarPLSum), if ((TradePL + dollarPLSum) > 0) then Color.GREEN else if ((TradePL + dollarPLSum) < 0) then Color.RED else Color.GRAY);

AddLabel(showLabels, "Avg per Trade: " + AsDollars(avgTrade), if avgTrade > 0 then Color.GREEN else if avgTrade < 0 then Color.RED else Color.GRAY);
AddLabel(showLabels, "Winners: " + PCTWin + "%", if PCTWin > 50 then Color.GREEN else if PCTWin > 40 then Color.YELLOW else Color.GRAY);

AddLabel(showLabels, "MaxUp: " + AsDollars(biggestWin) + " MaxDown: " + AsDollars(biggestLoss), Color.WHITE);
AddLabel(showLabels, "Long Profit: " + AsDollars(profitLong), if profitLong > 0 then Color.GREEN else if profitLong < 0 then Color.RED else Color.GRAY);
AddLabel(showLabels, "Short Profit: " + AsDollars(profitShort), if profitShort > 0 then Color.GREEN else if profitShort < 0 then Color.RED else Color.GRAY);
AddLabel(if !IsNaN(CurrentPosition) and showLabels and OpenTrades then 1 else 0, "Open: " + (if isLong then "Bought" else "Sold") + " @ " + orderPrice, Color.WHITE);
AddLabel(if !IsNaN(orderPrice) and showLabels and OpenTrades then 1 else 0, "Open Trade P/L: " + AsDollars(TradePL), if (TradePL > 0) then Color.GREEN else if (TradePL < 0) then Color.RED else Color.GRAY);
AddLabel(showLabels, "Profit Percentile: " + AsPercent(TradePL / biggestWin), if (TradePL > 0) then Color.GREEN else if (TradePL < 0) then Color.RED else Color.GRAY);
;
#######################################
##  Chart Bubbles for Profit/Loss
#######################################
AddChartBubble(showSignals and showBubbles and isOrder and isLong[1], low, "$" + dollarProfitLoss, if dollarProfitLoss == 0 then Color.LIGHT_GRAY else if dollarProfitLoss > 0 then Color.GREEN else Color.RED, 0);
AddChartBubble(showSignals and showBubbles and isOrder and isShort[1], high, "$" + dollarProfitLoss, if dollarProfitLoss == 0 then Color.LIGHT_GRAY else if dollarProfitLoss > 0 then Color.GREEN else Color.RED, 1);

AssignPriceColor(if coloredCandlesOn and (TradePL > (biggestWin * .75)) then Color.YELLOW else if ((price > TrailingStop)) then Color.GREEN else if coloredCandlesOn and ((price < TrailingStop)) then Color.RED else Color.GRAY);
#AssignPriceColor(if coloredCandlesOn and ((price > TrailingStop)) then Color.GREEN else if coloredCandlesOn and ((price < TrailingStop)) then Color.RED else Color.GRAY);


#######################################
#Assign Price Color
#######################################
def Ceiling = biggestWin;
def Floor = biggestLoss;
def MidCAT = (((biggestWin + avgTrade) / 2) + avgTrade) / 2;
def MidFAT = (((biggestLoss + avgTrade) / 2) + avgTrade) / 2;
def AvgProfitWinners = (((profitWinners) / (ClosedTradeCount + 1)));
input mult = 50;

########################################
##Long Stop
########################################
def LongStop = if (BuySig) then low else Double.NaN;
def LongStopext = if (IsNaN(LongStop) and isLong) then LongStopext[1] else LongStop;
plot LongStopextline = LongStopext;
LongStopextline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
LongStopextline.SetDefaultColor(Color.ORANGE);
LongStopextline.SetLineWeight(2);

########################################
##Long Targets
########################################
plot LongEntry = if isLong then (orderPrice) else Double.NaN;
LongEntry.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
LongEntry.SetDefaultColor(Color.GREEN);
LongEntry.SetLineWeight(2);

plot AvgProfitLL = if isLong then (orderPrice + ((dollarPLSum) / (ClosedTradeCount) / mult)) else Double.NaN;
AvgProfitLL.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
AvgProfitLL.SetDefaultColor(Color.WHITE);
AvgProfitLL.SetLineWeight(1);


#########################################
##Short Stop
#########################################
def ShortStop = if SellSig then high else Double.NaN;
def ShortStopext = if (IsNaN(ShortStop) and isShort) then ShortStopext[1] else ShortStop;
plot ShortStopextline = ShortStopext;
ShortStopextline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ShortStopextline.SetDefaultColor(Color.ORANGE);
ShortStopextline.SetLineWeight(2);

########################################
##Short Targets
########################################
plot ShortEntry = if isShort then (orderPrice) else Double.NaN;
;
ShortEntry.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ShortEntry.SetDefaultColor(Color.RED);
ShortEntry.SetLineWeight(2);

plot AvgProfitLS = if isShort then (orderPrice - ((dollarPLSum) / (ClosedTradeCount) / mult)) else Double.NaN;
AvgProfitLS.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
AvgProfitLS.SetDefaultColor(Color.WHITE);
AvgProfitLS.SetLineWeight(1);


###############################################
##OB_OS_Levels_v5 by Christopher84 12/10/2021
###############################################

input BarsUsedForRange = 2;

input BarsRequiredToRemainInRange = 2;

input TargetMultiple = 0.5;

input ColorPrice = yes;

input HideTargets = no;

input HideBalance = no;

input HideBoxLines = no;

input HideCloud = no;

input HideLabels = no;

#def TrailingStop = trail;
def H = Highest(TrailingStop, 12);
def L = Lowest(TrailingStop, 12);
def BulgeLengthPrice = 100;
def SqueezeLengthPrice = 100;
def BandwidthC3 = (H - L);
#def IntermResistance2 = Highest(BandwidthC3, BulgeLengthPrice);
def IntermSupport2 = Lowest(BandwidthC3, SqueezeLengthPrice);
def sqzTrigger = BandwidthC3 <= IntermSupport2;
def sqzLevel = if !sqzTrigger[1] and sqzTrigger then hl2
               else if !sqzTrigger then Double.NaN
               else sqzLevel[1];

plot Squeeze_Alert = sqzLevel;
Squeeze_Alert.SetPaintingStrategy(PaintingStrategy.POINTS);
Squeeze_Alert.SetLineWeight(3);
Squeeze_Alert.SetDefaultColor(Color.YELLOW);

#-----------------------------
#Yellow Candle_height (OB_OS)
#-----------------------------
def displace = 0;
def factorK2 = 3.25;
def lengthK2 = 20;
#def price = close;
def price1 = open;
def trueRangeAverageType = AverageType.SIMPLE;
def ATR_length = 15;
def SMA_lengthS = 6;
#input coloredCandlesOn = yes;
input ATRPeriod22 = 5;
input ATRFactor22 = 1.5;
#input averageType = AverageType.WILDERS;####Use Simple instead of Wilders
def HiLo22 = Min(high - low, 1.5 * Average(high - low, ATRPeriod));
def HRef22 = if low <= high[1]
    then high - close[1]
    else (high - close[1]) - 0.5 * (low - high[1]);
def LRef22 = if high >= low[1]
    then close[1] - low
    else (close[1] - low) - 0.5 * (low[1] - high);
def loss22 = ATRFactor2 * MovingAverage(averageType, trueRange, ATRPeriod2);

def multiplier_factor = 1.25;
def valS = Average(price, SMA_lengthS);
def average_true_range = Average(TrueRange(high, close, low), length = ATR_length);
def Upper_BandS = valS[-displace] + multiplier_factor * average_true_range[-displace];
def Middle_BandS = valS[-displace];
def Lower_BandS = valS[-displace] - multiplier_factor * average_true_range[-displace];

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

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

def fastLength = 12;
def slowLength = 26;
def MACDLength = 9;
input MACD_AverageType = {SMA, default EMA};

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

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

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

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

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

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

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

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

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

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

def condition5 = CIP_UP;
def condition5D = CIP_DOWN;

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

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

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

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

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

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

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

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

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

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

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

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

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

#Klinger Histogram
def Klinger_Length = 13;
def KVOsc = KlingerOscillator(Klinger_Length).KVOsc;
def KVOH = KVOsc - Average(KVOsc, Klinger_Length);
def condition13 = (KVOH > 0);
def condition13D = (KVOH < 0);

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

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

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

def factorK = 2.0;
def lengthK = 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 conditionK1UP = price >= Upper_BandK;
def conditionK2UP = (Upper_BandK[1] < Upper_BandK) and (Lower_BandK[1] < Lower_BandK);
def conditionK3DN = (Upper_BandK[1] > Upper_BandK) and (Lower_BandK[1] > Lower_BandK);
def conditionK4DN = price < Lower_BandK;
def Agreement_Level = condition1 + condition2 + condition3 + condition4 + condition5 + condition6 + condition7 + condition8 + condition9 + condition10 + condition11 + condition12 + condition13 + condition14 + conditionK1UP + conditionK2UP;

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

def Consensus_Level = Agreement_Level - Agreement_LevelD;

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

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

def Consensus_Level_OB = 14;
def Consensus_Level_OS = -12;

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

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

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

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



def use_line_limits = yes;#Yes, plots line from/to; No, plot line across entire chart
def linefrom = 100;#Hint linefrom: limits how far line plots in candle area
def lineto   = 12;#Hint lineto: limits how far into expansion the line will plot

def YHOB = if coloredCandlesOn and ((price1 > Upper_BandS) and (condition_BandRevDn)) then high else Double.NaN;
def YHOS = if coloredCandlesOn and ((price1 < Lower_BandS) and (condition_BandRevUp)) then high else Double.NaN;

def YLOB = if coloredCandlesOn and ((price1 > Upper_BandS) and (condition_BandRevDn)) then low else Double.NaN;
def YLOS = if coloredCandlesOn and ((price1 < Lower_BandS) and (condition_BandRevUp)) then low else Double.NaN;

#extend midline of yellow candle
plot YCOB = if !IsNaN(YHOB) then hl2 else Double.NaN;
YCOB.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
YCOB.SetDefaultColor(Color.GREEN);
def YHextOB = if IsNaN(YCOB) then YHextOB[1] else YCOB;
#plot YHextlineOB = YHextOB;
#YHextlineOB.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#YHextlineOB.SetDefaultColor(Color.ORANGE);
#YHextlineOB.SetLineWeight(2);

plot YCOS = if !IsNaN(YHOS) then hl2 else Double.NaN;
YCOS.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
YCOS.SetDefaultColor(Color.GREEN);
def YHextOS = if IsNaN(YCOS) then YHextOS[1] else YCOS;
#plot YHextlineOS = YHextOS;
#YHextlineOS.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#YHextlineOS.SetDefaultColor(Color.LIGHT_GREEN);
#YHextlineOS.SetLineWeight(2);

def YC = coloredCandlesOn and priceColor == 1 and price1 > Upper_BandS and condition_BandRevDn;

#Additional Signals
input showCloud = yes;
#AddCloud(if showCloud and condition_BandRevUp then Lower_BandK2 else Double.NaN,  Lower_BandS,  Color.LIGHT_GREEN,  Color.CURRENT);
#AddCloud(if showCloud and condition_BandRevDn then Upper_BandS else Double.NaN,  Upper_BandK2,  Color.LIGHT_RED,  Color.CURRENT);

# Identify Consolidation

def HH = Highest(high[1], BarsUsedForRange);

def LL = Lowest(low[1], BarsUsedForRange);

def maxH = Highest(HH, BarsRequiredToRemainInRange);

def maxL = Lowest(LL, BarsRequiredToRemainInRange);

def HHn = if maxH == maxH[1] or maxL == maxL then maxH else HHn[1];

def LLn = if maxH == maxH[1] or maxL == maxL then maxL else LLn[1];

def Bh = if high <= HHn and HHn == HHn[1] then HHn else Double.NaN;

def Bl = if low >= LLn and LLn == LLn[1] then LLn else Double.NaN;

def CountH = if IsNaN(Bh) or IsNaN(Bl) then 2 else CountH[1] + 1;

def CountL = if IsNaN(Bh) or IsNaN(Bl) then 2 else CountL[1] + 1;

def ExpH = if BarNumber() == 1 then Double.NaN else

            if CountH[-BarsRequiredToRemainInRange] >= BarsRequiredToRemainInRange then HHn[-BarsRequiredToRemainInRange] else

            if high <= ExpH[1] then ExpH[1] else Double.NaN;

def ExpL = if BarNumber() == 1 then Double.NaN else

            if CountL[-BarsRequiredToRemainInRange] >= BarsRequiredToRemainInRange then LLn[-BarsRequiredToRemainInRange] else

            if low >= ExpL[1] then ExpL[1] else Double.NaN;

# Plot the High and Low of the Box; Paint Cloud
def BoxHigh = if ((DOWN_OB) or (Upper_BandS crosses above Upper_BandK2) or (condition_BandRevDn) and (high > high[1]) and ((price > Upper_BandK2) or (price > Upper_BandS))) then Highest(ExpH) else Double.NaN;#if (DOWN_OB > 3) then Highest(ExpH) else if (Condition_BandRevDn and (price > AvgExp) and (High > High[1])) then Highest(ExpH) else Double.NaN;

def BoxLow = if (DOWN_OB) or ((Upper_BandS crosses above Upper_BandK2)) then Lowest(low) else Double.NaN;#if (DOWN_OB crosses above 3) then Lowest(low) else if ((Upper_BandS crosses above Upper_BandK2)) then Lowest(ExpH) else Double.NaN;#if ((DOWN_OB) or (Condition_BandRevDn and (price < price[1]))) then Highest(ExpL) else Double.NaN;

def BoxHigh2 = if ((UP_OS) or ((Lower_BandS crosses below Lower_BandK2))) then Highest(ExpH) else Double.NaN; #if (UP_OS) then Highest(ExpH) else if ((Lower_BandS crosses below Lower_BandK2)) then Highest(ExpH) else Double.NaN;
def BH2 = if !IsNaN(BoxHigh2) then high else Double.NaN;
#BH2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#BH2.SetDefaultColor(Color.GREEN);
def BH2ext = if IsNaN(BH2) then BH2ext[1] else BH2;
def BH2extline = BH2ext;
#BH2extline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#BH2extline.SetDefaultColor(Color.GREEN);
#BH2extline.SetLineWeight(3);
plot H_BH2extline = Lowest(BH2extline, 1);
H_BH2extline.SetDefaultColor(Color.GREEN);

def BoxLow2 = if ((UP_OS) or (Lower_BandS crosses below Lower_BandK2) or (condition_BandRevUp) and (low < low[1]) and ((price < Lower_BandK2) or (price < Lower_BandS))) or ((UP_OS[1]) and (low < low[1])) then Lowest(low) else Double.NaN;#if (UP_OS) then Lowest(low) else if (Condition_BandRevUp and (price < AvgExp) and (Low < Low[1])) then Lowest(low) else Double.NaN;

# extend the current YCHigh line to the right edge of the chart
def BH1 = if !IsNaN(BoxHigh) then high else Double.NaN;
#BH1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#BH1.SetDefaultColor(Color.GREEN);
def BH1ext = if IsNaN(BH1) then BH1ext[1] else BH1;
def BH1extline = BH1ext;
#BH1extline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#BH1extline.SetDefaultColor(Color.GREEN);
#BH1extline.SetLineWeight(3);

def BL1 = if !IsNaN(BoxLow) then low else Double.NaN;
#BL1.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#BL1.SetDefaultColor(Color.RED);
def BL1ext = if IsNaN(BL1) then BL1ext[1] else BL1;
plot BL1extline = BL1ext;
BL1extline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
BL1extline.SetDefaultColor(Color.RED);
BL1extline.SetLineWeight(1);

#def BH2 = if !IsNaN(BoxHigh2) then high else Double.NaN;
#BH2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#BH2.SetDefaultColor(Color.GREEN);
#def BH2ext = if IsNaN(BH2) then BH2ext[1] else BH2;
#def BH2extline = BH2ext;
#BH2extline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#BH2extline.SetDefaultColor(Color.GREEN);
#BH2extline.SetLineWeight(3);

def BL2 = if !IsNaN(BoxLow2) then low else Double.NaN;
#BL2.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#BL2.SetDefaultColor(Color.RED);
def BL2ext = if IsNaN(BL2) then BL2ext[1] else BL2;
plot BL2extline = BL2ext;
BL2extline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
BL2extline.SetDefaultColor(Color.GREEN);
BL2extline.SetLineWeight(1);

plot H_BH1extline = Highest(BH1extline, 1);
H_BH1extline.SetDefaultColor(Color.RED);
plot L_BL1extline = Highest(BL1extline, 1);
L_BL1extline.SetDefaultColor(Color.RED);

#plot H_BH2extline = Lowest(BH2extline, 1);
#     H_BH2extline.SetDefaultColor(Color.Green);
plot L_BL2extline = Lowest(BL2extline, 1);
L_BL2extline.SetDefaultColor(Color.GREEN);

#plot L_BL1extline = Highest(BL1extline, 1);
#     L_BL1extline.SetDefaultColor(Color.Red);

#plot YCELOB = Highest(YHextlineOB, 1);
#     YCELOB.SetDefaultColor(Color.DARK_ORANGE);
#     YCELOB.SetLineWeight(2);
#plot YCELOS = Highest(YHextlineOS, 1);
#     YCELOS.SetDefaultColor(Color.LIGHT_GREEN);
#     YCELOS.SetLineWeight(2);

AddCloud(if !HideCloud then BH1extline else Double.NaN, BL1extline, Color.RED, Color.GRAY);
AddCloud(if !HideCloud then BH2extline else Double.NaN, BL2extline, Color.GREEN, Color.GRAY);

############################################################
##C3_MF_Line_v2 Created by Christopher84 03/06/2022 
############################################################
# 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 BulgeLengthPrice2 = 20;
def SqueezeLengthPrice2 = 20;
def BulgeLengthPrice3 = 12;
def SqueezeLengthPrice3 = 12;

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

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

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

##########################################################################################################################

script WMA_Smooth {
    input price = hl2;
    plot smooth = (4 * price
+ 3 * price[1]
+ 2 * price[2]
+ price[3]) / 10;
}

script Phase_Accumulation {
# This is Ehler's Phase Accumulation code. It has a full cycle delay.
# However, it computes the correction factor to a very high degree.
#
    input price = hl2;

    rec Smooth;
    rec Detrender;
    rec Period;
    rec Q1;
    rec I1;
    rec I1p;
    rec Q1p;
    rec Phase1;
    rec Phase;
    rec DeltaPhase;
    rec DeltaPhase1;
    rec InstPeriod1;
    rec InstPeriod;
    def CorrectionFactor;

    if BarNumber() <= 5
    then {
        Period = 0;
        Smooth = 0;
        Detrender = 0;
        CorrectionFactor = 0;
        Q1 = 0;
        I1 = 0;
        Q1p = 0;
        I1p = 0;
        Phase = 0;
        Phase1 = 0;
        DeltaPhase1 = 0;
        DeltaPhase = 0;
        InstPeriod = 0;
        InstPeriod1 = 0;
    } else {
        CorrectionFactor = 0.075 * Period[1] + 0.54;

# Smooth and detrend my smoothed signal:
        Smooth = WMA_Smooth(price);
        Detrender = ( 0.0962 * Smooth
+ 0.5769 * Smooth[2]
- 0.5769 * Smooth[4]
- 0.0962 * Smooth[6] ) * CorrectionFactor;

# Compute Quadrature and Phase of Detrended signal:
        Q1p = ( 0.0962 * Detrender
+ 0.5769 * Detrender[2]
- 0.5769 * Detrender[4]
- 0.0962 * Detrender[6] ) * CorrectionFactor;
        I1p = Detrender[3];

# Smooth out Quadrature and Phase:
        I1 = 0.15 * I1p + 0.85 * I1p[1];
        Q1 = 0.15 * Q1p + 0.85 * Q1p[1];

# Determine Phase
        if I1 != 0
        then {
# Normally, ATAN gives results from -pi/2 to pi/2.
# We need to map this to circular coordinates 0 to 2pi

            if Q1 >= 0 and I1 > 0
            then { # Quarant 1
                Phase1 = ATan(AbsValue(Q1 / I1));
            } else if Q1 >= 0 and I1 < 0
            then { # Quadrant 2
                Phase1 = Double.Pi - ATan(AbsValue(Q1 / I1));
            } else if Q1 < 0 and I1 < 0
            then { # Quadrant 3
                Phase1 = Double.Pi + ATan(AbsValue(Q1 / I1));
            } else { # Quadrant 4
                Phase1 = 2 * Double.Pi - ATan(AbsValue(Q1 / I1));
            }
        } else if Q1 > 0
        then { # I1 == 0, Q1 is positive
            Phase1 = Double.Pi / 2;
        } else if Q1 < 0
        then { # I1 == 0, Q1 is negative
            Phase1 = 3 * Double.Pi / 2;
        } else { # I1 and Q1 == 0
            Phase1 = 0;
        }

# Convert phase to degrees
        Phase = Phase1 * 180 / Double.Pi;

        if Phase[1] < 90 and Phase > 270
        then {
# This occurs when there is a big jump from 360-0
            DeltaPhase1 = 360 + Phase[1] - Phase;
        } else {
            DeltaPhase1 = Phase[1] - Phase;
        }

# Limit our delta phases between 7 and 60
        if DeltaPhase1 < 7
        then {
            DeltaPhase = 7;
        } else if DeltaPhase1 > 60
        then {
            DeltaPhase = 60;
        } else {
            DeltaPhase = DeltaPhase1;
        }

# Determine Instantaneous period:
        InstPeriod1 =
-1 * (fold i = 0 to 40 with v=0 do
if v < 0 then
v
else if v > 360 then
-i
else
v + GetValue(DeltaPhase, i, 41)
);

        if InstPeriod1 <= 0
        then {
            InstPeriod = InstPeriod[1];
        } else {
            InstPeriod = InstPeriod1;
        }

        Period = 0.25 * InstPeriod + 0.75 * Period[1];
    }
    plot DC = Period;
}

script Ehler_MAMA {
    input price = hl2;
    input FastLimit = 0.5;
    input SlowLimit = 0.05;


    rec Period;
    rec Period_raw;
    rec Period_cap;
    rec Period_lim;

    rec Smooth;
    rec Detrender;
    rec I1;
    rec Q1;
    rec jI;
    rec jQ;
    rec I2;
    rec Q2;
    rec I2_raw;
    rec Q2_raw;

    rec Phase;
    rec DeltaPhase;
    rec DeltaPhase_raw;
    rec alpha;
    rec alpha_raw;

    rec Re;
    rec Im;
    rec Re_raw;
    rec Im_raw;

    rec SmoothPeriod;
    rec vmama;
    rec vfama;

    def CorrectionFactor = Phase_Accumulation(price).CorrectionFactor;

    if BarNumber() <= 5
    then {
        Smooth = 0;
        Detrender = 0;

        Period = 0;
        Period_raw = 0;
        Period_cap = 0;
        Period_lim = 0;
        I1 = 0;
        Q1 = 0;
        I2 = 0;
        Q2 = 0;
        jI = 0;
        jQ = 0;
        I2_raw = 0;
        Q2_raw = 0;
        Re = 0;
        Im = 0;
        Re_raw = 0;
        Im_raw = 0;
        SmoothPeriod = 0;
        Phase = 0;
        DeltaPhase = 0;
        DeltaPhase_raw = 0;
        alpha = 0;
        alpha_raw = 0;
        vmama = 0;
        vfama = 0;
    } else {
# Smooth and detrend my smoothed signal:
        Smooth = WMA_Smooth(price);
        Detrender = ( 0.0962 * Smooth
+ 0.5769 * Smooth[2]
- 0.5769 * Smooth[4]
- 0.0962 * Smooth[6] ) * CorrectionFactor;

        Q1 = ( 0.0962 * Detrender
+ 0.5769 * Detrender[2]
- 0.5769 * Detrender[4]
- 0.0962 * Detrender[6] ) * CorrectionFactor;
        I1 = Detrender[3];

        jI = ( 0.0962 * I1
+ 0.5769 * I1[2]
- 0.5769 * I1[4]
- 0.0962 * I1[6] ) * CorrectionFactor;

        jQ = ( 0.0962 * Q1
+ 0.5769 * Q1[2]
- 0.5769 * Q1[4]
- 0.0962 * Q1[6] ) * CorrectionFactor;

# This is the complex conjugate
        I2_raw = I1 - jQ;
        Q2_raw = Q1 + jI;

        I2 = 0.2 * I2_raw + 0.8 * I2_raw[1];
        Q2 = 0.2 * Q2_raw + 0.8 * Q2_raw[1];

        Re_raw = I2 * I2[1] + Q2 * Q2[1];
        Im_raw = I2 * Q2[1] - Q2 * I2[1];

        Re = 0.2 * Re_raw + 0.8 * Re_raw[1];
        Im = 0.2 * Im_raw + 0.8 * Im_raw[1];

# Compute the phase
        if Re != 0 and Im != 0
        then {
            Period_raw = 2 * Double.Pi / ATan(Im / Re);
        } else {
            Period_raw = 0;
        }

        if Period_raw > 1.5 * Period_raw[1]
        then {
            Period_cap = 1.5 * Period_raw[1];
        } else if Period_raw < 0.67 * Period_raw[1] {
            Period_cap = 0.67 * Period_raw[1];
        } else {
            Period_cap = Period_raw;
        }

        if Period_cap < 6
        then {
            Period_lim = 6;
        } else if Period_cap > 50
        then {
            Period_lim = 50;
        } else {
            Period_lim = Period_cap;
        }

        Period = 0.2 * Period_lim + 0.8 * Period_lim[1];
        SmoothPeriod = 0.33 * Period + 0.67 * SmoothPeriod[1];

        if I1 != 0
        then {
            Phase = ATan(Q1 / I1);
        } else if Q1 > 0
        then { # Quadrant 1:
            Phase = Double.Pi / 2;
        } else if Q1 < 0
        then { # Quadrant 4:
            Phase = -Double.Pi / 2;
        } else { # Both numerator and denominator are 0.
            Phase = 0;
        }

        DeltaPhase_raw = Phase[1] - Phase;
        if DeltaPhase_raw < 1
        then {
            DeltaPhase = 1;
        } else {
            DeltaPhase = DeltaPhase_raw;
        }

        alpha_raw = FastLimit / DeltaPhase;
        if alpha_raw < SlowLimit
        then {
            alpha = SlowLimit;
        } else {
            alpha = alpha_raw;
        }
        vmama = alpha * price + (1 - alpha) * vmama[1];
        vfama = 0.5 * alpha * vmama + (1 - 0.5 * alpha) * vfama[1];
    }

    plot MAMA = vmama;
    plot FAMA = vfama;
}


def price2 = hl2;
def FastLimit = 0.5;
def SlowLimit = 0.05;

def MAMA = Ehler_MAMA(price2, FastLimit, SlowLimit).MAMA;
def FAMA = Ehler_MAMA(price2, FastLimit, SlowLimit).FAMA;

def Crossing = Crosses((MAMA < FAMA), yes);
#Crossing.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);

def Crossing1 = Crosses((MAMA > FAMA), yes);
#Crossing1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);

##################################
plot C3_MF_Line = (MAMA + FAMA) / 2;
C3_MF_Line.SetPaintingStrategy(PaintingStrategy.LINE);
C3_MF_Line.SetLineWeight(3);
C3_MF_Line.AssignValueColor(if ((priceColor == 1) and (price1 > Upper_BandS) and (condition_BandRevDn)) then Color.YELLOW else if ((priceColor == -1) and (price1 < Lower_BandS) and (condition_BandRevUp)) then Color.YELLOW else if priceColor == -1 then Color.RED  else if (priceColor == 1) then Color.GREEN else Color.CURRENT);

###################################
##Consensus Level & Squeeze Label
###################################

def MomentumUP = Consensus_Level[1] < Consensus_Level;
def MomentumDOWN = Consensus_Level[1] > Consensus_Level;

def Squeeze_Signal = !IsNaN(Squeeze_Alert);
def conditionOB = (Consensus_Level >= 12) and (Consensus_Line >= 4);
def conditionOS = (Consensus_Level <= -12) and (Consensus_Line <= -3);

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

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

Hi @Christopher84 and @HODL-Lay-HE-hoo!

I loaded this MTF TS strategy on a 1min chart, turned off signals from current TF (1min) so that only 2nd TF signals would show (15min), yet none of the signals match what TS is shown on an actual 15min chart. Please advise. Thank you!
 
Hello, can anyone help please. On Chrisfopher84 comfirmationcandleindicater video, on the Spx code version. could not find the lower study code for the one he had in the video. I really liked that one. …Jim
 
@HODL-Lay-HE-hoo! : Can you please post a video or some details as how this Indicator works and What are indicators it's using in underlying implementation. It will really help me understand How and Why as I am new to this thread.
If there is already some postings on this, please point me to that
I agree! A video or some details would be super helpful! It would be much appreciated!
 
@HODL-Lay-HE-hoo! : Can you please post a video or some details as how this Indicator works and What are indicators it's using in underlying implementation. It will really help me understand How and Why as I am new to this thread.
If there is already some postings on this, please point me to that

Well this is not a video but I do have pretty thorough explanations on my thread of the indicators found here (created by the man amongst men @Christopher84) used as a whole, individually, and most have brief explanations of the code used by the indications. On my thread the indicators have been modified slightly but nothing that changes the vast majority of original.

https://usethinkscript.com/threads/...-all-for-thinkorswim.15257/page-9#post-133070

There is a video by someone else…. I forgot his name but the dude is a hero. I’ll have to find it. Some day I will get around to making a video…
 
Is there a scanning code for Confirmation Code version10 which has Confirmation Level from 0 to 16 to scan for specific Confirmation Level or higher or lower?
 
Hi @Christopher84

I have taken the initiative of tackling the scanner "too complex" issue with the C3_Max_2 system. Unfortunately, the code base, as a whole, is too complex. However, when I divided the big scan into two scans (Confirmation Level and Super_OB_OS) the TOS system had no problem processing result sets.

Screenshot of successful scan configuration: https://ibb.co/rp2HJtJ

Below please find the code for your review. Hope this helps :cool:


Confirmation Level SCAN

Code:
# filename: Confirm_Lvl_SCAN
# source: https://usethinkscript.com/threads/confirmation-candles-indicator-for-thinkorswim.6316/post-61246

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

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

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

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

def condition1 = Value[1] <= Value;

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

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

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

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

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

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

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

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

def condition5 = CIP_UP;

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

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

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

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

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

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

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

def condition8 = Osc >= ZeroLine;

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

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

def condition9 = Periods > 0;

#Polarized Fractal Efficiency
input PFE_length = 5;
input smoothingLength = 2.5;

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

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

def condition10 = PFE > ZERoLine;

#Bollinger Bands PercentB
input BBPB_averageType = AverageType.Simple;
input BBPB_length = 20;
def Num_Dev_Dn = -2.0;
def Num_Dev_up = 2.0;

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

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

def condition11 = PercentB > 50;

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

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

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

def condition13 = (PROSC > 50);

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

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


def Factor_Line = Confirmation_Factor;

#AssignBackgroundColor(if Sell_Alert then color.DARK_RED else if Buy_Alert then color.DARK_GREEN else color.BLACK);
  
plot scan = Agreement_Level >= 13;


Super_OB_OS SCAN

Code:
# filename: SuperOBOS_SCAN

# filename: Super_OB_OS_WL
# source: https://usethinkscript.com/threads/confirmation-candles-indicator-for-thinkorswim.6316/post-61246

#Super_OB_OS_Lower
#Created by Christopher84 04/22/2021
#Modified 5/12/2021 Adjusted OB/OS levels.

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

#RSI
def price2 = close;
def RSI_length2 = 14;
def RSI_AverageType2 = AverageType.WILDERS;
def RSI_OB2 = 70;
def RSI_OS2 = 30;

def NetChgAvg2 = MovingAverage(RSI_AverageType2, price2 - price2[1], RSI_length2);
def TotChgAvg2 = MovingAverage(RSI_AverageType2, AbsValue(price2 - price2[1]), RSI_length2);
def ChgRatio2 = if TotChgAvg2 != 0 then NetChgAvg2 / TotChgAvg2 else 0;
def RSI2 = 50 * (ChgRatio2 + 1);

def conditionOB1 = RSI2 > RSI_OB2;
def conditionOS1 = RSI2 < RSI_OS2;

#MFI
def MFI_Length2 = 14;
def MFIover_Sold2 = 20;
def MFIover_Bought2 = 80;
def movingAvgLength2 = 1;
def MoneyFlowIndex2 = Average(moneyflow(high, close, low, volume, MFI_Length2), movingAvgLength2);

def conditionOB2 = MoneyFlowIndex2 > MFIover_Bought2;
def conditionOS2 = MoneyFlowIndex2 < MFIover_Sold2;

#Forecast
def na2 = Double.NaN;
def MidLine2 = 50;
def Momentum2 = MarketForecast().Momentum;
def NearT2 =  MarketForecast().NearTerm;
def Intermed2 = MarketForecast().Intermediate;
def FOB2 = 80;
def FOS2 = 20;
def upperLine2 = 110;

def conditionOB3 = Intermed2 > FOB2;
def conditionOS3 = Intermed2 < FOS2;

def conditionOB4 = NearT2 > FOB2;
def conditionOS4 = NearT2 < FOS2;

#Polarized Fractal Efficiency
def PFE_length2 = 5;#Typically 10
def smoothingLength2 = 2.5;#Typically 5
def PFE_diff2 = close - close[PFE_length2 - 1];
def val2 = 100 * Sqrt(Sqr(PFE_diff2) + Sqr(PFE_length2)) / sum(Sqrt(1 + Sqr(close - close[1])), PFE_length2 - 1);
def PFE2 = ExpAverage(if PFE_diff2 > 0 then val2 else -val2, smoothingLength2);
def UpperLevel2 = 50;
def LowerLevel2 = -50;

def conditionOB5 = PFE2 > UpperLevel2;
def conditionOS5 = PFE2 < LowerLevel2;

#Bollinger Bands PercentB
input BBPB_averageType2 = AverageType.Simple;
def displaced = 0;
def BBPB_length2 = 20;
def Num_Dev_Dn2 = -2.0;
def Num_Dev_up2 = 2.0;
def BBPB_OB2 = 100;
def BBPB_OS2 = 0;
def upperBand2 = BollingerBands(price2, displaced, BBPB_length2, Num_Dev_Dn2, Num_Dev_up2, BBPB_averageType2).UpperBand;
def lowerBand2 = BollingerBands(price2, displaced, BBPB_length2, Num_Dev_Dn2, Num_Dev_up2, BBPB_averageType2).LowerBand;
def PercentB2 = (price2 - lowerBand2) / (upperBand2 - lowerBand2) * 100;
def HalfLine2 = 50;
def UnitLine2 = 100;

def conditionOB6 = PercentB2 > BBPB_OB2;
def conditionOS6 = PercentB2 < BBPB_OS2;

#Projection Oscillator
def ProjectionOsc_length2 = 30;#Typically 10
def MaxBound2 = HighestWeighted(high, ProjectionOsc_length2, LinearRegressionSlope(price=high, length=ProjectionOsc_length2));
def MinBound2 = LowestWeighted(low, ProjectionOsc_length2, LinearRegressionSlope(price=low, length=ProjectionOsc_length2));
def ProjectionOsc_diff2 = MaxBound2 - MinBound2;
def PROSC2 = if ProjectionOsc_diff2 != 0 then 100 * (close - MinBound2) / ProjectionOsc_diff2 else 0;
def PROSC_OB2 = 80;
def PROSC_OS2 = 20;

def conditionOB7 = PROSC2 > PROSC_OB2;
def conditionOS7 = PROSC2 < PROSC_OS2;

#OB/OS Calculation

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

def Consensus_Line = OB_Level - OS_Level;

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

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

AssignBackgroundColor(if OB then color.DARK_RED else if OS then color.DARK_GREEN else color.BLACK);
  
  
plot scan = Consensus_Line >= 7;


Please note: The Confirmation Level and Super OB_OS WL Column code can be found on Page 1 of this thread...
Actually, that is what I also ended up doing.
 
@Christopher84 I'm just now starting back to trade after a 2 year break. I was using your CC V3 and enjoyed some good success, so thank you! I was wondering what is your latest version and lower study that I could use. Also, what is the latest scan you are suing to find potential trades. I think you mentioned it in the last YouTube video of yours I watched. Any help would be greatly appreciated.
 
@Christopher84 I'm just now starting back to trade after a 2 year break. I was using your CC V3 and enjoyed some good success, so thank you! I was wondering what is your latest version and lower study that I could use. Also, what is the latest scan you are suing to find potential trades. I think you mentioned it in the last YouTube video of yours I watched. Any help would be greatly appreciated.
pretty sure he is using C3 Max TS on page one
 

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
309 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