B4 Balanced BB Breakout For ThinkOrSwim

Status
Not open for further replies.
From your screenshot it looks like it cleared out a ton of noise. That looks great. To clarify what I meant by statement - "check profitability against timeframes to choose the most profitable time frame for trading"?

You can see on the label that it took....... "2 orders (0%) | P/L $2.07"........So what I do is set the chart to 1 day, and say 10min aggregation. lets say it took 2 trades and made $100. I will change the time frame to say 15min. Lets say the 15 min time frame made $120. Then I know that I'm better off trading on a 15 min time frame....Then I will tweet the other settings to see if I can make the P/L show a more profitable environment.

Once I have my timeframe optimized and my indicator optimized I use it to trade.

One thing that is needed and I forgot to mention is a user interface to change the amount of contracts , Lots or stocks to use in the strategy.

What you have done so far is greatly appreciated. It looks like it cleaned up...Is their is a way to make the IFT RSI signal tiger the strategy..that would be awesome. I dont know if you noticed, but the clouded sections in the background turn red or green when RSI/MACD/AND FVO(Ibeleive 0 are in confluence....Is it possible to incorporate the IFT RSI into that mis for complete synchronization.

Again I am just blown away ....thank you for all that you have done.

Chuck
Is the idea that the Timeframe with the higher P&L is the one you want to trade?
If so, I think I see an issue with that and I'd ask a few other more experienced traders to chime in here. That is historical data and tweaking the TEMA/EMA to get a better P&L after the fact may not be valid in the future. I guess what I am saying is that there is no guarantee that the P&L you see based on historical data is going to play out the same going forward. Testing always looks great and we can tweak until we see the perfect test from historical data but it generally does not hold much weight going forward.

Please correct me here if I am misunderstanding. Thanks.
 

BenTen's Watchlist + Setup + Trade Recaps

Get access to Ben's watchlist, swing trading strategy, ThinkorSwim setup, and trade examples.

Learn more

Is the idea that the Timeframe with the higher P&L is the one you want to trade?
If so, I think I see an issue with that and I'd ask a few other more experienced traders to chime in here. That is historical data and tweaking the TEMA/EMA to get a better P&L after the fact may not be valid in the future. I guess what I am saying is that there is no guarantee that the P&L you see based on historical data is going to play out the same going forward. Testing always looks great and we can tweak until we see the perfect test from historical data but it generally does not hold much weight going forward.

Please correct me here if I am misunderstanding. Thanks.
@cos251, Your understanding of my statements are spot on. Past performance is not indicative of future results, is 100% true. I guess what my goal is to have my settings in sync with the present volatility and market conditions at the time of the trade. I dont think that would hurt anything. I guess I would feel more comphoratble in that situation. Hoping that that will increase the probability. I may be totally out of wack with that assumption. I don't have any statistical data to back that. It is only an assumption of a back woods country boy, LOL.
 
@cos251, Your understanding of my statements are spot on. Past performance is not indicative of future results, is 100% true. I guess what my goal is to have my settings in sync with the present volatility and market conditions at the time of the trade. I dont think that would hurt anything. I guess I would feel more comphoratble in that situation. Hoping that that will increase the probability. I may be totally out of wack with that assumption. I don't have any statistical data to back that. It is only an assumption of a back woods country boy, LOL.
On the other hand, I do like the P/L being part of the indicator. Nothing says you have to gauge the indicator to line up with currant market conditions. Its just an option that presents itself with the ability to check the P/L.
 
@Chuck and @cos251 I already tried to clean up the script and organize. I thought I would contribute.

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

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

# MACD_BB

input BBlength = 15;
input BBNum_Dev = 1.0;
input MACDfastLength = 12;
input MACDslowLength = 26;
input fastLengthMACD = 12;
input slowLengthMACD = 26;
input MACDLength = 25;
input averageTypeMACD = AverageType.WEIGHTED;
input showBreakoutSignals = no;

def MACD_Data = MACD(fastLength = MACDfastLength, slowLength = MACDslowLength, MACDLength = MACDLength);
plot MACD_Dots = MACD_Data;
plot MACD_Line = MACD_Data;

plot BB_Upper = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).UpperBand;
plot BB_Lower = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).Lowerband;
plot BB_Midline = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).MidLine;

BB_Upper.SetDefaultColor(Color.RED);
BB_Lower.SetDefaultColor(Color.GREEN);
BB_Midline.SetDefaultColor(Color.LIGHT_RED);
BB_Midline.SetStyle(Curve.FIRM);

