Smart Money Oscillator
Updated
January 8, 2024
TradingView

For free use on the TradingView platform

The "Smart Money Oscillator " is a premium and discount zone oscillator with BOS and CHoCH built in for further analysis of price action. This indicator works by first determining the the premium and discount zones by using pivot points and high/lows. The top of this oscillator represents the current premium zone while the bottom half of this oscillator represents the discount zone. This oscillator functionally works like a stochastic oscillator with more sophisticated upper and lower bounds generated using smart money concept theories. We have included a moving average to allow the user to visualize the currant momentum in the oscillator. Another key feature we have included lagging divergences to help traders visualize potential reversal conditions.

Understanding the concepts of Premium and Discount zones, as well as Break of Structure (BoS) and Change of Character (CHoCH), is crucial for traders using the Smart Money Oscillator. These concepts are rooted in market structure analysis, which involves studying price levels and movements.

Premium Zone is where the price is considered to be relatively high or 'overbought'. In this zone, prices have risen significantly and may indicate that the asset is becoming overvalued, potentially leading to a reversal or slowdown in the upward trend.

The Discount Zone represents a 'discount' or 'oversold' area. Here, prices have fallen substantially, suggesting that the asset might be undervalued. This could be an indicator of a potential upward reversal or a pause in the downward trend.

Break of Structure (BoS) is about the continuation of a trend. In a bullish trend, a BoS is identified by the break of a recent higher high. In a bearish trend, it's the break of a recent Lower Low. BoS indicates that the trend is strong and likely to continue in its current direction. It's a sign of strength in the prevailing trend, whether up or down.

Change of Character (CHoCH) is an indication of a potential end to a trend. It occurs when there's a significant change in the market's behavior, contradicting the current trend. For example, in an uptrend characterized by higher highs and higher lows, a CHoCH may occur if a new high is formed but then is followed by an impulsive move downwards. This suggests that the bullish trend may be weakening and a bearish reversal could be imminent. CHoCH is essentially a sign of trend exhaustion and potential reversal.

With each consecutive BoS, the signal line of the oscillator will deepen in color. This allows you to visually see the strength of the current trend. The maximum strength of the trend is found by keeping track of the maximum number of consecutive BoS's within a window of 10. This calculation excludes periods without any BoS's to allow for a more stable max.

Quick Update is a feature that implements a more aggressive algorithm to update the highs and lows. Instead of updating the pivot points exclusively to update the range levels, it will attempt to use the current historical highs/lows to update the bounds. This results in a more responsive range at the cost of stability. There are pros and cons for both settings. With Quick Update disabled, the indicator will allow for strong reversals to register without the indicator maxing out. With Quick Update enabled, the indicator will show shorter term extremes with the risk of the signal being pinned to the extremities during strong trends or large movements. With Quick Update disabled, the oscillator prioritizes stability, using a more historical perspective to set its bounds. When Quick Update is enabled, the oscillator becomes more responsive, adjusting its bounds rapidly to reflect the latest market movements.

The Scale Offset feature allows the indicator to break the boundaries of the oscillator. This can be useful when the market is breaking highs or lows allowing the user to identify extremities in price. With Scale Offset disabled the oscillator will always remain inside of the boundaries because the extremities will be updated instantly. When this feature is enabled it will update the boundaries one step behind instead of updating it instantly. This allows the user to more easily see overbought and oversold conditions at the cost of incurring a single bar lag to the boundaries. Generally this is a good idea as this behavior makes the oscillator more sensitive to recent price spikes or drops, reflecting sudden market movements more accurately. It accentuates the extremities of the market conditions, potentially offering a more aggressive analysis. The main trade-off with the Scale Offset feature is between sensitivity and potential overreaction. It offers a more immediate and exaggerated reflection of market conditions but might also lead to misinterpretations in certain scenarios, especially in highly volatile markets.

Divergence is used to predict potential trend reversals. It occurs when the price of an asset and the reading of an oscillator move in opposite directions. This discrepancy can signal a weakening of the current trend and possibly indicate a potential reversal.

Divergence doesn't always lead to a trend reversal, but it's a warning sign that the current trend might be weakening. Divergence can sometimes give false signals, particularly in strongly trending markets where the oscillator may remain in overbought or oversold conditions for extended periods. The lagging nature of using pivot points to calculate divergences means that all divergences are limited by the pivot look forward input. The upside of using a longer look forward is that the divergences will be more accurate. The obvious con here is that it will be more delayed and might be useless by the time it appears. Its recommended to use the built in divergences as a way to learn how these are formed so you can make your own in real time.

