Skip to main content

Elite Binary

//@version=6 indicator("RSI TMA", overlay=true) // Arrows on the main chart (overlay=true) // Input parameters rsiLength = input.int(2, title="RSI Length") rsiPrice = input.source(close, title="RSI Price") halfLength = input.int(2, title="Half Length") devPeriod = input.int(100, title="Deviation Period") deviations = input.float(0.7, title="Deviations") noDellArr = input.bool(false, title="No Delete Arrows") arrOtstup = input.int(0, title="Arrow Offset") arrUpColor = input.color(color.lime, title="Arrow Up Color") arrDnColor = input.color(color.red, title="Arrow Down Color") alertsMessage = input.bool(false, title="Alerts Message") alertsSound = input.bool(false, title="Alerts Sound") alertsEmail = input.bool(false, title="Alerts Email") alertsMobile = input.bool(false, title="Alerts Mobile") signalBar = input.int(0, title="Signal Bar") ...

Mayfair + Price Action

//@version=5

indicator("<Mayfair + Price Action >", "*[v1.6.6] Mayfair + Price Action*", overlay=true, max_labels_count=500, max_lines_count=500, max_boxes_count=500, max_bars_back=500)

max_bars_back = 1200
max_labels_count = 1200
max_lines_count = 1200
//-----------------------------------------------------------------------------{
    //Boolean set
//-----------------------------------------------------------------------------{
s_BOS        = 0
s_CHoCH      = 1
i_BOS        = 2
i_CHoCH      = 3
i_pp_CHoCH   = 4
green_candle = 5
red_candle   = 6
s_CHoCHP     = 7
i_CHoCHP     = 8

boolean = array.from(false, false, false, false, false, false, false, false, false)

//-----------------------------------------------------------------------------{
    // User inputs
//-----------------------------------------------------------------------------{
show_swing_ms                   = input.string      ("All"                            , "Swing        "               , inline = "1", group = "MARKET STRUCTURE"            , options = ["All", "CHoCH", "CHoCH+", "BOS", "None"])
show_internal_ms                = input.string      ("All"                            , "Internal     "               , inline = "2", group = "MARKET STRUCTURE"            , options = ["All", "CHoCH", "CHoCH+", "BOS", "None"])
internal_r_lookback             = input.int         (4                                , ""                            , inline = "2", group = "MARKET STRUCTURE"            , minval = 2)
swing_r_lookback                = input.int         (50                               , ""                            , inline = "1", group = "MARKET STRUCTURE"            , minval = 2)
ms_mode                         = input.string      ("Manual"                         , "Market Structure Mode"       , inline = "a", group = "MARKET STRUCTURE"            , tooltip = "[Manual] Use selected lenght\n[Dynamic] Use automatic lenght" ,options = ["Manual", "Dynamic"])

show_mtf_str                    = input.bool        (true                             , "MTF Scanner"                 , inline = "9", group = "MARKET STRUCTURE"            , tooltip = "Display Multi-Timeframe Market Structure Trend Directions. Green = Bullish. Red = Bearish")

show_itrend5 = input(true, title="Show 5m")
show_itrend15 = input(true, title="Show 15m")
show_itrend30 = input(true, title="Show 30m")
show_itrend1H = input(true, title="Show 1H")
show_itrend4H = input(true, title="Show 4H")
show_itrend1D = input(true, title="Show 1D")
show_itrend1W = input(true, title="Show 1W")
show_rsi = input(true, title="Show RSI")
show_adx = input(true, title="Show ADX")
lookback = 499

show_sfp = input.bool(false, "Show Swing Failure Patern", group="MARKET STRUCTURE")
pvllen = input.int(25, "Pivot Length", 1, 99, group="MARKET STRUCTURE")
show_eql                        = input.bool        (false                            , "Show EQH/EQL"                , inline = "6", group = "MARKET STRUCTURE")
plotcandle_bool                 = input.bool        (false                            , "Plotcandle"                  , inline = "3", group = "MARKET STRUCTURE"            , tooltip = "Displays a cleaner colored candlestick chart in place of the default candles. (requires hiding the current ticker candles)")
barcolor_bool                   = input.bool        (false                            , "Bar Color"                   , inline = "4", group = "MARKET STRUCTURE"            , tooltip = "Color the candle bodies according to market strucutre trend")