MACD_Line.AssignValueColor(
    if MACD_Line > MACD_Line[1] and MACD_Line >= BB_Upper then Color.GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line >= BB_Upper then Color.DARK_GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line <= BB_Lower then Color.RED else
    if MACD_Line > MACD_Line[1] and MACD_Line <= BB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACD_Line.SetLineWeight(1);

MACD_Dots.AssignValueColor(
    if MACD_Line > MACD_Line[1] and MACD_Line > BB_Upper then Color.GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line > BB_Upper then Color.DARK_GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line < BB_Lower then Color.RED
    else if MACD_Line > MACD_Line[1] and MACD_Line < BB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACD_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
MACD_Dots.SetLineWeight(1);

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

# Keltner Channels

input factor = 1.5;
input length = 20;
input averageType = AverageType.EXPONENTIAL;
input trueRangeAverageType = AverageType.EXPONENTIAL;

def shift = factor * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def average = MovingAverage(averageType, close, length);
def Upper_Band = average + shift;
def Lower_Band = average - shift;

# Bollinger Bands

input BBLength2 = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input bb_averageType = AverageType.SIMPLE;

def sDev = StDev(data = close, length = BBLength2);
def MidLine = MovingAverage(bb_averageType, data = close, length = BBLength2);
def LowerBand = MidLine + Num_Dev_Dn * sDev;
def UpperBand = MidLine + Num_Dev_up * sDev;

# BB Cloud

AddCloud(if UpperBand <= Upper_Band and LowerBand >= Lower_Band then BB_Upper else BB_Lower, BB_Lower, Color.YELLOW);
AddCloud(BB_Upper, BB_Lower, Color.LIGHT_RED);

# BB Alert

Alert(MACD_Line crosses above 0, "Time to Buy", Alert.BAR, Sound.Chimes);
Alert(MACD_Line crosses below 0, "Time to Sell", Alert.BAR, Sound.Bell);

# RSI/STOCASTIC/MACD CONFLUENCE COMBO

def Value = MovingAverage(averageTypeMACD, close, fastLengthMACD) - MovingAverage(averageTypeMACD, close, slowLengthMACD);
def Avg = MovingAverage(averageTypeMACD, Value, MACDLength);

plot Diff = Value - Avg;
Diff.SetDefaultColor(GetColor(5));
Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Diff.SetLineWeight(4);
Diff.DefineColor("Positive and Up", Color.GREEN);
Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
Diff.DefineColor("Negative and Down", Color.RED);
Diff.DefineColor("Negative and Up", Color.DARK_RED);
Diff.AssignValueColor(
    if Diff >= 0 then
        if Diff > Diff[1] then Diff.Color("Positive and Up") else Diff.Color("Positive and Down")
    else
        if Diff < Diff[1] then Diff.Color("Negative and Down") else Diff.Color("Negative and Up")
);

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

plot UpSignalMACD = if Diff crosses above ZeroLine then ZeroLine else Double.NaN;
UpSignalMACD.SetDefaultColor(Color.UPTICK);
UpSignalMACD.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpSignalMACD.SetHiding(!showBreakoutSignals);

plot DownSignalMACD = if Diff crosses below ZeroLine then ZeroLine else Double.NaN;
DownSignalMACD.SetDefaultColor(Color.DOWNTICK);
DownSignalMACD.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
DownSignalMACD.SetHiding(!showBreakoutSignals);

input lengthRSI = 7;
input averageTypeRSI = AverageType.EXPONENTIAL;

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

input KPeriod = 5;
input DPeriod = 3;
input averageTypeStoch = AverageType.WILDERS;

def SlowK = reference StochasticFull(80, 20, KPeriod, DPeriod, high, low, close, 3, averageTypeStoch).FullK;
def SlowD = reference StochasticFull(80, 20, KPeriod, DPeriod, high, low, close, 3, averageTypeStoch).FullD;

def rsiGreen = if RSI >= 50 then 1 else Double.NaN;
def rsiRed = if RSI < 50 then 1 else Double.NaN;
def stochGreen = if SlowK >= 50 then 1 else Double.NaN;
def stochRed = if SlowK < 50 then 1 else Double.NaN;
def macdGreen = if Value > Avg then 1 else Double.NaN;
def macdRed = if Value < Avg then 1 else Double.NaN;

input paintBars = yes;
AssignPriceColor(
    if paintBars and RSI >= 50 and SlowK >= 50 and Value > Avg then Color.GREEN
    else if paintBars and RSI < 50 and SlowK < 50 and Value < Avg then Color.RED
    else if paintBars then Color.DARK_GRAY
    else Color.CURRENT
);

# Shade areas based on criteria; adjust as needed

AddCloud(
    if rsiGreen and stochGreen and macdGreen then Double.POSITIVE_INFINITY else Double.NaN,
    if rsiGreen and stochGreen then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_GREEN
);
AddCloud(
    if rsiRed and stochRed and macdRed then Double.POSITIVE_INFINITY else Double.NaN,
    if rsiRed and stochRed then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_RED
);

# Balance of Power

input EMA = 20;
input TEMA = 20;

def THL = If(high != low, high - low, 0.01);
def BullOpen = (high - open) / THL;
def BearOpen = (open - low) / THL;
def BullClose = (close - low) / THL;
def BearClose = (high - close) / THL;
def BullOC = If(close > open, (close - open) / THL, 0);
def BearOC = If(open > close, (open - close) / THL, 0);
def BullReward = (BullOpen + BullClose + BullOC) / 1;
def BearReward = (BearOpen + BearClose + BearOC) / 1;

def BOP = BullReward - BearReward;
def SmoothBOP = ExpAverage(BOP, EMA);
def xPrice = SmoothBOP;
def xEMA1 = ExpAverage(SmoothBOP, TEMA);
def xEMA2 = ExpAverage(xEMA1, TEMA);
def xEMA3 = ExpAverage(xEMA2, TEMA);
def nRes = 3 * xEMA1 - 3 * xEMA2 + xEMA3;

def SmootherBOP = nRes;
def s1 = SmoothBOP;
def s2 = SmootherBOP;
def s3 = SmootherBOP[2];

def short = s2 < s3 and s2[1] > s3[1];
def long = s2 > s3 and s2[1] < s3[1];

AddVerticalLine(short, close, Color.RED, Curve.SHORT_DASH);
AddVerticalLine(long, close, Color.GREEN, Curve.SHORT_DASH);

# P/L Statement

input PandL_Label = No;
input IntraDayOnly = Yes;

def orderDir =  if IntraDayOnly and (SecondsTillTime(930) > 0 or SecondsFromTime(1600) > 0) then 0 else CompoundValue(1, if s2 < s3 then 1 else if s2 > s3 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()),
    if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY
);
 
@Chuck and @cos251 I already tried to clean up the script and organize. I thought I would contribute.

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

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

# MACD_BB

input BBlength = 15;
input BBNum_Dev = 1.0;
input MACDfastLength = 12;
input MACDslowLength = 26;
input fastLengthMACD = 12;
input slowLengthMACD = 26;
input MACDLength = 25;
input averageTypeMACD = AverageType.WEIGHTED;
input showBreakoutSignals = no;

def MACD_Data = MACD(fastLength = MACDfastLength, slowLength = MACDslowLength, MACDLength = MACDLength);
plot MACD_Dots = MACD_Data;
plot MACD_Line = MACD_Data;

plot BB_Upper = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).UpperBand;
plot BB_Lower = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).Lowerband;
plot BB_Midline = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).MidLine;

BB_Upper.SetDefaultColor(Color.RED);
BB_Lower.SetDefaultColor(Color.GREEN);
BB_Midline.SetDefaultColor(Color.LIGHT_RED);
BB_Midline.SetStyle(Curve.FIRM);

