# My Brain in an Indicator, Created From A Life Time Of Trading by Ricky Gaspard on 7-22-2023
# This section defines the input parameters that users can customize when applying the indicator to a chart.
input length = 50;
input multiplier = 1.5;
input emaLengthBuy = 8;
input emaLengthSell = 8;
input vol_change_pct_threshold_up = 100.0;
input vol_change_pct_threshold_down = 100.0;
# This section calculates and displays the Bid and Ask prices on the chart, as well as the spread (Ask - Bid) between them. If the spread is greater than the Spread_limit parameter, the spread label is displayed in light red; otherwise, it is displayed in green.
#Bid, Ask, Spreads Label
input Spread_limit = 0.09;
def priceB = close(priceType = PriceType.BID);
def priceA = close(priceType = PriceType.ASK);
AddLabel(yes, Concat(" Bid: ", priceB + " "), Color.WHITE);
AddLabel(yes, Concat(" Ask: ", priceA + " "), Color.WHITE);
AddLabel(yes, Concat(" Spread: ", priceA - priceB + " "), if priceA - priceB > Spread_limit then Color.LIGHT_RED else Color.GREEN);
# This section calculates a simple moving average (MA) of the closing price over the specified length. It calculates the pullbackValue, which is the moving average minus a multiple of the True Range over the same length. The True Range is the greatest of the following: the difference between the high and low, the absolute value of the difference between the high and the previous close, and the absolute value of the difference between the low and the previous close.
# The boolean variable isPullback is set to true when the closing price is below the pullbackValue.
# The script checks for various conditions involving the previous candle's state and the EMAs (Exponential Moving Averages) to identify potential bullish and bearish signals related to pullbacks.
# Pullback Indicator
def ma = MovingAverage(AverageType.SIMPLE, close, length);
def pullbackValue = ma - multiplier * Average(TrueRange(high, close, low), length);
def isPullback = close < pullbackValue;
def ema = ExpAverage(close, emaLengthBuy);
def isFirstGreenCandle = !isPullback and close > open and close[1] <= open[1] and close > ema;
def isFirstRedCandle = isPullback and close < open and close[1] >= open[1];
def isFirstGreenAfterRed = Sum(isFirstGreenCandle, 1) == 1;
def isFirstRedAfterGreen = Sum(isFirstRedCandle, 1) == 1;
def emaconfirmation = MovAvgExponential("length" = 8)."AvgExp" is greater than MovAvgExponential("length" = 21)."AvgExp";
# This section calculates the relative volume (rel_vol) by dividing the current volume by the 50-day average volume.
# It calculates the percentage change in volume (vol_change_pct) compared to the average volume.
# Two boolean variables are defined:
# is_spike: It is set to true when the percentage change in volume (vol_change_pct) is greater than or equal to the vol_change_pct_threshold_up.
# is_spike_down: It is set to true when the percentage change in volume (vol_change_pct) is greater than or equal to the vol_change_pct_threshold_down.
# Volume Spike Indicator
def rel_vol = volume / Average(volume, 50);
def vol_change_pct = (rel_vol - 1.0) * 100.0;
def is_spike = vol_change_pct >= vol_change_pct_threshold_up;
def is_spike_down = vol_change_pct >= vol_change_pct_threshold_down;
# Condition for Pullback Arrow Down
def label_value = if is_spike then vol_change_pct else Double.NaN;
def is_bullish = close > open;
def is_bearish = close < open;
def ema_sell = ExpAverage(close, emaLengthSell);
# A downward-pointing arrow (arrowDown) is plotted on the chart when the following conditions are met:
# There is a volume spike (is_spike_down).
# The candle is bearish (is_bearish).
# The low of the candle is below the value of the ema_sell Exponential Moving Average.
# Pullback Arrow Down
def arrowDownCondition = is_spike_down and is_bearish and low < ema_sell;
plot arrowDown = if arrowDownCondition then low else Double.NaN;
arrowDown.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
arrowDown.SetLineWeight(2);
arrowDown.SetDefaultColor(Color.light_Red);
# An upward-pointing arrow (arrowUp) is plotted on the chart when the following conditions are met:
# There is a volume spike (is_spike).
# The candle is bullish (is_bullish).
# The high of the candle is above the value of the ema Exponential Moving Average.
# Pullback Arrow Up
def arrowUpCondition = is_spike and is_bullish and emaconfirmation and high > ema;
plot arrowUp = if arrowUpCondition then high else Double.NaN;
arrowUp.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
arrowUp.SetLineWeight(2);
arrowUp.SetDefaultColor(Color.GREEN);
# If the show_label input parameter is set to yes, this section adds labels to the chart indicating whether the volume spike is bullish or bearish.
# The label also displays the percentage change in volume relative to the average volume.
# The labels are colored green for bullish volume spikes, light red for bearish volume spikes, and black otherwise.
# Volume Spike Labels:
# Show/hide volume spike labels
input show_label = yes;
AddLabel(show_label,
if is_spike and is_bullish then Concat(AsPercent(vol_change_pct / 10000.0), " - BULLISH" + " ")
else if is_spike and is_bearish then Concat(AsPercent(vol_change_pct / 10000.0), " - BEARISH" + " ")
else "",
if is_spike and is_bullish then Color.GREEN
else if is_spike and is_bearish then Color.LIGHT_RED
else Color.BLACK);
# Plot EMA 8 and EMA 21
plot ema8 = ExpAverage(close, 8);
plot ema21 = ExpAverage(close, 21);
ema8.SetLineWeight(2);
ema21.SetLineWeight(2);
ema8.SetDefaultColor(Color.YELLOW);
ema21.SetDefaultColor(Color.BLUE);