B4 Balanced BB Breakout For ThinkOrSwim

@Chuck the RSM indicator, which originally comes from PowerX by Markus Heitkoetter, is suggested to have the inputs to RSI, MACD and Stoch used for the indicator to be certain values. Do you change any of these values for your trading? Any one tweaks these params? If not, I’m going to hide them from the settings window in an effort to minimize and organize the input parameters.
 

New Indicator: Buy the Dip

Check out our Buy the Dip indicator and see how it can help you find profitable swing trading ideas. Scanner, watchlist columns, and add-ons are included.

Download the indicator

@Chuck the RSM indicator, which originally comes from PowerX by Markus Heitkoetter, is suggested to have the inputs to RSI, MACD and Stoch used for the indicator to be certain values. Do you change any of these values for your trading? Any one tweaks these params? If not, I’m going to hide them from the settings window in an effort to minimize and organize the input parameters.
I have changed them, but ended up putting them back. If you feel that’s best I trust your judgment.
 
I have changed them, but ended up putting them back. If you feel that’s best I trust your judgment.
@Chuck I see that RSM MACD length and MACD_BB length are tied together, and set to 25. RSM MACD length default is 9. Also, the RSM Stoch K Period is set to 5 instead of 14.

If I change these, I will end up effecting the past performance. Are these intentional changes?
 
@Chuck I see that RSM MACD length and MACD_BB length are tied together, and set to 25. RSM MACD length default is 9. Also, the RSM Stoch K Period is set to 5 instead of 14.

If I change these, I will end up effecting the past performance. Are these intentional changes?
A little color to the difference. Bottom is new with RSM fixed, and top is the current version.

I am inclined to leave it as-is, but let me know what you guys think.

d3kgTp2.png
 
Last edited:
A little color to the difference. Bottom is new with RSM fixed, and top is the current version.

I am inclined to leave it as-is, but let me know what you guys think.

d3kgTp2.png
I feel the bottom would be the most profitable. It is a little late at times, but I use it more for conformation than entry.
 
I feel the bottom would be the most profitable. It is a little late at times, but I use it more for conformation than entry.

Ok, are we confirming that we are going to make RSM as intended vs the original max you had? I have not backtested much, so no opinion there.

Also notice the MACD histogram change.
 
Ok, are we confirming that we are going to make RSM as intended vs the original max you had? I have not backtested much, so no opinion there.

Also notice the MACD histogram change.
As intended is probably better. Looking at it closely , MACD on the bottom actually looks like it depicts price action better. So I guess in my opinion the lower settings are better across the board.
 
Everyone, this is a beta version. There are good amount of changes and cleanup. Lets test it before making it an official version.

Code:
# Balanced BB Breakout Indicator
# Free for use. Header credits must be included when any form of the code included in this package is used.
# User assumes all risk. Author not responsible for errors or use of tool.
# v1.2 - Assembled by Chuck Edwards
# v2.0 - Barbaros - cleanup
# v2.1 - Barbaros - added RSI IFT, NumberOfShares, BB crossing options
# v2.2 - Barbaros - fixed PnL issues and removed intraDay filter
# BETA - Barbaros - added InSync, changed input and variable names, RSM is re-done

declare lower;

### Market Forecast

def pIntermediate = MarketForecast().Intermediate;

AddLabel(yes,
    "Market Forecast " +
    if pIntermediate >= 80 then "Bullish" else
    if pIntermediate <= 20 then "Bearish" else
    if pIntermediate > pIntermediate[1] then "Rising" else
    if pIntermediate < pIntermediate[1] then "Falling" else " ",
    if pIntermediate >= 80 then CreateColor(204, 255, 204) else # Pre_Cyan
    if pIntermediate <= 20 then Color.RED else
    if pIntermediate > pIntermediate[1] then CreateColor(0, 165, 0) else # LabelGreen
    if pIntermediate < pIntermediate[1] then Color.RED else Color.LIGHT_GRAY
);

### MACDBB

input MACDBB_FastLength = 12;
input MACDBB_SlowLength = 26;
input MACDBB_Length = 25;
input MACDBB_BandLength = 15;
input MACDBB_NumDev = 1.0;

def MACDBB_Data = MACD(fastLength = MACDBB_FastLength, slowLength = MACDBB_SlowLength, MACDLength = MACDBB_Length);
plot MACDBB_Dots = MACDBB_Data;
plot MACDBB_Line = MACDBB_Data;

plot MACDBB_Upper = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).UpperBand;
plot MACDBB_Lower = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).Lowerband;
plot MACDBB_Midline = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).MidLine;

MACDBB_Upper.SetDefaultColor(Color.RED);
MACDBB_Lower.SetDefaultColor(Color.GREEN);
MACDBB_Midline.SetDefaultColor(Color.LIGHT_RED);
MACDBB_Midline.SetStyle(Curve.FIRM);