MACD_Line.AssignValueColor(
    if MACD_Line > MACD_Line[1] and MACD_Line >= BB_Upper then Color.GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line >= BB_Upper then Color.DARK_GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line <= BB_Lower then Color.RED else
    if MACD_Line > MACD_Line[1] and MACD_Line <= BB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACD_Line.SetLineWeight(1);

MACD_Dots.AssignValueColor(
    if MACD_Line > MACD_Line[1] and MACD_Line > BB_Upper then Color.GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line > BB_Upper then Color.DARK_GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line < BB_Lower then Color.RED
    else if MACD_Line > MACD_Line[1] and MACD_Line < BB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACD_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
MACD_Dots.SetLineWeight(1);

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

# Keltner Channels

input factor = 1.5;
input length = 20;
input averageType = AverageType.EXPONENTIAL;
input trueRangeAverageType = AverageType.EXPONENTIAL;

def shift = factor * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def average = MovingAverage(averageType, close, length);
def Upper_Band = average + shift;
def Lower_Band = average - shift;

# Bollinger Bands

input BBLength2 = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input bb_averageType = AverageType.SIMPLE;

def sDev = StDev(data = close, length = BBLength2);
def MidLine = MovingAverage(bb_averageType, data = close, length = BBLength2);
def LowerBand = MidLine + Num_Dev_Dn * sDev;
def UpperBand = MidLine + Num_Dev_up * sDev;

# BB Cloud

AddCloud(if UpperBand <= Upper_Band and LowerBand >= Lower_Band then BB_Upper else BB_Lower, BB_Lower, Color.YELLOW);
AddCloud(BB_Upper, BB_Lower, Color.LIGHT_RED);

# BB Alert

Alert(MACD_Line crosses above 0, "Time to Buy", Alert.BAR, Sound.Chimes);
Alert(MACD_Line crosses below 0, "Time to Sell", Alert.BAR, Sound.Bell);

# RSI/STOCASTIC/MACD CONFLUENCE COMBO

def Value = MovingAverage(averageTypeMACD, close, fastLengthMACD) - MovingAverage(averageTypeMACD, close, slowLengthMACD);
def Avg = MovingAverage(averageTypeMACD, Value, MACDLength);

plot Diff = Value - Avg;
Diff.SetDefaultColor(GetColor(5));
Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Diff.SetLineWeight(4);
Diff.DefineColor("Positive and Up", Color.GREEN);
Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
Diff.DefineColor("Negative and Down", Color.RED);
Diff.DefineColor("Negative and Up", Color.DARK_RED);
Diff.AssignValueColor(
    if Diff >= 0 then
        if Diff > Diff[1] then Diff.Color("Positive and Up") else Diff.Color("Positive and Down")
    else
        if Diff < Diff[1] then Diff.Color("Negative and Down") else Diff.Color("Negative and Up")
);

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

plot UpSignalMACD = if Diff crosses above ZeroLine then ZeroLine else Double.NaN;
UpSignalMACD.SetDefaultColor(Color.UPTICK);
UpSignalMACD.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpSignalMACD.SetHiding(!showBreakoutSignals);

plot DownSignalMACD = if Diff crosses below ZeroLine then ZeroLine else Double.NaN;
DownSignalMACD.SetDefaultColor(Color.DOWNTICK);
DownSignalMACD.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
DownSignalMACD.SetHiding(!showBreakoutSignals);

input lengthRSI = 7;
input averageTypeRSI = AverageType.EXPONENTIAL;

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

input KPeriod = 5;
input DPeriod = 3;
input averageTypeStoch = AverageType.WILDERS;

def SlowK = reference StochasticFull(80, 20, KPeriod, DPeriod, high, low, close, 3, averageTypeStoch).FullK;
def SlowD = reference StochasticFull(80, 20, KPeriod, DPeriod, high, low, close, 3, averageTypeStoch).FullD;

def rsiGreen = if RSI >= 50 then 1 else Double.NaN;
def rsiRed = if RSI < 50 then 1 else Double.NaN;
def stochGreen = if SlowK >= 50 then 1 else Double.NaN;
def stochRed = if SlowK < 50 then 1 else Double.NaN;
def macdGreen = if Value > Avg then 1 else Double.NaN;
def macdRed = if Value < Avg then 1 else Double.NaN;

input paintBars = yes;
AssignPriceColor(
    if paintBars and RSI >= 50 and SlowK >= 50 and Value > Avg then Color.GREEN
    else if paintBars and RSI < 50 and SlowK < 50 and Value < Avg then Color.RED
    else if paintBars then Color.DARK_GRAY
    else Color.CURRENT
);

# Shade areas based on criteria; adjust as needed

AddCloud(
    if rsiGreen and stochGreen and macdGreen then Double.POSITIVE_INFINITY else Double.NaN,
    if rsiGreen and stochGreen then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_GREEN
);
AddCloud(
    if rsiRed and stochRed and macdRed then Double.POSITIVE_INFINITY else Double.NaN,
    if rsiRed and stochRed then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_RED
);

# Balance of Power

input EMA = 20;
input TEMA = 20;

def THL = If(high != low, high - low, 0.01);
def BullOpen = (high - open) / THL;
def BearOpen = (open - low) / THL;
def BullClose = (close - low) / THL;
def BearClose = (high - close) / THL;
def BullOC = If(close > open, (close - open) / THL, 0);
def BearOC = If(open > close, (open - close) / THL, 0);
def BullReward = (BullOpen + BullClose + BullOC) / 1;
def BearReward = (BearOpen + BearClose + BearOC) / 1;

def BOP = BullReward - BearReward;
def SmoothBOP = ExpAverage(BOP, EMA);
def xPrice = SmoothBOP;
def xEMA1 = ExpAverage(SmoothBOP, TEMA);
def xEMA2 = ExpAverage(xEMA1, TEMA);
def xEMA3 = ExpAverage(xEMA2, TEMA);
def nRes = 3 * xEMA1 - 3 * xEMA2 + xEMA3;

def SmootherBOP = nRes;
def s1 = SmoothBOP;
def s2 = SmootherBOP;
def s3 = SmootherBOP[2];

def short = s2 < s3 and s2[1] > s3[1];
def long = s2 > s3 and s2[1] < s3[1];

AddVerticalLine(short, close, Color.RED, Curve.SHORT_DASH);
AddVerticalLine(long, close, Color.GREEN, Curve.SHORT_DASH);

# P/L Statement

input PandL_Label = No;
input IntraDayOnly = Yes;

def orderDir =  if IntraDayOnly and (SecondsTillTime(930) > 0 or SecondsFromTime(1600) > 0) then 0 else CompoundValue(1, if s2 < s3 then 1 else if s2 > s3 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()),
    if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY
);
@barbaros, Thank you for your work on this. Vast improvement. I am not a coder and my attempt was very challenging. I appreciate the time and energy you put forth. Love the second label !
 
@barbaros, Thank you for your work on this. Vast improvement. I am not a coder and my attempt was very challenging. I appreciate the time and energy you put forth. Love the second label !
For momentum trading, I'm thinking that we should add another alert or arrow where the MACD dots cross the mid line BB. What are your thoughts? I see this as an early warning for UBI so far.
 
@Chuck and @cos251 I already tried to clean up the script and organize. I thought I would contribute.

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

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

# MACD_BB

input BBlength = 15;
input BBNum_Dev = 1.0;
input MACDfastLength = 12;
input MACDslowLength = 26;
input fastLengthMACD = 12;
input slowLengthMACD = 26;
input MACDLength = 25;
input averageTypeMACD = AverageType.WEIGHTED;
input showBreakoutSignals = no;

def MACD_Data = MACD(fastLength = MACDfastLength, slowLength = MACDslowLength, MACDLength = MACDLength);
plot MACD_Dots = MACD_Data;
plot MACD_Line = MACD_Data;

plot BB_Upper = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).UpperBand;
plot BB_Lower = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).Lowerband;
plot BB_Midline = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).MidLine;

