๐Ÿ”ฑ SMC Flow System โ€“ by Fatich.id

fatich_id ยท study ยท 1407 ่กŒ ยท ็‚น่ตž 7,693 ยท TradingView ๅŽŸ้กต

ๆœฌ้กตๆบ็ ๆฅ่‡ช TradingView ๅ…ฌๅผ€ๅ‘ๅธƒ็š„ๅผ€ๆบ่„šๆœฌ๏ผŒ็‰ˆๆƒๅฝ’ๅŽŸไฝœ่€…ๆ‰€ๆœ‰๏ผŒ ่ฏท้ตๅพชๅ…ถๅŽŸๅง‹่ฎธๅฏ๏ผˆPine ่„šๆœฌๅธธ่ง CC BY-NC-SA / MPL-2.0 / MIT๏ผ‰ใ€‚ ๆœฌ้กน็›ฎไป…็”จไบŽ็ ”็ฉถๆฃ€็ดขไธŽ่ฎธๅฏ่Œƒๅ›ดๅ†…็š„็งปๆคใ€‚

Pine Script

//@version=6
//==============================================================================
// ๐Ÿ”ฑ AETHER FLOW SYSTEM โ€“ Mxwll Fusion Engine (LuxAlgo OB Edition)
//==============================================================================
// ยฉ 2025 Fatich.id | All Rights Reserved
// Author: Fatich.id
// Contact: https://t.me/fatichid
// Version: 1.2 (LuxAlgo OB + UT Label Management)
// License: Custom ยฉ Fatich.id โ€“ Non-Redistributable
//------------------------------------------------------------------------------
// ๐Ÿ”ฐ DESCRIPTION:
// AETHER FLOW SYSTEM is a fully integrated Smart Money Concept and Hybrid 
// Market Structure Engine that merges institutional order flow analytics with 
// dynamic liquidity mapping. Designed for professional traders seeking 
// structure clarity and precision reversal timing.
//
// ๐Ÿ’ก Core Frameworks:
//   โ€ข Mxwll Suite (Market Structure + Auto Fibs + CHoCH/BOS Detection)
//   โ€ข UT Bot System (Adaptive ATR-based Trend Shifts) + Label Management โญ
//   โ€ข Hull Suite Engine (Trend Velocity & Momentum Filtering)
//   โ€ข LuxAlgo-Inspired FVG Engine (Mitigation and Unmitigated Zones)
//   โ€ข LuxAlgo Order Blocks (Volume Pivot Detection) โญ NEW
//   โ€ข Three-Bar Reversal Pattern Recognition (Trend-Filtered Confirmations)
//   โ€ข Real-Time Session Heatmap & Volume Activity Dashboard
//
// ๐Ÿงญ System Philosophy:
//   "See the unseen liquidity. Trade the rhythm of price flow."
//
//------------------------------------------------------------------------------
// ๐Ÿ“ CATEGORY:
//   - Smart Money Concepts
//   - Market Structure & Volume
//   - Liquidity Mapping / Order Flow
//   - Multi-Framework Hybrid Systems
//
//------------------------------------------------------------------------------
// โš ๏ธ DISCLAIMER:
// This indicator is for educational and analytical purposes only. 
// It is not intended as financial advice. Trading carries risk.
//------------------------------------------------------------------------------
//
// Developed with โค๏ธ by Fatich.id | Telegram: @fatichid
//==============================================================================
 
indicator("๐Ÿ”ฑ SMC Flow System โ€“ by Fatich.id",
     shorttitle="๐Ÿ”ฑ SMC Flow", overlay=true,
     max_labels_count=500, max_lines_count=500, max_boxes_count=500, max_bars_back=500)
 