MACDBB_Line.AssignValueColor(
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line >= MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line >= MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line <= MACDBB_Lower then Color.RED else
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line <= MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACDBB_Line.SetLineWeight(1);

MACDBB_Dots.AssignValueColor(
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.RED
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACDBB_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
MACDBB_Dots.SetLineWeight(1);

AddLabel(yes,
    "Trend " +
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then "Bullish"
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then "Falling"
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then "Bearish"
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then "Rising"
    else "Neutral",
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.RED
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);

### MACD BB Alert

input MACDBB_CrossFromAboveAlert = {default "Zero", "Lower", "Middle", "Upper"};
input MACDBB_CrossFromBelowAlert = {default "Zero", "Lower", "Middle", "Upper"};

def MACDBB_CrossFromAboveVal = if MACDBB_CrossFromAboveAlert == MACDBB_CrossFromAboveAlert.Lower then MACDBB_Lower
                               else if MACDBB_CrossFromAboveAlert == MACDBB_CrossFromAboveAlert.Upper then MACDBB_Upper
                              else 0;
def MACDBB_CrossFromBelowVal = if MACDBB_CrossFromBelowAlert == MACDBB_CrossFromBelowAlert.Lower then MACDBB_Lower
                               else if MACDBB_CrossFromBelowAlert == MACDBB_CrossFromBelowAlert.Upper then MACDBB_Upper
                               else 0;

Alert(MACDBB_Line crosses above MACDBB_CrossFromAboveVal, "Time to Buy", Alert.BAR, Sound.Chimes);
Alert(MACDBB_Line crosses below MACDBB_CrossFromBelowVal, "Time to Sell", Alert.BAR, Sound.Bell);

### Keltner Channels

input Keltner_Factor = 1.5;
input Keltner_length = 20;
input Keltner_AverageType = AverageType.EXPONENTIAL;
input Keltner_TrueRangeAverageType = AverageType.EXPONENTIAL;

def Keltner_Shift = Keltner_Factor * MovingAverage(Keltner_TrueRangeAverageType, TrueRange(high, close, low), Keltner_length);
def Keltner_Average = MovingAverage(Keltner_AverageType, close, Keltner_length);
def Keltner_Upper_Band = Keltner_Average + Keltner_Shift;
def Keltner_Lower_Band = Keltner_Average - Keltner_Shift;

### Bollinger Bands

input BB_Length = 20;
input BB_NumDevDn = -2.0;
input BB_NumDevUp = 2.0;
input BB_AverageType = AverageType.SIMPLE;

def BB_SDev = StDev(data = close, length = BB_Length);
def BB_MidLine = MovingAverage(BB_AverageType, data = close, length = BB_Length);
def BB_LowerBand = BB_MidLine + BB_NumDevDn * BB_SDev;
def BB_UpperBand = BB_MidLine + BB_NumDevUp * BB_SDev;

# BB Cloud

AddCloud(if BB_UpperBand <= Keltner_Upper_Band and BB_LowerBand >= Keltner_Lower_Band then MACDBB_Upper else MACDBB_Lower, MACDBB_Lower, Color.YELLOW);
AddCloud(MACDBB_Upper, MACDBB_Lower, Color.LIGHT_RED);

### RSI/STOCASTIC/MACD CONFLUENCE COMBO

input RSM_MACD_ShowBreakoutSignals = no;

plot RSM_MACD_Diff = reference MACD("fast length" = 12, "slow length" = 26, "macd length" = 9).Diff;
RSM_MACD_Diff.SetDefaultColor(GetColor(5));
RSM_MACD_Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
RSM_MACD_Diff.SetLineWeight(4);
RSM_MACD_Diff.DefineColor("Positive and Up", Color.GREEN);
RSM_MACD_Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
RSM_MACD_Diff.DefineColor("Negative and Down", Color.RED);
RSM_MACD_Diff.DefineColor("Negative and Up", Color.DARK_RED);
RSM_MACD_Diff.AssignValueColor(
    if RSM_MACD_Diff >= 0 then
        if RSM_MACD_Diff > RSM_MACD_Diff[1] then RSM_MACD_Diff.Color("Positive and Up") else RSM_MACD_Diff.Color("Positive and Down")
    else
        if RSM_MACD_Diff < RSM_MACD_Diff[1] then RSM_MACD_Diff.Color("Negative and Down") else RSM_MACD_Diff.Color("Negative and Up")
);

plot RSM_MACD_ZeroLine = 0;
RSM_MACD_ZeroLine.SetDefaultColor(Color.RED);
RSM_MACD_ZeroLine.HideTitle();
RSM_MACD_ZeroLine.HideBubble();

plot RSM_MACD_UpSignal = if RSM_MACD_Diff crosses above RSM_MACD_ZeroLine then RSM_MACD_ZeroLine else Double.NaN;
RSM_MACD_UpSignal.SetDefaultColor(Color.UPTICK);
RSM_MACD_UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
RSM_MACD_UpSignal.SetHiding(!RSM_MACD_ShowBreakoutSignals);

plot RSM_MACD_DownSignal = if RSM_MACD_Diff crosses below RSM_MACD_ZeroLine then RSM_MACD_ZeroLine else Double.NaN;
RSM_MACD_DownSignal.SetDefaultColor(Color.DOWNTICK);
RSM_MACD_DownSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
RSM_MACD_DownSignal.SetHiding(!RSM_MACD_ShowBreakoutSignals);

def RSM_RSI = reference RSI(length = 7).RSI;

def RSM_Stoch_Val = 100 * (close - lowest(low, 14)) / (highest(high, 14) - lowest(low, 14));
def RSM_StochSlowK = SimpleMovingAvg(SimpleMovingAvg(RSM_Stoch_Val,3),3);

def RSM_rsiGreen = RSM_RSI >= 50;
def RSM_rsiRed = RSM_RSI < 50;
def RSM_stochGreen = RSM_StochSlowK >= 50;
def RSM_stochRed = RSM_StochSlowK < 50;
def RSM_macdGreen = RSM_MACD_Diff >= 0;
def RSM_macdRed = RSM_MACD_Diff < 0;

input RSM_PaintBars = yes;
AssignPriceColor(
    if RSM_PaintBars and RSM_rsiGreen and RSM_stochGreen and RSM_macdGreen then Color.GREEN
    else if RSM_PaintBars and RSM_rsiRed and RSM_stochRed and RSM_macdRed then Color.RED
    else if RSM_PaintBars then Color.DARK_GRAY
    else Color.CURRENT
);

# Shade areas based on criteria; adjust as needed

AddCloud(
    if RSM_rsiGreen and RSM_stochGreen and RSM_macdGreen then Double.POSITIVE_INFINITY else Double.NaN,
    if RSM_rsiGreen and RSM_stochGreen then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_GREEN
);
AddCloud(
    if RSM_rsiRed and RSM_stochRed and RSM_macdRed then Double.POSITIVE_INFINITY else Double.NaN,
    if RSM_rsiRed and RSM_stochRed then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_RED
);

### Balance of Power

input BOP_EMA_Length = 20;
input BOP_TEMA_Length = 20;

def BOP_THL = If(high != low, high - low, 0.01);
def BOP_BullOpen = (high - open) / BOP_THL;
def BOP_BearOpen = (open - low) / BOP_THL;
def BOP_BullClose = (close - low) / BOP_THL;
def BOP_BearClose = (high - close) / BOP_THL;
def BOP_BullOC = If(close > open, (close - open) / BOP_THL, 0);
def BOP_BearOC = If(open > close, (open - close) / BOP_THL, 0);
def BOP_BullReward = (BOP_BullOpen + BOP_BullClose + BOP_BullOC) / 1;
def BOP_BearReward = (BOP_BearOpen + BOP_BearClose + BOP_BearOC) / 1;

def BOP_BOP = BOP_BullReward - BOP_BearReward;
def BOP_SmoothBOP = ExpAverage(BOP_BOP, BOP_EMA_Length);
def BOP_xPrice = BOP_SmoothBOP;
def BOP_xEMA1 = ExpAverage(BOP_SmoothBOP, BOP_TEMA_Length);
def BOP_xEMA2 = ExpAverage(BOP_xEMA1, BOP_TEMA_Length);
def BOP_xEMA3 = ExpAverage(BOP_xEMA2, BOP_TEMA_Length);
def BOP_nRes = 3 * BOP_xEMA1 - 3 * BOP_xEMA2 + BOP_xEMA3;

def BOP_SmootherBOP = BOP_nRes;
def BOP_s1 = BOP_SmoothBOP;
def BOP_s2 = BOP_SmootherBOP;
def BOP_s3 = BOP_SmootherBOP[2];

def BOP_Sell = BOP_s2 < BOP_s3 and BOP_s2[1] > BOP_s3[1];
def BOP_Buy = BOP_s2 > BOP_s3 and BOP_s2[1] < BOP_s3[1];

### RSI IFT

def RSI_IFT_R = reference RSI(5, close) - 50;
def RSI_IFT_AvgRSI = MovingAverage(AverageType.Exponential,RSI_IFT_R,9);
def RSI_IFT_InverseRSI = (Power(Double.E, 2 * RSI_IFT_AvgRSI) - 1) / (Power(Double.E, 2 * RSI_IFT_AvgRSI) + 1);
def RSI_IFT_Buy =  (RSI_IFT_InverseRSI > 0) and (RSI_IFT_InverseRSI[1] < 0);
def RSI_IFT_Sell = (RSI_IFT_InverseRSI[1] > 0) and (RSI_IFT_InverseRSI < 0);

### InSync

input InSync_Smooth = 1;

# Study Definitions
def InSync_bbCalc = bollingerPercentB();
def InSync_macd1 = MACD(8, 17);
def InSync_macd2 = InSync_macd1 - (MACD(8, 10) - MACD(17, 20));
def InSync_rsi = reference RSI(length = 2);
def InSync_change = RateOfChange(10);
def InSync_dpo = DetrendedPriceOsc();
def InSync_eom = EaseOfMovement();
def InSync_mf = MoneyFlowIndex();
def InSync_stoch = StochasticFull("k period" = 5);
def InSync_bomp = BalanceOfMarketPower();
def InSync_cc = CCI();

# Indicator Scoring
def InSync_bb = if InSync_bbCalc > 95 then 5 else if InSync_bbCalc < 5 then -5 else 0;
def InSync_cci = if InSync_cc > 100 then 5 else if InSync_cc < -100 then -5 else 0;
def InSync_macd = if InSync_macd1 > 0 and InSync_macd2 > 0 then 5 else if InSync_macd1 < 0 and InSync_macd2 < 0 then -5 else 0;
def InSync_roc = if InSync_change > 1 and InSync_change > ExpAverage(InSync_change, 10) then 5 else if InSync_change < 1 and InSync_change < ExpAverage(InSync_change, 10) then -5 else 0;
def InSync_sto = if InSync_stoch > 80 then 10 else if InSync_stoch < 20 then -10 else 0;
def InSync_rsiW = if InSync_rsi > 95 then 5 else if InSync_rsi < 5 then -5 else 0;
def InSync_bop = if InSync_bomp > 0 and InSync_bomp > ExpAverage(InSync_bomp, 10) then 5 else if InSync_bomp < 0 and InSync_bomp < ExpAverage(InSync_bomp, 10) then
-5 else 0;
def InSync_dp = if InSync_dpo > 0 then 5 else if InSync_dpo < 0 then -5 else 0;
def InSync_emv = if InSync_eom > 0 then 5 else if InSync_eom < 0 then -5 else 0;
def InSync_mfi = if InSync_mf > 50 then 5 else if InSync_mf < 40 then -5 else 0;

# Point Sum
def InSync_sum = InSync_bb + InSync_cci + InSync_macd + InSync_roc + InSync_sto + InSync_rsiW + InSync_bop + InSync_dp + InSync_emv + InSync_mfi;

# Value
def InSync_Val = ExpAverage(InSync_sum, InSync_smooth);
def InSync_Buy = (InSync_Val > 0) and (InSync_Val[1] <= 0) and (InSync_Val[2] <= 0);
def InSync_Sell = (InSync_Val < 0) and (InSync_Val[1] >= 0) and (InSync_Val[2] >= 0);

### Vertical Buy/Sell Signals

input BuySellStrategy = { "BalanceOfPower", "InSync", default "RSI_IFT" };

AddVerticalLine(

    if BuySellStrategy == BuySellStrategy.BalanceOfPower then BOP_Sell
    else if BuySellStrategy == BuySellStrategy.InSync then InSync_Sell
    else RSI_IFT_Sell,

    close, Color.RED, Curve.SHORT_DASH);

AddVerticalLine(
    
    if BuySellStrategy == BuySellStrategy.BalanceOfPower then BOP_Buy
    else if BuySellStrategy == BuySellStrategy.InSync then InSync_Buy
    else RSI_IFT_Buy,

    close, Color.GREEN, Curve.SHORT_DASH);

### P/L Statement

input PandL_Label = No;
input NumOfShares = 1;

Assert(NumOfShares >= 1, "Number of Shares needs to be equal or grater than 1");

def orderDir =  CompoundValue(1,
                        if BuySellStrategy == BuySellStrategy.BalanceOfPower then
                            if BOP_Buy then 1 else if BOP_Sell then -1 else orderDir[1]
                        else if BuySellStrategy == BuySellStrategy.InSync then
                            if InSync_Buy then 1 else if InSync_Sell then -1 else orderDir[1]
                        else
                            if RSI_IFT_Buy then 1 else if RSI_IFT_Sell then -1 else orderDir[1]
                , 0);
def isOrder = orderDir crosses 0;
def orderCount = CompoundValue(1, if IsNaN(isOrder) then 0 else if isOrder then orderCount[1] + 1 else orderCount[1], 0);
def noBar = IsNaN(open[-1]);
def orderPrice = if isOrder then if noBar then close else open[-1] else orderPrice[1];
def profitLoss = if !isOrder or orderCount == 1 then 0
                else if orderDir > 0 then orderPrice[1] - orderPrice
                else if orderDir < 0 then orderPrice - orderPrice[1]
                else 0;
def profitLossSum = CompoundValue(1, if IsNaN(isOrder) then 0 else if isOrder then profitLossSum[1] + profitLoss else profitLossSum[1], 0);
def orderWinners = CompoundValue(1, if IsNaN(isOrder) then orderWinners[1] else if orderCount > 1 and profitLoss > 0 then orderWinners[1] + 1 else orderWinners[1], 0);

AddLabel(PandL_Label,
    orderCount + " orders (" + AsPercent(orderWinners / orderCount) + ") | P/L " + AsDollars ((profitLossSum / TickSize()) * TickValue() * NumOfShares),
    if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY
);
 
Everyone, this is a beta version. There are good amount of changes and cleanup. Lets test it before making it an official version.

Code:
# Balanced BB Breakout Indicator
# Free for use. Header credits must be included when any form of the code included in this package is used.
# User assumes all risk. Author not responsible for errors or use of tool.
# v1.2 - Assembled by Chuck Edwards
# v2.0 - Barbaros - cleanup
# v2.1 - Barbaros - added RSI IFT, NumberOfShares, BB crossing options
# v2.2 - Barbaros - fixed PnL issues and removed intraDay filter
# BETA - Barbaros - added InSync, changed input and variable names, RSM is re-done

declare lower;

### Market Forecast

def pIntermediate = MarketForecast().Intermediate;

AddLabel(yes,
    "Market Forecast " +
    if pIntermediate >= 80 then "Bullish" else
    if pIntermediate <= 20 then "Bearish" else
    if pIntermediate > pIntermediate[1] then "Rising" else
    if pIntermediate < pIntermediate[1] then "Falling" else " ",
    if pIntermediate >= 80 then CreateColor(204, 255, 204) else # Pre_Cyan
    if pIntermediate <= 20 then Color.RED else
    if pIntermediate > pIntermediate[1] then CreateColor(0, 165, 0) else # LabelGreen
    if pIntermediate < pIntermediate[1] then Color.RED else Color.LIGHT_GRAY
);

### MACDBB

input MACDBB_FastLength = 12;
input MACDBB_SlowLength = 26;
input MACDBB_Length = 25;
input MACDBB_BandLength = 15;
input MACDBB_NumDev = 1.0;

def MACDBB_Data = MACD(fastLength = MACDBB_FastLength, slowLength = MACDBB_SlowLength, MACDLength = MACDBB_Length);
plot MACDBB_Dots = MACDBB_Data;
plot MACDBB_Line = MACDBB_Data;

plot MACDBB_Upper = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).UpperBand;
plot MACDBB_Lower = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).Lowerband;
plot MACDBB_Midline = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).MidLine;