By default, the oscillator uses a smoothing of 3 to allow for a more price like behavior while still being rather smooth compared to raw price data. Conversely, you can increase this value to make this indicator behave smoother. Something to keep in mind is that the amount of delay from real time is equal to half of the smoothing period.

We have included a verity of alerts in this indicator. Here is a list of all of the available alerts: Bullish BOS, Bearish BOS, Bullish CHoCH, Bearish CHoCH, Bullish Divergence, Hidden Bullish Divergence, Bearish Divergence, Hidden Bearish Divergence, Cross Over Average, Cross Under Average.

Below are all of the inputs and their tooltips to get you started:

Settings:

  • Smoothing: Specifies the degree of smoothing applied to the oscillator. Higher values result in smoother but potentially less responsive signals.
  • Average Length: Sets the length of the moving average applied to the oscillator, affecting its sensitivity and smoothness.
  • Pivot Length: Specifies the forward-looking length for pivot points, affecting how the oscillator anticipates future price movements. This directly impacts the delay in finding a pivot.
  • Max Length: Sets the maximum length to consider for calculating the highest values in the oscillator.
  • Min Length: Defines the minimum length for calculating the lowest values in the oscillator.
  • Quick Update: Activates a faster update mode for the oscillator's extremities, which may result in less stable range boundaries.
  • Scale Offset: When enabled, delays updating minimum and maximum values to enhance signal directionality, allowing the signal to occasionally exceed normal bounds.
  • Candle Color: Enables coloring of candles based on the current directional signal of the oscillator.

Labels:

  • Enable BOS/CHoCH Labels: Activates the display of BOS (Break of Structure) and CHoCH (Change of Character) labels on the chart.
  • Visual Padding: Turns on additional visual padding at the top and bottom of the chart to accommodate labels. Determines the amount of visual padding added to the chart for label display.

Divergence:

  • Divergence Pivot: Defines the number of bars to the right of the pivot in divergence calculations, influencing the oscillator's responsiveness.
  • Divergence Pivot Forward: Directly impacts latency. Longer periods results in more accurate results at the sacrifice of delay.
  • Upper Range: Sets the upper range limit for divergence calculations, influencing the oscillator's sensitivity to larger trends.
  • Lower Range: Determines the lower range limit for divergence calculations, affecting the oscillator's sensitivity to shorter trends.
  • Symbol: Allows selection of the label style for divergence indicators, with options for text or symbolic representation.
  • Regular Bullish: Activates the detection and marking of regular bullish divergences in the oscillator.
  • Hidden Bullish: Enables the identification and display of hidden bullish divergences.
  • Regular Bearish: Turns on the feature to detect and highlight regular bearish divergences.
  • Hidden Bearish: Activates the functionality for detecting and displaying hidden bearish divergences.

Color:

  • Bullish: Determines the minimum/maximum color gradient for bullish signals, impacting the chart's visual appearance.
  • Bearish: Defines the minimum/maximum color gradient for bearish signals, affecting their visual representation.
  • Average: Specifies the color for the average line of the oscillator, enhancing chart readability.
  • CHoCH: Sets the color for bullish/bearish CHoCH (Change of Character) signals.
  • Premium/Discount: Determines the color for the premium/discount zone in the oscillator's visual representation.
  • Text Color: Sets the color for the text in BoS/CHoCH labels.
  • Regular Bullish: Defines the color used to represent regular bullish divergences.
  • Hidden Bullish: Specifies the color for hidden bullish divergences.
  • Regular Bearish: Determines the color for hidden bearish divergences.
  • Divergence Text Color: Specifies the color for the text in divergence labels.


// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ChartPrime

//@version=5
indicator("Smart Money Oscillator [ChartPrime]", overlay = false, max_labels_count = 500, max_lines_count = 500)

smoothing = input.int(
   10
 , "Smoothing"
 , minval = 1
 , group = "Settings"
 , tooltip = "Specifies the degree of smoothing applied to the oscillator. Higher values result in smoother but 
     potentially less responsive signals."
 )

average = input.int(
   20
 , "Average Length"
 , minval = 1
 , group = "Settings"
 , tooltip = "Sets the length of the moving average applied to the oscillator, affecting its sensitivity and smoothness."
 )

pivot_length = input.int(
   30
 , "Pivot Length"
 , minval = 1
 , group = "Settings"
 , tooltip = "Determines the length of the pivot points used in calculating the oscillator. Longer lengths can provide 
     a more stable but less responsive signal."
 )