BB_Upper.SetDefaultColor(Color.RED);
BB_Lower.SetDefaultColor(Color.GREEN);
BB_Midline.SetDefaultColor(Color.LIGHT_RED);
BB_Midline.SetStyle(Curve.FIRM);

MACD_Line.AssignValueColor(
    if MACD_Line > MACD_Line[1] and MACD_Line >= BB_Upper then Color.GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line >= BB_Upper then Color.DARK_GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line <= BB_Lower then Color.RED else
    if MACD_Line > MACD_Line[1] and MACD_Line <= BB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACD_Line.SetLineWeight(1);

MACD_Dots.AssignValueColor(
    if MACD_Line > MACD_Line[1] and MACD_Line > BB_Upper then Color.GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line > BB_Upper then Color.DARK_GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line < BB_Lower then Color.RED
    else if MACD_Line > MACD_Line[1] and MACD_Line < BB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACD_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
MACD_Dots.SetLineWeight(1);

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

# Keltner Channels

input factor = 1.5;
input length = 20;
input averageType = AverageType.EXPONENTIAL;
input trueRangeAverageType = AverageType.EXPONENTIAL;

def shift = factor * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def average = MovingAverage(averageType, close, length);
def Upper_Band = average + shift;
def Lower_Band = average - shift;

# Bollinger Bands

input BBLength2 = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input bb_averageType = AverageType.SIMPLE;

def sDev = StDev(data = close, length = BBLength2);
def MidLine = MovingAverage(bb_averageType, data = close, length = BBLength2);
def LowerBand = MidLine + Num_Dev_Dn * sDev;
def UpperBand = MidLine + Num_Dev_up * sDev;

# BB Cloud

AddCloud(if UpperBand <= Upper_Band and LowerBand >= Lower_Band then BB_Upper else BB_Lower, BB_Lower, Color.YELLOW);
AddCloud(BB_Upper, BB_Lower, Color.LIGHT_RED);

# BB Alert

Alert(MACD_Line crosses above 0, "Time to Buy", Alert.BAR, Sound.Chimes);
Alert(MACD_Line crosses below 0, "Time to Sell", Alert.BAR, Sound.Bell);

# RSI/STOCASTIC/MACD CONFLUENCE COMBO

def Value = MovingAverage(averageTypeMACD, close, fastLengthMACD) - MovingAverage(averageTypeMACD, close, slowLengthMACD);
def Avg = MovingAverage(averageTypeMACD, Value, MACDLength);

plot Diff = Value - Avg;
Diff.SetDefaultColor(GetColor(5));
Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Diff.SetLineWeight(4);
Diff.DefineColor("Positive and Up", Color.GREEN);
Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
Diff.DefineColor("Negative and Down", Color.RED);
Diff.DefineColor("Negative and Up", Color.DARK_RED);
Diff.AssignValueColor(
    if Diff >= 0 then
        if Diff > Diff[1] then Diff.Color("Positive and Up") else Diff.Color("Positive and Down")
    else
        if Diff < Diff[1] then Diff.Color("Negative and Down") else Diff.Color("Negative and Up")
);

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

plot UpSignalMACD = if Diff crosses above ZeroLine then ZeroLine else Double.NaN;
UpSignalMACD.SetDefaultColor(Color.UPTICK);
UpSignalMACD.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpSignalMACD.SetHiding(!showBreakoutSignals);

plot DownSignalMACD = if Diff crosses below ZeroLine then ZeroLine else Double.NaN;
DownSignalMACD.SetDefaultColor(Color.DOWNTICK);
DownSignalMACD.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
DownSignalMACD.SetHiding(!showBreakoutSignals);

input lengthRSI = 7;
input averageTypeRSI = AverageType.EXPONENTIAL;

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

input KPeriod = 5;
input DPeriod = 3;
input averageTypeStoch = AverageType.WILDERS;

def SlowK = reference StochasticFull(80, 20, KPeriod, DPeriod, high, low, close, 3, averageTypeStoch).FullK;
def SlowD = reference StochasticFull(80, 20, KPeriod, DPeriod, high, low, close, 3, averageTypeStoch).FullD;

def rsiGreen = if RSI >= 50 then 1 else Double.NaN;
def rsiRed = if RSI < 50 then 1 else Double.NaN;
def stochGreen = if SlowK >= 50 then 1 else Double.NaN;
def stochRed = if SlowK < 50 then 1 else Double.NaN;
def macdGreen = if Value > Avg then 1 else Double.NaN;
def macdRed = if Value < Avg then 1 else Double.NaN;

input paintBars = yes;
AssignPriceColor(
    if paintBars and RSI >= 50 and SlowK >= 50 and Value > Avg then Color.GREEN
    else if paintBars and RSI < 50 and SlowK < 50 and Value < Avg then Color.RED
    else if paintBars then Color.DARK_GRAY
    else Color.CURRENT
);

# Shade areas based on criteria; adjust as needed

AddCloud(
    if rsiGreen and stochGreen and macdGreen then Double.POSITIVE_INFINITY else Double.NaN,
    if rsiGreen and stochGreen then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_GREEN
);
AddCloud(
    if rsiRed and stochRed and macdRed then Double.POSITIVE_INFINITY else Double.NaN,
    if rsiRed and stochRed then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_RED
);

# Balance of Power

input EMA = 20;
input TEMA = 20;

def THL = If(high != low, high - low, 0.01);
def BullOpen = (high - open) / THL;
def BearOpen = (open - low) / THL;
def BullClose = (close - low) / THL;
def BearClose = (high - close) / THL;
def BullOC = If(close > open, (close - open) / THL, 0);
def BearOC = If(open > close, (open - close) / THL, 0);
def BullReward = (BullOpen + BullClose + BullOC) / 1;
def BearReward = (BearOpen + BearClose + BearOC) / 1;

def BOP = BullReward - BearReward;
def SmoothBOP = ExpAverage(BOP, EMA);
def xPrice = SmoothBOP;
def xEMA1 = ExpAverage(SmoothBOP, TEMA);
def xEMA2 = ExpAverage(xEMA1, TEMA);
def xEMA3 = ExpAverage(xEMA2, TEMA);
def nRes = 3 * xEMA1 - 3 * xEMA2 + xEMA3;

def SmootherBOP = nRes;
def s1 = SmoothBOP;
def s2 = SmootherBOP;
def s3 = SmootherBOP[2];

def short = s2 < s3 and s2[1] > s3[1];
def long = s2 > s3 and s2[1] < s3[1];

AddVerticalLine(short, close, Color.RED, Curve.SHORT_DASH);
AddVerticalLine(long, close, Color.GREEN, Curve.SHORT_DASH);

# P/L Statement

input PandL_Label = No;
input IntraDayOnly = Yes;

def orderDir =  if IntraDayOnly and (SecondsTillTime(930) > 0 or SecondsFromTime(1600) > 0) then 0 else CompoundValue(1, if s2 < s3 then 1 else if s2 > s3 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()),
    if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY
);
@barbaros this is excellent. Let me know if you want the code to the IFT RSI Signal for testing. I think I will refrain from doing updates to this so as not to add different versions.
 
@Chuck and @cos251 I already tried to clean up the script and organize. I thought I would contribute.

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

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

# MACD_BB

input BBlength = 15;
input BBNum_Dev = 1.0;
input MACDfastLength = 12;
input MACDslowLength = 26;
input fastLengthMACD = 12;
input slowLengthMACD = 26;
input MACDLength = 25;
input averageTypeMACD = AverageType.WEIGHTED;
input showBreakoutSignals = no;

def MACD_Data = MACD(fastLength = MACDfastLength, slowLength = MACDslowLength, MACDLength = MACDLength);
plot MACD_Dots = MACD_Data;
plot MACD_Line = MACD_Data;

plot BB_Upper = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).UpperBand;
plot BB_Lower = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).Lowerband;
plot BB_Midline = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).MidLine;