MACDBB_Upper.SetDefaultColor(Color.RED);
MACDBB_Lower.SetDefaultColor(Color.GREEN);
MACDBB_Midline.SetDefaultColor(Color.LIGHT_RED);
MACDBB_Midline.SetStyle(Curve.FIRM);

MACDBB_Line.AssignValueColor(
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line >= MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line >= MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line <= MACDBB_Lower then Color.RED else
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line <= MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACDBB_Line.SetLineWeight(1);

MACDBB_Dots.AssignValueColor(
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.RED
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACDBB_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
MACDBB_Dots.SetLineWeight(1);

AddLabel(yes,
    "Trend " +
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then "Bullish"
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then "Falling"
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then "Bearish"
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then "Rising"
    else "Neutral",
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.RED
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);

### MACD BB Alert

input MACDBB_CrossFromAboveAlert = {default "Zero", "Lower", "Middle", "Upper"};
input MACDBB_CrossFromBelowAlert = {default "Zero", "Lower", "Middle", "Upper"};

def MACDBB_CrossFromAboveVal = if MACDBB_CrossFromAboveAlert == MACDBB_CrossFromAboveAlert.Lower then MACDBB_Lower
                               else if MACDBB_CrossFromAboveAlert == MACDBB_CrossFromAboveAlert.Upper then MACDBB_Upper
                              else 0;
def MACDBB_CrossFromBelowVal = if MACDBB_CrossFromBelowAlert == MACDBB_CrossFromBelowAlert.Lower then MACDBB_Lower
                               else if MACDBB_CrossFromBelowAlert == MACDBB_CrossFromBelowAlert.Upper then MACDBB_Upper
                               else 0;

Alert(MACDBB_Line crosses above MACDBB_CrossFromAboveVal, "Time to Buy", Alert.BAR, Sound.Chimes);
Alert(MACDBB_Line crosses below MACDBB_CrossFromBelowVal, "Time to Sell", Alert.BAR, Sound.Bell);

### Keltner Channels

input Keltner_Factor = 1.5;
input Keltner_length = 20;
input Keltner_AverageType = AverageType.EXPONENTIAL;
input Keltner_TrueRangeAverageType = AverageType.EXPONENTIAL;

def Keltner_Shift = Keltner_Factor * MovingAverage(Keltner_TrueRangeAverageType, TrueRange(high, close, low), Keltner_length);
def Keltner_Average = MovingAverage(Keltner_AverageType, close, Keltner_length);
def Keltner_Upper_Band = Keltner_Average + Keltner_Shift;
def Keltner_Lower_Band = Keltner_Average - Keltner_Shift;

### Bollinger Bands

input BB_Length = 20;
input BB_NumDevDn = -2.0;
input BB_NumDevUp = 2.0;
input BB_AverageType = AverageType.SIMPLE;

def BB_SDev = StDev(data = close, length = BB_Length);
def BB_MidLine = MovingAverage(BB_AverageType, data = close, length = BB_Length);
def BB_LowerBand = BB_MidLine + BB_NumDevDn * BB_SDev;
def BB_UpperBand = BB_MidLine + BB_NumDevUp * BB_SDev;

# BB Cloud

AddCloud(if BB_UpperBand <= Keltner_Upper_Band and BB_LowerBand >= Keltner_Lower_Band then MACDBB_Upper else MACDBB_Lower, MACDBB_Lower, Color.YELLOW);
AddCloud(MACDBB_Upper, MACDBB_Lower, Color.LIGHT_RED);

### RSI/STOCASTIC/MACD CONFLUENCE COMBO

input RSM_MACD_ShowBreakoutSignals = no;

plot RSM_MACD_Diff = reference MACD("fast length" = 12, "slow length" = 26, "macd length" = 9).Diff;
RSM_MACD_Diff.SetDefaultColor(GetColor(5));
RSM_MACD_Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
RSM_MACD_Diff.SetLineWeight(4);
RSM_MACD_Diff.DefineColor("Positive and Up", Color.GREEN);
RSM_MACD_Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
RSM_MACD_Diff.DefineColor("Negative and Down", Color.RED);
RSM_MACD_Diff.DefineColor("Negative and Up", Color.DARK_RED);
RSM_MACD_Diff.AssignValueColor(
    if RSM_MACD_Diff >= 0 then
        if RSM_MACD_Diff > RSM_MACD_Diff[1] then RSM_MACD_Diff.Color("Positive and Up") else RSM_MACD_Diff.Color("Positive and Down")
    else
        if RSM_MACD_Diff < RSM_MACD_Diff[1] then RSM_MACD_Diff.Color("Negative and Down") else RSM_MACD_Diff.Color("Negative and Up")
);

plot RSM_MACD_ZeroLine = 0;
RSM_MACD_ZeroLine.SetDefaultColor(Color.RED);
RSM_MACD_ZeroLine.HideTitle();
RSM_MACD_ZeroLine.HideBubble();

plot RSM_MACD_UpSignal = if RSM_MACD_Diff crosses above RSM_MACD_ZeroLine then RSM_MACD_ZeroLine else Double.NaN;
RSM_MACD_UpSignal.SetDefaultColor(Color.UPTICK);
RSM_MACD_UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
RSM_MACD_UpSignal.SetHiding(!RSM_MACD_ShowBreakoutSignals);

plot RSM_MACD_DownSignal = if RSM_MACD_Diff crosses below RSM_MACD_ZeroLine then RSM_MACD_ZeroLine else Double.NaN;
RSM_MACD_DownSignal.SetDefaultColor(Color.DOWNTICK);
RSM_MACD_DownSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
RSM_MACD_DownSignal.SetHiding(!RSM_MACD_ShowBreakoutSignals);

def RSM_RSI = reference RSI(length = 7).RSI;

def RSM_Stoch_Val = 100 * (close - lowest(low, 14)) / (highest(high, 14) - lowest(low, 14));
def RSM_StochSlowK = SimpleMovingAvg(SimpleMovingAvg(RSM_Stoch_Val,3),3);

def RSM_rsiGreen = RSM_RSI >= 50;
def RSM_rsiRed = RSM_RSI < 50;
def RSM_stochGreen = RSM_StochSlowK >= 50;
def RSM_stochRed = RSM_StochSlowK < 50;
def RSM_macdGreen = RSM_MACD_Diff >= 0;
def RSM_macdRed = RSM_MACD_Diff < 0;

input RSM_PaintBars = yes;
AssignPriceColor(
    if RSM_PaintBars and RSM_rsiGreen and RSM_stochGreen and RSM_macdGreen then Color.GREEN
    else if RSM_PaintBars and RSM_rsiRed and RSM_stochRed and RSM_macdRed then Color.RED
    else if RSM_PaintBars then Color.DARK_GRAY
    else Color.CURRENT
);

# Shade areas based on criteria; adjust as needed

AddCloud(
    if RSM_rsiGreen and RSM_stochGreen and RSM_macdGreen then Double.POSITIVE_INFINITY else Double.NaN,
    if RSM_rsiGreen and RSM_stochGreen then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_GREEN
);
AddCloud(
    if RSM_rsiRed and RSM_stochRed and RSM_macdRed then Double.POSITIVE_INFINITY else Double.NaN,
    if RSM_rsiRed and RSM_stochRed then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_RED
);

### Balance of Power

input BOP_EMA_Length = 20;
input BOP_TEMA_Length = 20;

def BOP_THL = If(high != low, high - low, 0.01);
def BOP_BullOpen = (high - open) / BOP_THL;
def BOP_BearOpen = (open - low) / BOP_THL;
def BOP_BullClose = (close - low) / BOP_THL;
def BOP_BearClose = (high - close) / BOP_THL;
def BOP_BullOC = If(close > open, (close - open) / BOP_THL, 0);
def BOP_BearOC = If(open > close, (open - close) / BOP_THL, 0);
def BOP_BullReward = (BOP_BullOpen + BOP_BullClose + BOP_BullOC) / 1;
def BOP_BearReward = (BOP_BearOpen + BOP_BearClose + BOP_BearOC) / 1;

def BOP_BOP = BOP_BullReward - BOP_BearReward;
def BOP_SmoothBOP = ExpAverage(BOP_BOP, BOP_EMA_Length);
def BOP_xPrice = BOP_SmoothBOP;
def BOP_xEMA1 = ExpAverage(BOP_SmoothBOP, BOP_TEMA_Length);
def BOP_xEMA2 = ExpAverage(BOP_xEMA1, BOP_TEMA_Length);
def BOP_xEMA3 = ExpAverage(BOP_xEMA2, BOP_TEMA_Length);
def BOP_nRes = 3 * BOP_xEMA1 - 3 * BOP_xEMA2 + BOP_xEMA3;

def BOP_SmootherBOP = BOP_nRes;
def BOP_s1 = BOP_SmoothBOP;
def BOP_s2 = BOP_SmootherBOP;
def BOP_s3 = BOP_SmootherBOP[2];

def BOP_Sell = BOP_s2 < BOP_s3 and BOP_s2[1] > BOP_s3[1];
def BOP_Buy = BOP_s2 > BOP_s3 and BOP_s2[1] < BOP_s3[1];

### RSI IFT

def RSI_IFT_R = reference RSI(5, close) - 50;
def RSI_IFT_AvgRSI = MovingAverage(AverageType.Exponential,RSI_IFT_R,9);
def RSI_IFT_InverseRSI = (Power(Double.E, 2 * RSI_IFT_AvgRSI) - 1) / (Power(Double.E, 2 * RSI_IFT_AvgRSI) + 1);
def RSI_IFT_Buy =  (RSI_IFT_InverseRSI > 0) and (RSI_IFT_InverseRSI[1] < 0);
def RSI_IFT_Sell = (RSI_IFT_InverseRSI[1] > 0) and (RSI_IFT_InverseRSI < 0);

### InSync

input InSync_Smooth = 1;

# Study Definitions
def InSync_bbCalc = bollingerPercentB();
def InSync_macd1 = MACD(8, 17);
def InSync_macd2 = InSync_macd1 - (MACD(8, 10) - MACD(17, 20));
def InSync_rsi = reference RSI(length = 2);
def InSync_change = RateOfChange(10);
def InSync_dpo = DetrendedPriceOsc();
def InSync_eom = EaseOfMovement();
def InSync_mf = MoneyFlowIndex();
def InSync_stoch = StochasticFull("k period" = 5);
def InSync_bomp = BalanceOfMarketPower();
def InSync_cc = CCI();

# Indicator Scoring
def InSync_bb = if InSync_bbCalc > 95 then 5 else if InSync_bbCalc < 5 then -5 else 0;
def InSync_cci = if InSync_cc > 100 then 5 else if InSync_cc < -100 then -5 else 0;
def InSync_macd = if InSync_macd1 > 0 and InSync_macd2 > 0 then 5 else if InSync_macd1 < 0 and InSync_macd2 < 0 then -5 else 0;
def InSync_roc = if InSync_change > 1 and InSync_change > ExpAverage(InSync_change, 10) then 5 else if InSync_change < 1 and InSync_change < ExpAverage(InSync_change, 10) then -5 else 0;
def InSync_sto = if InSync_stoch > 80 then 10 else if InSync_stoch < 20 then -10 else 0;
def InSync_rsiW = if InSync_rsi > 95 then 5 else if InSync_rsi < 5 then -5 else 0;
def InSync_bop = if InSync_bomp > 0 and InSync_bomp > ExpAverage(InSync_bomp, 10) then 5 else if InSync_bomp < 0 and InSync_bomp < ExpAverage(InSync_bomp, 10) then
-5 else 0;
def InSync_dp = if InSync_dpo > 0 then 5 else if InSync_dpo < 0 then -5 else 0;
def InSync_emv = if InSync_eom > 0 then 5 else if InSync_eom < 0 then -5 else 0;
def InSync_mfi = if InSync_mf > 50 then 5 else if InSync_mf < 40 then -5 else 0;

# Point Sum
def InSync_sum = InSync_bb + InSync_cci + InSync_macd + InSync_roc + InSync_sto + InSync_rsiW + InSync_bop + InSync_dp + InSync_emv + InSync_mfi;

# Value
def InSync_Val = ExpAverage(InSync_sum, InSync_smooth);
def InSync_Buy = (InSync_Val > 0) and (InSync_Val[1] <= 0) and (InSync_Val[2] <= 0);
def InSync_Sell = (InSync_Val < 0) and (InSync_Val[1] >= 0) and (InSync_Val[2] >= 0);

### Vertical Buy/Sell Signals

input BuySellStrategy = { "BalanceOfPower", "InSync", default "RSI_IFT" };

AddVerticalLine(

    if BuySellStrategy == BuySellStrategy.BalanceOfPower then BOP_Sell
    else if BuySellStrategy == BuySellStrategy.InSync then InSync_Sell
    else RSI_IFT_Sell,

    close, Color.RED, Curve.SHORT_DASH);

AddVerticalLine(
   
    if BuySellStrategy == BuySellStrategy.BalanceOfPower then BOP_Buy
    else if BuySellStrategy == BuySellStrategy.InSync then InSync_Buy
    else RSI_IFT_Buy,

    close, Color.GREEN, Curve.SHORT_DASH);

### P/L Statement

input PandL_Label = No;
input NumOfShares = 1;

Assert(NumOfShares >= 1, "Number of Shares needs to be equal or grater than 1");

def orderDir =  CompoundValue(1,
                        if BuySellStrategy == BuySellStrategy.BalanceOfPower then
                            if BOP_Buy then 1 else if BOP_Sell then -1 else orderDir[1]
                        else if BuySellStrategy == BuySellStrategy.InSync then
                            if InSync_Buy then 1 else if InSync_Sell then -1 else orderDir[1]
                        else
                            if RSI_IFT_Buy then 1 else if RSI_IFT_Sell then -1 else orderDir[1]
                , 0);
def isOrder = orderDir crosses 0;
def orderCount = CompoundValue(1, if IsNaN(isOrder) then 0 else if isOrder then orderCount[1] + 1 else orderCount[1], 0);
def noBar = IsNaN(open[-1]);
def orderPrice = if isOrder then if noBar then close else open[-1] else orderPrice[1];
def profitLoss = if !isOrder or orderCount == 1 then 0
                else if orderDir > 0 then orderPrice[1] - orderPrice
                else if orderDir < 0 then orderPrice - orderPrice[1]
                else 0;
def profitLossSum = CompoundValue(1, if IsNaN(isOrder) then 0 else if isOrder then profitLossSum[1] + profitLoss else profitLossSum[1], 0);
def orderWinners = CompoundValue(1, if IsNaN(isOrder) then orderWinners[1] else if orderCount > 1 and profitLoss > 0 then orderWinners[1] + 1 else orderWinners[1], 0);

AddLabel(PandL_Label,
    orderCount + " orders (" + AsPercent(orderWinners / orderCount) + ") | P/L " + AsDollars ((profitLossSum / TickSize()) * TickValue() * NumOfShares),
    if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY
);
@barbaros Looks like this version of code is not working for SPX while the previous version was working. Meaning the indicator is not showing up at all as a lower study now.
 
Everyone, this is a beta version. There are good amount of changes and cleanup. Lets test it before making it an official version.

Code:
# Balanced BB Breakout Indicator
# Free for use. Header credits must be included when any form of the code included in this package is used.
# User assumes all risk. Author not responsible for errors or use of tool.
# v1.2 - Assembled by Chuck Edwards
# v2.0 - Barbaros - cleanup
# v2.1 - Barbaros - added RSI IFT, NumberOfShares, BB crossing options
# v2.2 - Barbaros - fixed PnL issues and removed intraDay filter
# BETA - Barbaros - added InSync, changed input and variable names, RSM is re-done

declare lower;

### Market Forecast

def pIntermediate = MarketForecast().Intermediate;

AddLabel(yes,
    "Market Forecast " +
    if pIntermediate >= 80 then "Bullish" else
    if pIntermediate <= 20 then "Bearish" else
    if pIntermediate > pIntermediate[1] then "Rising" else
    if pIntermediate < pIntermediate[1] then "Falling" else " ",
    if pIntermediate >= 80 then CreateColor(204, 255, 204) else # Pre_Cyan
    if pIntermediate <= 20 then Color.RED else
    if pIntermediate > pIntermediate[1] then CreateColor(0, 165, 0) else # LabelGreen
    if pIntermediate < pIntermediate[1] then Color.RED else Color.LIGHT_GRAY
);

### MACDBB

input MACDBB_FastLength = 12;
input MACDBB_SlowLength = 26;
input MACDBB_Length = 25;
input MACDBB_BandLength = 15;
input MACDBB_NumDev = 1.0;

def MACDBB_Data = MACD(fastLength = MACDBB_FastLength, slowLength = MACDBB_SlowLength, MACDLength = MACDBB_Length);
plot MACDBB_Dots = MACDBB_Data;
plot MACDBB_Line = MACDBB_Data;

plot MACDBB_Upper = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).UpperBand;
plot MACDBB_Lower = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).Lowerband;
plot MACDBB_Midline = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).MidLine;