// ============================================
// MXWLL SUITE INPUTS
// ============================================
bullC       = input.color(defval = #14D990, title = "Bull Color", group = "Smart Money Concepts", inline = "7")
bearC       = input.color(defval = #F24968, title = "Bear Color", group = "Smart Money Concepts", inline = "7")
showInt     = input.bool(defval = true, title = "Show Internals", group = "Smart Money Concepts")
intSens     = input.int(5, "Internals Sensitivity", options =  [3 , 5 , 8 ], group = "Smart Money Concepts", inline = "20")
intStru     = input.string(defval = "All", title = "Internal Structure", options = ["All", "BoS", "CHoCH"], inline = "30", group = "Smart Money Concepts")
showExt     = input.bool(defval = true, title = "Show Externals" ,group = "Smart Money Concepts")
extSens     = input.int(25, "Externals Sensitivity", options = [10, 25, 50],group = "Smart Money Concepts", inline = "21")
extStru     = input.string(defval = "All", title = "External Structure", options = ["All", "BoS", "CHoCH"], inline = "31", group = "Smart Money Concepts")
 
showHHLH    = input.bool(defval = true, title = "Show HH/LH", group = "Swing Labels")
showHLLL    = input.bool(defval = true, title = "Show LH/LL", group = "Swing Labels")
 
show1D      = input.bool(defval = true, title = "Show Previous Day High", group = "High/Low")
show1DLab   = input.bool(defval = true, title = "Show 1 Day Labels", group = "High/Low")
show4H      = input.bool(defval = true, title = "Show 4 Hour High", group = "High/Low")
show4hLab   = input.bool(defval = true, title = "Show 4 Hour Labels", group = "High/Low")
 
showFibs    = input.bool(defval = true, title = "Show Auto Fibs", group = "Auto Fibs")
show236     = input.bool(defval = true,  title = "", inline = "1", group = "Auto Fibs")
show382     = input.bool(defval = true,  title = "", inline = "2", group = "Auto Fibs")
show5       = input.bool(defval = true,  title = "", inline = "3", group = "Auto Fibs")
show618     = input.bool(defval = true,  title = "", inline = "4", group = "Auto Fibs")
show786     = input.bool(defval = true,  title = "", inline = "5", group = "Auto Fibs")
show886     = input.bool(defval = true,  title = "", inline = "6", group = "Auto Fibs")
show113     = input.bool(defval = true,  title = "", inline = "7", group = "Auto Fibs")
show127     = input.bool(defval = true,  title = "", inline = "8", group = "Auto Fibs")
show141     = input.bool(defval = true,  title = "", inline = "9", group = "Auto Fibs")
show161     = input.bool(defval = true,  title = "", inline = "10", group = "Auto Fibs")
 
fib1        = input.float(defval = .236, title = "", minval = 0, step = 0.01, inline = "1", group = "Auto Fibs")
fib2        = input.float(defval = .382, title = "", minval = 0, step = 0.01, inline = "2", group = "Auto Fibs")
fib3        = input.float(defval = .5,   title = "", minval = 0, step = 0.01, inline = "3", group = "Auto Fibs")
fib4        = input.float(defval = .618, title = "", minval = 0, step = 0.01, inline = "4", group = "Auto Fibs")
fib5        = input.float(defval = .786, title = "", minval = 0, step = 0.01, inline = "5", group = "Auto Fibs")
fib6        = input.float(defval = .886, title = "", minval = 0, step = 0.01, inline = "6", group = "Auto Fibs")
fib7        = input.float(defval = 1.13, title = "", minval = 0, step = 0.01, inline = "7", group = "Auto Fibs")
fib8        = input.float(defval = 1.27, title = "", minval = 0, step = 0.01, inline = "8", group = "Auto Fibs")
fib9        = input.float(defval = 1.41, title = "", minval = 0, step = 0.01, inline = "9", group = "Auto Fibs")
fib10       = input.float(defval = 1.618, title = "", minval = 0, step = 0.01, inline = "10", group = "Auto Fibs")
 
fib1col     = input.color(title = "", defval = color.rgb(160, 165, 185), inline = "1", group = "Auto Fibs")
fib2col     = input.color(title = "", defval = color.lime, inline = "2", group = "Auto Fibs")
fib3col     = input.color(title = "", defval = color.yellow, inline = "3", group = "Auto Fibs")
fib4col     = input.color(title = "", defval = color.orange, inline = "4", group = "Auto Fibs")
fib5col     = input.color(title = "", defval = color.red, inline = "5", group = "Auto Fibs")
fib6col     = input.color(title = "", defval = color.purple, inline = "6", group = "Auto Fibs")
fib7col     = input.color(title = "", defval = color.blue, inline = "7", group = "Auto Fibs")
fib8col     = input.color(title = "", defval = color.teal, inline = "8", group = "Auto Fibs")
fib9col     = input.color(title = "", defval = color.maroon, inline = "9", group = "Auto Fibs")
fib10col    = input.color(title = "", defval = color.navy, inline = "10", group = "Auto Fibs")
 
nyCol = input.color(defval = #f24968, title = "NY Color", group = "Sessions")
asCol = input.color(defval = #14D990, title = "Asia Color", group = "Sessions")
loCol = input.color(defval = #F2B807, title = "London Color", group = "Sessions")
tra   = input.int(defval = 98, minval = 0, maxval = 100, title = "Transparency", group = "Sessions")
 
// ============================================
// UT BOT INPUTS (WITH LABEL MANAGEMENT)
// ============================================
a = input(2,     title = "UT Key Value", group = "UT Bot Settings")
c = input(6,    title = "UT ATR Period", group = "UT Bot Settings")
h = input(false, title = "UT Signals from Heikin Ashi", group = "UT Bot Settings")
 
// Label Management
showUTLabels = input.bool(true, "Show UT Labels", group = "UT Bot Settings")
keepRecentOnly = input.bool(true, "Keep Recent Signals Only", group = "UT Bot Settings", tooltip = "Jika ON, hanya menampilkan beberapa sinyal terakhir")
maxUTLabels = input.int(3, "Max Recent Signals", minval = 1, maxval = 10, group = "UT Bot Settings", tooltip = "Jumlah sinyal terakhir yang ditampilkan (1-10)")
 
// ============================================
// HULL SUITE INPUTS
// ============================================
srcHull = input(close, title="Hull Source", group = "Hull Suite Settings")
modeSwitch = input.string("Hma", title="Hull Variation", options=["Hma", "Thma", "Ehma"], group = "Hull Suite Settings")
length = input(55, title="Hull Length", group = "Hull Suite Settings")
lengthMult = input(1.0, title="Hull Length multiplier", group = "Hull Suite Settings")
useHtf = input(false, title="Show Hull MA from higher timeframe?", group = "Hull Suite Settings")
htf = input.timeframe("240", title="Hull Higher timeframe", group = "Hull Suite Settings")
switchColor = input(true, "Hull Color according to trend?", group = "Hull Suite Settings")
candleCol = input(false,title="Hull Color candles?", group = "Hull Suite Settings")
visualSwitch  = input(true, title="Hull Show as Band?", group = "Hull Suite Settings")
thicknesSwitch = input(1, title="Hull Line Thickness", group = "Hull Suite Settings")
transpSwitch = input(40, title="Hull Band Transparency", group = "Hull Suite Settings")
 
// ============================================
// LUXALGO FVG INPUTS
// ============================================
showLuxFVG = input.bool(defval = true, title = "Show FVG", group = "FVG")
thresholdPer = input.float(0, "Threshold %", minval = 0, maxval = 100, step = .1, inline = 'threshold', group = "LuxAlgo FVG")
auto = input(false, "Auto", inline = 'threshold', group = "FVG")
showLastFVG = input.int(0, 'Unmitigated Levels', minval = 0, group = "FVG")
mitigationLevels = input.bool(false, 'Mitigation Levels', group = "FVG")
tfFVG = input.timeframe('', "Timeframe", group = "FVG")
extendFVG = input.int(20, 'Extend', minval = 0, inline = 'extend', group = "FVG")
dynamicFVG = input(false, 'Dynamic', inline = 'extend', group = "FVG")
bullCss = input.color(color.new(#089981, 70), "Bullish FVG", group = "FVG")
bearCss = input.color(color.new(#f23645, 70), "Bearish FVG", group = "FVG")
showDash = input(false, 'Show Dashboard', group = "FVG")
dashLoc = input.string('Top Right', 'Location', options = ['Top Right', 'Bottom Right', 'Bottom Left'], group = "LuxAlgo FVG")
textSize = input.string('Small', 'Size', options = ['Tiny', 'Small', 'Normal'], group = "FVG")
 
// ============================================
// LUXALGO ORDER BLOCKS INPUTS
// ============================================
showLuxOB = input.bool(defval = true, title = "Show Order Blocks", group = "LuxAlgo Order Blocks")
lengthOB = input.int(5, 'Volume Pivot Length', minval = 1, group = "LuxAlgo Order Blocks")
 
bull_ext_last = input.int(3, 'Bullish OB Count', minval = 1, inline = 'bull', group = "LuxAlgo Order Blocks")
bg_bull_css = input.color(color.new(#089981, 80), '', inline = 'bull', group = "LuxAlgo Order Blocks")
bull_css = input.color(#089981, '', inline = 'bull', group = "LuxAlgo Order Blocks")
bull_avg_css = input.color(color.new(#9598a1, 37), '', inline = 'bull', group = "LuxAlgo Order Blocks")
 
bear_ext_last = input.int(3, 'Bearish OB Count', minval = 1, inline = 'bear', group = "LuxAlgo Order Blocks")
bg_bear_css = input.color(color.new(#f23645, 80), '', inline = 'bear', group = "LuxAlgo Order Blocks")
bear_css = input.color(#f23645, '', inline = 'bear', group = "LuxAlgo Order Blocks")
bear_avg_css = input.color(color.new(#9598a1, 37), '', inline = 'bear', group = "LuxAlgo Order Blocks")
 
line_style = input.string('โŽฏโŽฏโŽฏ', 'Average Line Style', options = ['โŽฏโŽฏโŽฏ', '----', 'ยทยทยทยท'], group = "LuxAlgo Order Blocks")
line_width = input.int(1, 'Average Line Width', minval = 1, group = "LuxAlgo Order Blocks")
mitigationOB = input.string('Wick', 'Mitigation Method', options = ['Wick', 'Close'], group = "LuxAlgo Order Blocks")
 
// ============================================
// THREE BAR REVERSAL INPUTS
// ============================================
show3BR = input.bool(defval = true, title = "Show Three Bar Reversal", group = "Three Bar Reversal")
brpType = input.string("All", "Pattern Type", options = ["Normal", "Enhanced", "All"], group = "Three Bar Reversal")
brpSR = input.string("Level", "Support/Resistance", options = ["Level", "Zone", "None"], group = "Three Bar Reversal")
brpAC = input.color(#2962ff, 'Bullish Pattern', group = "Three Bar Reversal")
brpSC = input.color(#ff9800, 'Bearish Pattern', group = "Three Bar Reversal")
trendType3BR = input.string("None", "Trend Filtering", options = ["Moving Average Cloud", "Supertrend", "Donchian Channels", "None"], group = "Three Bar Reversal")
trendFilt3BR = input.string("Aligned", "", options = ["Aligned", "Opposite"], group = "Three Bar Reversal")
trendAC3BR = input.color(#089981, 'Bullish Trend', group = "Three Bar Reversal")
trendSC3BR = input.color(#f23645, 'Bearish Trend', group = "Three Bar Reversal")
 
maType3BR = input.string("HMA", "MA Type", options = ["SMA", "EMA", "HMA", "RMA", "WMA", "VWMA"], group = "Three Bar Reversal")
maFLength3BR = input.int(50, 'Fast MA Length', minval = 1, maxval = 100, group = "Three Bar Reversal")
maSLength3BR = input.int(200, 'Slow MA Length', minval = 100, group = "Three Bar Reversal")
 
atrPeriod3BR = input.int(10, 'ST ATR Length', minval=1, group = "Three Bar Reversal")
factor3BR = input.float(3, 'ST Factor', minval = 2, step = 0.1, group = "Three Bar Reversal")
 
length3BR = input.int(13, 'DC Length', minval = 1, group = "Three Bar Reversal")
 
// ============================================
// REVERSAL SIGNALS INPUTS
// ============================================
showRS = input.bool(defval = true, title = "Show Reversal Signals", group = "Reversal Signals")
bShRS = input.string('Completed', 'Display Momentum Phases', options = ['Completed', 'Detailed', 'None'], group = "Reversal Signals")
srLRS = input.bool(true, 'Support & Resistance Levels', group = "Reversal Signals")
ptLTRS = input.string('Step Line w/ Diamonds', 'Phase Display Style', options = ['Circles', 'Step Line', 'Step Line w/ Diamonds'], group = "Reversal Signals")
rsBRS = input.bool(false, 'Momentum Phase Risk Levels', group = "Reversal Signals")
ptSRRS = input.string('Circles', 'Risk Display Style', options = ['Circles', 'Step Line'], group = "Reversal Signals")
eShRS = input.string('Completed', 'Display Exhaustion Phases', options = ['Completed', 'Detailed', 'None'], group = "Reversal Signals")
rsERS = input.bool(false, 'Exhaustion Phase Risk Levels', group = "Reversal Signals")
ttERS = input.bool(false, 'Exhaustion Phase Target Levels', group = "Reversal Signals")
tsoRS = input.string('None', 'Trade Setup Options', options = ['Momentum', 'Exhaustion', 'Qualified', 'None'], group = "Reversal Signals")
warRS = input.bool(false, 'Price Flip Warnings', group = "Reversal Signals")
 
// ============================================
// TYPE DEFINITIONS
// ============================================
type fvg
    float max
    float min
    bool  isbull
    int   t = time
 
type barRS
    float o = open
    float h = high
    float l = low
    float c = close
    int i = bar_index
 
type trbRS
    int bSC
    float bSH
    float bSL
    int sSC
    float sSH
    float sSL
 
type treRS
    int bCC
    float bC8
    float bCHt
    float bCH
    float bCL
    float bCLt
    float bCD
    int sCC
    float sC8
    float sCHt
    float sCH
    float sCL
    float sCLt
    float sCT
 
// ============================================
// METHODS
// ============================================
method tosolid(color id) => color.rgb(color.r(id), color.g(id), color.b(id))
 
// ============================================
// FUNCTIONS
// ============================================
movingAverage3BR(source, lengthMA, maType) => 
    switch maType
        "SMA" => ta.sma(source, lengthMA)
        "EMA" => ta.ema(source, lengthMA)
        "HMA" => ta.hma(source, lengthMA)
        "RMA" => ta.rma(source, lengthMA)
        "WMA" => ta.wma(source, lengthMA)
        "VWMA" => ta.vwma(source, lengthMA)
 
isBullishReversal3BR() =>
    (close[2] < open[2]) and
     (low[1] < low[2]) and (high[1] < high[2]) and (close[1] < open[1]) and
     (close > open) and (high > high[2])
 
isBearishReversal3BR() =>
    (close[2] > open[2]) and
     (high[1] > high[2]) and (low[1] > low[2]) and (close[1] > open[1]) and
     (close < open) and (low < low[2])
 
f_xLXRS(_p, _l) =>
    (_l > _p and _l < _p[1]) or (_l < _p and _l > _p[1])
 
f_lnSRS(_s) =>
    switch _s
        'Circles' => plot.style_circles
        'Step Line' => plot.style_steplinebr
        'Step Line w/ Diamonds' => plot.style_steplinebr
        => plot.style_circles
 
detectFVG() =>
    var new_fvg = fvg.new(na, na, false, na)
    threshold = auto ? ta.cum((high - low) / low) / bar_index : thresholdPer / 100
 
    bull_fvg = low > high[2] and close[1] > high[2] and (low - high[2]) / high[2] > threshold
    bear_fvg = high < low[2] and close[1] < low[2] and (low[2] - high) / high > threshold
    
    if bull_fvg
        new_fvg := fvg.new(low, high[2], true, time)
    else if bear_fvg
        new_fvg := fvg.new(low[2], high, false, time)
 
    [bull_fvg, bear_fvg, new_fvg]
 
// LuxAlgo OB Functions
get_line_style(style) =>
    out = switch style
        'โŽฏโŽฏโŽฏ'  => line.style_solid
        '----' => line.style_dashed
        'ยทยทยทยท' => line.style_dotted
 
get_coordinates(condition, top, btm, ob_val)=>
    var ob_top  = array.new_float(0)
    var ob_btm  = array.new_float(0)
    var ob_avg  = array.new_float(0)
    var ob_left = array.new_int(0)
 
    float ob = na
 
    if condition
        avg = math.avg(top, btm)
        
        array.unshift(ob_top, top)
        array.unshift(ob_btm, btm)
        array.unshift(ob_avg, avg)
        array.unshift(ob_left, time[lengthOB])
        
        ob := ob_val
    
    [ob_top, ob_btm, ob_avg, ob_left, ob]
 
remove_mitigated(ob_top, ob_btm, ob_left, ob_avg, target, bull)=>
    mitigated = false
    target_array = bull ? ob_btm : ob_top
 
    for element in target_array
        idx = array.indexof(target_array, element)
 
        if (bull ? target < element : target > element)
            mitigated := true
 
            array.remove(ob_top, idx)
            array.remove(ob_btm, idx)
            array.remove(ob_avg, idx)
            array.remove(ob_left, idx)
    
    mitigated
 
set_order_blocks(ob_top, ob_btm, ob_left, ob_avg, ext_last, bg_css, border_css, lvl_css)=>
    var ob_box = array.new_box(0)
    var ob_lvl = array.new_line(0)
 
    if barstate.isfirst
        for i = 0 to ext_last-1
            array.unshift(ob_box, box.new(na,na,na,na
              , xloc = xloc.bar_time
              , extend= extend.right
              , bgcolor = bg_css
              , border_color = color.new(border_css, 70)))
 
            array.unshift(ob_lvl, line.new(na,na,na,na
              , xloc = xloc.bar_time
              , extend = extend.right
              , color = lvl_css
              , style = get_line_style(line_style)
              , width = line_width))
 
    if barstate.islast
        if array.size(ob_top) > 0
            for i = 0 to math.min(ext_last-1, array.size(ob_top)-1)
                get_box = array.get(ob_box, i)
                get_lvl = array.get(ob_lvl, i)
 
                box.set_lefttop(get_box, array.get(ob_left, i), array.get(ob_top, i))
                box.set_rightbottom(get_box, array.get(ob_left, i), array.get(ob_btm, i))
 
                line.set_xy1(get_lvl, array.get(ob_left, i), array.get(ob_avg, i))
                line.set_xy2(get_lvl, array.get(ob_left, i)+1, array.get(ob_avg, i))
 
// ============================================
// MXWLL SUITE CODE  
// ============================================
var bigData = map.new<string, float>()
 
if bigData.size() == 0
    bigData.put("moving", 0)
    bigData.put("upaxis", 0.0) 
    bigData.put("upaxis2", 0)
    bigData.put("dnaxis", 0.0) 
    bigData.put("dnaxis2", 0)
    bigData.put("upside", 1)
    bigData.put("downside", 1)
 
[pdHigh, pdLow, dayHigh, dayLow, pdBar, dayBar] = request.security(syminfo.tickerid, "1D", [high[1], low[1], high, low, time[1], time])
 
var highArr = array.new_float(), var lowArr  = array.new_float()
var timeArr = array.new_int  (), var volArr  = array.new_float()
var closeArr = array.new_float(), var openArr = array.new_float()
 
highArr.unshift(high), lowArr.unshift(low)
timeArr.unshift(time), volArr.unshift(volume)
closeArr.unshift(close), openArr.unshift(open)
 
type rollingTF 
    float highTF                  = 0
    float lowTF                   = 1e8
    int   highTFt                 = 0
    int   lowTFt                  = 0
    float volTF                   = 0
    map   <string, line >         rTFdraw
    map   <string, label>         rTFlabel
 
method tfDraw(int tfDiff, bool showRollingLab, string tf, bool showLevels) => 
    TFhrdata = rollingTF.new(), var volRolling = array.new<float>()
 
    if highArr.size() > tfDiff
        for i = 0 to tfDiff
            if showLevels and barstate.islast
                getHigh = highArr.get(i), getLow = lowArr.get(i), 
                             getTime = timeArr.get(i)
 
                TFhrdata.highTF := math.max(TFhrdata.highTF, getHigh)
                TFhrdata.lowTF  := math.min(TFhrdata.lowTF , getLow )
 
                if TFhrdata.highTF == getHigh 
                    TFhrdata.highTFt := timeArr.get(i)
 
                if TFhrdata.lowTF == getLow
                    TFhrdata.lowTFt  := timeArr.get(i)
 
            TFhrdata.volTF += volArr.get(i)
 
        volRolling.push(TFhrdata.volTF)
 
        var lineDraw = rollingTF.new(rTFdraw = map.new<string, line>(), rTFlabel = map.new<string, label>())
 
        if showLevels
            switch lineDraw.rTFdraw.size() == 0
                true =>  lineDraw.rTFdraw.put("High", line.new(TFhrdata.highTFt, TFhrdata.highTF, time, TFhrdata.highTF, 
                                                 xloc = xloc.bar_time, color = color.aqua)),
                         lineDraw.rTFdraw.put("Low" , line.new(TFhrdata.lowTFt , TFhrdata.lowTF , time, TFhrdata.lowTF , 
                                                 xloc = xloc.bar_time, color = color.aqua))  
 
                =>       lineDraw.rTFdraw.get("High").set_xy1(TFhrdata.highTFt, TFhrdata.highTF),
                         lineDraw.rTFdraw.get("High").set_xy2(time, TFhrdata.highTF),
 
                         lineDraw.rTFdraw.get("Low").set_xy1(TFhrdata.lowTFt, TFhrdata.lowTF),
                         lineDraw.rTFdraw.get("Low").set_xy2(time, TFhrdata.lowTF)
 
            if showRollingLab 
                switch lineDraw.rTFlabel.size() == 0
                    true =>  lineDraw.rTFlabel.put("High", label.new(time, TFhrdata.highTF, xloc = xloc.bar_time, 
                                                         textcolor = color.aqua, 
                                                         text      = tf + "H", 
                                                         size      = size.tiny, 
                                                         style     = label.style_label_left, 
                                                         color     = #00000000
                                                         )),
                             lineDraw.rTFlabel.put("Low" , label.new(time, TFhrdata.lowTF , xloc = xloc.bar_time, 
                                                         textcolor = color.aqua, 
                                                         text      = tf + "L", 
                                                         size      = size.tiny, 
                                                         style     = label.style_label_left, 
                                                         color     = #00000000
                                                         ))  
 
                    =>       lineDraw.rTFlabel.get("High") .set_xy(time, TFhrdata.highTF),
                             lineDraw.rTFlabel.get("Low")  .set_xy(time, TFhrdata.lowTF)
 
    [TFhrdata.volTF, volRolling]
 
tfDrawLower(bool showRollingLab, simple string tf, bool showLevels) => 
    simple int end = switch tf 
        "240" => 240
        "1D"  => 1440
 
    [oLTF, hLTF, lLTF, cLTF, vLTF, tLTF] = request.security_lower_tf(syminfo.tickerid, "1", [open, high, low, close, volume, time])
 
    var oArr = array.new_float()
    var hArr = array.new_float()
    var lArr = array.new_float()
    var cArr = array.new_float()
    var vArr = array.new_float()
    var tArr = array.new_int()
 
    TFhrdata = rollingTF.new(), var volRolling = array.new<float>()
 
    if hLTF.size() > 0
        for i = 0 to hLTF.size() - 1
            oArr.push(oLTF.get(i))
            hArr.push(hLTF.get(i))
            lArr.push(lLTF.get(i))
            cArr.push(cLTF.get(i))
            vArr.push(vLTF.get(i))
            tArr.push(tLTF.get(i))
 
            if hArr.size() > end 
                oArr.shift()
                hArr.shift()
                lArr.shift()
                cArr.shift()
                vArr.shift()
                tArr.shift()
 
        for i = 0 to hArr.size() - 1
            if showLevels
                getHigh = hArr.get(i), getLow = lArr.get(i), 
                             getTime = tArr.get(i)
 
                TFhrdata.highTF := math.max(TFhrdata.highTF, getHigh)
                TFhrdata.lowTF  := math.min(TFhrdata.lowTF , getLow)
 
                if TFhrdata.highTF == getHigh 
                    TFhrdata.highTFt := tArr.get(i)
 
                if TFhrdata.lowTF == getLow
                    TFhrdata.lowTFt  := tArr.get(i)
 
            TFhrdata.volTF  += vArr.get(i)
 
        volRolling.push(TFhrdata.volTF)
 
        var lineDraw = rollingTF.new(rTFdraw = map.new<string, line>(), rTFlabel = map.new<string, label>())
 
        if showLevels
            switch lineDraw.rTFdraw.size() == 0
                true =>  lineDraw.rTFdraw.put("High", line.new(TFhrdata.highTFt, TFhrdata.highTF, time, TFhrdata.highTF, 
                                                 xloc = xloc.bar_time, color = color.aqua)),
                         lineDraw.rTFdraw.put("Low" , line.new(TFhrdata.lowTFt , TFhrdata.lowTF , time, TFhrdata.lowTF , 
                                                 xloc = xloc.bar_time, color = color.aqua))  
 
                =>       lineDraw.rTFdraw.get("High").set_xy1(TFhrdata.highTFt, TFhrdata.highTF),
                         lineDraw.rTFdraw.get("High").set_xy2(time, TFhrdata.highTF),
 
                         lineDraw.rTFdraw.get("Low").set_xy1(TFhrdata.lowTFt, TFhrdata.lowTF),
                         lineDraw.rTFdraw.get("Low").set_xy2(time, TFhrdata.lowTF)
 
            if showRollingLab 
                switch lineDraw.rTFlabel.size() == 0
                    true =>  lineDraw.rTFlabel.put("High", label.new(time, TFhrdata.highTF, xloc = xloc.bar_time, 
                                                         textcolor = color.aqua, 
                                                         text      = tf + "H", 
                                                         size      = size.tiny, 
                                                         style     = label.style_label_left, 
                                                         color     = #00000000
                                                         )),
                             lineDraw.rTFlabel.put("Low" , label.new(time, TFhrdata.lowTF , xloc = xloc.bar_time, 
                                                         textcolor = color.aqua, 
                                                         text      = tf + "L", 
                                                         size      = size.tiny, 
                                                         style     = label.style_label_left, 
                                                         color     = #00000000
                                                         ))  
 
                    =>       lineDraw.rTFlabel.get("High") .set_xy(time, TFhrdata.highTF),
                             lineDraw.rTFlabel.get("Low")  .set_xy(time, TFhrdata.lowTF)
 
    [TFhrdata.volTF, volRolling]
 
var r4hrbars = math.floor(timeframe.in_seconds("240") / timeframe.in_seconds(timeframe.period))
var rDbars   = math.floor(timeframe.in_seconds("1D") / timeframe.in_seconds(timeframe.period))
 
[vol4hr, vol4hrArr] = switch 
    timeframe.in_seconds() <= 60 => r4hrbars.tfDraw(show4hLab, "240", show4H)
    =>                              tfDrawLower(show4hLab, "240", show4H)
    
[vol1D, vol1DArr] = switch
    timeframe.in_seconds() <= 60 => rDbars.tfDraw(show1DLab, "1D", show1D) 
    =>                              tfDrawLower(show1DLab, "1D", show1D)
 
calculatePivots(lengthCalc)=>
    var int intraCalc = 0
 
    if bar_index > lengthCalc + 1
        up  = highArr.slice(0, lengthCalc).max()
        dn  = lowArr .slice(0, lengthCalc).min() 
        
        cHi = highArr.get(lengthCalc)
        cLo = lowArr .get(lengthCalc)
 
        intraCalc := switch 
            cHi > up => 0 
            cLo < dn => 1 
            =>          intraCalc[1]
 
        topSwing = switch 
            intraCalc == 0 and intraCalc[1] != 0 => cHi 
            =>                                      0 
 
        botSwing = switch 
            intraCalc == 1 and intraCalc[1] != 1 => cLo
            =>                                      0 
 
        [topSwing, botSwing]
 
[bigUpper    , bigLower   ]     = calculatePivots(extSens)
[smallUpper  , smallLower ]     = calculatePivots(intSens)
 
var label [] upLabel = array.new_label(1)
var label [] dnLabel = array.new_label(1)
 
drawChar(x, y, str, col, down) =>
    style = switch down 
        true => label.style_label_down
        =>      label.style_label_up
 
    line.new (int(x), y, bar_index, y, color = col, style = line.style_dashed)
    label.new(math.round(math.avg(x, bar_index)), y, str, color = #00000000, textcolor = col, style = style, size = size.small)
 
drawStructureExt() => 
    var int counter = 0
 
    if bigUpper != 0
        bigData.put("upside", 1)
        x1 = bar_index - extSens
 
        txt = switch bigUpper > bigData.get("upaxis")
            true => 'HH'
            =>      'LH'
 
        if showHHLH
            upLabel.set(0, label.new(x1, bigUpper, txt,
                          color     = color.new(color.white, 100), 
                          textcolor = bearC, 
                          style     = label.style_label_down, 
                          size      = size.small
                          ))
 
        bigData.put("upaxis" , bigUpper)
        bigData.put("upaxis2", x1)
 
        counter := 1
 
    if bigLower != 0
        bigData.put("downside", 1)
 
        x1 = bar_index - extSens
 
        txt = switch bigLower < bigData.get("dnaxis") 
            true => "LL" 
            =>      "HL"
 
        if showHLLL == true 
            dnLabel.set(0, label.new(x1, bigLower, txt, color = #ffffff00, 
                         textcolor = bullC, 
                         style     = label.style_label_up, 
                         size      = size.small
                         ))
        
        bigData.put("dnaxis" , bigLower)
        bigData.put("dnaxis2", x1)
 
        counter := -1
 
    if showExt
        if ta.crossover(close, bigData.get("upaxis"))
            if bigData.get("upside") != 0
                str = switch bigData.get("moving") < 0
                    true => extStru != "BoS"   ? 'CHoCH' : "" 
                    =>      extStru != 'CHoCH' ? 'BoS'   : ""
 
                if extStru == "All" or str.contains(extStru, str)
                    drawChar(bigData.get("upaxis2"), bigData.get("upaxis"), str, bullC, true)
 
                bigData.put("upside", 0)
                bigData.put("moving", 1)
 
        if ta.crossunder(close, bigData.get("dnaxis"))
            if bigData.get("downside") != 0
                str = switch bigData.get("moving") > 0
                    true => extStru != "BoS"   ? 'CHoCH' : "" 
                    =>      extStru != 'CHoCH' ? 'BoS'   : ""
 
                if extStru == "All" or str.contains(extStru, str)
                    drawChar(bigData.get("dnaxis2"), bigData.get("dnaxis"), str, bearC, false)
 
                bigData.put("downside", 0)
                bigData.put("moving", -1)
 
    counter 
 
counter = drawStructureExt()
 
method updateMain(line id) => 
    hi = 0.0 
    lo = 1e8
 
    if showFibs
        [bigUpperFibs, bigLowerFibs]    = calculatePivots(25)
 
        var int counterFibs = 0
 
        if bigUpperFibs != 0 
            counterFibs := 1
 
        if bigLowerFibs != 0 
            counterFibs := -1
 
        if counterFibs == 1 
            hi := 0.0
            
            id.set_xy1(int(bigData.get("upaxis2")), bigData.get("upaxis"))
 
            for i = 0 to bar_index - int(bigData.get("dnaxis2"))
                getLow = lowArr.get(i)
 
                lo := math.min(getLow, lo)
 
                if lo == getLow
                    id.set_xy2(bar_index - i, lo)
 
        else if counterFibs == -1
            lo := 1e8
            id.set_xy1(int(bigData.get("dnaxis2")), bigData.get("dnaxis"))
 
            for i = 0 to bar_index - bigData.get("upaxis2")
                getHigh = highArr.get(i)
                hi     := math.max(highArr.get(i), hi)
 
                if hi == getHigh 
                    id.set_xy2(bar_index - i, hi)
 
        if id.get_x2() < id.get_x1()
            x2 = id.get_x2(), x1 = id.get_x1()
            y2 = id.get_y2(), y1 = id.get_y1(),
 
                     id.set_xy2(x1, y1),
                     id.set_xy1(x2, y2)
 
        switch id.get_y2() < id.get_y1()
            true => id.set_color(#F24968)
            =>      id.set_color(#14D990)
 
    0
 
var main = line.new(dnLabel.first().get_x(), dnLabel.first().get_y(), upLabel.first().get_x(), upLabel.first().get_y(),
                                                 style = line.style_dashed, 
                                                 width = 2
                                                 )
 
main.updateMain()
 
quickLine(getX2, y, colorLine) => 
    line.new(getX2, y, bar_index + 5, y, color = color.new(colorLine, 75))
 
quickLabel(y, txt, colorLabel) => 
    label.new(bar_index + 5, y, text = str.tostring(txt), color = #00000000, style = label.style_label_left, textcolor = colorLabel)
 
drawFibs() => 
    if barstate.islast
        var fibLine = array.new<line>(10)
        var fibLab = array.new<label>(10) 
        
        if fibLine.size() > 0 
            for i = 0 to fibLine.size() - 1
                fibLine .get(i).delete()
                fibLab  .get(i).delete()
 
        if showFibs
            getY2 = main.get_y2(), sub   = main.get_y1() - getY2, 
            getX1 = main.get_x1(), getX2 = main.get_x2()
 
            for i = 0 to fibLine.size() - 1
                [y, col, txt] = switch i
                    0 => [sub * fib1 + getY2, show236 ? fib1col : color.new(chart.bg_color, 100), fib1]
                    1 => [sub * fib2 + getY2, show382 ? fib2col : color.new(chart.bg_color, 100), fib2]
                    2 => [sub * fib3 + getY2, show5   ? fib3col : color.new(chart.bg_color, 100), fib3]
                    3 => [sub * fib4 + getY2, show618 ? fib4col : color.new(chart.bg_color, 100), fib4]
                    4 => [sub * fib5 + getY2, show786 ? fib5col : color.new(chart.bg_color, 100), fib5]
                    5 => [sub * fib6 + getY2, show886 ? fib6col : color.new(chart.bg_color, 100), fib6]
                    6 => [sub * fib7 + getY2, show113 ? fib7col : color.new(chart.bg_color, 100), fib7]
                    7 => [sub * fib8 + getY2, show127 ? fib8col : color.new(chart.bg_color, 100), fib8]
                    8 => [sub * fib9 + getY2, show141 ? fib9col : color.new(chart.bg_color, 100), fib9]
                    => [sub * fib10 + getY2, show161 ? fib10col : color.new(chart.bg_color, 100), fib10]
 
                fibLine.set(i, quickLine  (getX2, y, col))
                fibLab .set(i, quickLabel (y, txt, col))
 
drawFibs()
 
drawStructureInternals() => 
    if showInt
        var keyValues = map.new<string, float>()
 
        if keyValues.size() == 0 
            keyValues.put("movingSmall", 0)
 
        if smallUpper != 0 
            keyValues.put("upsideSmall", 1)          
            keyValues.put("upaxisSmall", smallUpper) 
            keyValues.put("upaxis2Small", bar_index - intSens)
 
        if smallLower != 0 
            keyValues.put("downsideSmall", 1)       
            keyValues.put("dnaxisSmall", smallLower)
            keyValues.put("dnaxis2Small", bar_index - intSens)
 
        if ta.crossover(close, keyValues.get("upaxisSmall")) 
            if keyValues.get("upsideSmall") != 0
                str = switch 
                    keyValues.get("movingSmall") < 0 =>     intStru != "BoS"   ? 'I-CHoCH' : "" 
                    =>                                      intStru != "CHoCH" ? 'I-BoS'   : ""
 
                if intStru == "All" or str.contains(str, intStru)
                    drawChar(keyValues.get("upaxis2Small"), keyValues.get("upaxisSmall"), str, bullC, true)
 
                keyValues.put("upsideSmall", 0)
                keyValues.put("movingSmall", 1)
 
        if ta.crossunder(close, keyValues.get("dnaxisSmall"))
            if keyValues.get("downsideSmall") != 0
                str = switch 
                    keyValues.get("movingSmall") > 0 => intStru != "BoS"   ? 'I-CHoCH' : ""
                    =>                                  intStru != "CHoCH" ? 'I-BoS'   : ""
 
                if intStru == "All" or str.contains(str, intStru)
                    drawChar(keyValues.get("dnaxis2Small"), keyValues.get("dnaxisSmall"), str, bearC, false)
 
                keyValues.put("downsideSmall", 0)
                keyValues.put("movingSmall", -1)
 
drawStructureInternals()
 
var table tab2 = table.new(position.top_right, 13, 13,  bgcolor = #20222C, border_color = #363843, frame_color = #363843, border_width = 1, frame_width = 1)
 
nyHour   = hour  (timenow, "America/New_York")
nyMinute = minute(timenow, "America/New_York")
 
calculateTimeDifference(timestamp1, timestamp2) =>
    timeDifference = timestamp2 - timestamp1
    hours = math.floor(timeDifference / 3600000)
    minutes = math.floor((timeDifference % 3600000) / 60000)
    [hours, minutes]
 
dayAdjustment = (hour(timenow, "America/New_York") < 2) ? dayofmonth(timenow) + 1 : dayofmonth(timenow)
dayAdjustment2 = nyHour >= 20 or nyHour < 2 ? dayofmonth(timenow) + 1 : dayofmonth(timenow)
 
timeIsInRange(startHour, startMinute, endHour, endMinute) =>
    (nyHour > startHour or (nyHour == startHour and nyMinute >= startMinute)) and (nyHour < endHour or (nyHour == endHour and nyMinute <= endMinute))
 
[chartcol, timetilchange, stringCol, stringCol2] = switch 
    timeIsInRange(9, 30, 16, 0) => [#f24968  , timestamp("America/New_York", year(timenow), month(timenow), dayofmonth(timenow), 16, 0, 0), "New York", "Asia"]
    timeIsInRange(20, 0, 2 , 0) => [#14D990  , timestamp("America/New_York", year(timenow), month(timenow), dayAdjustment, 2, 0, 0), "Asia", "London"]
    timeIsInRange(3, 0, 11, 30) => [#F2B807  , timestamp("America/New_York", year(timenow), month(timenow), dayofmonth(timenow), 11, 30, 0), "London", "New York"]
    => [color.gray, int(na), "Dead Zone", (nyHour > 16 or nyHour < 3) ? "London" : (nyHour >= 11 and nyHour < 20) ? "Asia" : "New York"]                        
 
[hours, minutes] = calculateTimeDifference(timenow, timetilchange)
 
timetilchange2 = switch
    timeIsInRange(9, 30, 16, 0)  => timestamp("America/New_York", year(timenow), month(timenow), dayofmonth(timenow), 20, 0, 0) 
    timeIsInRange(20, 0, 2 , 0)  => timestamp("America/New_York", year(timenow), month(timenow), dayofmonth(timenow), 3, 0, 0)  
    timeIsInRange(3, 0, 11, 30)  => timestamp("America/New_York", year(timenow), month(timenow), dayofmonth(timenow), 9, 30, 0) 
    => na 
 
if na(timetilchange2)
    timetilchange2 := switch
        nyHour < 9 or (nyHour == 9 and nyMinute < 30) => timestamp("America/New_York", year(timenow), month(timenow), dayofmonth(timenow), 9, 30, 0) 
        nyHour < 20 or (nyHour >= 16 and nyHour < 20) => timestamp("America/New_York", year(timenow), month(timenow), dayofmonth(timenow), 20, 0, 0) 
        nyHour < 3 or (nyHour >= 2 and nyHour < 3)    => timestamp("America/New_York", year(timenow), month(timenow), dayofmonth(timenow), 3, 0, 0)     
        => na  
 
[hours2, minutes2] = calculateTimeDifference(timenow, timetilchange2)
 
method getActivity(array<float> id, float id2) => 
    if id.size() > 0
        volPerc1 = id.percentile_nearest_rank(10)
        volPerc2 = id.percentile_nearest_rank(33)
        volPerc3 = id.percentile_nearest_rank(50)
        volPerc4 = id.percentile_nearest_rank(66)
        volPerc5 = id.percentile_nearest_rank(90)
 
        log.warning(str.tostring(volPerc1) + "\n" + str.tostring(volPerc2) + "\n" + str.tostring(volPerc3) + "\n" + str.tostring(volPerc4) + "\n" + str.tostring(volPerc5))
 
        activity = switch 
            id2 <=  volPerc1 => "Very Low"   
            id2 <=  volPerc2 => "Low"   
            id2 <=  volPerc3 => "Average"   
            id2 <=  volPerc4 => "High"   
            =>                  "Very High"
 
        activity
    
if barstate.islast 
    hr4Act = vol4hrArr.getActivity(vol4hr)
    D1Act  = vol1DArr .getActivity(vol1D)
 
    str = str.tostring(timetilchange)
    ch  = str.substring(str, str.pos(str, ".") + 1, str.length(str))
    nu  = str.tonumber(ch) * 6
    nu2 = str.substring(str.tostring(nu), 0, 2)
 
    table.cell(tab2, 0, 2, text = "Session:"  ,       text_color = color.white, text_halign = text.align_left)
    table.cell(tab2, 0, 3, text = "Session Close:"  , text_color = color.white, text_halign = text.align_left)
    table.cell(tab2, 0, 4, text = "Next Session:"  , text_color = color.white, text_halign = text.align_left)
    table.cell(tab2, 0, 5, text = "Next Session Open:"  , text_color = color.white, text_halign = text.align_left)
 
    table.cell(tab2, 0, 6, text = "4-Hr Volume:"  ,   text_color = color.white, text_halign = text.align_left)
    table.cell(tab2, 0, 7, text = "24-Hr Volume:"  ,  text_color = color.white, text_halign = text.align_left)
 
    table.cell(tab2, 1, 2, text =  stringCol , text_color = color.white)
    table.cell(tab2, 1, 3, text = stringCol != "Dead Zone" ? str.tostring(hours)+ "h" + str.tostring(minutes) + "m": "Dead Zone", text_color = color.white)
    table.cell(tab2, 1, 4, text =stringCol2, text_color = color.white)
    table.cell(tab2, 1, 5, text = str.tostring(hours2) + "h:" + str.tostring(minutes2) + "m", text_color = color.white)
    table.cell(tab2, 1, 6, text = hr4Act, text_color = color.white)
    table.cell(tab2, 1, 7, text = D1Act, text_color = color.white)
 
nyHour2   = hour  (time, "America/New_York")
nyMinute2 = minute(time, "America/New_York")
 
timeIsInRange2(startHour, startMinute, endHour, endMinute) =>
    if endHour >= startHour
        (nyHour2 > startHour or (nyHour2 == startHour and nyMinute2 >= startMinute)) and 
         (nyHour2 < endHour or (nyHour2 == endHour and nyMinute2 <= endMinute))
    else
        (nyHour2 > startHour or (nyHour2 == startHour and nyMinute2 >= startMinute)) or
         (nyHour2 < endHour or (nyHour2 == endHour and nyMinute2 <= endMinute))
 
bgcolor(timeIsInRange2(9, 30, 16, 0) ? color.new(nyCol, tra) : na)
bgcolor(timeIsInRange2(20, 0, 2 , 0) ? color.new(asCol, tra) : na)
bgcolor(timeIsInRange2(3, 0, 11, 30) ? color.new(loCol, tra) : na)
 
// โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
// UT BOT CODE (WITH LABEL MANAGEMENT)
// โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
var utBuyLabels = array.new<label>()
var utSellLabels = array.new<label>()
 
xATR  = ta.atr(c)
nLoss = a * xATR
 
srcUT = h ? request.security(syminfo.tickerid, timeframe.period, close, lookahead = barmerge.lookahead_off) : close
 
var float xATRTrailingStop = 0.0
xATRTrailingStop := if srcUT > nz(xATRTrailingStop[1], 0) and srcUT[1] > nz(xATRTrailingStop[1], 0)
    math.max(nz(xATRTrailingStop[1]), srcUT - nLoss)
else if srcUT < nz(xATRTrailingStop[1], 0) and srcUT[1] < nz(xATRTrailingStop[1], 0)
    math.min(nz(xATRTrailingStop[1]), srcUT + nLoss)
else if srcUT > nz(xATRTrailingStop[1], 0)
    srcUT - nLoss
else
    srcUT + nLoss
 
var int pos = 0   
pos := if srcUT[1] < nz(xATRTrailingStop[1], 0) and srcUT > nz(xATRTrailingStop[1], 0)
    1
else if srcUT[1] > nz(xATRTrailingStop[1], 0) and srcUT < nz(xATRTrailingStop[1], 0)
    -1
else
    nz(pos[1], 0)
   
xcolor = pos == -1 ? color.red: pos == 1 ? color.green : color.blue 
 
emaUT   = ta.ema(srcUT,1)
above = ta.crossover(emaUT, xATRTrailingStop)
below = ta.crossover(xATRTrailingStop, emaUT)
 
buy  = srcUT > xATRTrailingStop and above 
sell = srcUT < xATRTrailingStop and below
 
barbuy  = srcUT > xATRTrailingStop 
barsell = srcUT < xATRTrailingStop 
 
if showUTLabels
    if buy
        newLabel = label.new(bar_index, low, 'Buy', 
                     yloc = yloc.belowbar, 
                     color = color.green, 
                     textcolor = color.white, 
                     style = label.style_label_up,
                     size = size.tiny)
        utBuyLabels.push(newLabel)
        
    if sell
        newLabel = label.new(bar_index, high, 'Sell', 
                     yloc = yloc.abovebar, 
                     color = color.red, 
                     textcolor = color.white, 
                     style = label.style_label_down,
                     size = size.tiny)
        utSellLabels.push(newLabel)
    
    if keepRecentOnly
        while utBuyLabels.size() > maxUTLabels
            oldLabel = utBuyLabels.shift()
            label.delete(oldLabel)
        
        while utSellLabels.size() > maxUTLabels
            oldLabel = utSellLabels.shift()
            label.delete(oldLabel)
 
// Plotshape for when label management is OFF
plotshape(not showUTLabels and buy,  title = "UT Buy",  text = 'Buy',  style = shape.labelup,   location = location.belowbar, color= color.green, textcolor = color.white, size = size.tiny)
plotshape(not showUTLabels and sell, title = "UT Sell", text = 'Sell', style = shape.labeldown, location = location.abovebar, color= color.red,   textcolor = color.white, size = size.tiny)
 
barcolor(barbuy  ? color.green : na)
barcolor(barsell ? color.red   : na)
 
if buy
    alert("UT Long", alert.freq_once_per_bar)
if sell
    alert("UT Short", alert.freq_once_per_bar)
 
// ============================================
// HULL SUITE CODE
// ============================================
HMA(_src, _length) =>  ta.wma(2 * ta.wma(_src, _length / 2) - ta.wma(_src, _length), math.round(math.sqrt(_length)))
EHMA(_src, _length) =>  ta.ema(2 * ta.ema(_src, _length / 2) - ta.ema(_src, _length), math.round(math.sqrt(_length)))
THMA(_src, _length) =>  ta.wma(ta.wma(_src,_length / 3) * 3 - ta.wma(_src, _length / 2) - ta.wma(_src, _length), _length)
    
Mode(modeSwitch, src, len) =>
    result = if modeSwitch == "Hma"
        HMA(src, len)
    else if modeSwitch == "Ehma"
        EHMA(src, len)
    else if modeSwitch == "Thma"
        THMA(src, len/2)
    else
        na
    result
 
_hull = Mode(modeSwitch, srcHull, int(length * lengthMult))
HULL = useHtf ? request.security(syminfo.tickerid, htf, _hull) : _hull
MHULL = HULL[0]
SHULL = HULL[2]
 
hullColor = switchColor ? (HULL > HULL[2] ? #00ff00 : #ff0000) : #ff9800
 
Fi1 = plot(MHULL, title="MHULL", color=hullColor, linewidth=thicknesSwitch)
Fi2 = plot(visualSwitch ? SHULL : na, title="SHULL", color=hullColor, linewidth=thicknesSwitch)
 
if ta.crossover(MHULL, SHULL)
    alert("Hull trending up.", alert.freq_once_per_bar)
if ta.crossover(SHULL, MHULL)
    alert("Hull trending down.", alert.freq_once_per_bar)
 
fill(Fi1, Fi2, title="Band Filler", color=color.new(hullColor, transpSwitch))
 
barcolor(color = candleCol ? (switchColor ? hullColor : na) : na)
 
// ============================================
// LUXALGO FVG CODE
// ============================================
var float max_bull_fvg = na
var float min_bull_fvg = na
var float max_bear_fvg = na
var float min_bear_fvg = na
 
if showLuxFVG
    var int bull_count = 0, var int bull_mitigated = 0
    var int bear_count = 0, var int bear_mitigated = 0
    var int t_fvg = 0
 
    var fvg_records = array.new<fvg>(0)
    var fvg_areas = array.new<box>(0)
 
    n_fvg = bar_index
 
    [bull_fvg, bear_fvg, new_fvg] = request.security(syminfo.tickerid, tfFVG, detectFVG())
 
    if bull_fvg and new_fvg.t != t_fvg
        if dynamicFVG
            max_bull_fvg := new_fvg.max
            min_bull_fvg := new_fvg.min
        
        if not dynamicFVG
            fvg_areas.unshift(box.new(n_fvg - 2, new_fvg.max, n_fvg + extendFVG, new_fvg.min, na, bgcolor = bullCss))
        fvg_records.unshift(new_fvg)
 
        bull_count += 1
        t_fvg := new_fvg.t
    else if dynamicFVG
        max_bull_fvg := math.max(math.min(close, max_bull_fvg), min_bull_fvg)
 
    if bear_fvg and new_fvg.t != t_fvg
        if dynamicFVG
            max_bear_fvg := new_fvg.max
            min_bear_fvg := new_fvg.min
        
        if not dynamicFVG
            fvg_areas.unshift(box.new(n_fvg - 2, new_fvg.max, n_fvg + extendFVG, new_fvg.min, na, bgcolor = bearCss))
        fvg_records.unshift(new_fvg)
 
        bear_count += 1
        t_fvg := new_fvg.t
    else if dynamicFVG
        min_bear_fvg := math.min(math.max(close, min_bear_fvg), max_bear_fvg) 
 
    if fvg_records.size() > 0
        for i = fvg_records.size() - 1 to 0
            get = fvg_records.get(i)
 
            if get.isbull
                if close < get.min
                    if mitigationLevels
                        line.new(get.t, get.min, time, get.min, xloc.bar_time, color = bullCss, style = line.style_dashed)
 
                    if not dynamicFVG
                        area = fvg_areas.remove(i)
                        area.delete()
 
                    fvg_records.remove(i)
                    bull_mitigated += 1
            else if close > get.max
                if mitigationLevels
                    line.new(get.t, get.max, time, get.max, xloc.bar_time, color = bearCss, style = line.style_dashed)
 
                if not dynamicFVG
                    area = fvg_areas.remove(i)
                    area.delete()
                
                fvg_records.remove(i)
                bear_mitigated += 1
 
    var unmitigated = array.new<line>(0)
 
    if barstate.islast and showLastFVG > 0 and fvg_records.size() > 0
        if unmitigated.size() > 0 
            for element in unmitigated
                element.delete()
            unmitigated.clear()
 
        for i = 0 to math.min(showLastFVG - 1, fvg_records.size() - 1)
            get = fvg_records.get(i)
            unmitigated.push(line.new(get.t, get.isbull ? get.min : get.max, time, get.isbull ? get.min : get.max, xloc.bar_time, color = get.isbull ? bullCss : bearCss))
 
    var table_position = dashLoc == 'Bottom Left' ? position.bottom_left : dashLoc == 'Top Right' ? position.top_right : position.bottom_right
    var table_size = textSize == 'Tiny' ? size.tiny : textSize == 'Small' ? size.small : size.normal
 
    var tb = table.new(table_position, 3, 3, bgcolor = #1e222d, border_color = #373a46, border_width = 1, frame_color = #373a46, frame_width = 1)
 
    if showDash
        if barstate.isfirst
            tb.cell(1, 0, 'Bullish', text_color = bullCss.tosolid(), text_size = table_size)
            tb.cell(2, 0, 'Bearish', text_color = bearCss.tosolid(), text_size = table_size)
        
            tb.cell(0, 1, 'Count', text_size = table_size, text_color = color.white)
            tb.cell(0, 2, 'Mitigated', text_size = table_size, text_color = color.white)
        
        if barstate.islast
            tb.cell(1, 1, str.tostring(bull_count), text_color = bullCss.tosolid(), text_size = table_size)
            tb.cell(2, 1, str.tostring(bear_count), text_color = bearCss.tosolid(), text_size = table_size)
            
            tb.cell(1, 2, str.tostring(bull_mitigated / bull_count * 100, format.percent), text_color = bullCss.tosolid(), text_size = table_size)
            tb.cell(2, 2, str.tostring(bear_mitigated / bear_count * 100, format.percent), text_color = bearCss.tosolid(), text_size = table_size)
 
    if bull_count > bull_count[1]
        alert('Bullish FVG detected', alert.freq_once_per_bar)
    if bear_count > bear_count[1]
        alert('Bearish FVG detected', alert.freq_once_per_bar)
 
    if bull_mitigated > bull_mitigated[1]
        alert('Bullish FVG mitigated', alert.freq_once_per_bar)
    if bear_mitigated > bear_mitigated[1]
        alert('Bearish FVG mitigated', alert.freq_once_per_bar)
 
max_bull_plot = plot(showLuxFVG ? max_bull_fvg : na, color = na, display = display.none)
min_bull_plot = plot(showLuxFVG ? min_bull_fvg : na, color = na, display = display.none)
fill(max_bull_plot, min_bull_plot, color = showLuxFVG ? bullCss : na)
 
max_bear_plot = plot(showLuxFVG ? max_bear_fvg : na, color = na, display = display.none)
min_bear_plot = plot(showLuxFVG ? min_bear_fvg : na, color = na, display = display.none)
fill(max_bear_plot, min_bear_plot, color = showLuxFVG ? bearCss : na)
 
// โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
// LUXALGO ORDER BLOCKS CODE
// โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
var os = 0
var target_bull = 0.
var target_bear = 0.
var bull_ob_plot = 0.0
var bear_ob_plot = 0.0
 
if showLuxOB
    n = bar_index
    upper = ta.highest(lengthOB)
    lower = ta.lowest(lengthOB)
 
    if mitigationOB == 'Close'
        target_bull := ta.lowest(close, lengthOB)
        target_bear := ta.highest(close, lengthOB)
    else
        target_bull := lower
        target_bear := upper
 
    os := high[lengthOB] > upper ? 0 : low[lengthOB] < lower ? 1 : os[1]
 
    phv = ta.pivothigh(volume, lengthOB, lengthOB)
    phv_detected = not na(phv)
 
    [bull_top, bull_btm, bull_avg, bull_left, bull_ob] = get_coordinates(phv_detected and os == 1, hl2[lengthOB], low[lengthOB], low[lengthOB])
 
    [bear_top, bear_btm, bear_avg, bear_left, bear_ob] = get_coordinates(phv_detected and os == 0, high[lengthOB], hl2[lengthOB], high[lengthOB])
 
    mitigated_bull = remove_mitigated(bull_top, bull_btm, bull_left, bull_avg, target_bull, true)
 
    mitigated_bear = remove_mitigated(bear_top, bear_btm, bear_left, bear_avg, target_bear, false)
 
    set_order_blocks(bull_top, bull_btm, bull_left, bull_avg, bull_ext_last, bg_bull_css, bull_css, bull_avg_css)
 
    set_order_blocks(bear_top, bear_btm, bear_left, bear_avg, bear_ext_last, bg_bear_css, bear_css, bear_avg_css)
    
    bull_ob_plot := bull_ob
    bear_ob_plot := bear_ob
    
    bull_ob_detected = not na(bull_ob)
    bear_ob_detected = not na(bear_ob)
 
    if bull_ob_detected
        alert('Bullish OB Formed', alert.freq_once_per_bar)
    if bear_ob_detected
        alert('Bearish OB Formed', alert.freq_once_per_bar)
    if mitigated_bull
        alert('Bullish OB Mitigated', alert.freq_once_per_bar)
    if mitigated_bear
        alert('Bearish OB Mitigated', alert.freq_once_per_bar)
 
// Plot in global scope
plot(showLuxOB ? bull_ob_plot : na, 'Bull OB', bull_css, 2, plot.style_linebr, offset = -lengthOB, display = display.none)
plot(showLuxOB ? bear_ob_plot : na, 'Bear OB', bear_css, 2, plot.style_linebr, offset = -lengthOB, display = display.none)
 
// ============================================
// THREE BAR REVERSAL CODE
// ============================================
if show3BR
    var int os3BR = 0
    C_DownTrend3BR = true
    C_UpTrend3BR = true
 
    if trendType3BR == 'Moving Average Cloud'
        maFast3BR = movingAverage3BR(close, maFLength3BR, maType3BR)
        maSlow3BR = movingAverage3BR(close, maSLength3BR, maType3BR)
        
        if trendFilt3BR == 'Aligned'
            C_DownTrend3BR := close < maFast3BR and maFast3BR < maSlow3BR
            C_UpTrend3BR := close > maFast3BR and maFast3BR > maSlow3BR
        else if trendFilt3BR == 'Opposite'
            C_DownTrend3BR := close > maFast3BR and maFast3BR > maSlow3BR
            C_UpTrend3BR := close < maFast3BR and maFast3BR < maSlow3BR
 
    if trendType3BR == 'Supertrend'
        [supertrend3BR, direction3BR] = ta.supertrend(factor3BR, atrPeriod3BR)
        
        if trendFilt3BR == 'Aligned'
            C_DownTrend3BR := direction3BR > 0
            C_UpTrend3BR := direction3BR < 0
        else if trendFilt3BR == 'Opposite'
            C_DownTrend3BR := direction3BR < 0
            C_UpTrend3BR := direction3BR > 0
 
    if trendType3BR == 'Donchian Channels'
        upper3BR = ta.highest(close, length3BR)
        lower3BR = ta.lowest(close, length3BR)
        os3BR := upper3BR > upper3BR[1] ? 1 : lower3BR < lower3BR[1] ? 0 : os3BR
        
        if trendFilt3BR == 'Aligned'
            C_DownTrend3BR := os3BR == 0
            C_UpTrend3BR := os3BR == 1
        else if trendFilt3BR == 'Opposite'
            C_DownTrend3BR := os3BR == 1
            C_UpTrend3BR := os3BR == 0
 
    bullishReversal3BR = isBullishReversal3BR() and C_UpTrend3BR
    bearishReversal3BR = isBearishReversal3BR() and C_DownTrend3BR
 
    var line lnAT = na
    var line lnAB = na
    var line lnAT2 = na
    var line lnAB2 = na
    var label lbAT = na
    var box bxA = na
    var bool bullProcess = false
    var bool bullProcess2 = false
    var float bullHigh = na
 
    if bullishReversal3BR and (brpType == 'All' ? true : brpType == 'Enhanced' ? close > high[2] : brpType == 'Normal' ? close < high[2] : false)
        bullProcess := true
 
        lbAT := label.new(bar_index, low, 'โ–ฒ', color = color(na), textcolor = color.new(brpAC, 7), style = label.style_label_up, size = size.small, tooltip = 'Bullish pattern' + (close > high[2] ? ' (enhanced)' : ' (normal)'))
 
        lnAT := line.new(bar_index[2], high[2], bar_index, high[2], color = color.new(brpAC, 53))
        lnAB := line.new(bar_index[1], math.min(low[1], low), bar_index[0], math.min(low[1], low), color = color.new(brpAC, 53))
        linefill.new(lnAT, lnAB, color.new(brpAC, 73))
 
        lnAT2 := line.new(bar_index[2], high[2], bar_index, high[2], color = color.new(brpAC, 53))
        lnAB2 := line.new(bar_index[1], math.min(low[1], low), bar_index[0], math.min(low[1], low), color = color.new(brpAC, 53))
 
        bullHigh := brpSR == 'Zone' ? math.max(low[1], low) : math.min(low[1], low)
 
    if bullProcess
        if close[1] > lnAT.get_price(bar_index)
            if bullProcess[1] and bullProcess[1] != bullProcess[2]
                lbAT.set_tooltip('Enhanced (confirmed at detection)')
            else
                lbAT.set_tooltip('Confirmed ' + str.tostring(bar_index[1] - lbAT.get_x()) + ' bars later')
                label.new(bar_index[1], low[1], 'โฆ', color = color(na), textcolor = color.new(brpAC, 7), style = label.style_label_up, size = size.small, tooltip = 'Confirmation bar')
            
            bullProcess := false
 
            bxA := box.new(bar_index, bullHigh, bar_index, lnAB.get_price(bar_index), color.new(brpAC, brpSR == 'Zone' ? 73 : 53), bgcolor = color.new(brpAC, 73))
            bullProcess2 := true
 
        if close[1] < lnAB.get_price(bar_index) or bearishReversal3BR
            lbAT.set_tooltip('Pattern failed')
            bullProcess := false
 
        if not bullProcess
            lnAT2.set_x2(bar_index[1])
            lnAB2.set_x2(bar_index[1])
        else
            lnAT2.set_x2(bar_index)
            lnAB2.set_x2(bar_index)
 
    if bullProcess2 and brpSR != 'None'
        if close > bxA.get_bottom()
            bxA.set_right(bar_index)
        else
            bxA.set_right(bar_index)
            bullProcess2 := false
 
    var line lnST = na
    var line lnSB = na
    var line lnST2 = na
    var line lnSB2 = na
    var label lbST = na
    var box bxS = na
    var bool bearProcess = false
    var bool bearProcess2 = false
    var float bearLow = na
 
    if bearishReversal3BR and (brpType == 'All' ? true : brpType == 'Enhanced' ? close < low[2] : brpType == 'Normal' ? close > low[2] : false)
        bearProcess := true
 
        lbST := label.new(bar_index, high, 'โ–ผ', color = color(na), textcolor = color.new(brpSC, 7), style = label.style_label_down, size = size.small, tooltip = 'Bearish pattern' + (close < low[2] ? ' (enhanced)' : ' (normal)'))
 
        lnSB := line.new(bar_index[2], low[2], bar_index, low[2], color = color.new(brpSC, 53))
        lnST := line.new(bar_index[1], math.max(high[1], high), bar_index[0], math.max(high[1], high), color = color.new(brpSC, 53))
        linefill.new(lnST, lnSB, color.new(brpSC, 73))
 
        lnSB2 := line.new(bar_index[2], low[2], bar_index, low[2], color = color.new(brpSC, 53))
        lnST2 := line.new(bar_index[1], math.max(high[1], high), bar_index[0], math.max(high[1], high), color = color.new(brpSC, 53))
 
        bearLow := brpSR == 'Zone' ? math.min(high[1], high) : math.max(high[1], high)
 
    if bearProcess
        if close[1] > lnST.get_price(bar_index) or bullishReversal3BR
            lbST.set_tooltip('Pattern failed')
            bearProcess := false
 
        if close[1] < lnSB.get_price(bar_index)
            if bearProcess[1] and bearProcess[1] != bearProcess[2]
                lbST.set_tooltip('Enhanced (confirmed at detection)')
            else
                lbST.set_tooltip('Confirmed ' + str.tostring(bar_index[1] - lbST.get_x()) + ' bars later')
                label.new(bar_index[1], high[1], 'โฆ', color = color(na), textcolor = color.new(brpSC, 7), style = label.style_label_down, size = size.small, tooltip = 'Confirmation bar')
 
            bearProcess := false
 
            bxS := box.new(bar_index, lnST.get_price(bar_index), bar_index, bearLow, color.new(brpSC, brpSR == 'Zone' ? 73 : 53), bgcolor = color.new(brpSC, 73))
            bearProcess2 := true
 
        if not bearProcess
            lnST2.set_x2(bar_index[1])
            lnSB2.set_x2(bar_index[1])
        else
            lnST2.set_x2(bar_index)
            lnSB2.set_x2(bar_index)
 
    if bearProcess2 and brpSR != 'None'
        if close < bxS.get_top()
            bxS.set_right(bar_index)
        else
            bxS.set_right(bar_index)
            bearProcess2 := false
 
// ============================================
// REVERSAL SIGNALS CODE (SIMPLIFIED)
// ============================================
var int bSCRS = 0
var int sSCRS = 0
var float bSRRS = na
var float sSSRS = na
var bool showBullMomentum = false
var bool showBearMomentum = false
 
if showRS
    conRS = close < close[4]
    
    if conRS
        bSCRS := bSCRS == 9 ? 1 : bSCRS + 1
        sSCRS := 0
    else
        sSCRS := sSCRS == 9 ? 1 : sSCRS + 1
        bSCRS := 0
    
    showBullMomentum := bSCRS == 9
    showBearMomentum := sSCRS == 9
    
    sRRS = ta.highest(9)
    bSRRS := bSCRS == 9 ? sRRS : close > bSRRS ? na : bSRRS
    
    sSRS = ta.lowest(9)
    sSSRS := sSCRS == 9 ? sSRS : close < sSSRS ? na : sSSRS
else
    showBullMomentum := false
    showBearMomentum := false
    bSRRS := na
    sSSRS := na
 
plotshape(showRS and showBullMomentum, 'Bullish Momentum', shape.labelup, location.belowbar, color.new(#089981, 25), text = '', textcolor = color.white, size = size.tiny)
plotshape(showRS and showBearMomentum, 'Bearish Momentum', shape.labeldown, location.abovebar, color.new(#f23645, 25), text = '', textcolor = color.white, size = size.tiny)
plot(showRS and srLRS and not na(bSRRS) ? bSRRS : na, "RS Resistance", color.new(#f23645, 50), 2)
plot(showRS and srLRS and not na(sSSRS) ? sSSRS : na, "RS Support", color.new(#089981, 50), 2)

โ† ่ฟ”ๅ›žๅˆ—่กจ