beta2 - removed InSync until we find a solution for indicies.
Code:
# Balanced BB Breakout Indicator
# Free for use. Header credits must be included when any form of the code included in this package is used.
# User assumes all risk. Author not responsible for errors or use of tool.
# v1.2 - Assembled by Chuck Edwards
# v2.0 - Barbaros - cleanup
# v2.1 - Barbaros - added RSI IFT, NumberOfShares, BB crossing options
# v2.2 - Barbaros - fixed PnL issues and removed intraDay filter
# beta2 - Barbaros - changed input and variable names, RSM is re-done
declare lower;
### Market Forecast
def pIntermediate = MarketForecast().Intermediate;
AddLabel(yes,
"Market Forecast " +
if pIntermediate >= 80 then "Bullish" else
if pIntermediate <= 20 then "Bearish" else
if pIntermediate > pIntermediate[1] then "Rising" else
if pIntermediate < pIntermediate[1] then "Falling" else " ",
if pIntermediate >= 80 then CreateColor(204, 255, 204) else # Pre_Cyan
if pIntermediate <= 20 then Color.RED else
if pIntermediate > pIntermediate[1] then CreateColor(0, 165, 0) else # LabelGreen
if pIntermediate < pIntermediate[1] then Color.RED else Color.LIGHT_GRAY
);
### MACDBB
input MACDBB_FastLength = 12;
input MACDBB_SlowLength = 26;
input MACDBB_Length = 25;
input MACDBB_BandLength = 15;
input MACDBB_NumDev = 1.0;
def MACDBB_Data = MACD(fastLength = MACDBB_FastLength, slowLength = MACDBB_SlowLength, MACDLength = MACDBB_Length);
plot MACDBB_Dots = MACDBB_Data;
plot MACDBB_Line = MACDBB_Data;
plot MACDBB_Upper = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).UpperBand;
plot MACDBB_Lower = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).Lowerband;
plot MACDBB_Midline = reference BollingerBands(price = MACDBB_Line, length = MACDBB_BandLength, Num_Dev_Dn = -MACDBB_NumDev, Num_Dev_Up = MACDBB_NumDev).MidLine;
MACDBB_Upper.SetDefaultColor(Color.RED);
MACDBB_Lower.SetDefaultColor(Color.GREEN);
MACDBB_Midline.SetDefaultColor(Color.LIGHT_RED);
MACDBB_Midline.SetStyle(Curve.FIRM);
MACDBB_Line.AssignValueColor(
if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line >= MACDBB_Upper then Color.GREEN
else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line >= MACDBB_Upper then Color.DARK_GREEN
else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line <= MACDBB_Lower then Color.RED else
if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line <= MACDBB_Lower then Color.DARK_RED
else Color.GRAY
);
MACDBB_Line.SetLineWeight(1);
MACDBB_Dots.AssignValueColor(
if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.GREEN
else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.DARK_GREEN
else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.RED
else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.DARK_RED
else Color.GRAY
);
MACDBB_Dots.SetPaintingStrategy(PaintingStrategy.LINE_VS_POINTS);
MACDBB_Dots.SetLineWeight(1);
AddLabel(yes,
"Trend " +
if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then "Bullish"
else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then "Falling"
else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then "Bearish"
else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then "Rising"
else "Neutral",
if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.GREEN
else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line > MACDBB_Upper then Color.DARK_GREEN
else if MACDBB_Line < MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.RED
else if MACDBB_Line > MACDBB_Line[1] and MACDBB_Line < MACDBB_Lower then Color.DARK_RED
else Color.GRAY
);
### MACD BB Alert
input MACDBB_CrossFromAboveAlert = {default "Zero", "Lower", "Middle", "Upper"};
input MACDBB_CrossFromBelowAlert = {default "Zero", "Lower", "Middle", "Upper"};
def MACDBB_CrossFromAboveVal = if MACDBB_CrossFromAboveAlert == MACDBB_CrossFromAboveAlert.Lower then MACDBB_Lower
else if MACDBB_CrossFromAboveAlert == MACDBB_CrossFromAboveAlert.Upper then MACDBB_Upper
else 0;
def MACDBB_CrossFromBelowVal = if MACDBB_CrossFromBelowAlert == MACDBB_CrossFromBelowAlert.Lower then MACDBB_Lower
else if MACDBB_CrossFromBelowAlert == MACDBB_CrossFromBelowAlert.Upper then MACDBB_Upper
else 0;
Alert(MACDBB_Line crosses above MACDBB_CrossFromAboveVal, "Time to Buy", Alert.BAR, Sound.Chimes);
Alert(MACDBB_Line crosses below MACDBB_CrossFromBelowVal, "Time to Sell", Alert.BAR, Sound.Bell);
### Keltner Channels
input Keltner_Factor = 1.5;
input Keltner_length = 20;
input Keltner_AverageType = AverageType.EXPONENTIAL;
input Keltner_TrueRangeAverageType = AverageType.EXPONENTIAL;
def Keltner_Shift = Keltner_Factor * MovingAverage(Keltner_TrueRangeAverageType, TrueRange(high, close, low), Keltner_length);
def Keltner_Average = MovingAverage(Keltner_AverageType, close, Keltner_length);
def Keltner_Upper_Band = Keltner_Average + Keltner_Shift;
def Keltner_Lower_Band = Keltner_Average - Keltner_Shift;
### Bollinger Bands
input BB_Length = 20;
input BB_NumDevDn = -2.0;
input BB_NumDevUp = 2.0;
input BB_AverageType = AverageType.SIMPLE;
def BB_SDev = StDev(data = close, length = BB_Length);
def BB_MidLine = MovingAverage(BB_AverageType, data = close, length = BB_Length);
def BB_LowerBand = BB_MidLine + BB_NumDevDn * BB_SDev;
def BB_UpperBand = BB_MidLine + BB_NumDevUp * BB_SDev;
# BB Cloud
AddCloud(if BB_UpperBand <= Keltner_Upper_Band and BB_LowerBand >= Keltner_Lower_Band then MACDBB_Upper else MACDBB_Lower, MACDBB_Lower, Color.YELLOW);
AddCloud(MACDBB_Upper, MACDBB_Lower, Color.LIGHT_RED);
### RSI/STOCASTIC/MACD CONFLUENCE COMBO
input RSM_MACD_ShowBreakoutSignals = no;
plot RSM_MACD_Diff = reference MACD("fast length" = 12, "slow length" = 26, "macd length" = 9).Diff;
RSM_MACD_Diff.SetDefaultColor(GetColor(5));
RSM_MACD_Diff.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
RSM_MACD_Diff.SetLineWeight(4);
RSM_MACD_Diff.DefineColor("Positive and Up", Color.GREEN);
RSM_MACD_Diff.DefineColor("Positive and Down", Color.DARK_GREEN);
RSM_MACD_Diff.DefineColor("Negative and Down", Color.RED);
RSM_MACD_Diff.DefineColor("Negative and Up", Color.DARK_RED);
RSM_MACD_Diff.AssignValueColor(
if RSM_MACD_Diff >= 0 then
if RSM_MACD_Diff > RSM_MACD_Diff[1] then RSM_MACD_Diff.Color("Positive and Up") else RSM_MACD_Diff.Color("Positive and Down")
else
if RSM_MACD_Diff < RSM_MACD_Diff[1] then RSM_MACD_Diff.Color("Negative and Down") else RSM_MACD_Diff.Color("Negative and Up")
);
plot RSM_MACD_ZeroLine = 0;
RSM_MACD_ZeroLine.SetDefaultColor(Color.RED);
RSM_MACD_ZeroLine.HideTitle();
RSM_MACD_ZeroLine.HideBubble();
plot RSM_MACD_UpSignal = if RSM_MACD_Diff crosses above RSM_MACD_ZeroLine then RSM_MACD_ZeroLine else Double.NaN;
RSM_MACD_UpSignal.SetDefaultColor(Color.UPTICK);
RSM_MACD_UpSignal.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
RSM_MACD_UpSignal.SetHiding(!RSM_MACD_ShowBreakoutSignals);
plot RSM_MACD_DownSignal = if RSM_MACD_Diff crosses below RSM_MACD_ZeroLine then RSM_MACD_ZeroLine else Double.NaN;
RSM_MACD_DownSignal.SetDefaultColor(Color.DOWNTICK);
RSM_MACD_DownSignal.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
RSM_MACD_DownSignal.SetHiding(!RSM_MACD_ShowBreakoutSignals);
def RSM_RSI = reference RSI(length = 7).RSI;
def RSM_Stoch_Val = 100 * (close - lowest(low, 14)) / (highest(high, 14) - lowest(low, 14));
def RSM_StochSlowK = SimpleMovingAvg(SimpleMovingAvg(RSM_Stoch_Val,3),3);
def RSM_rsiGreen = RSM_RSI >= 50;
def RSM_rsiRed = RSM_RSI < 50;
def RSM_stochGreen = RSM_StochSlowK >= 50;
def RSM_stochRed = RSM_StochSlowK < 50;
def RSM_macdGreen = RSM_MACD_Diff >= 0;
def RSM_macdRed = RSM_MACD_Diff < 0;
input RSM_PaintBars = yes;
AssignPriceColor(
if RSM_PaintBars and RSM_rsiGreen and RSM_stochGreen and RSM_macdGreen then Color.GREEN
else if RSM_PaintBars and RSM_rsiRed and RSM_stochRed and RSM_macdRed then Color.RED
else if RSM_PaintBars then Color.DARK_GRAY
else Color.CURRENT
);
# Shade areas based on criteria; adjust as needed
AddCloud(
if RSM_rsiGreen and RSM_stochGreen and RSM_macdGreen then Double.POSITIVE_INFINITY else Double.NaN,
if RSM_rsiGreen and RSM_stochGreen then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_GREEN
);
AddCloud(
if RSM_rsiRed and RSM_stochRed and RSM_macdRed then Double.POSITIVE_INFINITY else Double.NaN,
if RSM_rsiRed and RSM_stochRed then Double.NEGATIVE_INFINITY else Double.NaN, Color.LIGHT_RED
);
### Balance of Power
input BOP_EMA_Length = 20;
input BOP_TEMA_Length = 20;
def BOP_THL = If(high != low, high - low, 0.01);
def BOP_BullOpen = (high - open) / BOP_THL;
def BOP_BearOpen = (open - low) / BOP_THL;
def BOP_BullClose = (close - low) / BOP_THL;
def BOP_BearClose = (high - close) / BOP_THL;
def BOP_BullOC = If(close > open, (close - open) / BOP_THL, 0);
def BOP_BearOC = If(open > close, (open - close) / BOP_THL, 0);
def BOP_BullReward = (BOP_BullOpen + BOP_BullClose + BOP_BullOC) / 1;
def BOP_BearReward = (BOP_BearOpen + BOP_BearClose + BOP_BearOC) / 1;
def BOP_BOP = BOP_BullReward - BOP_BearReward;
def BOP_SmoothBOP = ExpAverage(BOP_BOP, BOP_EMA_Length);
def BOP_xPrice = BOP_SmoothBOP;
def BOP_xEMA1 = ExpAverage(BOP_SmoothBOP, BOP_TEMA_Length);
def BOP_xEMA2 = ExpAverage(BOP_xEMA1, BOP_TEMA_Length);
def BOP_xEMA3 = ExpAverage(BOP_xEMA2, BOP_TEMA_Length);
def BOP_nRes = 3 * BOP_xEMA1 - 3 * BOP_xEMA2 + BOP_xEMA3;
def BOP_SmootherBOP = BOP_nRes;
def BOP_s1 = BOP_SmoothBOP;
def BOP_s2 = BOP_SmootherBOP;
def BOP_s3 = BOP_SmootherBOP[2];
def BOP_Sell = BOP_s2 < BOP_s3 and BOP_s2[1] > BOP_s3[1];
def BOP_Buy = BOP_s2 > BOP_s3 and BOP_s2[1] < BOP_s3[1];
### RSI IFT
def RSI_IFT_R = reference RSI(5, close) - 50;
def RSI_IFT_AvgRSI = MovingAverage(AverageType.Exponential,RSI_IFT_R,9);
def RSI_IFT_InverseRSI = (Power(Double.E, 2 * RSI_IFT_AvgRSI) - 1) / (Power(Double.E, 2 * RSI_IFT_AvgRSI) + 1);
def RSI_IFT_Buy = (RSI_IFT_InverseRSI > 0) and (RSI_IFT_InverseRSI[1] < 0);
def RSI_IFT_Sell = (RSI_IFT_InverseRSI[1] > 0) and (RSI_IFT_InverseRSI < 0);
### Vertical Buy/Sell Signals
input BuySellStrategy = { "BalanceOfPower", "InSync", default "RSI_IFT" };
AddVerticalLine(
if BuySellStrategy == BuySellStrategy.BalanceOfPower then BOP_Sell
else RSI_IFT_Sell,
close, Color.RED, Curve.SHORT_DASH);
AddVerticalLine(
if BuySellStrategy == BuySellStrategy.BalanceOfPower then BOP_Buy
else RSI_IFT_Buy,
close, Color.GREEN, Curve.SHORT_DASH);
### P/L Statement
input PandL_Label = No;
input NumOfShares = 1;
Assert(NumOfShares >= 1, "Number of Shares needs to be equal or grater than 1");
def orderDir = CompoundValue(1,
if BuySellStrategy == BuySellStrategy.BalanceOfPower then
if BOP_Buy then 1 else if BOP_Sell then -1 else orderDir[1]
else
if RSI_IFT_Buy then 1 else if RSI_IFT_Sell then -1 else orderDir[1]
, 0);
def isOrder = orderDir crosses 0;
def orderCount = CompoundValue(1, if IsNaN(isOrder) then 0 else if isOrder then orderCount[1] + 1 else orderCount[1], 0);
def noBar = IsNaN(open[-1]);
def orderPrice = if isOrder then if noBar then close else open[-1] else orderPrice[1];
def profitLoss = if !isOrder or orderCount == 1 then 0
else if orderDir > 0 then orderPrice[1] - orderPrice
else if orderDir < 0 then orderPrice - orderPrice[1]
else 0;
def profitLossSum = CompoundValue(1, if IsNaN(isOrder) then 0 else if isOrder then profitLossSum[1] + profitLoss else profitLossSum[1], 0);
def orderWinners = CompoundValue(1, if IsNaN(isOrder) then orderWinners[1] else if orderCount > 1 and profitLoss > 0 then orderWinners[1] + 1 else orderWinners[1], 0);
AddLabel(PandL_Label,
orderCount + " orders (" + AsPercent(orderWinners / orderCount) + ") | P/L " + AsDollars ((profitLossSum / TickSize()) * TickValue() * NumOfShares),
if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY
);