MACDBB_Upper.SetDefaultColor(Color.RED);
MACDBB_Lower.SetDefaultColor(Color.GREEN);
MACDBB_Midline.SetDefaultColor(Color.LIGHT_RED);
MACDBB_Midline.SetStyle(Curve.FIRM);

MACDBB_Line.AssignValueColor(
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line >= MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line >= MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line <= MACDBB_Lower then Color.RED else
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line <= MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACDBB_Line.SetLineWeight(1);

MACDBB_Dots.AssignValueColor(
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.RED
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACDBB_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
MACDBB_Dots.SetLineWeight(1);

AddLabel(yes,
    "Trend " +
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then "Bullish"
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then "Falling"
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then "Bearish"
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then "Rising"
    else "Neutral",
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.RED
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);

### MACD BB Alert

input MACDBB_CrossFromAboveAlert = {default "Zero", "Lower", "Middle", "Upper"};
input MACDBB_CrossFromBelowAlert = {default "Zero", "Lower", "Middle", "Upper"};

def MACDBB_CrossFromAboveVal = if MACDBB_CrossFromAboveAlert == MACDBB_CrossFromAboveAlert.Lower then MACDBB_Lower
                               else if MACDBB_CrossFromAboveAlert == MACDBB_CrossFromAboveAlert.Upper then MACDBB_Upper
                              else 0;
def MACDBB_CrossFromBelowVal = if MACDBB_CrossFromBelowAlert == MACDBB_CrossFromBelowAlert.Lower then MACDBB_Lower
                               else if MACDBB_CrossFromBelowAlert == MACDBB_CrossFromBelowAlert.Upper then MACDBB_Upper
                               else 0;

Alert(MACDBB_Line crosses above MACDBB_CrossFromAboveVal, "Time to Buy", Alert.BAR, Sound.Chimes);
Alert(MACDBB_Line crosses below MACDBB_CrossFromBelowVal, "Time to Sell", Alert.BAR, Sound.Bell);

### Keltner Channels

input Keltner_Factor = 1.5;
input Keltner_length = 20;
input Keltner_AverageType = AverageType.EXPONENTIAL;
input Keltner_TrueRangeAverageType = AverageType.EXPONENTIAL;

def Keltner_Shift = Keltner_Factor * MovingAverage(Keltner_TrueRangeAverageType, TrueRange(high, close, low), Keltner_length);
def Keltner_Average = MovingAverage(Keltner_AverageType, close, Keltner_length);
def Keltner_Upper_Band = Keltner_Average + Keltner_Shift;
def Keltner_Lower_Band = Keltner_Average - Keltner_Shift;

### Bollinger Bands

input BB_Length = 20;
input BB_NumDevDn = -2.0;
input BB_NumDevUp = 2.0;
input BB_AverageType = AverageType.SIMPLE;

def BB_SDev = StDev(data = close, length = BB_Length);
def BB_MidLine = MovingAverage(BB_AverageType, data = close, length = BB_Length);
def BB_LowerBand = BB_MidLine + BB_NumDevDn * BB_SDev;
def BB_UpperBand = BB_MidLine + BB_NumDevUp * BB_SDev;

# BB Cloud

AddCloud(if BB_UpperBand <= Keltner_Upper_Band and BB_LowerBand >= Keltner_Lower_Band then MACDBB_Upper else MACDBB_Lower, MACDBB_Lower, Color.YELLOW);
AddCloud(MACDBB_Upper, MACDBB_Lower, Color.LIGHT_RED);

### RSI/STOCASTIC/MACD CONFLUENCE COMBO

input RSM_MACD_ShowBreakoutSignals = no;

plot RSM_MACD_Diff = reference MACD("fast length" = 12, "slow length" = 26, "macd length" = 9).Diff;
RSM_MACD_Diff.SetDefaultColor(GetColor(5));
RSM_MACD_Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
RSM_MACD_Diff.SetLineWeight(4);
RSM_MACD_Diff.DefineColor("Positive and Up", Color.GREEN);
RSM_MACD_Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
RSM_MACD_Diff.DefineColor("Negative and Down", Color.RED);
RSM_MACD_Diff.DefineColor("Negative and Up", Color.DARK_RED);
RSM_MACD_Diff.AssignValueColor(
    if RSM_MACD_Diff >= 0 then
        if RSM_MACD_Diff > RSM_MACD_Diff[1] then RSM_MACD_Diff.Color("Positive and Up") else RSM_MACD_Diff.Color("Positive and Down")
    else
        if RSM_MACD_Diff < RSM_MACD_Diff[1] then RSM_MACD_Diff.Color("Negative and Down") else RSM_MACD_Diff.Color("Negative and Up")
);

plot RSM_MACD_ZeroLine = 0;
RSM_MACD_ZeroLine.SetDefaultColor(Color.RED);
RSM_MACD_ZeroLine.HideTitle();
RSM_MACD_ZeroLine.HideBubble();

plot RSM_MACD_UpSignal = if RSM_MACD_Diff crosses above RSM_MACD_ZeroLine then RSM_MACD_ZeroLine else Double.NaN;
RSM_MACD_UpSignal.SetDefaultColor(Color.UPTICK);
RSM_MACD_UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
RSM_MACD_UpSignal.SetHiding(!RSM_MACD_ShowBreakoutSignals);

plot RSM_MACD_DownSignal = if RSM_MACD_Diff crosses below RSM_MACD_ZeroLine then RSM_MACD_ZeroLine else Double.NaN;
RSM_MACD_DownSignal.SetDefaultColor(Color.DOWNTICK);
RSM_MACD_DownSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
RSM_MACD_DownSignal.SetHiding(!RSM_MACD_ShowBreakoutSignals);

def RSM_RSI = reference RSI(length = 7).RSI;

def RSM_Stoch_Val = 100 * (close - lowest(low, 14)) / (highest(high, 14) - lowest(low, 14));
def RSM_StochSlowK = SimpleMovingAvg(SimpleMovingAvg(RSM_Stoch_Val,3),3);

def RSM_rsiGreen = RSM_RSI >= 50;
def RSM_rsiRed = RSM_RSI < 50;
def RSM_stochGreen = RSM_StochSlowK >= 50;
def RSM_stochRed = RSM_StochSlowK < 50;
def RSM_macdGreen = RSM_MACD_Diff >= 0;
def RSM_macdRed = RSM_MACD_Diff < 0;

input RSM_PaintBars = yes;
AssignPriceColor(
    if RSM_PaintBars and RSM_rsiGreen and RSM_stochGreen and RSM_macdGreen then Color.GREEN
    else if RSM_PaintBars and RSM_rsiRed and RSM_stochRed and RSM_macdRed then Color.RED
    else if RSM_PaintBars then Color.DARK_GRAY
    else Color.CURRENT
);

# Shade areas based on criteria; adjust as needed

AddCloud(
    if RSM_rsiGreen and RSM_stochGreen and RSM_macdGreen then Double.POSITIVE_INFINITY else Double.NaN,
    if RSM_rsiGreen and RSM_stochGreen then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_GREEN
);
AddCloud(
    if RSM_rsiRed and RSM_stochRed and RSM_macdRed then Double.POSITIVE_INFINITY else Double.NaN,
    if RSM_rsiRed and RSM_stochRed then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_RED
);

### Balance of Power

input BOP_EMA_Length = 20;
input BOP_TEMA_Length = 20;

def BOP_THL = If(high != low, high - low, 0.01);
def BOP_BullOpen = (high - open) / BOP_THL;
def BOP_BearOpen = (open - low) / BOP_THL;
def BOP_BullClose = (close - low) / BOP_THL;
def BOP_BearClose = (high - close) / BOP_THL;
def BOP_BullOC = If(close > open, (close - open) / BOP_THL, 0);
def BOP_BearOC = If(open > close, (open - close) / BOP_THL, 0);
def BOP_BullReward = (BOP_BullOpen + BOP_BullClose + BOP_BullOC) / 1;
def BOP_BearReward = (BOP_BearOpen + BOP_BearClose + BOP_BearOC) / 1;

def BOP_BOP = BOP_BullReward - BOP_BearReward;
def BOP_SmoothBOP = ExpAverage(BOP_BOP, BOP_EMA_Length);
def BOP_xPrice = BOP_SmoothBOP;
def BOP_xEMA1 = ExpAverage(BOP_SmoothBOP, BOP_TEMA_Length);
def BOP_xEMA2 = ExpAverage(BOP_xEMA1, BOP_TEMA_Length);
def BOP_xEMA3 = ExpAverage(BOP_xEMA2, BOP_TEMA_Length);
def BOP_nRes = 3 * BOP_xEMA1 - 3 * BOP_xEMA2 + BOP_xEMA3;

def BOP_SmootherBOP = BOP_nRes;
def BOP_s1 = BOP_SmoothBOP;
def BOP_s2 = BOP_SmootherBOP;
def BOP_s3 = BOP_SmootherBOP[2];

def BOP_Sell = BOP_s2 < BOP_s3 and BOP_s2[1] > BOP_s3[1];
def BOP_Buy = BOP_s2 > BOP_s3 and BOP_s2[1] < BOP_s3[1];

### RSI IFT

def RSI_IFT_R = reference RSI(5, close) - 50;
def RSI_IFT_AvgRSI = MovingAverage(AverageType.Exponential,RSI_IFT_R,9);
def RSI_IFT_InverseRSI = (Power(Double.E, 2 * RSI_IFT_AvgRSI) - 1) / (Power(Double.E, 2 * RSI_IFT_AvgRSI) + 1);
def RSI_IFT_Buy =  (RSI_IFT_InverseRSI > 0) and (RSI_IFT_InverseRSI[1] < 0);
def RSI_IFT_Sell = (RSI_IFT_InverseRSI[1] > 0) and (RSI_IFT_InverseRSI < 0);

### InSync

input InSync_Smooth = 1;

# Study Definitions
def InSync_bbCalc = bollingerPercentB();
def InSync_macd1 = MACD(8, 17);
def InSync_macd2 = InSync_macd1 - (MACD(8, 10) - MACD(17, 20));
def InSync_rsi = reference RSI(length = 2);
def InSync_change = RateOfChange(10);
def InSync_dpo = DetrendedPriceOsc();
def InSync_eom = EaseOfMovement();
def InSync_mf = MoneyFlowIndex();
def InSync_stoch = StochasticFull("k period" = 5);
def InSync_bomp = BalanceOfMarketPower();
def InSync_cc = CCI();

# Indicator Scoring
def InSync_bb = if InSync_bbCalc > 95 then 5 else if InSync_bbCalc < 5 then -5 else 0;
def InSync_cci = if InSync_cc > 100 then 5 else if InSync_cc < -100 then -5 else 0;
def InSync_macd = if InSync_macd1 > 0 and InSync_macd2 > 0 then 5 else if InSync_macd1 < 0 and InSync_macd2 < 0 then -5 else 0;
def InSync_roc = if InSync_change > 1 and InSync_change > ExpAverage(InSync_change, 10) then 5 else if InSync_change < 1 and InSync_change < ExpAverage(InSync_change, 10) then -5 else 0;
def InSync_sto = if InSync_stoch > 80 then 10 else if InSync_stoch < 20 then -10 else 0;
def InSync_rsiW = if InSync_rsi > 95 then 5 else if InSync_rsi < 5 then -5 else 0;
def InSync_bop = if InSync_bomp > 0 and InSync_bomp > ExpAverage(InSync_bomp, 10) then 5 else if InSync_bomp < 0 and InSync_bomp < ExpAverage(InSync_bomp, 10) then
-5 else 0;
def InSync_dp = if InSync_dpo > 0 then 5 else if InSync_dpo < 0 then -5 else 0;
def InSync_emv = if InSync_eom > 0 then 5 else if InSync_eom < 0 then -5 else 0;
def InSync_mfi = if InSync_mf > 50 then 5 else if InSync_mf < 40 then -5 else 0;

# Point Sum
def InSync_sum = InSync_bb + InSync_cci + InSync_macd + InSync_roc + InSync_sto + InSync_rsiW + InSync_bop + InSync_dp + InSync_emv + InSync_mfi;

# Value
def InSync_Val = ExpAverage(InSync_sum, InSync_smooth);
def InSync_Buy = (InSync_Val > 0) and (InSync_Val[1] <= 0) and (InSync_Val[2] <= 0);
def InSync_Sell = (InSync_Val < 0) and (InSync_Val[1] >= 0) and (InSync_Val[2] >= 0);

### Vertical Buy/Sell Signals

input BuySellStrategy = { "BalanceOfPower", "InSync", default "RSI_IFT" };

AddVerticalLine(

    if BuySellStrategy == BuySellStrategy.BalanceOfPower then BOP_Sell
    else if BuySellStrategy == BuySellStrategy.InSync then InSync_Sell
    else RSI_IFT_Sell,

    close, Color.RED, Curve.SHORT_DASH);

AddVerticalLine(
   
    if BuySellStrategy == BuySellStrategy.BalanceOfPower then BOP_Buy
    else if BuySellStrategy == BuySellStrategy.InSync then InSync_Buy
    else RSI_IFT_Buy,

    close, Color.GREEN, Curve.SHORT_DASH);

### P/L Statement

input PandL_Label = No;
input NumOfShares = 1;

Assert(NumOfShares >= 1, "Number of Shares needs to be equal or grater than 1");

def orderDir =  CompoundValue(1,
                        if BuySellStrategy == BuySellStrategy.BalanceOfPower then
                            if BOP_Buy then 1 else if BOP_Sell then -1 else orderDir[1]
                        else if BuySellStrategy == BuySellStrategy.InSync then
                            if InSync_Buy then 1 else if InSync_Sell then -1 else orderDir[1]
                        else
                            if RSI_IFT_Buy then 1 else if RSI_IFT_Sell then -1 else orderDir[1]
                , 0);
def isOrder = orderDir crosses 0;
def orderCount = CompoundValue(1, if IsNaN(isOrder) then 0 else if isOrder then orderCount[1] + 1 else orderCount[1], 0);
def noBar = IsNaN(open[-1]);
def orderPrice = if isOrder then if noBar then close else open[-1] else orderPrice[1];
def profitLoss = if !isOrder or orderCount == 1 then 0
                else if orderDir > 0 then orderPrice[1] - orderPrice
                else if orderDir < 0 then orderPrice - orderPrice[1]
                else 0;
def profitLossSum = CompoundValue(1, if IsNaN(isOrder) then 0 else if isOrder then profitLossSum[1] + profitLoss else profitLossSum[1], 0);
def orderWinners = CompoundValue(1, if IsNaN(isOrder) then orderWinners[1] else if orderCount > 1 and profitLoss > 0 then orderWinners[1] + 1 else orderWinners[1], 0);

AddLabel(PandL_Label,
    orderCount + " orders (" + AsPercent(orderWinners / orderCount) + ") | P/L " + AsDollars ((profitLossSum / TickSize()) * TickValue() * NumOfShares),
    if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY
);
It loaded and execute well on my side. It shows up clear and I love being able to alternate between strategies. Tha MACD setting change appears to make more since. It would be awesome to choose BB crossing as a strategy that showed up in the P/L. Your work is amazing.
 
Earhian, did you copy all the code? Is it showing up as a red?
I put an end of code statement at the end of all of my renditions just because it’s common for people to not copy the last portion of the code and in the process have errors.
 
I trade Renko bars and this newer version seems to work really well with them. Can't say the same with candlesticks it looks like. Although it seems to get in and out of trades a little slower.
 
It loaded and execute well on my side. It shows up clear and I love being able to alternate between strategies. Tha MACD setting change appears to make more since. It would be awesome to choose BB crossing as a strategy that showed up in the P/L. Your work is amazing.

I was thinking the same, but after we solidify strategies. We need to finalize a list of buy/sell strategies and I’ll revamp that section.

Is there any benefit to InSync? If not, we can remove to make is slimmer.
 
I trade Renko bars and this newer version seems to work really well with them. Can't say the same with candlesticks it looks like. Although it seems to get in and out of trades a little slower.
@The Bataylor, when you say it seems to get you in and out of trades a little slower. What portion of the indicator do you use as an entry and exit?
@barbaros Looks like this version of code is not working for SPX while the previous version was working. Meaning the indicator is not showing up at all as a lower study now.
It does not appear to work on any indicies!
 
beta2 - removed InSync until we find a solution for indicies.

Code:
# Balanced BB Breakout Indicator
# Free for use. Header credits must be included when any form of the code included in this package is used.
# User assumes all risk. Author not responsible for errors or use of tool.
# v1.2 - Assembled by Chuck Edwards
# v2.0 - Barbaros - cleanup
# v2.1 - Barbaros - added RSI IFT, NumberOfShares, BB crossing options
# v2.2 - Barbaros - fixed PnL issues and removed intraDay filter
# beta2 - Barbaros - changed input and variable names, RSM is re-done

declare lower;

### Market Forecast

def pIntermediate = MarketForecast().Intermediate;

AddLabel(yes,
    "Market Forecast " +
    if pIntermediate >= 80 then "Bullish" else
    if pIntermediate <= 20 then "Bearish" else
    if pIntermediate > pIntermediate[1] then "Rising" else
    if pIntermediate < pIntermediate[1] then "Falling" else " ",
    if pIntermediate >= 80 then CreateColor(204, 255, 204) else # Pre_Cyan
    if pIntermediate <= 20 then Color.RED else
    if pIntermediate > pIntermediate[1] then CreateColor(0, 165, 0) else # LabelGreen
    if pIntermediate < pIntermediate[1] then Color.RED else Color.LIGHT_GRAY
);

### MACDBB

input MACDBB_FastLength = 12;
input MACDBB_SlowLength = 26;
input MACDBB_Length = 25;
input MACDBB_BandLength = 15;
input MACDBB_NumDev = 1.0;

def MACDBB_Data = MACD(fastLength = MACDBB_FastLength, slowLength = MACDBB_SlowLength, MACDLength = MACDBB_Length);
plot MACDBB_Dots = MACDBB_Data;
plot MACDBB_Line = MACDBB_Data;

plot MACDBB_Upper = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).UpperBand;
plot MACDBB_Lower = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).Lowerband;
plot MACDBB_Midline = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).MidLine;