pivot_length_forward = input.int(
   20
 , "Pivot Forward Length"
 , minval = 1
 , group = "Settings"
 , tooltip = "Specifies the forward-looking length for pivot points, affecting how the oscillator anticipates 
     future price movements. This directly impacts the delay in finding a pivot."
 )

max_high_length = input.int(
   20
 , "Max Length"
 , minval = 1
 , group = "Settings"
 , tooltip = "Sets the maximum length to consider for calculating the highest values in the oscillator."
 )

min_low_length = input.int(
   20
 , "Min Length"
 , minval = 1
 , group = "Settings"
 , tooltip = "Defines the minimum length for calculating the lowest values in the oscillator."
 )

quick_update = input.bool(
   false
 , "Quick Update"
 , group = "Settings"
 , tooltip = "Activates a faster update mode for the oscillator's extremities, which may result in less stable 
     range boundaries."
 )

accentuate = input.bool(
   true
 , "Scale Offset"
 , group = "Settings"
 , tooltip = "When enabled, delays updating minimum and maximum values to enhance signal directionality, allowing the 
     signal to occasionally exceed normal bounds."
 )

candle_color = input.bool(
   false
 , "Candle Color"
 , group = "Settings"
 , tooltip = "Enables coloring of candles based on the current directional signal of the oscillator."
 )

enable_labels = input.bool(
   true
 , "Enable BOS/CHoCH Labels"
 , group = "Labels"
 , tooltip = "Activates the display of BOS (Break of Structure) and CHoCH (Change of Character) labels on the chart."
 )

enable_visual_padding = input.bool(
   true
 , "Visual Padding"
 , group = "Labels"
 , inline = "Padding"
 )

padding_level = input.int(
   30
 , ""
 , minval = 0
 , group = "Labels"
 , inline = "Padding"
 , tooltip = "Turns on additional visual padding at the top and bottom of the chart to accommodate labels.\n
     Determines the amount of visual padding added to the chart for label display."
 )

right = input.int(
   20
 , "Divergence Pivot"
 , minval = 1
 , group = "Divergence"
 , tooltip = "Defines the number of bars to the right of the pivot in divergence calculations, influencing the 
     oscillator's responsiveness."
 )

left = input.int(
   20
 , "Divergence Pivot Forward"
 , minval = 1
 , group = "Divergence"
 , tooltip = "Directly impacts latency. Longer periods results in more accurate results at the sacrifice of delay."
 )

upper_range = input.int(
   500
 , "Upper Range"
 , minval = 0
 , group = "Divergence"
 , tooltip = "Sets the upper range limit for divergence calculations, influencing the oscillator's sensitivity to 
     larger trends."
 )

lower_range = input.int(
   25
 , "Lower Range"
 , minval = 0
 , group = "Divergence"
 , tooltip = "Determines the lower range limit for divergence calculations, affecting the oscillator's sensitivity to 
     shorter trends."
 )

labels = input.string(
   "Symbol"
 , "Divergence Label Style"
 , ["Text", "Symbol"]
 , group = "Divergence"
 , tooltip = "Allows selection of the label style for divergence indicators, with options for text or symbolic 
     representation."
 )

enable_regular_bullish = input.bool(
   true
 , "Regular Bullish"
 , group = "Divergence"
 , tooltip = "Activates the detection and marking of regular bullish divergences in the oscillator."
 )

enable_hidden_bullish = input.bool(
   false
 , "Hidden Bullish"
 , group = "Divergence"
 , tooltip = "Enables the identification and display of hidden bullish divergences."
 )

enable_regular_bearish = input.bool(
   true
 , "Regular Bearish"
 , group = "Divergence"
 , tooltip = "Turns on the feature to detect and highlight regular bearish divergences."
 )

enable_hidden_bearish = input.bool(
   false
 , "Hidden Bearish"
 , group = "Divergence"
 , tooltip = "Activates the functionality for detecting and displaying hidden bearish divergences."
 )

bullish_color_min = input.color(
   #52FF52
 , "Bullish"
 , group = "Color"
 , inline = "Bullish"
 )

bullish_color_max = input.color(
   #00AA00
 , ""
 , group = "Color"
 , inline = "Bullish"
 , tooltip = "Determines the minimum/maximum color gradient for bullish signals, impacting the chart's visual appearance."
 )