BB_Upper.SetDefaultColor(Color.RED);
BB_Lower.SetDefaultColor(Color.GREEN);
BB_Midline.SetDefaultColor(Color.LIGHT_RED);
BB_Midline.SetStyle(Curve.FIRM);

MACD_Line.AssignValueColor(
    if MACD_Line > MACD_Line[1] and MACD_Line >= BB_Upper then Color.GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line >= BB_Upper then Color.DARK_GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line <= BB_Lower then Color.RED else
    if MACD_Line > MACD_Line[1] and MACD_Line <= BB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACD_Line.SetLineWeight(1);

MACD_Dots.AssignValueColor(
    if MACD_Line > MACD_Line[1] and MACD_Line > BB_Upper then Color.GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line > BB_Upper then Color.DARK_GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line < BB_Lower then Color.RED
    else if MACD_Line > MACD_Line[1] and MACD_Line < BB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACD_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
MACD_Dots.SetLineWeight(1);

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

# Keltner Channels

input factor = 1.5;
input length = 20;
input averageType = AverageType.EXPONENTIAL;
input trueRangeAverageType = AverageType.EXPONENTIAL;

def shift = factor * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def average = MovingAverage(averageType, close, length);
def Upper_Band = average + shift;
def Lower_Band = average - shift;

# Bollinger Bands

input BBLength2 = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input bb_averageType = AverageType.SIMPLE;

def sDev = StDev(data = close, length = BBLength2);
def MidLine = MovingAverage(bb_averageType, data = close, length = BBLength2);
def LowerBand = MidLine + Num_Dev_Dn * sDev;
def UpperBand = MidLine + Num_Dev_up * sDev;

# BB Cloud

AddCloud(if UpperBand <= Upper_Band and LowerBand >= Lower_Band then BB_Upper else BB_Lower, BB_Lower, Color.YELLOW);
AddCloud(BB_Upper, BB_Lower, Color.LIGHT_RED);

# BB Alert

Alert(MACD_Line crosses above 0, "Time to Buy", Alert.BAR, Sound.Chimes);
Alert(MACD_Line crosses below 0, "Time to Sell", Alert.BAR, Sound.Bell);

# RSI/STOCASTIC/MACD CONFLUENCE COMBO

def Value = MovingAverage(averageTypeMACD, close, fastLengthMACD) - MovingAverage(averageTypeMACD, close, slowLengthMACD);
def Avg = MovingAverage(averageTypeMACD, Value, MACDLength);

plot Diff = Value - Avg;
Diff.SetDefaultColor(GetColor(5));
Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Diff.SetLineWeight(4);
Diff.DefineColor("Positive and Up", Color.GREEN);
Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
Diff.DefineColor("Negative and Down", Color.RED);
Diff.DefineColor("Negative and Up", Color.DARK_RED);
Diff.AssignValueColor(
    if Diff >= 0 then
        if Diff > Diff[1] then Diff.Color("Positive and Up") else Diff.Color("Positive and Down")
    else
        if Diff < Diff[1] then Diff.Color("Negative and Down") else Diff.Color("Negative and Up")
);

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

plot UpSignalMACD = if Diff crosses above ZeroLine then ZeroLine else Double.NaN;
UpSignalMACD.SetDefaultColor(Color.UPTICK);
UpSignalMACD.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpSignalMACD.SetHiding(!showBreakoutSignals);

plot DownSignalMACD = if Diff crosses below ZeroLine then ZeroLine else Double.NaN;
DownSignalMACD.SetDefaultColor(Color.DOWNTICK);
DownSignalMACD.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
DownSignalMACD.SetHiding(!showBreakoutSignals);

input lengthRSI = 7;
input averageTypeRSI = AverageType.EXPONENTIAL;

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

input KPeriod = 5;
input DPeriod = 3;
input averageTypeStoch = AverageType.WILDERS;

def SlowK = reference StochasticFull(80, 20, KPeriod, DPeriod, high, low, close, 3, averageTypeStoch).FullK;
def SlowD = reference StochasticFull(80, 20, KPeriod, DPeriod, high, low, close, 3, averageTypeStoch).FullD;

def rsiGreen = if RSI >= 50 then 1 else Double.NaN;
def rsiRed = if RSI < 50 then 1 else Double.NaN;
def stochGreen = if SlowK >= 50 then 1 else Double.NaN;
def stochRed = if SlowK < 50 then 1 else Double.NaN;
def macdGreen = if Value > Avg then 1 else Double.NaN;
def macdRed = if Value < Avg then 1 else Double.NaN;

input paintBars = yes;
AssignPriceColor(
    if paintBars and RSI >= 50 and SlowK >= 50 and Value > Avg then Color.GREEN
    else if paintBars and RSI < 50 and SlowK < 50 and Value < Avg then Color.RED
    else if paintBars then Color.DARK_GRAY
    else Color.CURRENT
);

# Shade areas based on criteria; adjust as needed

AddCloud(
    if rsiGreen and stochGreen and macdGreen then Double.POSITIVE_INFINITY else Double.NaN,
    if rsiGreen and stochGreen then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_GREEN
);
AddCloud(
    if rsiRed and stochRed and macdRed then Double.POSITIVE_INFINITY else Double.NaN,
    if rsiRed and stochRed then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_RED
);

# Balance of Power

input EMA = 20;
input TEMA = 20;

def THL = If(high != low, high - low, 0.01);
def BullOpen = (high - open) / THL;
def BearOpen = (open - low) / THL;
def BullClose = (close - low) / THL;
def BearClose = (high - close) / THL;
def BullOC = If(close > open, (close - open) / THL, 0);
def BearOC = If(open > close, (open - close) / THL, 0);
def BullReward = (BullOpen + BullClose + BullOC) / 1;
def BearReward = (BearOpen + BearClose + BearOC) / 1;

def BOP = BullReward - BearReward;
def SmoothBOP = ExpAverage(BOP, EMA);
def xPrice = SmoothBOP;
def xEMA1 = ExpAverage(SmoothBOP, TEMA);
def xEMA2 = ExpAverage(xEMA1, TEMA);
def xEMA3 = ExpAverage(xEMA2, TEMA);
def nRes = 3 * xEMA1 - 3 * xEMA2 + xEMA3;

def SmootherBOP = nRes;
def s1 = SmoothBOP;
def s2 = SmootherBOP;
def s3 = SmootherBOP[2];

def short = s2 < s3 and s2[1] > s3[1];
def long = s2 > s3 and s2[1] < s3[1];

AddVerticalLine(short, close, Color.RED, Curve.SHORT_DASH);
AddVerticalLine(long, close, Color.GREEN, Curve.SHORT_DASH);

# P/L Statement

input PandL_Label = No;
input IntraDayOnly = Yes;

def orderDir =  if IntraDayOnly and (SecondsTillTime(930) > 0 or SecondsFromTime(1600) > 0) then 0 else CompoundValue(1, if s2 < s3 then 1 else if s2 > s3 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()),
    if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY
);
@barbaros I lined your updated version up with the pre-existing version, and it looks like entry/exit conditions have changed. Unless I'm missing something, the vertical lines were in correlation with entries and exits, correct? That does not seem to be the case in your version.
 
For momentum trading, I'm thinking that we should add another alert or arrow where the MACD dots cross the mid line BB. What are your thoughts? I see this as an early warning for UBI so far.
@barbaros, I think that if you are trading futures like I do sometimes and have a small account(and cant take a huge drawdown) that the Balance of power getting you in and out of trades is good. However It can be a little unsettling at times when it changes back and forth. In that case having the option to allow arrows or alert or both is good. I would like to see it in confluence with the MACD Histigram bar going in the same direction. That would help keep down the noise. Also it would be nice if the user had the option to choose what line to use as a signal, (Upper,Middle,Lower). For other styles of trading I love @cos251 's IFT RSI Signal, that thing rocks. It will keep you in till the end and is a super clean signal .....hardly any noise.
 
@barbaros I lined your updated version up with the pre-existing version, and it looks like entry/exit conditions have changed. Unless I'm missing something, the vertical lines were in correlation with entries and exits, correct? That does not seem to be the case in your version.
I am not sure which version you are using, but it lines up the same with v1.2.

teTTZJT.png
 
@barbaros, I think that if you are trading futures like I do sometimes and have a small account(and cant take a huge drawdown) that the Balance of power getting you in and out of trades is good. However It can be a little unsettling at times when it changes back and forth. In that case having the option to allow arrows or alert or both is good. I would like to see it in confluence with the MACD Histigram bar going in the same direction. That would help keep down the noise. Also it would be nice if the user had the option to choose what line to use as a signal, (Upper,Middle,Lower). For other styles of trading I love @cos251 's IFT RSI Signal, that thing rocks. It will keep you in till the end and is a super clean signal .....hardly any noise.
This sounds great. Lets define what we want to do with the script as a spec, and I'm sure @cos251 and I can handle the coding part.
 
  • If it is possible, the indicator would be better if it had the ability to switch between the Balance of Power strategy or the IFT RSI (if not too complicated). This would allow for multiple trading styles.
  • As for the Balance of Power section (if still used), I certainly like @barbaros idea to make it able to get a signal arrow and notification when the RSI crosses Bollinger line, my opinion is it would be better if the User Interface had the Options: Upper, Middle and Lower. Perhaps he could handle this section
  • The strategy needs to be fixed for Shure! It needs the ability to key in the trade size. It is set to one now and doesn’t reflect a realistic P/L as it stands. Works good for one futures contract now LOL.
  • The cleaning up the syntax logic has already been done as far as I can tell, and I want to thank you borbaros for doing that. The portion with the added trend labels is great, but at the same time I personally like the idea of having all three timeframes as it is in @cos251 's the work version.


Any further help from you guys would be great. Perhaps you guys could choose a a task if appropriate and go from their? This indicator has great potential in my opinion and I would love to see it progress here as a collaboration project. Again, thank you each for your generosity.
 
  • If it is possible, the indicator would be better if it had the ability to switch between the Balance of Power strategy or the IFT RSI (if not too complicated). This would allow for multiple trading styles.
  • As for the Balance of Power section (if still used), I certainly like @barbaros idea to make it able to get a signal arrow and notification when the RSI crosses Bollinger line, my opinion is it would be better if the User Interface had the Options: Upper, Middle and Lower. Perhaps he could handle this section
  • The strategy needs to be fixed for Shure! It needs the ability to key in the trade size. It is set to one now and doesn’t reflect a realistic P/L as it stands. Works good for one futures contract now LOL.
  • The cleaning up the syntax logic has already been done as far as I can tell, and I want to thank you borbaros for doing that. The portion with the added trend labels is great, but at the same time I personally like the idea of having all three timeframes as it is in @cos251 's the work version.


Any further help from you guys would be great. Perhaps you guys could choose a a task if appropriate and go from their? This indicator has great potential in my opinion and I would love to see it progress here as a collaboration project. Again, thank you each for your generosity.
Sounds like a plan.

Can someone direct me to IFT RSI script? I'll start with adding it first and then make it selectable.

Adding trade size into the PnL calculations shouldn't be a problem. I'll do that as well. However, switching strategies for PnL will take longer, so after adding IFT RSI, we'll plan on making PnL switch with it too.

We can add the rest incrementally. :)