i_ms_up_BOS                   = input.color       (#089981                          , ""                            , inline = "2", group = "MARKET STRUCTURE")
i_ms_dn_BOS                   = input.color       (#f23645                          , ""                            , inline = "2", group = "MARKET STRUCTURE")
s_ms_up_BOS                   = input.color       (#089981                          , ""                            , inline = "1", group = "MARKET STRUCTURE")
s_ms_dn_BOS                   = input.color       (#f23645                          , ""                            , inline = "1", group = "MARKET STRUCTURE")

lvl_daily                       = input.bool        (false                            , "Day   "                      , inline = "1", group = "HIGHS & LOWS MTF")
lvl_weekly                      = input.bool        (false                            , "Week "                       , inline = "2", group = "HIGHS & LOWS MTF")
lvl_monthly                     = input.bool        (false                            , "Month"                       , inline = "3", group = "HIGHS & LOWS MTF")
lvl_yearly                      = input.bool        (false                            , "Year  "                      , inline = "4", group = "HIGHS & LOWS MTF")
css_d                           = input.color       (color.blue                     , ""                            , inline = "1", group = "HIGHS & LOWS MTF")
css_w                           = input.color       (color.blue                     , ""                            , inline = "2", group = "HIGHS & LOWS MTF")
css_m                           = input.color       (color.blue                     , ""                            , inline = "3", group = "HIGHS & LOWS MTF")
css_y                           = input.color       (color.blue                     , ""                            , inline = "4", group = "HIGHS & LOWS MTF")
s_d                             = input.string      ('⎯⎯⎯'                            , ''                            , inline = '1', group = 'HIGHS & LOWS MTF'                , options = ['⎯⎯⎯', '----', '····'])
s_w                             = input.string      ('⎯⎯⎯'                            , ''                            , inline = '2', group = 'HIGHS & LOWS MTF'                , options = ['⎯⎯⎯', '----', '····'])
s_m                             = input.string      ('⎯⎯⎯'                            , ''                            , inline = '3', group = 'HIGHS & LOWS MTF'                , options = ['⎯⎯⎯', '----', '····'])
s_y                             = input.string      ('⎯⎯⎯'                            , ''                            , inline = '4', group = 'HIGHS & LOWS MTF'                , options = ['⎯⎯⎯', '----', '····'])

ob_show                         = input.bool        (true                             , "Show Last    "               , inline = "1", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "Display volumetric order blocks on the chart \n\n[Input] Ammount of volumetric order blocks to show")
ob_num                          = input.int         (5                                , ""                            , inline = "1", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "Orderblocks number", minval = 1, maxval = 10)
ob_tf       = input.timeframe("","Timeframe", inline = "b", group = "VOLUMETRIC ORDER BLOCKS", tooltip="Enter Timeframe for Order Blocks ")
ob_metrics_show                 = input.bool        (true                             , "Internal Buy/Sell Activity"  , inline = "2", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "Display volume metrics that have formed the orderblock")
css_metric_up                   = input.color       (color.new(#089981,  40)        , "         "                   , inline = "2", group = "VOLUMETRIC ORDER BLOCKS")
css_metric_dn                   = input.color       (color.new(#f23645 , 40)        , ""                            , inline = "2", group = "VOLUMETRIC ORDER BLOCKS")

ob_filter                       = input.string      ("None"                           , "Filtering             "      , inline = "d", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "Filter out volumetric order blocks by BOS/CHoCH/CHoCH+", options = ["None", "BOS", "CHoCH", "CHoCH+"])
ob_mitigation                   = input.string      ("Absolute"                       , "Mitigation           "       , inline = "4", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "Trigger to remove volumetric order blocks", options = ["Absolute", "Middle"])
ob_pos                          = input.string      ("Precise"                        , "Positioning          "       , inline = "k", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "Position of the Order Block\n[Full] Cover the whole candle\n[Middle] Cover half candle\n[Accurate] Adjust to volatility\n[Precise] Same as Accurate but more precise", options = ["Full", "Middle", "Accurate", "Precise"])
use_grayscale                   = input.bool        (false                            , "Grayscale"                   , inline = "6", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "Use gray as basic order blocks color")
use_show_metric                 = input.bool        (true                             , "Show Metrics"                , inline = "7", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "Show volume associated with the orderblock and his relevance")
obtxt                           = input.string("Normal"            , "Metric Size"                    , ["Tiny", "Small", "Normal", "Large", "Huge"], inline = "8", group = "VOLUMETRIC ORDER BLOCKS" )
use_middle_line                 = input.bool        (true                             , "Show Middle-Line"            , inline = "9", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "Show mid-line order blocks")

use_overlap                     = input.bool        (true                             , "Hide Overlap"                , inline = "10", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "Hide overlapping order blocks")
use_overlap_method              = input.string      ("Previous"                       , "Overlap Method    "          , inline = "Z", group = "VOLUMETRIC ORDER BLOCKS"         , tooltip = "[Recent] Preserve the most recent volumetric order blocks\n\n[Previous] Preserve the previous volumetric order blocks", options = ["Recent", "Previous"])
ob_bull_css                     = input.color       (color.new(#089981 ,  80)       , ""                            , inline = "1", group = "VOLUMETRIC ORDER BLOCKS")
ob_bear_css                     = input.color       (color.new(#f23645 ,  80)       , ""                            , inline = "1", group = "VOLUMETRIC ORDER BLOCKS")

show_acc_dist_zone              = input.bool        (false                            , ""                            , inline = "1", group = "Accumulation And Distribution")
zone_mode                       = input.string      ("Fast"                           , ""                            , inline = "1", group = "Accumulation And Distribution"   , tooltip = "[Fast] Find small zone pattern formation\n[Slow] Find bigger zone pattern formation" ,options = ["Slow", "Fast"])
acc_css                         = input.color       (color.new(#089981   , 60)      , ""                            , inline = "1", group = "Accumulation And Distribution")
dist_css                        = input.color       (color.new(#f23645   , 60)      , ""                            , inline = "1", group = "Accumulation And Distribution")

show_lbl                        = input.bool        (true                            , "Show swing point"            , inline = "1", group = "High and Low"                    , tooltip = "Display swing point")
show_mtb                        = input.bool        (true                            , "Show High/Low/Equilibrium"   , inline = "2", group = "High and Low"                    , tooltip = "Display Strong/Weak High And Low and Equilibrium")
toplvl                          = input.color       (color.rgb(255, 0, 0)                      , "Premium Zone   "             , inline = "3", group = "High and Low")
midlvl                          = input.color       (color.gray                    , "Equilibrium Zone"            , inline = "4", group = "High and Low")
btmlvl                          = input.color       (#089981                        , "Discount Zone    "           , inline = "5", group = "High and Low")

fvg_enable                      = input.bool        (false                            , "        "                            , inline = "1", group = "FAIR VALUE GAP"          , tooltip = "Display fair value gap")
what_fvg                        = input.string      ("FVG"                            , ""                            , inline = "1", group = "FAIR VALUE GAP"                  , tooltip = "Display fair value gap", options = ["FVG", "VI", "OG"])
fvg_num                         = input.int         (5                                , "Show Last  "                   , inline = "1a", group = "FAIR VALUE GAP"               , tooltip = "Number of fvg to show")
fvg_upcss                       = input.color       (color.new(#089981,  80)        , ""                            , inline = "1", group = "FAIR VALUE GAP")
fvg_dncss                       = input.color       (color.new(color.red ,  80)     , ""                            , inline = "1", group = "FAIR VALUE GAP")
fvg_extend                      = input.int         (10                               , "Extend FVG"                  , inline = "2", group = "FAIR VALUE GAP"                  , tooltip = "Extend the display of the FVG.")
fvg_src                         = input.string      ("Close"                          , "Mitigation  "                , inline = "3", group = "FAIR VALUE GAP"                  , tooltip = "[Close] Use the close of the body as trigger\n\n[Wick] Use the extreme point of the body as trigger", options = ["Close", "Wick"])
fvg_tf                          = input.timeframe   (""                               , "Timeframe "                  , inline = "4", group = "FAIR VALUE GAP"                  , tooltip = "Timeframe of the fair value gap")
rsi_enable                          = input.bool        (true                             , "Enable RSI"                                     , group = "RSI"                                         , tooltip = "Plot overbought and oversold price to bars")
rsi_src                             = close        
rsi_overbought_src                  = close
rsi_oversold_src                    = close 
rsi_length                          = input.int         (14, minval=1                      , title="Length"                                  , group = "RSI")
rsi_overbought_length               = input.int         (80, minval=1                      , title="Overbought               "               , inline="overbought"                                    , group = "RSI")
rsi_oversold_length                 = input.int         (20, minval=1                      , title="Oversold                   "             , inline = "oversold"                                    , group = "RSI")
rsi_overbought_color                = input.color       (#ff0000                     , "", inline = "overbought"                       , group = "RSI")
rsi_oversold_color                  = input.color       (#089981                      , "", inline = "oversold"                         , group = "RSI")

t                               = color.t           (ob_bull_css)
invcol                          = color.new         (color.white                    , 100)

method txSz(string s) =>
    out = switch s
        "Tiny"   => size.tiny
        "Small"  => size.small
        "Normal" => size.normal
        "Large"  => size.large
        "Huge"   => size.huge
    out

type bar
    float   o = open
    float   c = close
    float   h = high
    float   l = low
    float   v = volume
    int     n = bar_index
    int     t = time

type Zphl
    line   top
    line   bottom
    label  top_label
    label  bottom_label
    bool   stopcross
    bool   sbottomcross
    bool   itopcross
    bool   ibottomcross
    string txtup
    string txtdn
    float  topy
    float  bottomy
    float  topx
    float  bottomx
    float  tup
    float  tdn
    int    tupx
    int    tdnx
    float  itopy
    float  itopx
    float  ibottomy
    float  ibottomx
    float  uV
    float  dV

type FVG
    box [] box
    line[] ln
    bool   bull
    float  top
    float  btm
    int    left
    int    right

type ms
	float[] p
	int  [] n
    float[] l

type msDraw
	int    n
	float  p
	color  css
	string txt
	bool   bull

type obC 
    float[] top
    float[] btm
    int  [] left
    float[] avg
    float[] dV 
    float[] cV 
    int  [] wM 
    int  [] blVP 
    int  [] brVP 
    int  [] dir  
    float[] h
    float[] l
    int  [] n

type obD 
    box [] ob 
    box [] eOB
    box [] blB 
    box [] brB 
    line[] mL

type zone
    chart.point points
    float p
    int   c
    int   t

type hqlzone
    box   pbx
    box   ebx
    box   lbx
    label plb
    label elb
    label lbl

type ehl
    float pt
    int   t
    float pb
    int   b

type pattern
    string found = "None"
    bool isfound = false
    int   period = 0
    bool  bull   = false

type alerts
    bool chochswing     = false
    bool chochplusswing = false
    bool swingbos       = false
    bool chochplus      = false
    bool choch          = false
    bool bos            = false
    bool equal          = false
    bool ob             = false
    bool swingob        = false
    bool zone           = false
    bool fvg            = false
    bool obtouch        = false


bar         b      = bar.new()
var pattern p      = pattern.new()

alerts      blalert = alerts.new()
alerts      bralert = alerts.new()

if p.isfound

    p.period += 1

if p.period == 50

    p.period  := 0
    p.found   := "None"
    p.isfound := false
    p.bull    := na

switch

    b.c > b.o => boolean.set(green_candle, true)
    b.c < b.o => boolean.set(red_candle  , true)

f_zscore(src, lookback) =>

    (src - ta.sma(src, lookback)) / ta.stdev(src, lookback)

var int iLen = internal_r_lookback
var int sLen = swing_r_lookback

vv = f_zscore(((close - close[iLen]) / close[iLen]) * 100,iLen)

if ms_mode == "Dynamic"

    switch

        vv >= 1.5 or vv <= -1.5 => iLen := 10
        vv >= 1.6 or vv <= -1.6 => iLen := 9
        vv >= 1.7 or vv <= -1.7 => iLen := 8
        vv >= 1.8 or vv <= -1.8 => iLen := 7
        vv >= 1.9 or vv <= -1.9 => iLen := 6
        vv >= 2.0 or vv <= -2.0 => iLen := 5
        =>                         iLen

var msline = array.new<line>(0)

iH = ta.pivothigh(high, iLen, iLen)
sH = ta.pivothigh(high, sLen, sLen)
iL = ta.pivotlow (low , iLen, iLen)
sL = ta.pivotlow (low , sLen, sLen)

hl  () => [high, low]

[pdh, pdl] = request.security(syminfo.tickerid , 'D'  , hl() , lookahead = barmerge.lookahead_on)
[pwh, pwl] = request.security(syminfo.tickerid , 'W'  , hl() , lookahead = barmerge.lookahead_on)
[pmh, pml] = request.security(syminfo.tickerid , 'M'  , hl() , lookahead = barmerge.lookahead_on)
[pyh, pyl] = request.security(syminfo.tickerid , '12M', hl() , lookahead = barmerge.lookahead_on)

lstyle(style) =>

    out = switch style

        '⎯⎯⎯'  => line.style_solid
        '----' => line.style_dashed
        '····' => line.style_dotted

mtfphl(h, l ,tf ,css, pdhl_style) =>

    var line hl = line.new(
       na
     , na
     , na
     , na
     , xloc      = xloc.bar_time
     , color     = css
     , style     = lstyle(pdhl_style)
     )

    var line ll   = line.new(
       na
     , na
     , na
     , na
     , xloc      = xloc.bar_time
     , color     = css
     , style     = lstyle(pdhl_style)
     )

    var label lbl = label.new(
       na
     , na
     , xloc      = xloc.bar_time
     , text      = str.format('P{0}L', tf)
     , color     = invcol
     , textcolor = css
     , size      = size.small
     , style     = label.style_label_left
     )

    var label hlb = label.new(
       na
     , na
     , xloc      = xloc.bar_time
     , text      = str.format('P{0}H', tf)
     , color     = invcol
     , textcolor = css
     , size      = size.small
     , style     = label.style_label_left
     )

    hy = ta.valuewhen(h != h[1] , h    , 1)
    hx = ta.valuewhen(h == high , time , 1)
    ly = ta.valuewhen(l != l[1] , l    , 1)
    lx = ta.valuewhen(l == low  , time , 1)

    if barstate.islast

        extension = time + (time - time[1]) * 50
    
        line.set_xy1(hl , hx        , hy)
        line.set_xy2(hl , extension , hy)
        label.set_xy(hlb, extension , hy)
        line.set_xy1(ll , lx        , ly)
        line.set_xy2(ll , extension , ly)
        label.set_xy(lbl, extension , ly)

if lvl_daily

    mtfphl(pdh   , pdl , 'D'  , css_d, s_d)

if lvl_weekly

    mtfphl(pwh   , pwl , 'W'  , css_w, s_w)

if lvl_monthly

    mtfphl(pmh   , pml,  'M'  , css_m, s_m)

if lvl_yearly

    mtfphl(pyh   , pyl , '12M', css_y, s_y)
    
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - End                                                                                                                                        }
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - Market Structure                                                                                                                           }
//{----------------------------------------------------------------------------------------------------------------------------------------------}
method darkcss(color css, float factor, bool bull) =>

    blue  = color.b(css) * (1 - factor)
    red   = color.r(css) * (1 - factor)
    green = color.g(css) * (1 - factor)

    color.rgb(red, green, blue, 0)

method f_line(msDraw d, size, style) =>

    var line  id  = na
    var label lbl = na

    id := line.new(
       d.n
     , d.p
     , b.n
     , d.p
     , color = d.css
     , width = 1
     , style = style
     )

    if msline.size() >= 250

        line.delete(msline.shift())

    msline.push(id)

    lbl := label.new(
       int(math.avg(d.n, b.n))
     , d.p
     , d.txt
     , color            = invcol
     , textcolor        = d.css
     , style            = d.bull ? label.style_label_down : label.style_label_up
     , size             = size
     )

structure(bool mtf) =>

	msDraw drw     = na

    bool isdrw     = false
    bool isdrwS   = false

    var color css  = na
    var color icss = na

	var int itrend = 0
    var int  trend = 0

    bool bull_ob   = false
    bool bear_ob   = false

    bool s_bull_ob = false
    bool s_bear_ob = false

    n = bar_index
	
	var ms up = ms.new(
		   array.new<float>()
		 , array.new< int >()
         , array.new<float>()
		 )

	var ms dn = ms.new(
		   array.new<float>()
		 , array.new< int >()
         , array.new<float>()
		 )

	var ms sup = ms.new(
		   array.new<float>()
		 , array.new< int >()
         , array.new<float>()
		 )

	var ms sdn = ms.new(
		   array.new<float>()
		 , array.new< int >()
         , array.new<float>()
		 )

    switch show_swing_ms

        "All"      =>  boolean.set(s_BOS , true ),  boolean.set(s_CHoCH, true ) , boolean.set(s_CHoCHP, true  )  
        "CHoCH"    =>  boolean.set(s_BOS , false),  boolean.set(s_CHoCH, true ) , boolean.set(s_CHoCHP, false )   
        "CHoCH+"   =>  boolean.set(s_BOS , false),  boolean.set(s_CHoCH, false) , boolean.set(s_CHoCHP, true  )  
        "BOS"      =>  boolean.set(s_BOS , true ),  boolean.set(s_CHoCH, false) , boolean.set(s_CHoCHP, false )  
        "None"     =>  boolean.set(s_BOS , false),  boolean.set(s_CHoCH, false) , boolean.set(s_CHoCHP, false )  
        => na

    switch show_internal_ms

        "All"      =>  boolean.set(i_BOS, true ),  boolean.set(i_CHoCH, true  ),  boolean.set(i_CHoCHP, true )
        "CHoCH"    =>  boolean.set(i_BOS, false),  boolean.set(i_CHoCH, true  ),  boolean.set(i_CHoCHP, false) 
        "CHoCH+"   =>  boolean.set(i_BOS, false),  boolean.set(i_CHoCH, false ),  boolean.set(i_CHoCHP, true ) 
        "BOS"      =>  boolean.set(i_BOS, true ),  boolean.set(i_CHoCH, false ),  boolean.set(i_CHoCHP, false) 
        "None"     =>  boolean.set(i_BOS, false),  boolean.set(i_CHoCH, false ),  boolean.set(i_CHoCHP, false) 
        => na
        
    switch
        iH =>

            up.p.unshift(b.h[iLen])
            up.l.unshift(b.h[iLen])
            up.n.unshift(n  [iLen])

        iL =>

            dn.p.unshift(b.l[iLen])
            dn.l.unshift(b.l[iLen])
            dn.n.unshift(n  [iLen])

        sL =>

            sdn.p.unshift(b.l[sLen])
            sdn.l.unshift(b.l[sLen])
            sdn.n.unshift(n  [sLen])

        sH =>

            sup.p.unshift(b.h[sLen])
            sup.l.unshift(b.h[sLen])
            sup.n.unshift(n  [sLen])

	// INTERNAL BULLISH STRUCTURE
	if up.p.size() > 0 and dn.l.size() > 1

		if ta.crossover(b.c, up.p.first())

			bool CHoCH = na
			string txt = na

			if itrend < 0

				CHoCH := true

			switch

				not CHoCH =>

					txt := "BOS"
					css := i_ms_up_BOS

                    blalert.bos := true

					if boolean.get(i_BOS) and mtf == false and na(drw)

                        isdrw := true
						drw := msDraw.new(
							   up.n.first()
							 , up.p.first()
							 , i_ms_up_BOS
							 , txt
							 , true
							 )	

				CHoCH => 

                    dn.l.first() > dn.l.get(1) ? blalert.chochplus : blalert.choch

					txt := dn.l.first() > dn.l.get(1) ? "CHoCH+" : "CHoCH"
					css := i_ms_up_BOS.darkcss(0.25, true)

					if (dn.l.first() > dn.l.get(1) ? boolean.get(i_CHoCHP) : boolean.get(i_CHoCH)) and mtf == false and na(drw)

                        isdrw := true
						drw := msDraw.new(
							   up.n.first()
							 , up.p.first()
							 , i_ms_up_BOS.darkcss(0.25, true)
							 , txt
							 , true
							 )				

			if mtf == false

				switch

					ob_filter == "None" 					    => bull_ob := true
					ob_filter == "BOS"    and txt == "BOS"      => bull_ob := true
					ob_filter == "CHoCH"  and txt == "CHoCH"    => bull_ob := true
					ob_filter == "CHoCH+" and txt == "CHoCH+"   => bull_ob := true

			itrend := 1
            up.n.clear()
            up.p.clear()

	// INTERNAL BEARISH STRUCTURE
	if dn.p.size() > 0 and up.l.size() > 1

		if ta.crossunder(b.c, dn.p.first())
            
			bool CHoCH = na
			string txt = na

			if itrend > 0

				CHoCH := true

			switch

				not CHoCH =>

                    bralert.bos := true

					txt := "BOS"
					css := i_ms_dn_BOS

					if boolean.get(i_BOS) and mtf == false and na(drw)

                        isdrw := true
						drw := msDraw.new(
							   dn.n.first()
							 , dn.p.first()
							 , i_ms_dn_BOS
							 , txt
							 , false
							 )	

				CHoCH => 

                    if up.l.first() < up.l.get(1)
                        bralert.chochplus := true
                    else 
                        bralert.choch := true

					txt := up.l.first() < up.l.get(1) ? "CHoCH+" : "CHoCH"
					css := i_ms_dn_BOS.darkcss(0.25, false)

					if (up.l.first() < up.l.get(1) ? boolean.get(i_CHoCHP) : boolean.get(i_CHoCH)) and mtf == false and na(drw)

                        isdrw := true
						drw := msDraw.new(
							   dn.n.first()
							 , dn.p.first()
							 , i_ms_dn_BOS.darkcss(0.25, false)
							 , txt
							 , false
							 )			

			if mtf == false

				switch

					ob_filter == "None" 					    => bear_ob := true
					ob_filter == "BOS"    and txt == "BOS"      => bear_ob := true
					ob_filter == "CHoCH"  and txt == "CHoCH"    => bear_ob := true
					ob_filter == "CHoCH+" and txt == "CHoCH+"   => bear_ob := true

			itrend := -1
            dn.n.clear()
            dn.p.clear()

	// SWING BULLISH STRUCTURE
	if sup.p.size() > 0 and sdn.l.size() > 1

		if ta.crossover(b.c, sup.p.first())

			bool CHoCH = na
			string txt = na

			if trend < 0

				CHoCH := true

			switch

				not CHoCH =>

                    blalert.swingbos := true

					txt := "BOS"
					icss := s_ms_up_BOS

					if boolean.get(s_BOS) and mtf == false and na(drw)

                        isdrwS := true
						drw := msDraw.new(
							   sup.n.first()
							 , sup.p.first()
							 , s_ms_up_BOS
							 , txt
							 , true
							 )	

				CHoCH => 

                    if sdn.l.first() > sdn.l.get(1)
                        blalert.chochplusswing := true
                    else 
                        blalert.chochswing := true

					txt := sdn.l.first() > sdn.l.get(1) ? "CHoCH+" : "CHoCH"
					icss := s_ms_up_BOS.darkcss(0.25, true)

					if (sdn.l.first() > sdn.l.get(1) ? boolean.get(s_CHoCHP) : boolean.get(s_CHoCH)) and mtf == false and na(drw)

                        isdrwS := true
						drw := msDraw.new(
							   sup.n.first()
							 , sup.p.first()
							 , s_ms_up_BOS.darkcss(0.25, true)
							 , txt
							 , true
							 )	

			if mtf == false

				switch
                
					ob_filter == "None" 					  => s_bull_ob := true
					ob_filter == "BOS"    and txt == "BOS"    => s_bull_ob := true
					ob_filter == "CHoCH"  and txt == "CHoCH"  => s_bull_ob := true
					ob_filter == "CHoCH+" and txt == "CHoCH+" => s_bull_ob := true

			trend := 1
            sup.n.clear()
            sup.p.clear()

	// SWING BEARISH STRUCTURE
	if sdn.p.size() > 0 and sup.l.size() > 1

		if ta.crossunder(b.c, sdn.p.first())

			bool CHoCH = na
			string txt = na

			if trend > 0

				CHoCH := true

			switch

				not CHoCH =>

                    bralert.swingbos := true

					txt := "BOS"
					icss := s_ms_dn_BOS

					if boolean.get(s_BOS) and mtf == false and na(drw)

                        isdrwS := true
						drw := msDraw.new(
							   sdn.n.first()
							 , sdn.p.first()
							 , s_ms_dn_BOS
							 , txt
							 , false
							 )	

				CHoCH => 

                    if sup.l.first() < sup.l.get(1)
                        bralert.chochplusswing := true
                    else
                        bralert.chochswing := true

					txt := sup.l.first() < sup.l.get(1) ? "CHoCH+" : "CHoCH"
					icss := s_ms_dn_BOS.darkcss(0.25, false)

					if (sup.l.first() < sup.l.get(1) ? boolean.get(s_CHoCHP) : boolean.get(s_CHoCH)) and mtf == false and na(drw)

                        isdrwS := true
						drw := msDraw.new(
							   sdn.n.first()
							 , sdn.p.first()
							 , s_ms_dn_BOS.darkcss(0.25, false)
							 , txt
							 , false
							 )		

			if mtf == false

				switch

					ob_filter == "None" 					   => s_bear_ob := true
					ob_filter == "BOS"     and txt == "BOS"    => s_bear_ob := true
					ob_filter == "CHoCH"   and txt == "CHoCH"  => s_bear_ob := true
					ob_filter == "CHoCH+"  and txt == "CHoCH+" => s_bear_ob := true

			trend := -1
            sdn.n.clear()
            sdn.p.clear()

    [css, bear_ob, bull_ob, itrend, drw, isdrw, s_bear_ob, s_bull_ob, trend, icss, isdrwS]

[css, bear_ob, bull_ob, itrend, drw, isdrw, s_bear_ob, s_bull_ob, trend, icss, isdrwS] = structure(false)

if isdrw
    f_line(drw, size.small, line.style_dashed)

if isdrwS
    f_line(drw, size.small, line.style_solid)

// ADX Function
adxlen = input(14, title="ADX Smoothing")
dilen = input(14, title="DI Length")

dirmov(len) =>
    up = ta.change(high)
    down = -ta.change(low)
    plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
    minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
    truerange = ta.rma(ta.tr, len)
    plus = fixnan(100 * ta.rma(plusDM, len) / truerange)
    minus = fixnan(100 * ta.rma(minusDM, len) / truerange)
    [plus, minus]

adx(dilen, adxlen) =>
    [plus, minus] = dirmov(dilen)
    sum = plus + minus
    adx = 100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), adxlen)
    adx

//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - RSI                                                                                                                                        }
//{----------------------------------------------------------------------------------------------------------------------------------------------}
up = ta.rma(math.max(ta.change(rsi_src), 0), rsi_length)
down = ta.rma(-math.min(ta.change(rsi_src), 0), rsi_length)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))

isoverbought() => rsi > rsi_overbought_length
isoversold() => rsi < rsi_oversold_length

p_css = css
b_css = css
w_css = css

p_css := plotcandle_bool ? (css) : na
b_css := barcolor_bool   ? (css) : na
w_css := plotcandle_bool ? color.rgb(120, 123, 134, 50)           : na

plotcandle(open,high,low,close , color = p_css , wickcolor = w_css , bordercolor = p_css , editable = false)
barcolor(b_css, editable = false)

//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - END                                                                                                                                        }
//{----------------------------------------------------------------------------------------------------------------------------------------------}
// Multi-Timeframe Analysis
[_, _, _, itrend5, _, _, _, _, _, _, _]  = request.security("", "5"      , structure(true))
[_, _, _, itrend15, _, _, _, _, _, _, _] = request.security("", "15"     , structure(true))
[_, _, _, itrend30, _, _, _, _, _, _, _] = request.security("", "30"     , structure(true))
[_, _, _, itrend1H, _, _, _, _, _, _, _] = request.security("", "60"     , structure(true))
[_, _, _, itrend4H, _, _, _, _, _, _, _] = request.security("", "240"    , structure(true))
[_, _, _, itrend1D, _, _, _, _, _, _, _] = request.security("", "1440"   , structure(true))
[_, _, _, itrend1W, _, _, _, _, _, _, _] = request.security("", "1W"     , structure(true))

rsi_value = ta.rsi(close, rsi_length)
rsi_value_str = str.format("{0,number,#.##}", rsi_value)

var tab = table.new(position = position.top_right, columns = 20, rows = 20, bgcolor = #000000, frame_color = #000000, border_width = 1)
    
// Table headers
if show_itrend5 and show_mtf_str
    table.cell(tab, 0, 1, text = show_itrend5 ? "5m" : "", text_color = color.silver, text_halign = text.align_center, text_size = size.normal, bgcolor = chart.bg_color, text_font_family = font.family_monospace, width = 4)
if show_itrend15 and show_mtf_str
    table.cell(tab, 0, 2, text = show_itrend15 ? "15m" : "", text_color = color.silver, text_halign = text.align_center, text_size = size.normal, bgcolor = chart.bg_color, text_font_family = font.family_monospace, width = 4)
if show_itrend30 and show_mtf_str
    table.cell(tab, 0, 3, text = show_itrend30 ? "30m" : "", text_color = color.silver, text_halign = text.align_center, text_size = size.normal, bgcolor = chart.bg_color, text_font_family = font.family_monospace, width = 4)
if show_itrend1H and show_mtf_str
    table.cell(tab, 0, 4, text = show_itrend1H ? "1H" : "", text_color = color.silver, text_halign = text.align_center, text_size = size.normal, bgcolor = chart.bg_color, text_font_family = font.family_monospace, width = 4)
if show_itrend4H and show_mtf_str
    table.cell(tab, 0, 5, text = show_itrend4H ? "4H" : "", text_color = color.silver, text_halign = text.align_center, text_size = size.normal, bgcolor = chart.bg_color, text_font_family = font.family_monospace, width = 4)
if show_itrend1D and show_mtf_str
    table.cell(tab, 0, 6, text = show_itrend1D ? "1D" : "", text_color = color.silver, text_halign = text.align_center, text_size = size.normal, bgcolor = chart.bg_color, text_font_family = font.family_monospace, width = 4)
if show_itrend1W and show_mtf_str
    table.cell(tab, 0, 7, text = show_itrend1W ? "1W" : "", text_color = color.silver, text_halign = text.align_center, text_size = size.normal, bgcolor = chart.bg_color, text_font_family = font.family_monospace, width = 4)
if show_rsi and show_mtf_str
    table.cell(tab, 0, 8, text = show_rsi ? "RSI" : "", text_color = color.yellow, text_halign = text.align_center, text_size = size.normal, bgcolor = chart.bg_color, text_font_family = font.family_monospace, width = 4)

    // Table data based on user preferences
if show_itrend5 and show_mtf_str
    table.cell(tab, 1, 1, text = itrend5 == 1 ? "BULLISH" : itrend5 == -1 ? "BEARISH" : na, text_halign = text.align_center, text_size = size.normal, text_color = itrend5 == 1 ? #089981 : itrend5 == -1 ? #ff0000 : color.gray, bgcolor = chart.bg_color, text_font_family = font.family_monospace)
if show_itrend15 and show_mtf_str
    table.cell(tab, 1, 2, text = itrend15 == 1 ? "BULLISH" : itrend15 == -1 ? "BEARISH" : na, text_halign = text.align_center, text_size = size.normal, text_color = itrend15 == 1 ? #089981 : itrend15 == -1 ? #ff0000 : color.gray, bgcolor = chart.bg_color, text_font_family = font.family_monospace)
if show_itrend30 and show_mtf_str
    table.cell(tab, 1, 3, text = itrend30 == 1 ? "BULLISH" : itrend30 == -1 ? "BEARISH" : na, text_halign = text.align_center, text_size = size.normal, text_color = itrend30 == 1 ? #089981 : itrend30 == -1 ? #ff0000 : color.gray, bgcolor = chart.bg_color, text_font_family = font.family_monospace)
if show_itrend1H and show_mtf_str
    table.cell(tab, 1, 4, text = itrend1H == 1 ? "BULLISH" : itrend1H == -1 ? "BEARISH" : na, text_halign = text.align_center, text_size = size.normal, text_color = itrend1H == 1 ? #089981 : itrend1H == -1 ? #ff0000 : color.gray, bgcolor = chart.bg_color, text_font_family = font.family_monospace)
if show_itrend4H and show_mtf_str
    table.cell(tab, 1, 5, text = itrend4H == 1 ? "BULLISH" : itrend4H == -1 ? "BEARISH" : na, text_halign = text.align_center, text_size = size.normal, text_color = itrend4H == 1 ? #089981 : itrend4H == -1 ? #ff0000 : color.gray, bgcolor = chart.bg_color, text_font_family = font.family_monospace)
if show_itrend1D and show_mtf_str
    table.cell(tab, 1, 6, text = itrend1D == 1 ? "BULLISH" : itrend1D == -1 ? "BEARISH" : na, text_halign = text.align_center, text_size = size.normal, text_color = itrend1D == 1 ? #089981 : itrend1D == -1 ? #ff0000 : color.gray, bgcolor = chart.bg_color, text_font_family = font.family_monospace)
if show_itrend1W and show_mtf_str
    table.cell(tab, 1, 7, text = itrend1W == 1 ? "BULLISH" : itrend1W == -1 ? "BEARISH" : na, text_halign = text.align_center, text_size = size.normal, text_color = itrend1W == 1 ? #089981 : itrend1W == -1 ? #ff0000 : color.gray, bgcolor = chart.bg_color, text_font_family = font.family_monospace)
if show_rsi and show_mtf_str
    table.cell(tab, 1, 8, text = rsi_value_str, text_halign = text.align_center, text_size = size.normal, text_color = isoverbought() ? #ff0000 : isoversold() ? #089981 : color.yellow, bgcolor = chart.bg_color, text_font_family = font.family_monospace)
// ADX data
if show_adx and show_mtf_str
    adx_value = adx(dilen, adxlen)
    table.cell(tab, 0, 9, text="ADX", text_halign=text.align_center, text_size=size.normal, text_color=#00e2ff, bgcolor=chart.bg_color, text_font_family=font.family_monospace, width=4)
    table.cell(tab, 1, 9, text=str.tostring(adx_value, "#.##"), text_halign=text.align_center, text_size=size.normal, text_color=#00e2ff, bgcolor=chart.bg_color, text_font_family=font.family_monospace)
    // Merged cells for pattern detection
if show_mtf_str
    table.cell(tab, 0, 10, text = "Detected Pattern", text_halign = text.align_center, text_size = size.normal, text_color = color.silver, bgcolor = chart.bg_color, text_font_family = font.family_monospace)
    table.cell(tab, 0, 11, text = p.found, text_halign = text.align_center, text_size = size.normal, text_color = na(p.bull) ? color.white : p.bull ? #089981 : #ff0000, bgcolor = chart.bg_color, text_font_family = font.family_monospace)
    
    table.merge_cells(tab, 0, 10, 1, 10)
    table.merge_cells(tab, 0, 11, 1, 11)

var phl = Zphl.new(
   na
 , na
 , label.new(na , na , color = invcol , textcolor = i_ms_dn_BOS , style = label.style_label_down , size = size.tiny , text = "")
 , label.new(na , na , color = invcol , textcolor = i_ms_up_BOS , style = label.style_label_up   , size = size.tiny , text = "")
 , true
 , true
 , true
 , true
 , ""
 , ""
 , 0
 , 0
 , 0
 , 0
 , high
 , low
 , 0
 , 0
 , 0
 , 0
 , 0
 , 0
 , na
 , na
 )

zhl(len)=>    

    upper = ta.highest(len)
    lower = ta.lowest(len)

    var float out = 0
    out := b.h[len] > upper ? 0 : b.l[len] < lower ? 1 : out[1]

    top = out == 0 and out[1] != 0 ? b.h[len] : 0
    btm = out == 1 and out[1] != 1 ? b.l[len] : 0

    [top, btm]

[top , btm ] = zhl(sLen)
[itop, ibtm] = zhl(iLen)

upphl(trend) =>

    var label lbl = label.new(
       na
     , na
     , color     = invcol
     , textcolor = toplvl
     , style     = label.style_label_down
     , size      = size.small
     )

    if top

        phl.stopcross := true
        phl.txtup     := top > phl.topy ? "HH" : "HL"

        if show_lbl

            topl = label.new(
               b.n - swing_r_lookback
             , top
             , phl.txtup
             , color     = invcol
             , textcolor = toplvl
             , style     = label.style_label_down
             , size      = size.small
             )

        line.delete(phl.top[1])

        phl.top := line.new(
               b.n - sLen
             , top
             , b.n
             , top
             , color = toplvl)

        phl.topy      := top
        phl.topx      := b.n - sLen
        phl.tup       := top
        phl.tupx      := b.n - sLen

    if itop

        phl.itopcross := true
        phl.itopy     := itop
        phl.itopx     := b.n - iLen

    phl.tup           := math.max(high, phl.tup)
    phl.tupx          := phl.tup == high ? b.n : phl.tupx
    phl.uV            := phl.tup != phl.tup[1] ? b.v : phl.uV

    if barstate.islast 

        line.set_xy1(
               phl.top
             , phl.tupx
             , phl.tup
             )

        line.set_xy2(
               phl.top
             , b.n + 50
             , phl.tup
             )

        label.set_x(
               lbl
             , b.n + 50
             )

        label.set_y(
               lbl
             , phl.tup
             )

        dist = math.abs(phl.uV / (phl.uV + phl.dV)) * 100
        label.set_text (lbl, trend < 0 
             ? "Strong High | " + str.tostring(phl.uV, format.volume) + " (" + str.tostring(math.round(dist,0)) + "%)" 
             : "Weak High | "   + str.tostring(phl.uV, format.volume) + " (" + str.tostring(math.round(dist,0)) + "%)")

dnphl(trend) =>

    var label lbl = label.new(
       na
     , na
     , color     = invcol
     , textcolor = btmlvl
     , style     = label.style_label_up
     , size      = size.small
     )

    if btm

        phl.sbottomcross := true
        phl.txtdn        := btm > phl.bottomy ? "LH" : "LL"

        if show_lbl

            btml = label.new(
               b.n - swing_r_lookback
             , btm, phl.txtdn
             , color = invcol
             , textcolor = btmlvl
             , style = label.style_label_up
             , size = size.small
             )

        line.delete(phl.bottom[1])
        
        phl.bottom := line.new(
           b.n - sLen
         , btm
         , b.n
         , btm
         , color = btmlvl
         )

        phl.bottomy      := btm
        phl.bottomx      := b.n - sLen
        phl.tdn          := btm
        phl.tdnx         := b.n - sLen

    if ibtm

        phl.ibottomcross := true
        phl.ibottomy     := ibtm
        phl.ibottomx     := b.n - iLen

    phl.tdn              := math.min(low, phl.tdn)
    phl.tdnx             := phl.tdn == low ? b.n : phl.tdnx
    phl.dV               := phl.tdn != phl.tdn[1] ? b.v : phl.dV

    if barstate.islast

        line.set_xy1(
           phl.bottom
         , phl.tdnx
         , phl.tdn
         )

        line.set_xy2(
           phl.bottom
         , b.n + 50
         , phl.tdn
         )

        label.set_x(
           lbl
         , b.n + 50
         )

        label.set_y(
           lbl
         , phl.tdn
         )
         
        dist = math.abs(phl.dV / (phl.uV + phl.dV)) * 100
        label.set_text (lbl, trend > 0 
             ? "Strong Low | " + str.tostring(phl.dV, format.volume) + " (" + str.tostring(math.round(dist,0)) + "%)" 
             : "Weak Low | "   + str.tostring(phl.uV, format.volume) + " (" + str.tostring(math.round(dist,0)) + "%)")

midphl() =>

    avg = math.avg(phl.bottom.get_y2(), phl.top.get_y2())
    
    var line l = line.new(
       y1 = avg
     , y2 = avg
     , x1 = b.n - sLen
     , x2 = b.n + 50
     , color = midlvl
     , style = line.style_solid
     )

    var label lbl = label.new(
       x = b.n + 50
     , y = avg
     , text = "Equilibrium"
     , style = label.style_label_left
     , color = invcol
     , textcolor = midlvl
     , size = size.small
     )
     
    if barstate.islast

        more = (phl.bottom.get_x1() + phl.bottom.get_x2()) > (phl.top.get_x1() + phl.top.get_x2()) ? phl.top.get_x1() : phl.bottom.get_x1()
        line.set_xy1(l   , more    , avg)
        line.set_xy2(l   , b.n + 50, avg)
        label.set_x (lbl , b.n + 50     )
        label.set_y (lbl , avg          )
        dist = math.abs((l.get_y2() - close) / close) * 100
        label.set_text (lbl, "Equilibrium (" + str.tostring(math.round(dist,0)) + "%)")     
          
hqlzone() =>

    if barstate.islast

        var hqlzone dZone = hqlzone.new(
           box.new(
               na
             , na
             , na
             , na
             , bgcolor = color.new(toplvl, 70)
             , border_color = na
             )
         , box.new(
               na
             , na
             , na
             , na
             , bgcolor = color.new(midlvl, 70)
             , border_color = na
             )
         , box.new(
               na
             , na
             , na
             , na
             , bgcolor = color.new(btmlvl, 70)
             , border_color = na
             )

         , label.new(na, na, text = "Premium"    , color = invcol, textcolor = toplvl, style = label.style_label_down, size = size.small)
         , label.new(na, na, text = "Equilibrium", color = invcol, textcolor = midlvl, style = label.style_label_left, size = size.small)
         , label.new(na, na, text = "Discount"   , color = invcol, textcolor = btmlvl, style = label.style_label_up  , size = size.small)
         )

        dZone.pbx.set_lefttop(int(math.max(phl.topx, phl.bottomx))                          , phl.tup)
        dZone.pbx.set_rightbottom(b.n + 50                        , 0.95  * phl.tup + 0.05  * phl.tdn)

        dZone.ebx.set_lefttop(int(math.max(phl.topx, phl.bottomx)), 0.525 * phl.tup + 0.475 * phl.tdn)
        dZone.ebx.set_rightbottom(b.n + 50                        , 0.525 * phl.tdn + 0.475 * phl.tup)

        dZone.lbx.set_lefttop(int(math.max(phl.topx, phl.bottomx)), 0.95  * phl.tdn + 0.05  * phl.tup)
        dZone.lbx.set_rightbottom(b.n + 50                                                  , phl.tdn)

        dZone.plb.set_xy( int(math.avg(math.max(phl.topx, phl.bottomx), int(b.n + 50))) , phl.tup)
        dZone.elb.set_xy( int(b.n + 50)                                                 , math.avg(phl.tup, phl.tdn))
        dZone.lbl.set_xy( int(math.avg(math.max(phl.topx, phl.bottomx), int(b.n + 50))) , phl.tdn)
        
if show_mtb

    upphl (trend)
    dnphl (trend)
    hqlzone()

//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - End                                                                                                                                        }
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - Volumetric Order Block                                                                                                                     }
//{----------------------------------------------------------------------------------------------------------------------------------------------}

method eB(box[] b, bool ext, color css, bool swing, ob_tf) =>
    b.unshift(
         box.new(
               na
             , na
             , na
             , na
             , xloc             = xloc.bar_time
             , extend           = ext ? extend.right : extend.none
             , border_color     = swing ? color.new(css, 0) : color.new(color.white,100)
             , bgcolor          = css
             , border_width     = 1
              )
             )

method eL(line[] l, bool ext, bool solid, color css, ob_tf) =>
    l.unshift(
         line.new(
               na
             , na
             , na
             , na
             , width  = 1
             , color  = css
             , xloc   = xloc.bar_time
             , extend = ext   ? extend.right     : extend.none
             , style  = solid ? line.style_solid : line.style_dashed
              )
             )

method drawVOB(bool cdn, bool bull, color css, int loc, bool swing) =>

    [cC, oO, hH, lL, vV] = request.security(
         syminfo.tickerid
         , ob_tf

         ,   [

               close
             , open
             , high
             , low
             , volume

             ]

         , lookahead = barmerge.lookahead_off
                                           )
    var obC obj  = obC.new(
                   array.new<float>()
                 , array.new<float>()
                 , array.new< int >()
                 , array.new<float>()
                 , array.new<float>()
                 , array.new<float>()
                 , array.new< int >()
                 , array.new< int >()
                 , array.new< int >()
                 , array.new< int >()
                 , array.new<float>()
                 , array.new<float>()
                 , array.new< int >()
                 )

    var obD draw = obD.new(
                   array.new<box >()
                 , array.new<box >()
                 , array.new<box >()
                 , array.new<box >()
                 , array.new<line>()
                 )
    if barstate.isfirst
        for i = 0 to ob_num - 1
            draw.mL.eL(false, false, use_grayscale ? color.new(color.gray, 0) : color.new(css,0), ob_tf)
            draw.ob.eB(false, use_grayscale ? color.new(color.gray, 90) : css, swing, ob_tf)
            draw.blB.eB(false, css_metric_up, swing, ob_tf)
            draw.brB.eB(false, css_metric_dn, swing, ob_tf)
            draw.eOB.eB(true, use_grayscale ? color.new(color.gray, 90) : css, swing, ob_tf)

// Define variables to hold the data from request.security()
    float high_tf = request.security(syminfo.tickerid, ob_tf, high, lookahead=barmerge.lookahead_on)
    float low_tf = request.security(syminfo.tickerid, ob_tf, low, lookahead=barmerge.lookahead_on)
    float ohlc4_tf = request.security(syminfo.tickerid, ob_tf, ohlc4, lookahead=barmerge.lookahead_on)
    float hl2_tf = request.security(syminfo.tickerid, ob_tf, hl2, lookahead=barmerge.lookahead_on)

// Calculate 'pos' based on 'ob_pos' and the corresponding data from the 'ob_tf' timeframe
    float pos = na
    if ob_pos == "Full" 
        pos := bull ? high_tf : low_tf
    else if ob_pos == "Middle" 
        pos := ohlc4_tf
    else if ob_pos == "Accurate" 
        pos := hl2_tf
    else
        pos := hl2_tf


    if cdn

        obj.h.clear()
        obj.l.clear()
        obj.n.clear()

        for i = 1 to math.abs((loc - b.n)) - 1

            obj.h.push(hH[i])
            obj.l.push(lL[i])
            obj.n.push(b.t[i])

        // obj.h.reverse()
        // obj.l.reverse()

        int iU = obj.l.indexof(obj.l.min()) + 1
        int iD = obj.h.indexof(obj.h.max()) + 1

        obj.dir.unshift(
             bull 
                 ? (b.c[iU] > b.o[iU] ? 1 : -1) 
                 : (b.c[iD] > b.o[iD] ? 1 : -1)
             )

        obj.top.unshift(
             bull 
                 ? pos[iU] 
                 : obj.h.max()
             )

        obj.btm.unshift(
             bull 
                 ? obj.l.min() 
                 : pos[iD]
             )

        obj.left.unshift(
             bull 
                 ? obj.n.get(obj.l.indexof(obj.l.min())) 
                 : obj.n.get(obj.h.indexof(obj.h.max()))
             )

        obj.avg.unshift(
             math.avg(obj.top.first(), obj.btm.first())
             )

        obj.cV.unshift(
             bull 
                 ? b.v[iU] 
                 : b.v[iD]
             )

        if ob_pos == "Precise"

            switch bull
                true =>
                    if obj.avg.get(0) < (b.c[iU] < b.o[iU] ? b.c[iU] : b.o[iU]) and obj.top.get(0) > hlcc4[iU]
                        obj.top.set(0, obj.avg.get(0))
                        obj.avg.set(0, math.avg(obj.top.first(), obj.btm.first()))
                false =>
                    if obj.avg.get(0) > (b.c[iU] < b.o[iU] ? b.o[iD] : b.c[iD]) and obj.btm.get(0) < hlcc4[iD]
                        obj.btm.set(0, obj.avg.get(0))
                        obj.avg.set(0, math.avg(obj.top.first(), obj.btm.first()))

        obj.blVP.unshift ( 0 )
        obj.brVP.unshift ( 0 )
        obj.wM  .unshift ( 1 )

        if use_overlap

            int rmP = use_overlap_method == "Recent" ? 1 : 0

            if obj.avg.size() > 1

                if bull 

                     ? obj.btm.first() < obj.top.get(1) 
                     : obj.top.first() > obj.btm.get(1)
                    obj.wM   .remove(rmP)
                    obj.cV   .remove(rmP)
                    obj.dir  .remove(rmP)
                    obj.top  .remove(rmP)
                    obj.avg  .remove(rmP) 
                    obj.btm  .remove(rmP)
                    obj.left .remove(rmP)
                    obj.blVP .remove(rmP)
                    obj.brVP .remove(rmP)

    if barstate.isconfirmed

        for x = 0 to ob_num - 1

            tg = switch ob_mitigation
                "Middle"   => obj.avg
                "Absolute" => bull ? obj.btm : obj.top

            for [idx, pt] in tg

                if (bull ? cC < pt : cC > pt)
                    obj.wM   .remove(idx)
                    obj.cV   .remove(idx)
                    obj.dir  .remove(idx)
                    obj.top  .remove(idx)
                    obj.avg  .remove(idx) 
                    obj.btm  .remove(idx)
                    obj.left .remove(idx)
                    obj.blVP .remove(idx)
                    obj.brVP .remove(idx)
            
    if barstate.islast

        if obj.avg.size() > 0

            // Alert

            if bull 
                 ? ta.crossunder(low , obj.top.get(0)) 
                 : ta.crossover (high, obj.btm.get(0)) 
                switch bull 
                    true  => blalert.obtouch := true 
                    false => bralert.obtouch := true


            float tV = 0
            obj.dV.clear()
            seq = math.min(ob_num - 1, obj.avg.size() - 1)

            for j = 0 to seq

                tV += obj.cV.get(j)

                if j == seq

                    for y = 0 to seq

                        obj.dV.unshift(
                             math.floor(
                                 (obj.cV.get(y) / tV) * 100)
                         )

                obj.dV.reverse()

            for i = 0 to math.min(ob_num - 1, obj.avg.size() - 1)

                dmL   = draw.mL .get(i)
                dOB   = draw.ob .get(i)
                dblB  = draw.blB.get(i)
                dbrB  = draw.brB.get(i)
                deOB  = draw.eOB.get(i)

                dOB.set_lefttop     (obj.left .get(i)           , obj.top.get(i))
                deOB.set_lefttop    (b.t                        , obj.top.get(i))
                dOB.set_rightbottom (b.t                        , obj.btm.get(i))
                deOB.set_rightbottom(b.t + (b.t - b.t[1]) * 100 , obj.btm.get(i))

                if use_middle_line

                    dmL.set_xy1(obj.left.get(i), obj.avg.get(i))
                    dmL.set_xy2(b.t            , obj.avg.get(i))

                if ob_metrics_show

                    dblB.set_lefttop    (obj.left.get(i), obj.top.get(i))
                    dbrB.set_lefttop    (obj.left.get(i), obj.avg.get(i))
                    dblB.set_rightbottom(obj.left.get(i), obj.avg.get(i))
                    dbrB.set_rightbottom(obj.left.get(i), obj.btm.get(i))

                    rpBL = dblB.get_right()
                    rpBR = dbrB.get_right()
                    dbrB.set_right(rpBR + (b.t - b.t[1]) * obj.brVP.get(i))
                    dblB.set_right(rpBL + (b.t - b.t[1]) * obj.blVP.get(i))

                if use_show_metric

                    txt = switch

                        obj.cV.get(i) >= 1000000000 => str.tostring(math.round(obj.cV.get(i) / 1000000000,3)) + "B"
                        obj.cV.get(i) >= 1000000    => str.tostring(math.round(obj.cV.get(i) / 1000000,3))    + "M"
                        obj.cV.get(i) >= 1000       => str.tostring(math.round(obj.cV.get(i) / 1000,3))       + "K"
                        obj.cV.get(i) <  1000       => str.tostring(math.round(obj.cV.get(i)))

                    deOB.set_text(
                         str.tostring(
                         txt + " (" + str.tostring(obj.dV.get(i)) + "%)")
                         )

                    deOB.set_text_size (obtxt.txSz())
                    deOB.set_text_halign(text.align_left)
                    deOB.set_text_color (use_grayscale ? color.silver : color.new(css, 0))

    if ob_metrics_show and barstate.isconfirmed

        if obj.wM.size() > 0
            
            for i = 0 to obj.avg.size() - 1

                switch obj.dir.get(i)

                    1  =>

                        switch obj.wM.get(i)

                            1 => obj.blVP.set(i, obj.blVP.get(i) + 1), obj.wM.set(i, 2)
                            2 => obj.blVP.set(i, obj.blVP.get(i) + 1), obj.wM.set(i, 3)
                            3 => obj.brVP.set(i, obj.brVP.get(i) + 1), obj.wM.set(i, 1)
                    -1 =>

                        switch obj.wM.get(i)

                            1 => obj.brVP.set(i, obj.brVP.get(i) + 1), obj.wM.set(i, 2)
                            2 => obj.brVP.set(i, obj.brVP.get(i) + 1), obj.wM.set(i, 3)
                            3 => obj.blVP.set(i, obj.blVP.get(i) + 1), obj.wM.set(i, 1)

var hN = array.new<int>(1, b.n)
var lN = array.new<int>(1, b.n)
var hS = array.new<int>(1, b.n)
var lS = array.new<int>(1, b.n)

if iH

    hN.pop()
    hN.unshift(int(b.n[iLen]))

if iL

    lN.pop()
    lN.unshift(int(b.n[iLen]))

if sH

    hS.pop()
    hS.unshift(int(b.n[sLen]))

if sL

    lS.pop()
    lS.unshift(int(b.n[sLen]))

if ob_show

    bull_ob.drawVOB(true, ob_bull_css, hN.first(), false)
    bear_ob.drawVOB(false, ob_bear_css, lN.first(), false)

if bull_ob
    blalert.ob := true

if bear_ob
    bralert.ob := true

if s_bull_ob
    blalert.swingob := true

if s_bear_ob
    blalert.swingob := true

//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - End                                                                                                                                        }
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - FVG | VI | OG                                                                                                                              }
//{----------------------------------------------------------------------------------------------------------------------------------------------}

ghl() => request.security(syminfo.tickerid, fvg_tf, [high[2], low[2], close[1], open[1]])
tfG() => request.security(syminfo.tickerid, fvg_tf, [open, high, low, close])

cG(bool bull) =>

    [h, l, c, o]     = ghl()
    [go, gh, gl, gc] = tfG()

    var FVG draw   = FVG.new(
           array.new<box>()
         , array.new<line>()
         )

    var FVG[] cords = array.new<FVG>()

    float pup = na
    float pdn = na
    bool  cdn = na
    int   pos = 2
    cc        = timeframe.change(fvg_tf)

    if barstate.isfirst

        for i = 0 to fvg_num - 1

            draw.box.unshift(box.new (na, na, na, na, border_color = color.new(color.white, 100), xloc = xloc.bar_time))
            draw.ln.unshift (line.new(na, na, na, na, xloc = xloc.bar_time, width = 1, style = line.style_solid))

    switch what_fvg

        "FVG" => 

            pup := bull ?            gl : l
            pdn := bull ?      h        : gh
            cdn := bull ? gl > h and cc : gh < l and cc
            pos := 2

        "VI" =>

            pup := bull 
                 ? (gc > go 
                  ? go 
                   : gc) 
                 : (gc[1] > go[1] 
                  ? go[1] 
                   : gc[1])
            pdn := bull 
                 ? (gc[1] > go[1] 
                  ? gc[1] 
                   : go[1]) 
                 : (gc > go 
                  ? gc 
                   : go)
            cdn := bull 
                 ? go > gc[1] and gh[1] > gl and gc > gc[1] and go > go[1] and gh[1]  < math.min(gc, go) and cc
                 : go < gc[1] and gl[1] < gh and gc < gc[1] and go < go[1] and gl[1]  > math.max(gc, go) and cc
            pos := 1

        "OG" =>

            pup := bull ?               b.l : gl[1]
            pdn := bull ?      gh[1]        : gh
            cdn := bull ? gl > gh[1] and cc : gh < gl[1] and cc
            pos := 1       

    if not na(cdn) and cdn

        cords.unshift(
             FVG.new(
               na
             , na
             , bull 
              ? true 
              : false 
             , pup 
             , pdn
             , b.t - (b.t - b.t[1]) * pos
             , b.t + (b.t - b.t[1]) * fvg_extend)
             )
            
        if bull
            blalert.fvg := true
        else
            bralert.fvg := true
    
    if barstate.isconfirmed

        for [idx, obj] in cords

            if obj.bull ? b.c < obj.btm : b.c > obj.top

                cords.remove(idx)
        
    if barstate.islast

        if cords.size() > 0

            for i = math.min(fvg_num - 1, cords.size() - 1) to 0

                gbx = draw.box.get(i)
                gln = draw.ln.get(i)
                gcd = cords.get(i)
                
                gtop   = gcd.top
                gbtm   = gcd.btm
                left  = gcd.left
                right = gcd.right

                gbx.set_lefttop(left, gtop)
                gbx.set_rightbottom(right, gbtm)
                gbx.set_bgcolor(gcd.bull ? fvg_upcss : fvg_dncss)

                gln.set_xy1(left, math.avg(gbx.get_top(), gbx.get_bottom()))
                gln.set_xy2(right, math.avg(gbx.get_top(), gbx.get_bottom()))
                gln.set_color(gcd.bull ? fvg_upcss : fvg_dncss)

if fvg_enable       

    cG(true )
    cG(false)

//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - END                                                                                                                                        }
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - Accumulation And Distribution                                                                                                              }
//{----------------------------------------------------------------------------------------------------------------------------------------------}

drawZone(int len) =>
    var zone[]  z = array.new<zone>()

    if iH

        z.unshift(
             zone.new(
                 chart.point.from_time(
                       time[len]
                     , high [len]
                     )
                     , high [len]
                     ,  1
                     , time[len]
                 )
             )
    if iL
        z.unshift(
             zone.new(
                 chart.point.from_time(
                       time[len]
                     , low [len]
                     )
                     , low [len]
                     , -1
                     , time[len]
                 )
             )
    if z.size() > 1
        if z.get(0).c == z.get(1).c
            z.clear()
    
    switch

        zone_mode == "Slow" =>

            if z.size() > 5

                if z.get(0).c == -1 and z.get(1).c == 1 and z.get(2).c == -1 and z.get(3).c == 1 and z.get(4).c == -1 and z.get(5).c == 1

                    if z.get(0).p > z.get(2).p and z.get(2).p > z.get(4).p

                        if z.get(1).p < z.get(3).p and z.get(3).p < z.get(5).p   

                            blalert.zone := true

                            box.new(top = z.get(5).p, bottom = z.get(4).p, left = z.get(5).t, right = z.get(0).t, bgcolor = acc_css, border_color = color.new(color.white, 100), xloc = xloc.bar_time)
                            slice = array.new<chart.point>()

                            for i = 0 to 5

                                slice.unshift(z.get(i).points)

                            polyline.new(slice, xloc = xloc.bar_time, line_color = color.new(acc_css, 0), line_width = 2)
                            p.found := "Accumulation Zone"
                            p.bull := true
                            p.isfound := true
                            p.period := 0
                            z.clear()

            if z.size() > 5

                if z.get(0).c == 1 and z.get(1).c == -1 and z.get(2).c == 1 and z.get(3).c == -1 and z.get(4).c == 1 and z.get(5).c == -1

                    if z.get(0).p < z.get(2).p and z.get(2).p < z.get(4).p

                        if z.get(1).p > z.get(3).p and z.get(3).p > z.get(5).p    

                            bralert.zone := true

                            box.new(top = z.get(5).p, bottom = z.get(4).p, left = z.get(5).t, right = z.get(0).t, bgcolor = dist_css, border_color = color.new(color.white, 100), xloc = xloc.bar_time)
                            slice = array.new<chart.point>()

                            for i = 0 to 5

                                slice.unshift(z.get(i).points)

                            polyline.new(slice, xloc = xloc.bar_time, line_color = color.new(dist_css, 0), line_width = 2)
                            p.found := "Distribution Zone"
                            p.bull := false
                            p.isfound := true
                            p.period := 0
                            z.clear()   

        zone_mode == "Fast" =>    

            if z.size() > 3

                if z.get(0).c == -1 and z.get(1).c == 1 and z.get(2).c == -1 and z.get(3).c == 1

                    if z.get(0).p > z.get(2).p

                        if z.get(1).p < z.get(3).p   

                            blalert.zone := true

                            box.new(top = z.get(3).p, bottom = z.get(2).p, left = z.get(3).t, right = z.get(0).t, bgcolor = acc_css, border_color = color.new(color.white, 100), xloc = xloc.bar_time)
                            slice = array.new<chart.point>()

                            for i = 0 to 3

                                slice.unshift(z.get(i).points)

                            polyline.new(slice, xloc = xloc.bar_time, line_color = color.new(acc_css, 0), line_width = 2)
                            p.found := "Accumulation Zone"
                            p.bull := true
                            p.isfound := true
                            p.period := 0
                            z.clear()

            if z.size() > 3

                if z.get(0).c == 1 and z.get(1).c == -1 and z.get(2).c == 1 and z.get(3).c == -1

                    if z.get(0).p < z.get(2).p

                        if z.get(1).p > z.get(3).p  

                            bralert.zone := true

                            box.new(top = z.get(2).p, bottom = z.get(3).p, left = z.get(3).t, right = z.get(0).t, bgcolor = dist_css, border_color = color.new(color.white, 100), xloc = xloc.bar_time)
                            slice = array.new<chart.point>()

                            for i = 0 to 3

                                slice.unshift(z.get(i).points)

                            polyline.new(slice, xloc = xloc.bar_time, line_color = color.new(dist_css, 0), line_width = 2)
                            p.found := "Distribution Zone"
                            p.bull := false
                            p.isfound := true
                            p.period := 0
                            z.clear()   

if show_acc_dist_zone

    drawZone(iLen)

//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - END                                                                                                                                        }
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - EQH / EQL                                                                                                                                  }
//{----------------------------------------------------------------------------------------------------------------------------------------------}

dEHL() =>

    var ehl w = ehl.new(0, 0, 0, 0)
    top = ta.pivothigh(high, 1, 1)
    btm = ta.pivotlow(low  , 1, 1)
    atr = ta.atr(200)

    switch

        top =>

            mx = math.max(top, w.pt)
            mn = math.min(top, w.pt)

            switch

                mx < mn + atr * 0.1 =>

                    var aZ = array.new<line>()
                    var aL = array.new<label>()

                    if aZ.size() > 50

                        aZ.pop().delete()
                        aL.pop().delete()

                    aZ.unshift(line.new(w.t, w.pt, b.n - 1, top, color = i_ms_dn_BOS, style = line.style_dotted))
                    aL.unshift(label.new(int(math.avg(b.n - 1, w.t)), top, "EQH", color = invcol, textcolor = i_ms_dn_BOS, style = label.style_label_down, size = size.tiny))

                    bralert.equal := true

            w.pt := top
            w.t := b.n - 1

        btm =>

            mx = math.max(btm, w.pb)
            mn = math.min(btm, w.pb)

            switch

                mn > mx - atr * 0.1 =>

                    var aZ = array.new<line>()
                    var aL = array.new<label>()

                    if aZ.size() > 50

                        aZ.pop().delete()
                        aL.pop().delete()

                    aZ.unshift(line.new(w.b, w.pb, b.n - 1, btm, color = i_ms_up_BOS, style = line.style_dotted))
                    aL.unshift(label.new(int(math.avg(b.n - 1, w.b)), btm, "EQL", color = invcol, textcolor = i_ms_up_BOS, style = label.style_label_up, size = size.tiny))

                    blalert.equal := true

            w.pb := btm
            w.b := b.n - 1


if show_eql
    dEHL()

//{----------------------------------------------------------------------------------------------------------------------------------------------}
//{ - End                                                                                                                                        }
//{----------------------------------------------------------------------------------------------------------------------------------------------}

// Define User Inputs
simple bool       showAtr                 =        input.bool(true, "Plot Dema?", group='EMA & ATR', inline="Show EMA's & ATR")
simple bool       haCandles               =        input.bool(false, "Use HA Candles?")
simple int        periodDema              =        input.int(4, "Dema Period", group = "Dema Atr")
series float      sourceDema              =        input.source(close, "Calculation Source", group = "Dema Atr")
simple int        periodAtr               =        input.int(36, "Period", group = "Dema Atr")
simple float      factorAtr               =        input.float(1.7, "Factor", step = 0.01, group = "Dema Atr")

simple color      longColour              =       #00ff00
simple color      shortColour             =       #ff0000
// Use HA Candles?
heikinashi_close = request.security(
 symbol = ticker.heikinashi(syminfo.tickerid),
 timeframe =  timeframe.period,
 expression = close, 
 gaps = barmerge.gaps_off, 
 lookahead = barmerge.lookahead_off
 )

var series float source = close
if haCandles == true
    source := heikinashi_close
if haCandles == false
    source := sourceDema 
// Function
DemaAtrWithBands(periodDema, source, lookback, atrFactor)=>
    ema1   = ta.ema(source,  periodDema)
    ema2   = ta.ema(ema1, periodDema)
    demaOut = 2 * ema1 - ema2

    atr = ta.atr(lookback)
    trueRange = atr * atrFactor 

    DemaAtr = demaOut 
    DemaAtr := nz(DemaAtr[1], DemaAtr)

    trueRangeUpper = demaOut + trueRange
    trueRangeLower  = demaOut - trueRange 

    if trueRangeLower > DemaAtr 
        DemaAtr := trueRangeLower
    if trueRangeUpper < DemaAtr 
        DemaAtr := trueRangeUpper
    DemaAtr 

// Function Out
DemaAtr = DemaAtrWithBands(periodDema, source, periodAtr, factorAtr)
// Conditions
DemaAtrLong = DemaAtr > DemaAtr[1] 
DemaAtrShort = DemaAtr < DemaAtr[1]
// Colour Condtions
var color Trend = #ffffff
if DemaAtrLong
    Trend := longColour
if DemaAtrShort
    Trend := shortColour

// Plotting
plot(showAtr ? DemaAtr : na, "ATR", color=Trend, linewidth=2)
// Alerts
alertcondition(DemaAtrLong, title="Dema ATR Trend Up", message="Dema ATR Trend Up - {{ticker}} - {{interval}}")
alertcondition(DemaAtrShort, title="Dema ATR Trend Down", message="Dema ATR Trend Down - {{ticker}} - {{interval}}")

//====================================================================================================================//

confidence(pearsonR) =>
    switch
        pearsonR < 0.2  => "Крайне слабый"
        pearsonR < 0.3  => "Очень слабый"
        pearsonR < 0.4  => "Слабый"
        pearsonR < 0.5  => "В основном слабый"
        pearsonR < 0.6  => "Относительно слабый"
        pearsonR < 0.7  => "Умеренно слабый"
        pearsonR < 0.8  => "Умеренный"
        pearsonR < 0.9  => "Умеренно сильный"
        pearsonR < 0.92 => "В основном сильный"
        pearsonR < 0.94 => "Сильный"
        pearsonR < 0.96 => "Очень сильный"
        pearsonR < 0.98 => "Исключительно сильный"
        =>                        "Ультра сильный"

getTablePosition(string pos) =>
    switch pos
        "Справа внизу"   => position.bottom_right
        "Внизу по центру" => position.bottom_center        
        "Слева внизу"   => position.bottom_left
        "Справа вверху"     => position.top_right
        "Слева вверху"      => position.top_left
        "Вверху по центру"    => position.top_center
        "Правый центр"  => position.middle_right
        =>                 position.middle_left // "Слева в центре" - по умолчанию

// Рассчитать отклонения для заданной длины
calcDev(float source, int length) =>
    float logSource  = math.log(source)
    var int period_1 = length - 1
    if barstate.islast
        float sumX  = 0.0
        float sumXX = 0.0
        float sumYX = 0.0
        float sumY  = 0.0
        for int i=1 to length
            float lSrc = logSource[i-1]
            sumX  += i
            sumXX += i * i
            sumYX += i * lSrc
            sumY  +=     lSrc
        float slope     = nz((length * sumYX - sumX * sumY) / (length * sumXX - sumX * sumX))
        float average   = sumY / length
        float intercept = average - (slope * sumX / length) + slope
        float sumDev = 0.0
        float sumDxx = 0.0
        float sumDyy = 0.0
        float sumDyx = 0.0
        float regres = intercept + slope * period_1 * 0.5
        float sumSlp = intercept
        for int i=0 to period_1
            float lSrc = logSource[i]
            float dxt  =   lSrc - average
            float dyt  = sumSlp - regres
            lSrc   -= sumSlp
            sumSlp += slope
            sumDxx +=  dxt * dxt
            sumDyy +=  dyt * dyt
            sumDyx +=  dxt * dyt
            sumDev += lSrc * lSrc
        float unStdDev = math.sqrt(sumDev / period_1) // Несмещенное
        float divisor  =    sumDxx * sumDyy
        float pearsonR = nz(sumDyx / math.sqrt(divisor))
        [unStdDev, pearsonR, slope, intercept]
    else
        [na, na, na, na]

string t1 = "В режиме долгосрочного канала, если канал не виден, прокрутите график для дополнительных исторических данных."
string t2 = "Коэффициент Пирсона R, статистический показатель в адаптивном поиске трендов, оценивает линейную зависимость между ценой и проекцией тренда. Значение, близкое к 1, указывает на сильную положительную корреляцию, укрепляя уверенность в направлении тренда на основе исторических движений цен."

sourceInput = input.source(close, title="Источник")

string group0 = "НАСТРОЙКИ КАНАЛА"
bool   periodMode       = input.bool  (         false, "Использовать долгосрочный канал", group=group0, tooltip=t1)
float  devMultiplier    = input.float (           2.0, "Множитель отклонения:", group=group0, step=0.1)
color  colorInput       = input.color (  color.gray,             "", group=group0, inline=group0)
string lineStyle1       = input.string(       "Сплошная",             "", group=group0, inline=group0, options=["Сплошная", "Пунктирная", "Штриховая"])
string extendStyle      = input.string("Не расширять",             "", group=group0, inline=group0, options=["Расширить справа", "Расширить обе", "Не расширять", "Расширить слева"])
int    fillTransparency = input.int   (            93, "Прозрачность заливки:", group=group0, inline="середина", minval=0, maxval=100, step=1)
int channelTransparency = input.int   (            40, "Прозрачность линии:", group=group0, inline="середина", minval=0, maxval=100, step=1)

string group1 = "НАСТРОЙКИ СРЕДНЕЙ ЛИНИИ"
int    transpInput  = input.int   (     100,      "Прозрачность:", group=group1, inline=group1, minval=0, maxval=100, step=10)
int    lineWidth    = input.int   (       1,  "Толщина линии:", group=group1, inline=group1)
string midLineStyle = input.string("Сплошная",              "", group=group1, inline=group1, options=["Пунктирная", "Сплошная", "Штриховая"])

string group2 = "НАСТРОЙКИ ТАБЛИЦЫ"
string tablePositionInput = input.string("Справа внизу", "Положение таблицы", options=["Справа внизу", "Слева внизу", "Справа вверху", "Слева вверху", "Вверху по центру", "Внизу по центру", "Правый центр", "Левый центр"], group=group2)
bool   showPearsonInput   = input.bool  (         false, "Показать коэффициент Пирсона R вместо Уровня Уверенности", group=group2, tooltip=t2)
string textSizeInput      = input.string(      "Обычный",      "Размер текста", options=["Обычный", "Большой"], group=group2)

var string EXTEND_STYLE = switch extendStyle
    "Расширить справа" => extend.right
    "Расширить обе"  => extend.both
    "Не расширять"  => extend.none
    =>                extend.left

// Длины периодов
var array<int> Periods = periodMode ? array.from(na,300,350,400,450,500,550,600,650,700,750,800,850,900,950,1000,1050,1100,1150,1200) : array.from(na,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200)

// Рассчитать отклонения, корреляцию, наклон и перехват для разных длин периодов
[stdDev01, pearsonR01, slope01, intercept01] = calcDev(sourceInput, Periods.get( 1))
[stdDev02, pearsonR02, slope02, intercept02] = calcDev(sourceInput, Periods.get( 2))
[stdDev03, pearsonR03, slope03, intercept03] = calcDev(sourceInput, Periods.get( 3))
[stdDev04, pearsonR04, slope04, intercept04] = calcDev(sourceInput, Periods.get( 4))
[stdDev05, pearsonR05, slope05, intercept05] = calcDev(sourceInput, Periods.get( 5))
[stdDev06, pearsonR06, slope06, intercept06] = calcDev(sourceInput, Periods.get( 6))
[stdDev07, pearsonR07, slope07, intercept07] = calcDev(sourceInput, Periods.get( 7))
[stdDev08, pearsonR08, slope08, intercept08] = calcDev(sourceInput, Periods.get( 8))
[stdDev09, pearsonR09, slope09, intercept09] = calcDev(sourceInput, Periods.get( 9))
[stdDev10, pearsonR10, slope10, intercept10] = calcDev(sourceInput, Periods.get(10))
[stdDev11, pearsonR11, slope11, intercept11] = calcDev(sourceInput, Periods.get(11))
[stdDev12, pearsonR12, slope12, intercept12] = calcDev(sourceInput, Periods.get(12))
[stdDev13, pearsonR13, slope13, intercept13] = calcDev(sourceInput, Periods.get(13))
[stdDev14, pearsonR14, slope14, intercept14] = calcDev(sourceInput, Periods.get(14))
[stdDev15, pearsonR15, slope15, intercept15] = calcDev(sourceInput, Periods.get(15))
[stdDev16, pearsonR16, slope16, intercept16] = calcDev(sourceInput, Periods.get(16))
[stdDev17, pearsonR17, slope17, intercept17] = calcDev(sourceInput, Periods.get(17))
[stdDev18, pearsonR18, slope18, intercept18] = calcDev(sourceInput, Periods.get(18))
[stdDev19, pearsonR19, slope19, intercept19] = calcDev(sourceInput, Periods.get(19))

if barstate.islast
    // Найти наибольший коэффициент Пирсона R
    float highestPearsonR = math.max(pearsonR01, pearsonR02, pearsonR03, pearsonR04, pearsonR05, pearsonR06, pearsonR07, pearsonR08, pearsonR09, pearsonR10, pearsonR11, pearsonR12, pearsonR13, pearsonR14, pearsonR15, pearsonR16, pearsonR17, pearsonR18, pearsonR19)

    // Определить выбранную длину, наклон и перехват
    int   detectedPeriod  = na
    float detectedSlope   = na
    float detectedIntrcpt = na
    float detectedStdDev  = na

    switch highestPearsonR
        pearsonR01 =>
            detectedPeriod  := Periods.get(1)
            detectedSlope   :=     slope01
            detectedIntrcpt := intercept01
            detectedStdDev  :=    stdDev01
        pearsonR02 =>
            detectedPeriod  := Periods.get(2)
            detectedSlope   :=     slope02
            detectedIntrcpt := intercept02
            detectedStdDev  :=    stdDev02
        pearsonR03 =>
            detectedPeriod  := Periods.get(3)
            detectedSlope   :=     slope03
            detectedIntrcpt := intercept03
            detectedStdDev  :=    stdDev03
        pearsonR04 =>
            detectedPeriod  := Periods.get(4)
            detectedSlope   :=     slope04
            detectedIntrcpt := intercept04
            detectedStdDev  :=    stdDev04
        pearsonR05 =>
            detectedPeriod  := Periods.get(5)
            detectedSlope   :=     slope05
            detectedIntrcpt := intercept05
            detectedStdDev  :=    stdDev05
        pearsonR06 =>
            detectedPeriod  := Periods.get(6)
            detectedSlope   :=     slope06
            detectedIntrcpt := intercept06
            detectedStdDev  :=    stdDev06
        pearsonR07 =>
            detectedPeriod  := Periods.get(7)
            detectedSlope   :=     slope07
            detectedIntrcpt := intercept07
            detectedStdDev  :=    stdDev07
        pearsonR08 =>
            detectedPeriod  := Periods.get(8)
            detectedSlope   :=     slope08
            detectedIntrcpt := intercept08
            detectedStdDev  :=    stdDev08
        pearsonR09 =>
            detectedPeriod  := Periods.get(9)
            detectedSlope   :=     slope09
            detectedIntrcpt := intercept09
            detectedStdDev  :=    stdDev09
        pearsonR10 => 
            detectedPeriod  := Periods.get(10)
            detectedSlope   :=     slope10
            detectedIntrcpt := intercept10
            detectedStdDev  :=    stdDev10
        pearsonR11 =>        
            detectedPeriod  := Periods.get(11)
            detectedSlope   :=     slope11
            detectedIntrcpt := intercept11
            detectedStdDev  :=    stdDev11
        pearsonR12 =>
            detectedPeriod  := Periods.get(12)
            detectedSlope   :=     slope12
            detectedIntrcpt := intercept12
            detectedStdDev  :=    stdDev12
        pearsonR13 =>
            detectedPeriod  := Periods.get(13)
            detectedSlope   :=     slope13
            detectedIntrcpt := intercept13
            detectedStdDev  :=    stdDev13
        pearsonR14 =>
            detectedPeriod  := Periods.get(14)
            detectedSlope   :=     slope14
            detectedIntrcpt := intercept14
            detectedStdDev  :=    stdDev14
        pearsonR15 =>
            detectedPeriod  := Periods.get(15)
            detectedSlope   :=     slope15
            detectedIntrcpt := intercept15
            detectedStdDev  :=    stdDev15
        pearsonR16 =>
            detectedPeriod  := Periods.get(16)
            detectedSlope   :=     slope16
            detectedIntrcpt := intercept16
            detectedStdDev  :=    stdDev16
        pearsonR17 =>
            detectedPeriod  := Periods.get(17)
            detectedSlope   :=     slope17
            detectedIntrcpt := intercept17
            detectedStdDev  :=    stdDev17
        pearsonR18 =>
            detectedPeriod  := Periods.get(18)
            detectedSlope   :=     slope18
            detectedIntrcpt := intercept18
            detectedStdDev  :=    stdDev18
        => // ПирсонR19
            detectedPeriod  := Periods.get(19)
            detectedSlope   :=     slope19
            detectedIntrcpt := intercept19
            detectedStdDev  :=    stdDev19

    var line upperLine = na,   var linefill upperFill = na
    var line  baseLine = na
    var line lowerLine = na,   var linefill lowerFill = na

    // Рассчитать начальную и конечную цену на основе обнаруженного наклона и точки пересечения
    float startPrice = math.exp(detectedIntrcpt + detectedSlope * (detectedPeriod - 1))
    float   endPrice = math.exp(detectedIntrcpt)
    
    int         startAtBar = bar_index - detectedPeriod + 1
    var color ChannelColor = color.new(colorInput, channelTransparency)

    if na(baseLine)
        baseLine := line.new(startAtBar, startPrice, bar_index, endPrice,
                             width=lineWidth, extend=EXTEND_STYLE,
                             color=color.new(colorInput, transpInput),
                             style=midLineStyle == "Пунктирный" ? line.style_dotted :
                                   midLineStyle == "Пунктирная" ? line.style_dashed : line.style_solid)
    else
        line.set_xy1(baseLine, startAtBar, startPrice)
        line.set_xy2(baseLine,  bar_index,   endPrice)

    float upperStartPrice = startPrice * math.exp(devMultiplier * detectedStdDev)
    float upperEndPrice   =   endPrice * math.exp(devMultiplier * detectedStdDev)
    if na(upperLine)
        upperLine := line.new(startAtBar, upperStartPrice, bar_index, upperEndPrice,
                             width=1, extend=EXTEND_STYLE,
                             color=ChannelColor,
                             style=lineStyle1 == "Пунктирный" ? line.style_dotted :
                                   lineStyle1 == "Пунктирная" ? line.style_dashed : line.style_solid)
    else
        line.set_xy1  (upperLine, startAtBar, upperStartPrice)
        line.set_xy2  (upperLine,  bar_index,   upperEndPrice)
        line.set_color(upperLine, colorInput)

    float lowerStartPrice = startPrice / math.exp(devMultiplier * detectedStdDev)
    float   lowerEndPrice =   endPrice / math.exp(devMultiplier * detectedStdDev)
    if na(lowerLine)
        lowerLine := line.new(startAtBar, lowerStartPrice, bar_index, lowerEndPrice,
                             width=1, extend=EXTEND_STYLE,
                             color=ChannelColor,
                             style=lineStyle1 == "Пунктирный" ? line.style_dotted :
                                   lineStyle1 == "Пунктирная" ? line.style_dashed : line.style_solid)
    else
        line.set_xy1  (lowerLine, startAtBar, lowerStartPrice)
        line.set_xy2  (lowerLine,  bar_index,   lowerEndPrice)
        line.set_color(lowerLine, colorInput)

    if na(upperFill)
        upperFill := linefill.new(upperLine, baseLine, color=color.new(colorInput, fillTransparency))
    if na(lowerFill)
        lowerFill := linefill.new(baseLine, lowerLine, color=color.new(colorInput, fillTransparency))

    table t  = table.new(getTablePosition(tablePositionInput), 3, 2)   
    string text1 = periodMode ? "Автоматически выбранный период (долгосрочный): " + str.tostring(detectedPeriod)
                              : "Автоматически выбранный период:"             + str.tostring(detectedPeriod)
    var colorInputLight = color.new(colorInput, 40)
    table.cell(t, 0, 0, text1, text_color=colorInputLight, text_size=textSizeInput == "Большой" ? size.large : size.normal)
    if showPearsonInput
        table.cell(t, 1, 0, "Пирсон's R: " + str.tostring(detectedSlope > 0.0 ? -highestPearsonR : highestPearsonR, "#.###"), text_color=colorInput, text_size=textSizeInput == "Большой" ? size.large : size.normal)
    else
        table.cell(t, 1, 0, "Сила тренда:" + confidence(highestPearsonR), text_color=colorInput, text_size=textSizeInput == "Большой" ? size.large : size.normal)

    var my_table_logo = table.new(position.top_center, 1, 1)
    if barstate.islast
        table.cell(my_table_logo, 0, 0, '📈💲УДАЧНОЙ ТОРГОВЛИ💲📉', text_size=size.large, text_color=color(#00897b))

    //================================================================================================================================================================================================//

// Входные данные для полос Боллинджера
bb_use_ema = input.bool(false, title="Использовать основу EMA?")
bb_length = input.int(20, title="Длина Боллинджера")
bb_source = input(close, title="Источник Боллинджера")
bb_mult = input.float(2.0, title="Базовый множитель", minval=0.001, maxval=50)
bb_mult_inc = input.float(0.5, title="Прирост множителя", minval=0.001, maxval=2)
// Входные данные для индикатора разрыва
break_mult = input.float(2.7, title="Множитель разрыва", minval=0.001, maxval=50)
breakhigh_source = input(high, title="Источник верхнего разрыва")
breaklow_source = input(low, title="Источник нижнего разрыва")

bb_basis = bb_use_ema ? ta.ema(bb_source, bb_length) : ta.sma(bb_source, bb_length)
// Стандартное отклонение
dev = ta.stdev(bb_source, bb_length)
bb_dev_inner = bb_mult * dev
bb_dev_mid = (bb_mult + bb_mult_inc) * dev
bb_dev_outer = (bb_mult + (bb_mult_inc * 2)) * dev
break_dev = break_mult * dev
// Верхние полосы
inner_high = bb_basis + bb_dev_inner
mid_high = bb_basis + bb_dev_mid
outer_high = bb_basis + bb_dev_outer
// Нижние полосы
inner_low = bb_basis - bb_dev_inner
mid_low = bb_basis - bb_dev_mid
outer_low = bb_basis - bb_dev_outer
// Полосы разрыва
break_high = bb_basis + break_dev
break_low = bb_basis - break_dev
// отрисовка и заливка верхних полос
ubi = plot(inner_high, title="Внутренняя верхняя полоса", color=color.new(color.red, 90))
ubm = plot(mid_high, title="Средняя верхняя полоса", color=color.new(color.red, 85))
ubo = plot(outer_high, title="Внешняя верхняя полоса", color=color.new(color.red, 0))
fill(ubi, ubm, title="Заливка верхних полос", color=color.new(color.red, 90))
fill(ubm, ubo, title="Заливка внешних верхних полос",color=color.new(color.red, 80))
// отрисовка и заливка нижних полос
lbi = plot(inner_low, title="Внутренняя нижняя полоса", color=color.new(color.green, 90))
lbm = plot(mid_low, title="Средняя нижняя полоса", color=color.new(color.green, 85))
lbo = plot(outer_low, title="Внешняя нижняя полоса", color=color.new(color.green, 0))
fill(lbi, lbm, title="Заливка внутренних нижних полос", color=color.new(color.green, 90))
fill(lbm, lbo, title="Заливка внешних нижних полос", color=color.new(color.green, 80))
// заливка центрального канала
fill(ubi, lbi, title="Заливка центрального канала", color=color.new(color.silver, 100))
// отрисовка разрывов
plotshape(breakhigh_source >= break_high, title="Верхний разрыв", style=shape.triangledown, location=location.abovebar, size=size.tiny, color=color.red)
plotshape(breaklow_source <= break_low, title="Нижний разрыв", style=shape.triangleup, location=location.belowbar, size=size.tiny, color=color.green)

//========================================================================================================================================================//

FPeriod = input(144, title='Фибо-период')
plotF1618 = input(title='Участок 1.618 Уровень?', defval=true)

Fhigh = ta.highest(FPeriod)
Flow = ta.lowest(FPeriod)
FH = ta.highestbars(high, FPeriod)
FL = ta.lowestbars(low, FPeriod)
downfibo = FH < FL

F0 = downfibo ? Flow : Fhigh
F236 = downfibo ? (Fhigh - Flow) * 0.236 + Flow : Fhigh - (Fhigh - Flow) * 0.236
F382 = downfibo ? (Fhigh - Flow) * 0.382 + Flow : Fhigh - (Fhigh - Flow) * 0.382
F500 = downfibo ? (Fhigh - Flow) * 0.500 + Flow : Fhigh - (Fhigh - Flow) * 0.500
F618 = downfibo ? (Fhigh - Flow) * 0.618 + Flow : Fhigh - (Fhigh - Flow) * 0.618
F786 = downfibo ? (Fhigh - Flow) * 0.786 + Flow : Fhigh - (Fhigh - Flow) * 0.786
F1000 = downfibo ? (Fhigh - Flow) * 1.000 + Flow : Fhigh - (Fhigh - Flow) * 1.000
F1618 = downfibo ? (Fhigh - Flow) * 1.618 + Flow : Fhigh - (Fhigh - Flow) * 1.618

Fcolor = downfibo ? #03ff033a : #970008
Foffset = downfibo ? FH : FL

plot(F0, color=Fcolor, linewidth=2, trackprice=true, show_last=1, title='0')
plot(F236, color=Fcolor, linewidth=1, trackprice=true, show_last=1, title='0.236')
plot(F382, color=Fcolor, linewidth=1, trackprice=true, show_last=1, title='0.382')
plot(F500, color=Fcolor, linewidth=2, trackprice=true, show_last=1, title='0.5')
plot(F618, color=Fcolor, linewidth=1, trackprice=true, show_last=1, title='0.618')
plot(F786, color=Fcolor, linewidth=1, trackprice=true, show_last=1, title='0.786')
plot(F1000, color=Fcolor, linewidth=2, trackprice=true, show_last=1, title='1')
plot(plotF1618 ? F1618 : na, color=Fcolor, linewidth=3, trackprice=true, show_last=1, title='1.618')

plotshape(F0, style=shape.labeldown, location=location.absolute, color=Fcolor, textcolor=#ffffff, show_last=1, text='%0', offset=15)
plotshape(F236, style=shape.labeldown, location=location.absolute, color=Fcolor, textcolor=#ffffff, show_last=1, text='%23.6', offset=15)
plotshape(F382, style=shape.labeldown, location=location.absolute, color=Fcolor, textcolor=#ffffff, show_last=1, text='%38.2', offset=15)
plotshape(F500, style=shape.labeldown, location=location.absolute, color=Fcolor, textcolor=#ffffff, show_last=1, text='%50', offset=15)
plotshape(F618, style=shape.labeldown, location=location.absolute, color=Fcolor, textcolor=#ffffff, show_last=1, text='%61.8', offset=15)
plotshape(F786, style=shape.labeldown, location=location.absolute, color=Fcolor, textcolor=#ffffff, show_last=1, text='%78.6', offset=15)
plotshape(F1000, style=shape.labeldown, location=location.absolute, color=Fcolor, textcolor=#ffffff, show_last=1, text='%100', offset=15)

//==========================================================================================================================================//

Comments

Popular posts from this blog

Best Survey Apps That Pay Instantly On Mobile

  Best Survey Apps That Pay Instantly On Mobile In today’s fast-paced world, earning extra cash or rewards right from your mobile device is easier than ever—thanks to survey apps! Whether you're looking to make a little extra money or simply want gift cards for your favorite stores, survey apps can provide you with instant payouts for your opinions. Imagine getting paid in cash or gift cards for answering questions while you’re on the go—sounds great, right? We’ve compiled a list of the best survey apps that pay instantly on mobile , so you can start earning right away! 1. Swagbucks Swagbucks is one of the most well-known and trusted survey apps, and it’s known for offering instant rewards. Swagbucks offers users a wide range of ways to earn points, including surveys, shopping online, watching videos, and even searching the web. Key Features: Instant Payment Options : You can redeem your Swagbucks for gift cards to retailers like Amazon, PayPal, and iTunes almost instantly...

Online Dating VS Traditional Dating: Which Is Right for You?

  Online Dating VS Traditional Dating: Which Is Right for You? In the age of smartphones, social media, and instant messaging, online dating has revolutionized the way we meet potential partners. But how does it compare to traditional dating? With both offering unique opportunities and challenges, the debate between online dating and traditional dating continues to grow. In this article, we’ll explore the differences between the two, and help you decide which one is best suited for your personal preferences and dating goals. 1. Convenience and Accessibility Online Dating : One of the biggest advantages of online dating is convenience. With just a few taps, you can browse hundreds (if not thousands) of profiles without leaving the comfort of your home. Online dating apps and websites are available 24/7, allowing you to meet potential partners at any time, from anywhere. Whether you’re busy with work, school, or other commitments, online dating provides flexibility for people w...

Best Apps That Give You Free Bitcoin on Mobile

  Best Apps That Give You Free Bitcoin on Mobile In a world where cryptocurrency is becoming more popular by the day, Bitcoin remains the king of digital currencies. With Bitcoin’s rise, people everywhere are looking for ways to get in on the action without spending their hard-earned cash. Fortunately, there are several apps out there that offer ways to earn free Bitcoin directly on your mobile device. Whether you’re a seasoned crypto enthusiast or just dipping your toes into the world of digital currency, these apps provide an easy way to get started. Here are some of the best apps that give you free Bitcoin on mobile! 1. Coinbase Earn Best for: Beginners looking for easy education and rewards Coinbase is one of the most popular and user-friendly cryptocurrency exchanges globally. Its "Coinbase Earn" feature allows you to earn free Bitcoin (and other cryptocurrencies) by completing educational tasks. These tasks typically involve watching short videos, reading articles,...