bearish_color_min = input.color(
   #FF5252
 , "Bearish"
 , group = "Color"
 , inline = "Bearish"
 )

bearish_color_max = input.color(
   #AA0000
 , ""
 , group = "Color"
 , inline = "Bearish"
 , tooltip = "Defines the minimum/maximum color gradient for bearish signals, affecting their visual representation."
 )

average_color = input.color(
   #ff9a16
 , "Average"
 , group = "Color"
 , tooltip = "Specifies the color for the average line of the oscillator, enhancing chart readability."
 )

choch_bullish_color = input.color(
   #22ff22
 , "CHoCH"
 , group = "Color"
 , inline = "CHoCH"
 )

choch_bearish_color = input.color(
   #FF2222
 , ""
 , group = "Color"
 , inline = "CHoCH"
 , tooltip = "Sets the color for bullish/bearish CHoCH (Change of Character) signals."
 )

premium_color = input.color(
   #FF2222
 , "Premium/Discount"
 , group = "Color"
 , inline = "Boundry"
 )

discount_color = input.color(
   #22ff22
 , ""
 , group = "Color"
 , inline = "Boundry"
 , tooltip = "Determines the color for the premium/discount zone in the oscillator's visual representation."
 )

text_color = input.color(
   #EEEEEE
 , "Text Color"
 , group = "Color"
 , tooltip = "Sets the color for the text in BoS/CHoCH labels"
 )

regular_bullish_color = input.color(
   #55FF77
 , "Regular Bullish"
 , group = "Color"
 , tooltip = "Defines the color used to represent regular bullish divergences."
 )

hidden_bullish_color = input.color(
   #5577FF
 , "Hidden Bullish"
 , group = "Color"
 , tooltip = "Specifies the color for hidden bullish divergences."
 )

regular_bearish_color = input.color(
   #FF3333
 , "Regular Bearish"
 , group = "Color"
 , tooltip = "Sets the color for regular bearish divergence signals."
 )

hidden_bearish_color = input.color(
   #FF8833
 , "Hidden Bearish"
 , group = "Color"
 , tooltip = "Determines the color for hidden bearish divergences."
 )

text_color_div = input.color(
   #000000
 , "Divergence Text Color"
 , group = "Color"
 , tooltip = "Specifies the color for the text in divergence labels."
 )


type nibble
    bool a = na
    bool b = na
    bool c = na
    bool d = na

in_range(bool cond, int lower_range, int upper_range) =>
    bars = ta.barssince(cond == true)
    lower_range <= bars and bars <= upper_range