MACDBB_Upper.SetDefaultColor(Color.RED);
MACDBB_Lower.SetDefaultColor(Color.GREEN);
MACDBB_Midline.SetDefaultColor(Color.LIGHT_RED);
MACDBB_Midline.SetStyle(Curve.FIRM);

MACDBB_Line.AssignValueColor(
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line >= MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line >= MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line <= MACDBB_Lower then Color.RED else
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line <= MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACDBB_Line.SetLineWeight(1);

MACDBB_Dots.AssignValueColor(
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.RED
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACDBB_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
MACDBB_Dots.SetLineWeight(1);

AddLabel(yes,
    "Trend " +
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then "Bullish"
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then "Falling"
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then "Bearish"
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then "Rising"
    else "Neutral",
    if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.DARK_GREEN
    else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.RED
    else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.DARK_RED
    else Color.GRAY
);

### MACD BB Alert

input MACDBB_CrossFromAboveAlert = {default "Zero", "Lower", "Middle", "Upper"};
input MACDBB_CrossFromBelowAlert = {default "Zero", "Lower", "Middle", "Upper"};

def MACDBB_CrossFromAboveVal = if MACDBB_CrossFromAboveAlert == MACDBB_CrossFromAboveAlert.Lower then MACDBB_Lower
                               else if MACDBB_CrossFromAboveAlert == MACDBB_CrossFromAboveAlert.Upper then MACDBB_Upper
                              else 0;
def MACDBB_CrossFromBelowVal = if MACDBB_CrossFromBelowAlert == MACDBB_CrossFromBelowAlert.Lower then MACDBB_Lower
                               else if MACDBB_CrossFromBelowAlert == MACDBB_CrossFromBelowAlert.Upper then MACDBB_Upper
                               else 0;

Alert(MACDBB_Line crosses above MACDBB_CrossFromAboveVal, "Time to Buy", Alert.BAR, Sound.Chimes);
Alert(MACDBB_Line crosses below MACDBB_CrossFromBelowVal, "Time to Sell", Alert.BAR, Sound.Bell);

### Keltner Channels

input Keltner_Factor = 1.5;
input Keltner_length = 20;
input Keltner_AverageType = AverageType.EXPONENTIAL;
input Keltner_TrueRangeAverageType = AverageType.EXPONENTIAL;

def Keltner_Shift = Keltner_Factor * MovingAverage(Keltner_TrueRangeAverageType, TrueRange(high, close, low), Keltner_length);
def Keltner_Average = MovingAverage(Keltner_AverageType, close, Keltner_length);
def Keltner_Upper_Band = Keltner_Average + Keltner_Shift;
def Keltner_Lower_Band = Keltner_Average - Keltner_Shift;

### Bollinger Bands

input BB_Length = 20;
input BB_NumDevDn = -2.0;
input BB_NumDevUp = 2.0;
input BB_AverageType = AverageType.SIMPLE;

def BB_SDev = StDev(data = close, length = BB_Length);
def BB_MidLine = MovingAverage(BB_AverageType, data = close, length = BB_Length);
def BB_LowerBand = BB_MidLine + BB_NumDevDn * BB_SDev;
def BB_UpperBand = BB_MidLine + BB_NumDevUp * BB_SDev;

# BB Cloud

AddCloud(if BB_UpperBand <= Keltner_Upper_Band and BB_LowerBand >= Keltner_Lower_Band then MACDBB_Upper else MACDBB_Lower, MACDBB_Lower, Color.YELLOW);
AddCloud(MACDBB_Upper, MACDBB_Lower, Color.LIGHT_RED);

### RSI/STOCASTIC/MACD CONFLUENCE COMBO

input RSM_MACD_ShowBreakoutSignals = no;

plot RSM_MACD_Diff = reference MACD("fast length" = 12, "slow length" = 26, "macd length" = 9).Diff;
RSM_MACD_Diff.SetDefaultColor(GetColor(5));
RSM_MACD_Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
RSM_MACD_Diff.SetLineWeight(4);
RSM_MACD_Diff.DefineColor("Positive and Up", Color.GREEN);
RSM_MACD_Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
RSM_MACD_Diff.DefineColor("Negative and Down", Color.RED);
RSM_MACD_Diff.DefineColor("Negative and Up", Color.DARK_RED);
RSM_MACD_Diff.AssignValueColor(
    if RSM_MACD_Diff >= 0 then
        if RSM_MACD_Diff > RSM_MACD_Diff[1] then RSM_MACD_Diff.Color("Positive and Up") else RSM_MACD_Diff.Color("Positive and Down")
    else
        if RSM_MACD_Diff < RSM_MACD_Diff[1] then RSM_MACD_Diff.Color("Negative and Down") else RSM_MACD_Diff.Color("Negative and Up")
);

plot RSM_MACD_ZeroLine = 0;
RSM_MACD_ZeroLine.SetDefaultColor(Color.RED);
RSM_MACD_ZeroLine.HideTitle();
RSM_MACD_ZeroLine.HideBubble();

plot RSM_MACD_UpSignal = if RSM_MACD_Diff crosses above RSM_MACD_ZeroLine then RSM_MACD_ZeroLine else Double.NaN;
RSM_MACD_UpSignal.SetDefaultColor(Color.UPTICK);
RSM_MACD_UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
RSM_MACD_UpSignal.SetHiding(!RSM_MACD_ShowBreakoutSignals);

plot RSM_MACD_DownSignal = if RSM_MACD_Diff crosses below RSM_MACD_ZeroLine then RSM_MACD_ZeroLine else Double.NaN;
RSM_MACD_DownSignal.SetDefaultColor(Color.DOWNTICK);
RSM_MACD_DownSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
RSM_MACD_DownSignal.SetHiding(!RSM_MACD_ShowBreakoutSignals);

def RSM_RSI = reference RSI(length = 7).RSI;

def RSM_Stoch_Val = 100 * (close - lowest(low, 14)) / (highest(high, 14) - lowest(low, 14));
def RSM_StochSlowK = SimpleMovingAvg(SimpleMovingAvg(RSM_Stoch_Val,3),3);

def RSM_rsiGreen = RSM_RSI >= 50;
def RSM_rsiRed = RSM_RSI < 50;
def RSM_stochGreen = RSM_StochSlowK >= 50;
def RSM_stochRed = RSM_StochSlowK < 50;
def RSM_macdGreen = RSM_MACD_Diff >= 0;
def RSM_macdRed = RSM_MACD_Diff < 0;

input RSM_PaintBars = yes;
AssignPriceColor(
    if RSM_PaintBars and RSM_rsiGreen and RSM_stochGreen and RSM_macdGreen then Color.GREEN
    else if RSM_PaintBars and RSM_rsiRed and RSM_stochRed and RSM_macdRed then Color.RED
    else if RSM_PaintBars then Color.DARK_GRAY
    else Color.CURRENT
);

# Shade areas based on criteria; adjust as needed

AddCloud(
    if RSM_rsiGreen and RSM_stochGreen and RSM_macdGreen then Double.POSITIVE_INFINITY else Double.NaN,
    if RSM_rsiGreen and RSM_stochGreen then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_GREEN
);
AddCloud(
    if RSM_rsiRed and RSM_stochRed and RSM_macdRed then Double.POSITIVE_INFINITY else Double.NaN,
    if RSM_rsiRed and RSM_stochRed then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_RED
);

### Balance of Power

input BOP_EMA_Length = 20;
input BOP_TEMA_Length = 20;

def BOP_THL = If(high != low, high - low, 0.01);
def BOP_BullOpen = (high - open) / BOP_THL;
def BOP_BearOpen = (open - low) / BOP_THL;
def BOP_BullClose = (close - low) / BOP_THL;
def BOP_BearClose = (high - close) / BOP_THL;
def BOP_BullOC = If(close > open, (close - open) / BOP_THL, 0);
def BOP_BearOC = If(open > close, (open - close) / BOP_THL, 0);
def BOP_BullReward = (BOP_BullOpen + BOP_BullClose + BOP_BullOC) / 1;
def BOP_BearReward = (BOP_BearOpen + BOP_BearClose + BOP_BearOC) / 1;

def BOP_BOP = BOP_BullReward - BOP_BearReward;
def BOP_SmoothBOP = ExpAverage(BOP_BOP, BOP_EMA_Length);
def BOP_xPrice = BOP_SmoothBOP;
def BOP_xEMA1 = ExpAverage(BOP_SmoothBOP, BOP_TEMA_Length);
def BOP_xEMA2 = ExpAverage(BOP_xEMA1, BOP_TEMA_Length);
def BOP_xEMA3 = ExpAverage(BOP_xEMA2, BOP_TEMA_Length);
def BOP_nRes = 3 * BOP_xEMA1 - 3 * BOP_xEMA2 + BOP_xEMA3;

def BOP_SmootherBOP = BOP_nRes;
def BOP_s1 = BOP_SmoothBOP;
def BOP_s2 = BOP_SmootherBOP;
def BOP_s3 = BOP_SmootherBOP[2];

def BOP_Sell = BOP_s2 < BOP_s3 and BOP_s2[1] > BOP_s3[1];
def BOP_Buy = BOP_s2 > BOP_s3 and BOP_s2[1] < BOP_s3[1];

### RSI IFT

def RSI_IFT_R = reference RSI(5, close) - 50;
def RSI_IFT_AvgRSI = MovingAverage(AverageType.Exponential,RSI_IFT_R,9);
def RSI_IFT_InverseRSI = (Power(Double.E, 2 * RSI_IFT_AvgRSI) - 1) / (Power(Double.E, 2 * RSI_IFT_AvgRSI) + 1);
def RSI_IFT_Buy =  (RSI_IFT_InverseRSI > 0) and (RSI_IFT_InverseRSI[1] < 0);
def RSI_IFT_Sell = (RSI_IFT_InverseRSI[1] > 0) and (RSI_IFT_InverseRSI < 0);

### Vertical Buy/Sell Signals

input BuySellStrategy = { "BalanceOfPower", "InSync", default "RSI_IFT" };

AddVerticalLine(

    if BuySellStrategy == BuySellStrategy.BalanceOfPower then BOP_Sell
    else RSI_IFT_Sell,

    close, Color.RED, Curve.SHORT_DASH);

AddVerticalLine(
   
    if BuySellStrategy == BuySellStrategy.BalanceOfPower then BOP_Buy
    else RSI_IFT_Buy,

    close, Color.GREEN, Curve.SHORT_DASH);

### P/L Statement

input PandL_Label = No;
input NumOfShares = 1;

Assert(NumOfShares >= 1, "Number of Shares needs to be equal or grater than 1");

def orderDir =  CompoundValue(1,
                        if BuySellStrategy == BuySellStrategy.BalanceOfPower then
                            if BOP_Buy then 1 else if BOP_Sell then -1 else orderDir[1]
                        else
                            if RSI_IFT_Buy then 1 else if RSI_IFT_Sell then -1 else orderDir[1]
                , 0);
def isOrder = orderDir crosses 0;
def orderCount = CompoundValue(1, if IsNaN(isOrder) then 0 else if isOrder then orderCount[1] + 1 else orderCount[1], 0);
def noBar = IsNaN(open[-1]);
def orderPrice = if isOrder then if noBar then close else open[-1] else orderPrice[1];
def profitLoss = if !isOrder or orderCount == 1 then 0
                else if orderDir > 0 then orderPrice[1] - orderPrice
                else if orderDir < 0 then orderPrice - orderPrice[1]
                else 0;
def profitLossSum = CompoundValue(1, if IsNaN(isOrder) then 0 else if isOrder then profitLossSum[1] + profitLoss else profitLossSum[1], 0);
def orderWinners = CompoundValue(1, if IsNaN(isOrder) then orderWinners[1] else if orderCount > 1 and profitLoss > 0 then orderWinners[1] + 1 else orderWinners[1], 0);

AddLabel(PandL_Label,
    orderCount + " orders (" + AsPercent(orderWinners / orderCount) + ") | P/L " + AsDollars ((profitLossSum / TickSize()) * TickValue() * NumOfShares),
    if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY
);
 

Volatility Trading Range

VTR is a momentum indicator that shows if a stock is overbought or oversold based on its Weekly and Monthly average volatility trading range.

Download the indicator

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
352 Online
Create Post

Similar threads

Similar threads

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