I'm starting to use this combo indicator, so I'll dedicate more time to it. I watched it all day today with /ES 3200t and it is promising.
 
Sounds like a plan.

Can someone direct me to IFT RSI script? I'll start with adding it first and then make it selectable.

Adding trade size into the PnL calculations shouldn't be a problem. I'll do that as well. However, switching strategies for PnL will take longer, so after adding IFT RSI, we'll plan on making PnL switch with it too.

We can add the rest incrementally. :)

I'm starting to use this combo indicator, so I'll dedicate more time to it. I watched it all day today with /ES 3200t and it is promising.
Here you go.

Code:
# FVO_RSI_IFT (Inverse Fisher Transform RSI)
# Change Log
# 2021.01.29    v1.0    @cos251    -    Intial Script
#
#

declare lower;

#input length = 5;
def over_Bought = .5;
def over_Sold = -.5;

def R = reference RSI(5, close) - 50;
def AvgRSI = MovingAverage(AverageType.Exponential,R,9);
def inverseRSI = (Power(Double.E, 2 * AvgRSI) - 1) / (Power(Double.E, 2 * AvgRSI) + 1);
plot Inverse_RSI = inverseRSI;
Inverse_RSI.SetDefaultColor(Color.DARK_GRAY);
Inverse_RSI.AssignValueColor(if Inverse_RSI > .5 then Color.GREEN else if Inverse_RSI < -.5 then Color.RED else Color.Current);
plot ob = over_Bought;
plot os = over_Sold;
ob.SetDefaultColor(Color.DARK_GRAY);
os.SetDefaultColor(Color.DARK_GRAY);


