FBMA
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Relese version: 22.0

// © Developer: tarasenko_

//@version=5

indicator("FBMA", overlay = true) 
  
 


// Inputs
atr_period          = input.int(14, "ATR Period", group = "Main Settings", minval = 1,display=display.none)
show_ma_labels      = input(true, "Sign MAs?", group = "Settings of Moving Averages",display=display.none)
fix_overlapping     = input(true, "Fix MAs' signatures overlapping?", group = "Settings of Moving Averages",display=display.none)
f                   = input.float(20, "Min distance between MAs' signatures (in % of 1 ATR)", group = "Settings of Moving Averages",display=display.none)/100.

ma1_src             = input(close, "Source MA №1"       , group = "MA №1 Settings",display=display.none)
ma1_src_tf          = input.timeframe('Current', "Source Timeframe", options = ['Current', '1', '3', '5', '10', '15', '30', '45', '60', '120', '180', '240', '360', '480', '720', '1D', '2D', '3D', '1W', '2W', '3W', '1M'], group = "MA №1 Settings",display=display.none)
ma1_period          = input.int(10, "МА №1 Period"      , group = "MA №1 Settings", minval = 1,display=display.none)
show_ema1           = input(true, "EMA №1"              , group = "MA №1 Settings", inline = "MA 1",display=display.none)
show_sma1           = input(false, "SMA №1"             , group = "MA №1 Settings", inline = "MA 1",display=display.none)
ma1_signature_color = input.color(#000000, "Signature color for MA №1", group = "MA №1 Settings",display=display.none)

ma2_src             = input(close, "Source MA №2"       , group = "MA №2 Settings",display=display.none)
ma2_src_tf          = input.timeframe('Current', "Source Timeframe", options = ['Current', '1', '3', '5', '10', '15', '30', '45', '60', '120', '180', '240', '360', '480', '720', '1D', '2D', '3D', '1W', '2W', '3W', '1M'], group = "MA №2 Settings",display=display.none)
ma2_period          = input.int(20, "МА №2 Period"      , group = "MA №2 Settings", minval = 1,display=display.none)
show_ema2           = input(true, "EMA №2"              , group = "MA №2 Settings", inline = "MA 2",display=display.none)
show_sma2           = input(false, "SMA №2"             , group = "MA №2 Settings", inline = "MA 2",display=display.none)
ma2_signature_color = input.color(#000000 , "Signature color for MA №2", group = "MA №2 Settings",display=display.none)

ma3_src             = input(close, "Source MA №3"       , group = "MA №3 Settings",display=display.none)
ma3_src_tf          = input.timeframe('Current', "Source Timeframe", options = ['Current', '1', '3', '5', '10', '15', '30', '45', '60', '120', '180', '240', '360', '480', '720', '1D', '2D', '3D', '1W', '2W', '3W', '1M'], group = "MA №3 Settings",display=display.none)
ma3_period          = input.int(50, "МА №3 Period"      , group = "MA №3 Settings", minval = 1,display=display.none)
show_ema3           = input(true, "EMA №3"              , group = "MA №3 Settings", inline = "MA 3",display=display.none)
show_sma3           = input(false, "SMA №3"             , group = "MA №3 Settings", inline = "MA 3",display=display.none)
ma3_signature_color = input.color(#000000 , "Signature color for MA №3", group = "MA №3 Settings",display=display.none)

ma4_src             = input(close, "Source MA №4"       , group = "MA №4 Settings",display=display.none)
ma4_src_tf          = input.timeframe('Current', "Source Timeframe", options = ['Current', '1', '3', '5', '10', '15', '30', '45', '60', '120', '180', '240', '360', '480', '720', '1D', '2D', '3D', '1W', '2W', '3W', '1M'], group = "MA №4 Settings",display=display.none)
ma4_period          = input.int(100, "МА №4 Period"     , group = "MA №4 Settings", minval = 1,display=display.none)
show_ema4           = input(true, "EMA №4"              , group = "MA №4 Settings", inline = "MA 4",display=display.none)
show_sma4           = input(false, "SMA №4"             , group = "MA №4 Settings", inline = "MA 4",display=display.none)
ma4_signature_color = input.color(#000eff , "Signature color for MA №4", group = "MA №4 Settings",display=display.none)

ma5_src             = input(close, "Source MA №5"       , group = "MA №5 Settings",display=display.none)
ma5_src_tf          = input.timeframe('Current', "Source Timeframe", options = ['Current', '1', '3', '5', '10', '15', '30', '45', '60', '120', '180', '240', '360', '480', '720', '1D', '2D', '3D', '1W', '2W', '3W', '1M'], group = "MA №5 Settings",display=display.none)
ma5_period          = input.int(200, "МА №5 Period"     , group = "MA №5 Settings", minval = 1,display=display.none)
show_ema5           = input(true, "EMA №5"              , group = "MA №5 Settings", inline = "MA 5",display=display.none)
show_sma5           = input(false, "SMA №5"             , group = "MA №5 Settings", inline = "MA 5",display=display.none)
ma5_signature_color = input.color(#ff0000 , "Signature color for MA №5", group = "MA №5 Settings",display=display.none)

ma6_src             = input(close, "Source MA №6"       , group = "MA №6 Settings",display=display.none)
ma6_src_tf          = input.timeframe('Current', "Source Timeframe", options = ['Current', '1', '3', '5', '10', '15', '30', '45', '60', '120', '180', '240', '360', '480', '720', '1D', '2D', '3D', '1W', '2W', '3W', '1M'], group = "MA №6 Settings",display=display.none)
ma6_period          = input.int(5, "МА №6 Period"       , group = "MA №6 Settings", minval = 1,display=display.none)
show_ema6           = input(false, "EMA №6"             , group = "MA №6 Settings", inline = "MA 6",display=display.none)
show_sma6           = input(false, "SMA №6"             , group = "MA №6 Settings", inline = "MA 6",display=display.none)
ma6_signature_color = input.color(#000000 , "Signature color for MA №6", group = "MA №6 Settings",display=display.none)

draw_cloud_ema12    = input(false, "Show cloud between 1st and 2nd EMA?", group = "Addons",display=display.none)
draw_cloud_sma12    = input(false, "Show cloud between 1st and 2nd SMA?", group = "Addons",display=display.none)
draw_lines_for_rp   = input(true, "Draw lines for round prices?", group = "Addons", tooltip = "Draw two lines for nearest round price around current close price of the asset.\n\n* The more lines, the slower the script.",display=display.none)
pn_for_rp           = input.int(2, "Number of pairs of round prices' lines", group = "Addons", minval = 1, maxval = 20, tooltip = "Max amount of pairs is 20, because after 20 pairs PineScript can't clean old drawings.\n\n* Too much lines slow the script.",display=display.none)
ul_col              = input.color(#000eff, "Upper line colour", group = "Addons",display=display.none)
ll_col              = input.color(#000eff, "Lower line colour", group = "Addons",display=display.none)

show_dashboard      = input(true, "Show dashboard?", group = "Dashboard", inline = "Enables/disables dashboard with recommended ATR Take-Profit and Stop-Loss values.",display=display.none)
db_pos              = input.string("Bottom right", "Dashboard position", options = ["Bottom right", "Bottom middle", "Bottom left", "Middle right", "Middle center", "Middle left", "Top right", "Top middle", "Top left"], group = "Dashboard",display=display.none)
db_sl_mult          = input.float(1.0, "ATR Stop-Loss Multiplier (1.0 by default)", 0.1, step = 0.05, group = "Dashboard", inline = "Defines dashboard's ATR Stop-Loss multiplier (set to 1.0 by default).", tooltip = "Changes 1st row of dashboard.",display=display.none)
db_tp_mult          = input.float(1.5, "ATR Take-Profit Multiplier (1.5 by default)", 0.1, step = 0.05, group = "Dashboard", inline = "Defines dashboard's ATR Take-Profit multiplier (set to 1.5 by default).", tooltip = "Changes 2nd row of dashboard.",display=display.none)



// Drumroll... Classes! Thanks to TradingView team for that, very useful in this particural situation!
// In the next update make recursion available, please.
//
// Moving Average class
//
// I am using classes in order to reduce amount of cycles for different
// operations and making process of plotting MAs' signatures a lot easier.
// Code itself also becomes cleaner and more comprehensive.
//
// BUT! Be careful while using classes in sorting algorithms,
// Because the size of the class affects the speed of your algorithm
// simply because when you do swapping objects, for example,
// all variables from one object will be transfered to another one by one,
// so such things will take time because of that.
type MovingAverage
    float   ma_value
    string  ma_type
    int     ma_period
    color   ma_colour




// Functions

// Get risk background color for dashboard
// Somewhat of gradient
get_risk_bgcol(r) =>
    risk = r * 100
    col = color.green
    if risk <= 1
        col := #00CC00
    if risk <= 4 and risk > 1
        col := #269401
    if risk <= 5 and risk > 4
        col := #33B900
    if risk <= 10 and risk > 5
        col := #695C00
    if risk <= 15 and risk > 10
        col := #C26100
    if risk > 15
        col := #C73601
    col


// Get dashboard position
get_db_pos(p) =>
    pos = position.bottom_right
    if p == "Bottom middle"
        pos := position.bottom_center
    if p == "Bottom left"
        pos := position.bottom_left
    if p == "Middle right"
        pos := position.middle_right
    if p == "Middle center"
        pos := position.middle_center
    if p == "Middle left"
        pos := position.middle_left
    if p == "Top right"
        pos := position.top_right
    if p == "Top middle"
        pos := position.top_center
    if p == "Top left"
        pos := position.top_left
    pos


// get highest price
highest_price(int bars) =>
    float max = 0
    for i = 0 to bars
        max := high[i] > max ? high[i] : max
    max


// Get lowest price
lowest_price(int bars) =>
    float min = open
    for i = 0 to bars
        min := low[i] < min ? low[i] : min
    min


// Get MA source's tf's value
get_source_from_tf(string tf, float src) =>
    float val = 0.0
    val := request.security(syminfo.tickerid, tf == 'Current' ? timeframe.period : tf, src)
    val




// Calculations
// ATR & risk
atr = ta.atr(atr_period)
risk = 1 - (close - atr) / close
risk_bgcol_sl = get_risk_bgcol(risk * db_sl_mult)


// Getting MAs' values if they are chosen to be plotted (show_ema should be true)
ema1 = show_ema1 ? get_source_from_tf(ma1_src_tf, ta.ema(ma1_src, ma1_period)) : na // EMAs
ema2 = show_ema2 ? get_source_from_tf(ma2_src_tf, ta.ema(ma2_src, ma2_period)) : na
ema3 = show_ema3 ? get_source_from_tf(ma3_src_tf, ta.ema(ma3_src, ma3_period)) : na
ema4 = show_ema4 ? get_source_from_tf(ma4_src_tf, ta.ema(ma4_src, ma4_period)) : na
ema5 = show_ema5 ? get_source_from_tf(ma5_src_tf, ta.ema(ma5_src, ma5_period)) : na
ema6 = show_ema6 ? get_source_from_tf(ma6_src_tf, ta.ema(ma6_src, ma6_period)) : na

sma1 = show_sma1 ? get_source_from_tf(ma1_src_tf, ta.sma(ma1_src, ma1_period)) : na // SMAs
sma2 = show_sma2 ? get_source_from_tf(ma2_src_tf, ta.sma(ma2_src, ma2_period)) : na
sma3 = show_sma3 ? get_source_from_tf(ma3_src_tf, ta.sma(ma3_src, ma3_period)) : na
sma4 = show_sma4 ? get_source_from_tf(ma4_src_tf, ta.sma(ma4_src, ma4_period)) : na
sma5 = show_sma5 ? get_source_from_tf(ma5_src_tf, ta.sma(ma5_src, ma5_period)) : na
sma6 = show_sma6 ? get_source_from_tf(ma6_src_tf, ta.sma(ma6_src, ma6_period)) : na

// MA ma_values array
ma_array = array.new<MovingAverage>(0)   // Size is 0 because when you push elements size increases. Works like C++'s vector

 // Filling MA Array
if show_ema1 and not na(ema1)   // If MA value is NaN, it means that current bar index is less than MA's period so we don't need to push this element in array
    array.push(ma_array, MovingAverage.new(ema1, "EMA", ma1_period, ma1_signature_color))
if show_ema2 and not na(ema2)
    array.push(ma_array, MovingAverage.new(ema2, "EMA", ma2_period, ma2_signature_color))
if show_ema3 and not na(ema3)
    array.push(ma_array, MovingAverage.new(ema3, "EMA", ma3_period, ma3_signature_color))
if show_ema4 and not na(ema4)
    array.push(ma_array, MovingAverage.new(ema4, "EMA", ma4_period, ma4_signature_color))
if show_ema5 and not na(ema5)
    array.push(ma_array, MovingAverage.new(ema5, "EMA", ma5_period, ma5_signature_color))
if show_ema6 and not na(ema6)
    array.push(ma_array, MovingAverage.new(ema6, "EMA", ma6_period, ma6_signature_color))

if show_sma1 and not na(sma1)
    array.push(ma_array, MovingAverage.new(sma1, "SMA", ma1_period, ma1_signature_color))
if show_sma2 and not na(sma2)
    array.push(ma_array, MovingAverage.new(sma2, "SMA", ma2_period, ma2_signature_color))
if show_sma3 and not na(sma3)
    array.push(ma_array, MovingAverage.new(sma3, "SMA", ma3_period, ma3_signature_color))
if show_sma4 and not na(sma4)
    array.push(ma_array, MovingAverage.new(sma4, "SMA", ma4_period, ma4_signature_color))
if show_sma5 and not na(sma5)
    array.push(ma_array, MovingAverage.new(sma5, "SMA", ma5_period, ma5_signature_color))
if show_sma6 and not na(sma6)
    array.push(ma_array, MovingAverage.new(sma6, "SMA", ma6_period, ma6_signature_color))

// MA array size
size_ma_array = array.size(ma_array)

// If we don't sign MAs, then there is not need to do signature fixing 
if show_ma_labels

    if size_ma_array >= 2

        // Fixing overlapping of MAs' signatures
        overlapping_fix_array = array.new<float>(0)
        for i = 0 to size_ma_array - 1
            MovingAverage obj = array.get(ma_array, i)
            array.push(overlapping_fix_array, obj.ma_value)

        // Creating array for sorting MA array. It's values will be then used in creating labels
        array<MovingAverage> sorted_ma_array = array.copy(ma_array)

        if fix_overlapping

            // Sorting overlapping_fix_array in descending order for purpose of fast overlapping fix
            array.sort(overlapping_fix_array, order.descending)

            // Fixing overlapping itself
            for i = 0 to size_ma_array - 2
                val1 = array.get(overlapping_fix_array, i)
                val2 = array.get(overlapping_fix_array, i + 1)

                if val1 < val2 or val1 - val2 < atr * f
                    array.set(overlapping_fix_array, i + 1, val1 - atr * f)


            // Sorting MA array by value (Bubble sort *)
            //
            // * As it is impossible to do recursion in PineScript and there is no algo without recursion that could 
            // do sorting in O(n) or O(n*log(n)), bubble sort is the only way.
            //
            // But I think that even if I applied quick sort, the result still won't be much better, because
            // there the maximum amount of elements in array is 12, not 10000, so it can't really affect the speed.
            for i = 0 to size_ma_array - 2
                for j = 0 to size_ma_array - 2 - i
                    curr_j = array.get(sorted_ma_array, j)
                    prev_j = array.get(sorted_ma_array, j + 1)
                    if curr_j.ma_value < prev_j.ma_value 
                        array.set(sorted_ma_array, j, prev_j)
                        array.set(sorted_ma_array, j + 1, curr_j)


        // MA labels
        ma_labels = array.new<label>(size_ma_array)
        for i = 0 to size_ma_array - 1
            obj = array.get(sorted_ma_array, i)                     // Getting current MA object to plot

            fixed_ma_value  = array.get(overlapping_fix_array, i)   // Obtained MA value after overlapping fix
            ma_value        = obj.ma_value                          // Original MA value
            ma_type         = obj.ma_type                           // Original MA type
            ma_period       = obj.ma_period                         // Original MA period
            ma_colour       = obj.ma_colour                         // Original MA colour

            // Creating MA label, while pushing into MA labels array
            // Using array for that makes this system more flexible,
            // because now we don't care which MAs are enabled, we just
            // push them in our MA array, make some math and plot them, that's it!
            array.push(ma_labels, label.new(bar_index + 1, fixed_ma_value, str.tostring(ma_value, format.mintick) + " (" + ma_type + " " + str.tostring(ma_period) + ")", color = #ffffff01, style = label.style_label_left, textcolor = ma_colour) )
                

        // Deleting old labels
        while array.size(label.all) > size_ma_array
            label.delete(array.shift(label.all))

    else if size_ma_array == 1         // If there is only one MA in MA array, then there is no need to sort it and etc. Just plot it
        obj = array.get(ma_array, 0)
        ma_value  = obj.ma_value
        ma_type   = obj.ma_type
        ma_period = obj.ma_period
        ma_colour = obj.ma_colour

        MA_label  = label.new(bar_index + 1, ma_value, str.tostring(ma_value, format.mintick) + " (" + ma_type + " " + str.tostring(ma_period) + ")", color = #ffffff01, style = label.style_label_left, textcolor = ma_colour)
        label.delete(MA_label[1])   // Don't really care about the fact that I am deleting local object as long it works :) For safety purposes make MA_label global and use operator := to change it's value




// Round price's lines
if draw_lines_for_rp

    array<line> rp_lines = array.new<line>(0)
    array<label> rp_labels = array.new<label>(0)

    // Cleaning previous lines
    while array.size(line.all) != 0
        line.delete(array.pop(line.all))

    // Cleaning previous labels
    // We add size_ma_array so we don't delete MA's signatures
    while array.size(label.all) > (show_ma_labels ? size_ma_array : 0)
        label.delete(array.shift(label.all))

    if close >= 1 and close <= 10
        for i = 0 to pn_for_rp - 1
            ur_y = int(close) + (i + 1)                                                 // Upper Line y-coordinate
            lr_y = close != int(close) - i ? int(close) - i : int(close) - (1 + i)      // Lower line y-coordinate

            array.push(rp_lines, line.new(bar_index, ur_y, bar_index + 20, ur_y, xloc.bar_index, extend.left, ul_col, width = 1))
            array.push(rp_labels, label.new(bar_index + 20, ur_y, str.tostring(ur_y) + " " + syminfo.currency, color = #ffffff01, textcolor = ul_col, style = label.style_label_left))

            // If lower round price's y-coordinate is negative, then we don't plot it
            if lr_y > 0 
                array.push(rp_lines, line.new(bar_index, lr_y, bar_index + 20, lr_y, xloc.bar_index, extend.left, ll_col, width = 1))
                array.push(rp_labels, label.new(bar_index + 20, lr_y, str.tostring(lr_y) + " " + syminfo.currency, color = #ffffff01, textcolor = ll_col, style = label.style_label_left))


    if close > 10 and close < 1000
        for i = 0 to pn_for_rp - 1
            ur_y = close - (close % 10) + 10 * (i + 1)                                        
            lr_y = close != close - (close % 10) ? close - (close % 10) - 10 * i : close - 10 * (i + 1) 

            array.push(rp_lines, line.new(bar_index, ur_y, bar_index + 20, ur_y, xloc.bar_index, extend.left, ul_col, width = 1))
            array.push(rp_labels, label.new(bar_index + 20, ur_y, str.tostring(ur_y) + " " + syminfo.currency, color = #ffffff01, textcolor = ul_col, style = label.style_label_left))
            if lr_y > 0
                array.push(rp_lines, line.new(bar_index, lr_y, bar_index + 20, lr_y, xloc.bar_index, extend.left, ll_col, width = 1))
                array.push(rp_labels, label.new(bar_index + 20, lr_y, str.tostring(lr_y) + " " + syminfo.currency, color = #ffffff01, textcolor = ll_col, style = label.style_label_left))


    if close >= 1000
        for i = 0 to pn_for_rp - 1
            ur_y = close - (close % 100) + 100 * (i + 1)
            lr_y = close != close - (close % 100) ? close - (close % 100) - 100 * i : close - 100 * (i + 1)

            array.push(rp_lines, line.new(bar_index, ur_y, bar_index + 20, ur_y, xloc.bar_index, extend.left, ul_col, width = 1))
            array.push(rp_labels, label.new(bar_index + 20, ur_y, str.tostring(ur_y) + " " + syminfo.currency, color = #ffffff01, textcolor = ul_col, style = label.style_label_left))
            if lr_y > 0
                array.push(rp_lines, line.new(bar_index, lr_y, bar_index + 20, lr_y, xloc.bar_index, extend.left, ll_col, width = 1))
                array.push(rp_labels, label.new(bar_index + 20, lr_y, str.tostring(lr_y) + " " + syminfo.currency, color = #ffffff01, textcolor = ll_col, style = label.style_label_left))

    // For assets, whose current close is below 1$, we need to apply different calculation technique
    if close < 1
        price = close
        float mult = 1

        while price < 1
            price *= 10
            mult *= 10
        
        for i = 0 to pn_for_rp - 1
            ur_y = (int(price) + 1 + i) / mult
            lr_y = price != int(price) ? (int(price) - i) / mult : (int(price) - 1 - i) / mult

            array.push(rp_lines, line.new(bar_index, ur_y, bar_index + 20, ur_y, xloc.bar_index, extend.left, ul_col, width = 1))
            array.push(rp_labels, label.new(bar_index + 20, ur_y, str.tostring(ur_y) + " " + syminfo.currency, color = #ffffff01, textcolor = ul_col, style = label.style_label_left))
            if lr_y > 0
                array.push(rp_lines, line.new(bar_index, lr_y, bar_index + 20, lr_y, xloc.bar_index, extend.left, ll_col, width = 1))
                array.push(rp_labels, label.new(bar_index + 20, lr_y, str.tostring(lr_y) + " " + syminfo.currency, color = #ffffff01, textcolor = ll_col, style = label.style_label_left))




PLOT_EMA1 = plot(show_ema1 ? ema1 : na, "EMA 1"  , #000000, 2, plot.style_linebr,display = display.pane)
PLOT_EMA2 = plot(show_ema2 ? ema2 : na, "EMA 2"  , #000000, 2, plot.style_linebr,display = display.pane)
PLOT_EMA3 = plot(show_ema3 ? ema3 : na, "EMA 3"  , #000000, 2, plot.style_linebr,display = display.pane)
PLOT_EMA4 = plot(show_ema4 ? ema4 : na, "EMA 4"  , #000eff, 2, plot.style_linebr,display = display.pane)
PLOT_EMA5 = plot(show_ema5 ? ema5 : na, "EMA 5"  , #ff0000, 2, plot.style_linebr,display = display.pane)
PLOT_EMA6 = plot(show_ema6 ? ema6 : na, "EMA 6"  , #000000, 2, plot.style_linebr,display = display.pane)

PLOT_SMA1 = plot(show_sma1 ? sma1 : na, "SMA 1"  , #000000, 2, plot.style_linebr,display = display.pane)
PLOT_SMA2 = plot(show_sma2 ? sma2 : na, "SMA 2"  , #000000, 2, plot.style_linebr,display = display.pane)
PLOT_SMA3 = plot(show_sma3 ? sma3 : na, "SMA 3"  , #000000, 2, plot.style_linebr,display = display.pane)
PLOT_SMA4 = plot(show_sma4 ? sma4 : na, "SMA 4"  , #000eff, 2, plot.style_linebr,display = display.pane)
PLOT_SMA5 = plot(show_sma5 ? sma5 : na, "SMA 5"  , #ff0000, 2, plot.style_linebr,display = display.pane)
PLOT_SMA6 = plot(show_sma6 ? sma6 : na, "SMA 6"  , #000000, 2, plot.style_linebr,display = display.pane)


// Clouds
fill(plot(ema1, "Cloud EMA №1", na,display = display.pane), plot(ema2, "Cloud EMA №2", na,display = display.pane), title = "Cloud of EMA №1 and EMA №2", color = draw_cloud_ema12 ? (ema1 > ema2 ? #00800059 : #ff000059) : na)
fill(plot(sma1, "Cloud SMA №1", na,display = display.pane), plot(sma2, "Cloud SMA №2", na,display = display.pane), title = "Cloud of SMA №1 and SMA №2", color = draw_cloud_sma12 ? (sma1 > sma2 ? #00800059 : #ff000059) : na)




// Dashboard
pos = get_db_pos(db_pos)
table db = table.new(pos, 2, 4, color.black, color.gray, 1, color.gray, 1)
if show_dashboard
    table.cell(db, 0, 0, str.tostring(db_sl_mult) + " ATR"                    , text_color = color.white)
    table.cell(db, 1, 0, str.tostring(db_sl_mult * atr, format.mintick) + " (" + str.tostring((db_sl_mult * atr) / close, '#####.##%') + ")"     , text_color = color.white, bgcolor = risk_bgcol_sl)
    table.cell(db, 0, 1, str.tostring(db_tp_mult) + " ATR"                    , text_color = color.white)
    table.cell(db, 1, 1, str.tostring(db_tp_mult * atr, format.mintick) + " (" + str.tostring((db_tp_mult * atr) / close, '#####.##%') + ")"     , text_color = color.white, bgcolor = color.gray)
    



// Alerts
alertcondition(ta.cross(close, ema1), "Price hit ЕМА №1" , "Price hit ЕМА №1.")
alertcondition(ta.cross(close, ema2), "Price hit ЕМА №2" , "Price hit ЕМА №2.")
alertcondition(ta.cross(close, ema3), "Price hit ЕМА №3" , "Price hit ЕМА №3.")
alertcondition(ta.cross(close, ema4), "Price hit ЕМА №4" , "Price hit ЕМА №4.")
alertcondition(ta.cross(close, ema5), "Price hit ЕМА №5" , "Price hit ЕМА №5.")
alertcondition(ta.cross(close, ema6), "Price hit ЕМА №6" , "Price hit ЕМА №6.")

alertcondition(ta.cross(close, sma1), "Price hit SМА №1" , "Price hit SМА №1.")
alertcondition(ta.cross(close, sma2), "Price hit SМА №2" , "Price hit SМА №2.")
alertcondition(ta.cross(close, sma3), "Price hit SМА №3" , "Price hit SМА №3.")
alertcondition(ta.cross(close, sma4), "Price hit SМА №4" , "Price hit SМА №4.")
alertcondition(ta.cross(close, sma5), "Price hit SМА №5" , "Price hit SМА №5.")
alertcondition(ta.cross(close, sma6), "Price hit SМА №6" , "Price hit SМА №6.")




// Originally developed by @ChrisMoody
// CM Price Action 
period_ctP = input.int(66,  "Percentage Input For Pin Bars, What % The Wick Of Candle Has To Be"                    , minval = 1, maxval = 99 , group = "Price Action",display=display.none)
period_blb = input.int(6, "Pin Bars Look Back Period To Define The Trend of Highs and Lows"                         , minval = 1, maxval = 100, group = "Price Action",display=display.none)
period_ctS = input.int(5, "Percentage Input For Shaved Bars, Percent of Range it Has To Close On The Lows or Highs" , minval = 1, maxval = 99 , group = "Price Action",display=display.none)

show_pin_bars     = input(false, "Show Pin Bars?")
show_shaved_bars  = input(false, "Show Shaved Bars?")
show_inside_bars  = input(false, "Show Inside Bars?")
show_outside_bars = input(false, "Show Outside Bars?")

make_bars_gray = input(false, "Color bars in gray?", tooltip = "Helps better indentify price action bars.")

//Pin Bar Percentages
pctCp = period_ctP * .01
pctCPO = 1 - pctCp

//Shaved Bars Percentages
pctCs = period_ctS * .01
period_ctSPO = pctCs

// Price range
Range = high - low

///Pin Bars
pinBarUp = show_pin_bars and open > high - (Range * pctCPO) and close > high - (Range * pctCPO) and low <= ta.lowest(period_blb) ? 1 : 0
pinBarDn = show_pin_bars and open < high - (Range *  pctCp) and close < high-(Range * pctCp) and high >= ta.highest(period_blb) ? 1 : 0

//Shaved Bars
shavedBarUp = show_shaved_bars and (close >= (high - (Range * pctCs)))
shavedBarDown = show_shaved_bars and close <= (low + (Range * pctCs))

//Inside Bars
insideBar = show_inside_bars and high <= high[1] and low >= low[1] ? 1 : 0
outsideBar = show_outside_bars and (high > high[1] and low < low[1]) ? 1 : 0

bar_colour = color(na) 
if pinBarUp
    bar_colour := color.lime 
else if pinBarDn
    bar_colour := color.red
else if shavedBarUp
    bar_colour := color.fuchsia
else if shavedBarDown
    bar_colour := color.aqua 
else if insideBar
    bar_colour := color.yellow 
else if outsideBar
    bar_colour := color.orange
else if make_bars_gray
    bar_colour := color.gray
else 
    bar_colour := na

barcolor(bar_colour)