divergence(
 float source, 
 int right, 
 int left, 
 int upper_range, 
 int lower_range, 
 bool enable_regular_bullish, 
 color regular_bullish_color,
 bool enable_hidden_bullish, 
 color hidden_bullish_color,
 bool enable_regular_bearish, 
 color regular_bearish_color,
 bool enable_hidden_bearish, 
 color hidden_bearish_color,
 string labels,
 color text_color) =>
    repaint = barstate.ishistory or barstate.isconfirmed
    
    pl = na(ta.pivotlow(source, left, right)) ? false : true
    ph = na(ta.pivothigh(source, left, right)) ? false : true

    source_hl = source[right] > ta.valuewhen(pl, source[right], 1) and in_range(pl[1], lower_range, upper_range)
    price_ll = low[right] < ta.valuewhen(pl, low[right], 1)
    bullish_condition = enable_regular_bullish and price_ll and source_hl and pl and repaint
    
    oscLL = source[right] < ta.valuewhen(pl, source[right], 1) and in_range(pl[1], lower_range, upper_range)
    priceHL = low[right] > ta.valuewhen(pl, low[right], 1)
    hidden_bullish_condition = enable_hidden_bullish and priceHL and oscLL and pl and repaint
    
    oscLH = source[right] < ta.valuewhen(ph, source[right], 1) and in_range(ph[1], lower_range, upper_range)
    priceHH = high[right] > ta.valuewhen(ph, high[right], 1)
    bearish_condition = enable_regular_bearish and priceHH and oscLH and ph and repaint
    
    oscHH = source[right] > ta.valuewhen(ph, source[right], 1) and in_range(ph[1], lower_range, upper_range)
    priceLH = high[right] < ta.valuewhen(ph, high[right], 1)
    hidden_bearish_condition = enable_hidden_bearish and priceLH and oscHH and ph and repaint
    
    offset = -right

    var float current_bullish_value = 0
    var int current_bull_idx = 0
    var float last_bullish_value = 0
    var int last_bullish_idx = 0
    var float current_hidden_bullish_value = 0
    var int current_hidden_bullish_idx = 0
    var float last_hidden_bullish_value = 0
    var int last_hidden_bullish_idx = 0
    var float current_bearish_value = 0
    var int current_bearish_idx = 0
    var float last_bearish_value = 0
    var int last_bearish_idx = 0
    var float current_hidden_bearish_value = 0
    var int current_hidden_bearish_idx = 0
    var float last_hidden_bearish_idx = 0
    var int last_hidden_bearish_value = 0

    if pl
        last_bullish_value := current_bullish_value
        last_bullish_idx := current_bull_idx
        current_bullish_value := source[right]
        current_bull_idx := bar_index - right
        last_hidden_bullish_value := current_hidden_bullish_value
        last_hidden_bullish_idx := current_hidden_bullish_idx
        current_hidden_bullish_value := source[right]
        current_hidden_bullish_idx := bar_index - right

    if ph
        last_bearish_value := current_bearish_value
        last_bearish_idx := current_bearish_idx
        current_bearish_value := source[right]
        current_bearish_idx := bar_index - right
        last_hidden_bearish_idx := current_hidden_bearish_value
        last_hidden_bearish_value := current_hidden_bearish_idx
        current_hidden_bearish_value := source[right]
        current_hidden_bearish_idx := bar_index - right

    label_style_bullish = switch labels
        "Text" => label.style_label_up
        "Symbol" => label.style_triangleup
        => label.style_none

    label_style_bearish = switch labels
        "Text" => label.style_label_down
        "Symbol" => label.style_triangledown
        => label.style_none

    size = switch labels
        "Text" => size.small
        "Symbol" => size.tiny
        => size.auto

    distance = 20

    if bullish_condition
        line.new(last_bullish_idx, last_bullish_value, current_bull_idx, current_bullish_value
         , width = 2, color = regular_bullish_color)
         
        if labels != "Disabled"
            label.new(bar_index - right, source[right] - distance, labels == "Text" ? "Bullish" : ""
             , color = regular_bullish_color, textcolor = text_color, style = label_style_bullish, size = size
             , tooltip = "Bullish")

    if hidden_bullish_condition
        line.new(last_hidden_bullish_idx, last_hidden_bullish_value, current_hidden_bullish_idx
         , current_hidden_bullish_value, width = 2, color = hidden_bullish_color)
         
        if labels != "Disabled"
            label.new(bar_index - right, source[right] - distance, labels == "Text" ? "Hidden Bullish" : ""
             , color = hidden_bullish_color, textcolor = text_color, style = label_style_bullish, size = size
             , tooltip = "Hidden Bullish")

    if bearish_condition
        line.new(last_bearish_idx, last_bearish_value, current_bearish_idx, current_bearish_value
         , width = 2, color = regular_bearish_color)
         
        if labels != "Disabled"
            label.new(bar_index - right, source[right] + distance, labels == "Text" ? "Bearish" : ""
             , color = regular_bearish_color, textcolor = text_color, style = label_style_bearish, size = size
             , tooltip = "Bearish")

    if hidden_bearish_condition
        line.new(last_hidden_bearish_value, last_hidden_bearish_idx, current_hidden_bearish_idx
         , current_hidden_bearish_value, width = 2, color = hidden_bearish_color)
         
        if labels != "Disabled"
            label.new(bar_index - right, source[right] + distance, labels == "Text" ? "Hidden Bearish" : ""
             , color = hidden_bearish_color, textcolor = text_color, style = label_style_bearish, size = size
             , tooltip = "Hidden Bearish")

    nibble.new(bullish_condition
     , hidden_bullish_condition
     , bearish_condition
     , hidden_bearish_condition)

method max_size(int[] self, int length)=>
    if self.size() > length
        self.shift()

var active_up = false
var active_down = false

ph = ta.pivothigh(high, pivot_length, pivot_length_forward)
current_ph = fixnan(ph)

pl = ta.pivotlow(low, pivot_length, pivot_length_forward)
current_pl = fixnan(pl)

if not na(ph)
    active_up := true
    
if not na(pl)
    active_down := true

max = ta.highest(high, max_high_length)
min = ta.lowest(low, min_low_length)

var float top = na
var float bottom = na

var bool polarity = false

bos = false
choch = false

hh = high > current_ph
ll = low < current_pl

hh_neg = hh and not hh[1]
ll_neg = ll and not ll[1]