AddVerticalLine( (inverseRSI > 0) and (inverseRSI[1] < 0), "Entry BUY", Color.GRAY);
AddVerticalLine( (inverseRSI[1] > 0) and (inverseRSI < 0), "Entry SELL", Color.YELLOW);
 
Here you go.

Code:
# FVO_RSI_IFT (Inverse Fisher Transform RSI)
# Change Log
# 2021.01.29    v1.0    @cos251    -    Intial Script
#
#

declare lower;

#input length = 5;
def over_Bought = .5;
def over_Sold = -.5;

def R = reference RSI(5, close) - 50;
def AvgRSI = MovingAverage(AverageType.Exponential,R,9);
def inverseRSI = (Power(Double.E, 2 * AvgRSI) - 1) / (Power(Double.E, 2 * AvgRSI) + 1);
plot Inverse_RSI = inverseRSI;
Inverse_RSI.SetDefaultColor(Color.DARK_GRAY);
Inverse_RSI.AssignValueColor(if Inverse_RSI > .5 then Color.GREEN else if Inverse_RSI < -.5 then Color.RED else Color.Current);
plot ob = over_Bought;
plot os = over_Sold;
ob.SetDefaultColor(Color.DARK_GRAY);
os.SetDefaultColor(Color.DARK_GRAY);


AddVerticalLine( (inverseRSI > 0) and (inverseRSI[1] < 0), "Entry BUY", Color.GRAY);
AddVerticalLine( (inverseRSI[1] > 0) and (inverseRSI < 0), "Entry SELL", Color.YELLOW);
Thanks @cos251.

@Chuck I think I found a bug in the current script in the PnL calculations.

In the Balance of Power script, short and long are defined like this:
Code:
def short = s2 < s3 and s2[1] > s3[1];
def long = s2 > s3 and s2[1] < s3[1];

However, the PnL defines short and longs like this:
Code:
if s2 < s3 then 1 else if s2 > s3 then -1 else orderDir[1]

Assuming the obvious, orderDir == 1 is for long, it is actually trading the opposite of what BOP is intending for signals. Am I missing something? If not, I'll correct this.

I also checked the BOP original forum post of BOP and it has the same issue.
https://usethinkscript.com/threads/balance-of-power-trend-indicator-for-thinkorswim.701/#post-25586
 
Does it have anything to do with trading both bullish and bearish? I am not sure. I watched it some and it seemed to be tracking wins and losses correctly. I haven't really paid that much attention to it. I will evaluate it on some simulated trades and update you ASAP.
 
Everyone, here is the Balanced BB Breakout v2.1.

Release notes:
  • Added RSI IFT
  • Added option to select between Balance of Power and RSI IFT
  • PnL is hidden by default now
  • Added BB Crossing options, crossing from above or below. You may want to alert on crossing below the upper BB band but alert when crossing above the lower BB band. You can also set this to zero or middle line for both if you like.
  • Changed how the Balance of Power order direction is calculated. @Chuck, I have good evidence that it was buying the BOP signal instead of selling and it was selling the BOP signal instead of buying. The vertical lines were correct, but the PnL calculation was reversed. Let me know if I am incorrect and we can revert it back.
  • Added an option to enter number of shares/contracts for PnL
Also, from the previous v2.0 cleanup, you can show/hide the PnL label and limit the PnL calculation to intra day.

I1kXW5T.png


Python:
# 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

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

# MACD_BB
input BBlength = 15;
input BBNum_Dev = 1.0;
input MACDfastLength = 12;
input MACDslowLength = 26;
input fastLengthMACD = 12;
input slowLengthMACD = 26;
input MACDLength = 25;
input averageTypeMACD = AverageType.WEIGHTED;
input showBreakoutSignals = no;

def MACD_Data = MACD(fastLength = MACDfastLength, slowLength = MACDslowLength, MACDLength = MACDLength);
plot MACD_Dots = MACD_Data;
plot MACD_Line = MACD_Data;

plot BB_Upper = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).UpperBand;
plot BB_Lower = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).Lowerband;
plot BB_Midline = reference BollingerBands(price = MACD_Line, length = BBlength, Num_Dev_Dn = -BBNum_Dev, Num_Dev_Up = BBNum_Dev).MidLine;

BB_Upper.SetDefaultColor(Color.RED);
BB_Lower.SetDefaultColor(Color.GREEN);
BB_Midline.SetDefaultColor(Color.LIGHT_RED);
BB_Midline.SetStyle(Curve.FIRM);

