Repaints B4 Balanced BB Breakout For ThinkOrSwim

Repaints
Status
Not open for further replies.
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
);
 

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

Amazing and lightning fast. I am just completely blown away. I cant express my gratitude enouth. I will be monitoring theP/L section to see if it is calculating correctly.

It’s a team work. Thank you and @cos251. I have a few more tweaks on the way to clean it up further.

I’ll watch it live again tomorrow. Let me know if anyone has more ideas.
 
I adjusted the bb number deviation to 1.5.....and the band crosses almost to the t on the balance of power. I have noticed if the BOP gives a sell signal and the RSI is still over the top band that a long position is till holding.

still checking out all the improvements. Love it so far. I noticed that the P/L stamens from BOP is better so far. I was not expecting that. And yes , thank you @cos251. I appreciate your hard work and everything you did to help out. Good team effort.

Check out what I am saying about the 1.5 setting on the bb number deviation. I think that is a game changer. maybe Im wrong...please guys weigh in and let me know what you think!!!!!
 
I adjusted the bb number deviation to 1.5.....and the band crosses almost to the t on the balance of power. I have noticed if the BOP gives a sell signal and the RSI is still over the top band that a long position is till holding.

still checking out all the improvements. Love it so far. I noticed that the P/L stamens from BOP is better so far. I was not expecting that. And yes , thank you @cos251. I appreciate your hard work and everything you did to help out. Good team effort.

Check out what I am saying about the 1.5 setting on the bb number deviation. I think that is a game changer. maybe Im wrong...please guys weigh in and let me know what you think!!!!!
Just nailed a 6pt move with /ES on 3200t TF.
 
Small update for PnL calculations. I believe I resolved some issues but removed the ability to limit to intraday only. May be @cos251 can add the intraday limit. I will need to rewrite the PnL calculator to make it work for only intraday.

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
# v2.2 - Barbaros - fixed PnL issues and removed intraDay filter

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;

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

def orderDir =  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
);
 
Small update for PnL calculations. I believe I resolved some issues but removed the ability to limit to intraday only. May be @cos251 can add the intraday limit. I will need to rewrite the PnL calculator to make it work for only intraday.

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
# v2.2 - Barbaros - fixed PnL issues and removed intraDay filter

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;

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

def orderDir =  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
);
I monitored this today. I really like the ability to choose what line of the BB is crossed to be alerted.

I noticed when the stock is balanced and in equilibrium, (all BB lines tight) any little move in price action makes it jump.

in those instances I want to be notified when the highet BB is crossed from underneath (for bullish trades).

Price will be bouncing from top to bottom across the middle and everywhere in that situation and it only means something to me when it comes from underneath and then crosses over the top BB. In my experience that will confirm a strong move to the upside.
 
I monitored this today. I really like the ability to choose what line of the BB is crossed to be alerted.

I noticed when the stock is balanced and in equilibrium, (all BB lines tight) any little move in price action makes it jump.

in those instances I want to be notified when the highet BB is crossed from underneath (for bullish trades).

Price will be bouncing from top to bottom across the middle and everywhere in that situation and it only means something to me when it comes from underneath and then crosses over the top BB. In my experience that will confirm a strong move to the upside.

That’s how I executed it today too @Chuck. May be we can put together a chart combo for trading ES.
 
Last edited:
First off thanks to all who created this indicator. I really like it and have been using it on all my charts. I was curious if the new version has the option for a tick chart. I didn't see it and I was wondering if it makes a huge difference. I'm very new at this and really appreciate all the great work you guys do.
 
First off thanks to all who created this indicator. I really like it and have been using it on all my charts. I was curious if the new version has the option for a tick chart. I didn't see it and I was wondering if it makes a huge difference. I'm very new at this and really appreciate all the great work you guys do.

It works on tick charts. I use tick charts sometimes.
 
Status
Not open for further replies.

BenTen's Watchlist + Setup + Trade Recaps

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

Learn more

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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