var int bos_up_count = 0
var int bos_down_count = 0

var bos_up_array = array.new()
var bos_down_array = array.new()

if hh_neg
    if active_up
        if polarity
            bos := true
            bos_up_count += 1

    if not polarity
        choch := true

        if bos_down_count != 0
            bos_down_array.push(bos_down_count)

        bos_up_count := 0
        bos_down_count := 0

    polarity := true
    active_up := false

    bottom := current_pl <= bottom ? (quick_update ? (bottom > min ? bottom : min) : bottom) : current_pl

if ll_neg
    if active_down
        if not polarity
            bos := true
            bos_down_count += 1

    if polarity
        choch := true
        if bos_up_count != 0
            bos_up_array.push(bos_up_count)
            
        bos_up_count := 0
        bos_down_count := 0

    polarity := false
    active_down := false

    top := current_ph >= top ? (quick_update ? (top < max ? max : top) : top) : current_ph

bos_up_array.max_size(20)
bos_down_array.max_size(20)

bullish_bos_max = math.max(1, bos_up_array.max())
bearish_bos_max = math.max(1, bos_down_array.max())

bullish_color = color.from_gradient(bos_up_count, 0, bullish_bos_max, bullish_color_min, bullish_color_max)
bearish_color = color.from_gradient(bos_down_count, 0, bearish_bos_max, bearish_color_min, bearish_color_max)

if high > max[1] and high > top
    top := max

if low < min[1] and low < bottom
    bottom := min

alpha = color.new(color.black, 100)
polarity_color = polarity ? bullish_color : bearish_color

center = math.avg(top, bottom)

offset = accentuate ? 1 : 0

scaled_price = -100 + (close - bottom[offset]) * 200 / (top[offset] - bottom[offset])

price = ta.sma(scaled_price, smoothing)
avg = ta.wma(price, average)

barcolor(candle_color ? polarity_color : na)

plot(avg, "Average", average_color)

mx = plot(100, "Top", premium_color)
c = plot(0, "Center", color.gray)
mn = plot(-100, "Bottom", discount_color)

fill(c, mx, 100, 0, color.new(premium_color, 87), alpha, "Premium Zone")
fill(c, mn, 0, -100, alpha, color.new(discount_color, 87), "Discount Zone")

plot(price, "Price", polarity_color)

plotshape(enable_labels and polarity and bos ? math.min(-120, price - 20) : na, "BOS Bullish"
 , shape.triangleup, location.absolute, bullish_color, 0, "BOS", text_color, true, size.tiny)

plotshape(enable_labels and not polarity and bos ? math.max(110, price + 10) : na, "BOS Bullish"
 , shape.triangledown, location.absolute, bearish_color, 0, "BOS", text_color, true, size.tiny)

plotshape(enable_labels and polarity and choch ? math.min(-120, price - 20) : na, "CHoCH Bullish"
 , shape.circle, location.absolute, choch_bullish_color, 0, "ChoCH", text_color, true, size.tiny)

plotshape(enable_labels and not polarity and choch ? math.max(110, price + 10) : na, "CHoCH Bullish"
 , shape.circle, location.absolute, choch_bearish_color, 0, "ChoCH", text_color, true, size.tiny)


plot(enable_visual_padding ? 110 + padding_level : na, "buffer", alpha, editable = false, display = display.pane)
plot(enable_visual_padding ? -100 + -padding_level : na, "buffer", alpha, editable = false, display = display.pane)

div_alerts = divergence(price
 , right
 , left
 , upper_range
 , lower_range
 , enable_regular_bullish
 , regular_bullish_color
 , enable_hidden_bullish
 , hidden_bullish_color
 , enable_regular_bearish
 , regular_bearish_color
 , enable_hidden_bearish
 , hidden_bearish_color
 , labels
 , text_color)


alertcondition(polarity and bos, "Bullish BOS")
alertcondition(not polarity and bos, "Bearish BOS") 

alertcondition(polarity and choch, "Bullish CHoCH")
alertcondition(not polarity and choch, "Bearish CHoCH")

alertcondition(div_alerts.a, "Bullish Divergence")
alertcondition(div_alerts.b, "Hidden Bullish Divergence")
alertcondition(div_alerts.c, "Bearish Divergence")
alertcondition(div_alerts.d, "Hidden Bearish Divergence")

alertcondition(ta.crossover(price, avg), "Cross Over Average")
alertcondition(ta.crossunder(price, avg), "Cross Under Average")

Get access to our Exclusive
premium indicators