MACD_Line.AssignValueColor(
    if MACD_Line > MACD_Line[1] and MACD_Line >= BB_Upper then Color.GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line >= BB_Upper then Color.DARK_GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line <= BB_Lower then Color.RED else
    if MACD_Line > MACD_Line[1] and MACD_Line <= BB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACD_Line.SetLineWeight(1);

MACD_Dots.AssignValueColor(
    if MACD_Line > MACD_Line[1] and MACD_Line > BB_Upper then Color.GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line > BB_Upper then Color.DARK_GREEN
    else if MACD_Line < MACD_Line[1] and MACD_Line < BB_Lower then Color.RED
    else if MACD_Line > MACD_Line[1] and MACD_Line < BB_Lower then Color.DARK_RED
    else Color.GRAY
);
MACD_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
MACD_Dots.SetLineWeight(1);

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

# Keltner Channels
input factor = 1.5;
input length = 20;
input averageType = AverageType.EXPONENTIAL;
input trueRangeAverageType = AverageType.EXPONENTIAL;

def shift = factor * MovingAverage(trueRangeAverageType, TrueRange(high, close, low), length);
def average = MovingAverage(averageType, close, length);
def Upper_Band = average + shift;
def Lower_Band = average - shift;

# Bollinger Bands

input BBLength2 = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input bb_averageType = AverageType.SIMPLE;

def sDev = StDev(data = close, length = BBLength2);
def MidLine = MovingAverage(bb_averageType, data = close, length = BBLength2);
def LowerBand = MidLine + Num_Dev_Dn * sDev;
def UpperBand = MidLine + Num_Dev_up * sDev;

# BB Cloud

AddCloud(if UpperBand <= Upper_Band and LowerBand >= Lower_Band then BB_Upper else BB_Lower, BB_Lower, Color.YELLOW);
AddCloud(BB_Upper, BB_Lower, Color.LIGHT_RED);

# BB Alert

input BBCrossFromAboveAlert = {default "Zero", "Lower", "Middle", "Upper"};
input BBCrossFromBelowAlert = {default "Zero", "Lower", "Middle", "Upper"};

def BBCrossFromAboveVal = if BBCrossFromAboveAlert == BBCrossFromAboveAlert.Lower then BB_Lower
                          else if BBCrossFromAboveAlert == BBCrossFromAboveAlert.Upper then BB_Upper
                          else 0;
def BBCrossFromBelowVal = if BBCrossFromBelowAlert == BBCrossFromBelowAlert.Lower then BB_Lower
                          else if BBCrossFromBelowAlert == BBCrossFromBelowAlert.Upper then BB_Upper
                          else 0;

Alert(MACD_Line crosses above BBCrossFromBelowVal, "Time to Buy", Alert.BAR, Sound.Chimes);
Alert(MACD_Line crosses below BBCrossFromBelowVal, "Time to Sell", Alert.BAR, Sound.Bell);

# RSI/STOCASTIC/MACD CONFLUENCE COMBO

def Value = MovingAverage(averageTypeMACD, close, fastLengthMACD) - MovingAverage(averageTypeMACD, close, slowLengthMACD);
def Avg = MovingAverage(averageTypeMACD, Value, MACDLength);

plot Diff = Value - Avg;
Diff.SetDefaultColor(GetColor(5));
Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Diff.SetLineWeight(4);
Diff.DefineColor("Positive and Up", Color.GREEN);
Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
Diff.DefineColor("Negative and Down", Color.RED);
Diff.DefineColor("Negative and Up", Color.DARK_RED);
Diff.AssignValueColor(
    if Diff >= 0 then
        if Diff > Diff[1] then Diff.Color("Positive and Up") else Diff.Color("Positive and Down")
    else
        if Diff < Diff[1] then Diff.Color("Negative and Down") else Diff.Color("Negative and Up")
);

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

plot UpSignalMACD = if Diff crosses above ZeroLine then ZeroLine else Double.NaN;
UpSignalMACD.SetDefaultColor(Color.UPTICK);
UpSignalMACD.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
UpSignalMACD.SetHiding(!showBreakoutSignals);

plot DownSignalMACD = if Diff crosses below ZeroLine then ZeroLine else Double.NaN;
DownSignalMACD.SetDefaultColor(Color.DOWNTICK);
DownSignalMACD.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
DownSignalMACD.SetHiding(!showBreakoutSignals);

input lengthRSI = 7;
input averageTypeRSI = AverageType.EXPONENTIAL;

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

input KPeriod = 5;
input DPeriod = 3;
input averageTypeStoch = AverageType.WILDERS;

def SlowK = reference StochasticFull(80, 20, KPeriod, DPeriod, high, low, close, 3, averageTypeStoch).FullK;
def SlowD = reference StochasticFull(80, 20, KPeriod, DPeriod, high, low, close, 3, averageTypeStoch).FullD;

def rsiGreen = if RSI >= 50 then 1 else Double.NaN;
def rsiRed = if RSI < 50 then 1 else Double.NaN;
def stochGreen = if SlowK >= 50 then 1 else Double.NaN;
def stochRed = if SlowK < 50 then 1 else Double.NaN;
def macdGreen = if Value > Avg then 1 else Double.NaN;
def macdRed = if Value < Avg then 1 else Double.NaN;

input paintBars = yes;
AssignPriceColor(
    if paintBars and RSI >= 50 and SlowK >= 50 and Value > Avg then Color.GREEN
    else if paintBars and RSI < 50 and SlowK < 50 and Value < Avg then Color.RED
    else if paintBars then Color.DARK_GRAY
    else Color.CURRENT
);

# Shade areas based on criteria; adjust as needed

AddCloud(
    if rsiGreen and stochGreen and macdGreen then Double.POSITIVE_INFINITY else Double.NaN,
    if rsiGreen and stochGreen then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_GREEN
);
AddCloud(
    if rsiRed and stochRed and macdRed then Double.POSITIVE_INFINITY else Double.NaN,
    if rsiRed and stochRed then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_RED
);

# Balance of Power

input EMA = 20;
input TEMA = 20;

def THL = If(high != low, high - low, 0.01);
def BullOpen = (high - open) / THL;
def BearOpen = (open - low) / THL;
def BullClose = (close - low) / THL;
def BearClose = (high - close) / THL;
def BullOC = If(close > open, (close - open) / THL, 0);
def BearOC = If(open > close, (open - close) / THL, 0);
def BullReward = (BullOpen + BullClose + BullOC) / 1;
def BearReward = (BearOpen + BearClose + BearOC) / 1;

def BOP = BullReward - BearReward;
def SmoothBOP = ExpAverage(BOP, EMA);
def xPrice = SmoothBOP;
def xEMA1 = ExpAverage(SmoothBOP, TEMA);
def xEMA2 = ExpAverage(xEMA1, TEMA);
def xEMA3 = ExpAverage(xEMA2, TEMA);
def nRes = 3 * xEMA1 - 3 * xEMA2 + xEMA3;

def SmootherBOP = nRes;
def s1 = SmoothBOP;
def s2 = SmootherBOP;
def s3 = SmootherBOP[2];

def BOPshort = s2 < s3 and s2[1] > s3[1];
def BOPlong = s2 > s3 and s2[1] < s3[1];

# RSI IFT

def over_Bought = .5;
def over_Sold = -.5;

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

# Vertical Buy/Sell Signals

input buySellStrategy = { "BalanceOfPower", default "RSI_IFT" };

AddVerticalLine(if buySellStrategy == buySellStrategy.BalanceOfPower then BOPshort else RSI_IFT_Sell,
    close, Color.RED, Curve.SHORT_DASH);
AddVerticalLine(if buySellStrategy == buySellStrategy.BalanceOfPower then BOPlong else RSI_IFT_Buy,
    close, Color.GREEN, Curve.SHORT_DASH);

# P/L Statement

input PandL_Label = No;
input NumOfShares = 1;
input IntraDayOnly = Yes;

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

def orderDir =  if IntraDayOnly and (SecondsTillTime(930) > 0 or SecondsFromTime(1600) > 0) then 0
                else CompoundValue(1,
                        if buySellStrategy == buySellStrategy.BalanceOfPower then
                            if BOPlong then 1 else if BOPShort 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
);
 
Status
Not open for further replies.

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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