JADU-TONA

 //@version=6
indicator("RM'S JADU TONA", overlay=true, max_lines_count=500, max_labels_count=500, max_boxes_count=500)

// ==================================================================
// INPUTS
// ==================================================================
grpMain = "Main"
inpStartTime         = input.time(timestamp("2026-01-01T00:00:00"), "Start Time",       group=grpMain)
inpMaxBars           = input.int(12000, "Max Bars", minval=20,                          group=grpMain)

grpDisp = "Structure Display"
inpShowSwings        = input.bool(true,  "Show Swings",                                 group=grpDisp)
inpShowBOS           = input.bool(true,  "Show BOS",                                    group=grpDisp)
inpShowCHOCH         = input.bool(true,  "Show CHOCH",                                  group=grpDisp)
inpShowLevels        = input.bool(true,  "Show Levels",                                 group=grpDisp)
inpShowTJL           = input.bool(true,  "Show TJL",                                    group=grpDisp)
inpShowISS           = input.bool(true,  "Show ISS",                                    group=grpDisp)
inpKeepOnlyLastCHOCH = input.bool(false, "Keep Only Last CHOCH",                        group=grpDisp)

grpIndiv = "Individual Level Visibility"
inpShowTJL1         = input.bool(true, "Show TJL 1",                                    group=grpIndiv)
inpShowTJL2         = input.bool(true, "Show TJL 2",                                    group=grpIndiv)
inpShowQML          = input.bool(true, "Show QML",                                      group=grpIndiv)
inpShowSBR          = input.bool(true, "Show SBR",                                      group=grpIndiv)
inpShowRBS          = input.bool(true, "Show RBS",                                      group=grpIndiv)
inpShowDB           = input.bool(true, "Show DB",                                       group=grpIndiv)
inpShowDT           = input.bool(true, "Show DT",                                       group=grpIndiv)
inpShowBestQML      = input.bool(true, "Show Best Levels",                              group=grpIndiv)
inpShowISS1         = input.bool(false, "Show ISS 1",                                   group=grpIndiv)
inpShowISS3         = input.bool(true, "Show ISS 3",                                    group=grpIndiv)
inpShowISS4         = input.bool(true, "Show ISS 4",                                    group=grpIndiv)

grpISS = "ISS Controls"
inpEnableISS          = input.bool(true, "Enable ISS Logic",                            group=grpISS)
inpShowISSLabel       = input.bool(true, "Show ISS Label",                              group=grpISS)
inpShowISSBOS         = input.bool(true, "Show ISS BOS",                                group=grpISS)
inpStopISS34ByWickTap = input.bool(true, "Stop ISS 3/4 on Wick Tap",                    group=grpISS)

grpCol = "Level Colors"
inpCHColor           = input.color(color.white,             "CH Color",                 group=grpCol)
inpCLColor           = input.color(color.orange,            "CL Color",                 group=grpCol)
inpBullBOSColor      = input.color(color.green,             "Bull BOS Color",           group=grpCol)
inpBearBOSColor      = input.color(color.red,               "Bear BOS Color",           group=grpCol)
inpBullTJLColor      = input.color(color.green,             "Bull TJL Color",           group=grpCol)
inpBearTJLColor      = input.color(color.orange,            "Bear TJL Color",           group=grpCol)
inpSBRColor          = input.color(color.red,               "SBR Color",                group=grpCol)
inpRBSColor          = input.color(color.green,             "RBS Color",                group=grpCol)
inpQMLColor          = input.color(color.rgb(186, 85, 211), "QML Color",                group=grpCol)
inpDTDBColor         = input.color(color.blue,              "DT/DB Color",              group=grpCol)
inpISSColor          = input.color(color.yellow,            "ISS Color",                group=grpCol)
inpBestQMLColor      = input.color(color.rgb(255, 215, 0),  "Best QML Color",           group=grpCol)

grpSt = "Style"
inpLineWidth         = input.int(2,   "Line Width",      minval=1,                      group=grpSt)
inpMaxLiveLevels     = input.int(140, "Max Live Levels", minval=1,                      group=grpSt)
inpMaxLabels         = input.int(180, "Max Labels",      minval=1,                      group=grpSt)
inpMaxLines          = input.int(180, "Max Lines",       minval=1,                      group=grpSt)
inpZoneBodyPct       = input.float(1.0, "Zone Body %", minval=0.0, maxval=100.0, step=0.1, group=grpSt)
tapByWick  = "TapByWick"
tapByClose = "TapByClose"
inpStopOnTap = input.bool(true,        "Stop On Tap",                                   group=grpSt)
inpTapSource = input.string(tapByWick, "Tap Source", options=[tapByWick, tapByClose],   group=grpSt)
inpLevelTextVPos = input.string("Inside", "Level Text Vertical", options=["Top", "Inside", "Bottom"], group=grpSt)
inpLevelTextHPos = input.string("Right", "Level Text Horizontal", options=["Left", "Center", "Right"], group=grpSt)

grpSMC = "Smart Money Concepts (SMC)"
inpShowFVG         = input.bool(false, "Show FVG (Fair Value Gap / IPDA)",              group=grpSMC)
inpFVGDeleteOnTap  = input.bool(true, "Delete FVG on Tap",                              group=grpSMC)
inpMaxFVG          = input.int(30,    "Max FVG Levels",  minval=1, maxval=50,           group=grpSMC)
inpShowOB          = input.bool(false, "Show Order Blocks (Opposite Candle Before Move)",group=grpSMC)
inpOBDeleteOnTap   = input.bool(true, "Delete OB on Tap",                               group=grpSMC)
inpMaxOB           = input.int(20,    "Max Order Block Levels", minval=1, maxval=30,    group=grpSMC)
inpShowKZ          = input.bool(false, "Show Kill Zones (IST)",                         group=grpSMC)
inpBullFVGColor    = input.color(color.new(color.teal,    70), "Bull FVG Color",        group=grpSMC)
inpBearFVGColor    = input.color(color.new(color.maroon,  70), "Bear FVG Color",        group=grpSMC)
inpBullOBColor     = input.color(color.new(color.lime,    75), "Demand OB Color",       group=grpSMC)
inpBearOBColor     = input.color(color.new(color.red,     75), "Supply OB Color",       group=grpSMC)
inpLondonColor     = input.color(color.new(color.blue,    92), "London KZ Color",       group=grpSMC)
inpNYColor         = input.color(color.new(color.purple,  92), "NY KZ Color",           group=grpSMC)

grpDash = "Trend Dashboard"
inpShowTrendDash   = input.bool(false, "Show MTF Trend Dashboard",                      group=grpDash)
inpDashShowTf1     = input.bool(true, "Show Timeframe 1",                               group=grpDash)
inpDashTf1         = input.timeframe("1",   "Timeframe 1",                              group=grpDash)
inpDashShowTf2     = input.bool(true, "Show Timeframe 2",                               group=grpDash)
inpDashTf2         = input.timeframe("3",   "Timeframe 2",                              group=grpDash)
inpDashShowTf3     = input.bool(true, "Show Timeframe 3",                               group=grpDash)
inpDashTf3         = input.timeframe("5",   "Timeframe 3",                              group=grpDash)
inpDashShowTf4     = input.bool(true, "Show Timeframe 4",                               group=grpDash)
inpDashTf4         = input.timeframe("15",  "Timeframe 4",                              group=grpDash)
inpDashShowTf5     = input.bool(true, "Show Timeframe 5",                               group=grpDash)
inpDashTf5         = input.timeframe("30",  "Timeframe 5",                              group=grpDash)
inpDashShowTf6     = input.bool(true, "Show Timeframe 6",                               group=grpDash)
inpDashTf6         = input.timeframe("45",  "Timeframe 6",                              group=grpDash)
inpDashShowTf7     = input.bool(true, "Show Timeframe 7",                               group=grpDash)
inpDashTf7         = input.timeframe("60",  "Timeframe 7",                              group=grpDash)
inpDashShowTf8     = input.bool(true, "Show Timeframe 8",                               group=grpDash)
inpDashTf8         = input.timeframe("120", "Timeframe 8",                              group=grpDash)
inpDashShowTf9     = input.bool(true, "Show Timeframe 9",                               group=grpDash)
inpDashTf9         = input.timeframe("180", "Timeframe 9",                              group=grpDash)
inpDashShowTf10    = input.bool(true, "Show Timeframe 10",                              group=grpDash)
inpDashTf10        = input.timeframe("240", "Timeframe 10",                             group=grpDash)
inpDashShowTf11    = input.bool(true, "Show Timeframe 11",                              group=grpDash)
inpDashTf11        = input.timeframe("D",   "Timeframe 11",                             group=grpDash)
inpDashShowTf12    = input.bool(true, "Show Timeframe 12",                              group=grpDash)
inpDashTf12        = input.timeframe("W",   "Timeframe 12",                             group=grpDash)
inpDashShowTf13    = input.bool(true, "Show Timeframe 13",                              group=grpDash)
inpDashTf13        = input.timeframe("M",   "Timeframe 13",                             group=grpDash)

grpAnalyzer = "Level Analyzer"
inpShowLevelAnalyzer = input.bool(false, "Show Level Accuracy Analyzer",                 group=grpAnalyzer)
inpAnalyzerTargetPips = input.float(100.0, "Win Target (Pips)", minval=0.1, step=0.1,    group=grpAnalyzer)
inpAnalyzerLossPips = input.float(50.0, "Loss Target (Pips)", minval=0.1, step=0.1,      group=grpAnalyzer)
inpAnalyzerPipMode = input.string("Auto", "Pip Size Mode", options=["Auto", "Custom"],   group=grpAnalyzer)
inpAnalyzerCustomPipSize = input.float(0.0001, "Custom Pip Size", minval=0.00000001, step=0.00000001, group=grpAnalyzer)
inpAnalyzerMinDone = input.int(3, "Min Finished Tests To Rank", minval=1,                group=grpAnalyzer)
inpAnalyzerShowBuyTJL1 = input.bool(true, "Table: BUY TJL1",                             group=grpAnalyzer)
inpAnalyzerShowBuyTJL2 = input.bool(true, "Table: BUY TJL2",                             group=grpAnalyzer)
inpAnalyzerShowSellTJL1 = input.bool(true, "Table: SELL TJL1",                           group=grpAnalyzer)
inpAnalyzerShowSellTJL2 = input.bool(true, "Table: SELL TJL2",                           group=grpAnalyzer)
inpAnalyzerShowSBR = input.bool(true, "Table: SBR",                                      group=grpAnalyzer)
inpAnalyzerShowRBS = input.bool(true, "Table: RBS",                                      group=grpAnalyzer)
inpAnalyzerShowDT = input.bool(true, "Table: DT",                                        group=grpAnalyzer)
inpAnalyzerShowDB = input.bool(true, "Table: DB",                                        group=grpAnalyzer)
inpAnalyzerShowBuyQML = input.bool(true, "Table: BUY QML",                               group=grpAnalyzer)
inpAnalyzerShowSellQML = input.bool(true, "Table: SELL QML",                             group=grpAnalyzer)
inpAnalyzerShowISS4 = input.bool(true, "Table: ISS 4",                                   group=grpAnalyzer)
inpAnalyzerShowBestSBR = input.bool(true, "Table: BEST SBR",                             group=grpAnalyzer)
inpAnalyzerShowBestRBS = input.bool(true, "Table: BEST RBS",                             group=grpAnalyzer)
inpAnalyzerShowBestDT = input.bool(true, "Table: BEST DT",                               group=grpAnalyzer)
inpAnalyzerShowBestDB = input.bool(true, "Table: BEST DB",                               group=grpAnalyzer)
inpAnalyzerShowBestBuyQML = input.bool(true, "Table: BEST BUY QML",                      group=grpAnalyzer)
inpAnalyzerShowBestSellQML = input.bool(true, "Table: BEST SELL QML",                    group=grpAnalyzer)

// ==================================================================
// EMA (Merged from Code 2)
// ==================================================================
grpEMA = "EMA"
emaLen = input.int(132, minval=1, title="EMA Length", group=grpEMA)
emaSrc = input.source(close, title="EMA Source", group=grpEMA)
emaOffset = input.int(title="EMA Offset", defval=0, minval=-500, maxval=500, group=grpEMA)
emaColor = input.color(color.blue, "EMA Color", group=grpEMA)
emaOut = ta.ema(emaSrc, emaLen)
plot(emaOut, title="EMA", color=emaColor, offset=emaOffset)

// Smoothing MA inputs
emaSmoothGrp = "EMA Smoothing"
emaTTBB = "Only applies when 'SMA + Bollinger Bands' is selected. Determines the distance between the SMA and the bands."
emaMaTypeInput = input.string("None", "Type", options=["None", "SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group=emaSmoothGrp)
emaIsBB = emaMaTypeInput == "SMA + Bollinger Bands"
emaMaLengthInput = input.int(14, "Length", group=emaSmoothGrp, active=emaMaTypeInput != "None")
emaBbMultInput = input.float(2.0, "BB StdDev", minval=0.001, maxval=50, step=0.5, tooltip=emaTTBB, group=emaSmoothGrp, active=emaIsBB)
emaEnableMA = emaMaTypeInput != "None"

// Smoothing MA Calculation
f_emaMa(source, length, maType) =>
    switch maType
        "SMA" => ta.sma(source, length)
        "SMA + Bollinger Bands" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "SMMA (RMA)" => ta.rma(source, length)
        "WMA" => ta.wma(source, length)
        "VWMA" => ta.vwma(source, length)

emaSmoothingMA = emaEnableMA ? f_emaMa(emaOut, emaMaLengthInput, emaMaTypeInput) : na
emaSmoothingStDev = emaIsBB ? ta.stdev(emaOut, emaMaLengthInput) * emaBbMultInput : na
plot(emaSmoothingMA, "EMA-based MA", color=color.yellow, display=emaEnableMA ? display.all : display.none, editable=emaEnableMA)
emaBbUpperBand = plot(emaSmoothingMA + emaSmoothingStDev, title="Upper Bollinger Band", color=color.green, display=emaIsBB ? display.all : display.none, editable=emaIsBB)
emaBbLowerBand = plot(emaSmoothingMA - emaSmoothingStDev, title="Lower Bollinger Band", color=color.green, display=emaIsBB ? display.all : display.none, editable=emaIsBB)
fill(emaBbUpperBand, emaBbLowerBand, color=emaIsBB ? color.new(color.green, 90) : na, title="Bollinger Bands Background Fill", display=emaIsBB ? display.all : display.none, editable=emaIsBB)

// ==================================================================
// TYPES
// ==================================================================
type Snap
    int   t
    int   bar
    float o
    float c
    float h
    float l
    float lvl

type Level
    int    left
    int    right
    float  top
    float  bot
    color  col
    string txt
    int    kind
    int    dir
    bool   active
    bool   deleted
    bool   stopReady
    int    stopReadyBar
    int    bornBar
    box    bx
    label  lb
    bool   anaStarted
    bool   anaActive
    int    anaStartBar

type FVGLevel
    int   left
    int   right
    float top
    float bot
    bool  bull
    bool  active
    bool  deleted
    box   bx

type OBLevel
    int   left
    int   right
    float top
    float bot
    bool  bull
    bool  active
    bool  deleted
    box   bx

// ==================================================================
// HELPERS
// ==================================================================
f_initSnap() =>
    Snap.new(0, 0, 0.0, 0.0, 0.0, 0.0, 0.0)

f_makeSnapCurrent(float level) =>
    Snap.new(time, bar_index, open, close, high, low, level)

f_makeSnapAtBar(int srcBar, float level) =>
    off = bar_index - srcBar
    off >= 0 ? Snap.new(time[off], srcBar, open[off], close[off], high[off], low[off], level) : f_initSnap()

f_candleZone(float o, float c, float h, float l, bool isHigh) =>
    bodyTop = math.max(o, c)
    bodyBot = math.min(o, c)
    pad     = math.max(bodyTop - bodyBot, 0.0) * inpZoneBodyPct * 0.01
    top_    = isHigh ? h : bodyBot + pad
    bot_    = isHigh ? bodyTop - pad : l
    [top_, bot_]

f_isTapped(float rClose, float rHigh, float rLow, float top_, float bot_) =>
    if inpTapSource == tapByClose
        rClose <= top_ and rClose >= bot_
    else
        rHigh >= bot_ and rLow <= top_

f_levelDir(int kind, bool isHigh) =>
    if kind == 1 or kind == 2
        isHigh ? -1 : 1
    else if kind == 4 or kind == 6
        1
    else if kind == 3 or kind == 5
        -1
    else if kind == 7
        isHigh ? -1 : 1
    else if kind == 30 or kind == 31
        1
    else if kind == 32 or kind == 33
        -1
    else
        0

f_levelDisplayText(int kind, int dir, string txt) =>
    if kind == 1
        dir == 1 ? "SELL TJL1" : "BUY TJL1"
    else if kind == 2
        dir == 1 ? "BUY TJL2" : "SELL TJL2"
    else
        txt

f_analyzerSlot(string txt) =>
    if txt == "BUY TJL1"
        0
    else if txt == "BUY TJL2"
        1
    else if txt == "SELL TJL1"
        2
    else if txt == "SELL TJL2"
        3
    else if txt == "SBR"
        4
    else if txt == "RBS"
        5
    else if txt == "DT"
        6
    else if txt == "DB"
        7
    else if txt == "BUY QML"
        8
    else if txt == "SELL QML"
        9
    else if txt == "ISS 4"
        10
    else if txt == "BEST SBR"
        11
    else if txt == "BEST RBS"
        12
    else if txt == "BEST DT"
        13
    else if txt == "BEST DB"
        14
    else if txt == "BEST BUY QML"
        15
    else if txt == "BEST SELL QML"
        16
    else
        -1

f_analyzerLabel(int slot) =>
    switch slot
        0 => "BUY TJL1"
        1 => "BUY TJL2"
        2 => "SELL TJL1"
        3 => "SELL TJL2"
        4 => "SBR"
        5 => "RBS"
        6 => "DT"
        7 => "DB"
        8 => "BUY QML"
        9 => "SELL QML"
        10 => "ISS 4"
        11 => "BEST SBR"
        12 => "BEST RBS"
        13 => "BEST DT"
        14 => "BEST DB"
        15 => "BEST BUY QML"
        16 => "BEST SELL QML"
        => ""

f_analyzerShowSlot(int slot) =>
    switch slot
        0 => inpAnalyzerShowBuyTJL1
        1 => inpAnalyzerShowBuyTJL2
        2 => inpAnalyzerShowSellTJL1
        3 => inpAnalyzerShowSellTJL2
        4 => inpAnalyzerShowSBR
        5 => inpAnalyzerShowRBS
        6 => inpAnalyzerShowDT
        7 => inpAnalyzerShowDB
        8 => inpAnalyzerShowBuyQML
        9 => inpAnalyzerShowSellQML
        10 => inpAnalyzerShowISS4
        11 => inpAnalyzerShowBestSBR
        12 => inpAnalyzerShowBestRBS
        13 => inpAnalyzerShowBestDT
        14 => inpAnalyzerShowBestDB
        15 => inpAnalyzerShowBestBuyQML
        16 => inpAnalyzerShowBestSellQML
        => false

f_analyzerRateText(int wins, int losses) =>
    done = wins + losses
    done > 0 ? str.tostring((wins * 100.0) / done, "#.##") + "%" : "n/a"

f_analyzerPipSize() =>
    inpAnalyzerPipMode == "Custom" ? inpAnalyzerCustomPipSize : syminfo.type == "forex" ? syminfo.mintick * 10.0 : syminfo.mintick

// FIX 1: Loop extended from 14 → 16 to cover all 17 slots (0–16).
// Previously only evaluated slots 0–14, so BEST BUY QML (15) and
// BEST SELL QML (16) were never considered for the best-slot highlight.
f_bestAnalyzerSlot(array<int> wins, array<int> losses) =>
    int bestSlot = -1
    float bestRate = na
    for i = 0 to 16
        w = array.get(wins, i)
        l = array.get(losses, i)
        done = w + l
        if f_analyzerShowSlot(i) and done >= inpAnalyzerMinDone
            rate = (w * 1.0) / done
            if na(bestRate) or rate > bestRate
                bestRate := rate
                bestSlot := i
    bestSlot

f_updateLevelAnalyzer(Level lv, float rClose, float rHigh, float rLow, int barNum, array<int> tests, array<int> wins, array<int> losses) =>
    slot = f_analyzerSlot(lv.txt)
    if inpShowLevelAnalyzer and slot >= 0 and lv.dir != 0
        targetMove = inpAnalyzerTargetPips * f_analyzerPipSize()
        lossMove = inpAnalyzerLossPips * f_analyzerPipSize()
        tapped = f_isTapped(rClose, rHigh, rLow, lv.top, lv.bot)
        if not lv.anaStarted and barNum > lv.bornBar and tapped
            lv.anaStarted := true
            lv.anaActive := true
            lv.anaStartBar := barNum
            array.set(tests, slot, array.get(tests, slot) + 1)
        if lv.anaActive and barNum > lv.anaStartBar
            win = lv.dir == 1 ? rHigh >= lv.top + targetMove : rLow <= lv.bot - targetMove
            loss = lv.dir == 1 ? rLow <= lv.bot - lossMove : rHigh >= lv.top + lossMove
            if win
                array.set(wins, slot, array.get(wins, slot) + 1)
                lv.anaActive := false
            else if loss
                array.set(losses, slot, array.get(losses, slot) + 1)
                lv.anaActive := false
    lv

f_levelTextHAlign() =>
    if inpLevelTextHPos == "Left"
        text.align_left
    else if inpLevelTextHPos == "Right"
        text.align_right
    else
        text.align_center

f_levelTextVAlign() =>
    if inpLevelTextVPos == "Top"
        text.align_top
    else if inpLevelTextVPos == "Bottom"
        text.align_bottom
    else
        text.align_center

f_applyLevelText(box bx, string txt, color col) =>
    box.set_text(bx, txt)
    box.set_text_color(bx, col)
    box.set_text_size(bx, size.small)
    box.set_text_halign(bx, f_levelTextHAlign())
    box.set_text_valign(bx, f_levelTextVAlign())

f_bestLevelText(int kind, int dir) =>
    if kind == 3
        "BEST SBR"
    else if kind == 4
        "BEST RBS"
    else if kind == 5
        "BEST DT"
    else if kind == 6
        "BEST DB"
    else if kind == 7 and dir == 1
        "BEST BUY QML"
    else if kind == 7 and dir == -1
        "BEST SELL QML"
    else
        "BEST QML"

f_bestLevelColor(int kind, color srcCol) =>
    kind == 7 ? inpBestQMLColor : srcCol

f_promoteLastChochLevelsToBest(array<Level> lvs, int qmlLeft) =>
    if not na(qmlLeft) and array.size(lvs) > 0
        int srcBornBar = na
        for i = array.size(lvs) - 1 to 0
            lv = array.get(lvs, i)
            if lv.kind == 7 and not lv.deleted and lv.left == qmlLeft
                srcBornBar := lv.bornBar
                break
        if not na(srcBornBar)
            for i = array.size(lvs) - 1 to 0
                srcLv = array.get(lvs, i)
                if srcLv.kind >= 3 and srcLv.kind <= 7 and not srcLv.deleted and srcLv.bornBar == srcBornBar
                    bestTxt = f_bestLevelText(srcLv.kind, srcLv.dir)
                    bestCol = f_bestLevelColor(srcLv.kind, srcLv.col)
                    srcLv.active := true
                    srcLv.right := bar_index
                    srcLv.bornBar := bar_index
                    srcLv.stopReady := false
                    srcLv.stopReadyBar := 0
                    if not na(srcLv.bx)
                        f_applyLevelText(srcLv.bx, srcLv.txt, srcLv.col)
                        box.set_border_color(srcLv.bx, srcLv.col)
                        box.set_bgcolor(srcLv.bx, color.new(srcLv.col, 75))
                        box.set_right(srcLv.bx, bar_index)
                    if not na(srcLv.lb)
                        label.delete(srcLv.lb)
                        srcLv.lb := na
                    array.set(lvs, i, srcLv)

                    bool bestFound = false
                    for j = array.size(lvs) - 1 to 0
                        foundBestLv = array.get(lvs, j)
                        if foundBestLv.kind == 8 and not foundBestLv.deleted and foundBestLv.left == srcLv.left and foundBestLv.top == srcLv.top and foundBestLv.bot == srcLv.bot and foundBestLv.txt == bestTxt
                            foundBestLv.active := true
                            foundBestLv.right := bar_index
                            foundBestLv.bornBar := bar_index
                            foundBestLv.stopReady := false
                            foundBestLv.stopReadyBar := 0
                            foundBestLv.col := bestCol
                            foundBestLv.txt := bestTxt
                            if not na(foundBestLv.bx)
                                f_applyLevelText(foundBestLv.bx, bestTxt, bestCol)
                                box.set_border_color(foundBestLv.bx, bestCol)
                                box.set_bgcolor(foundBestLv.bx, color.new(bestCol, 80))
                                box.set_right(foundBestLv.bx, bar_index)
                            if not na(foundBestLv.lb)
                                label.delete(foundBestLv.lb)
                                foundBestLv.lb := na
                            array.set(lvs, j, foundBestLv)
                            bestFound := true
                            break
                    if not bestFound
                        newBestLv = Level.new(srcLv.left, bar_index, srcLv.top, srcLv.bot, bestCol, bestTxt, 8, srcLv.dir, true, false, false, 0, bar_index, na, na, false, false, 0)
                        array.push(lvs, newBestLv)

f_addLevel(array<Level> lvs, int left_, float o, float c, float h, float l,
           bool isHigh, color col, string txt, int kind, int bornBar, int right_) =>
    [top_, bot_] = f_candleZone(o, c, h, l, isHigh)
    dir_ = f_levelDir(kind, isHigh)
    lv = Level.new(left_, right_, top_, bot_, col, f_levelDisplayText(kind, dir_, txt), kind, dir_, true, false, false, 0, bornBar, na, na, false, false, 0)
    array.push(lvs, lv)

f_addLevelFromBar(array<Level> lvs, int leftBar, int srcBar, bool isHigh, color col, string txt, int kind, int bornBar, int rightBar) =>
    off = bar_index - srcBar
    if off >= 0
        [top_, bot_] = f_candleZone(open[off], close[off], high[off], low[off], isHigh)
        dir_ = f_levelDir(kind, isHigh)
        lv = Level.new(leftBar, rightBar, top_, bot_, col, f_levelDisplayText(kind, dir_, txt), kind, dir_, true, false, false, 0, bornBar, na, na, false, false, 0)
        array.push(lvs, lv)

f_addLevelFromBarReady(array<Level> lvs, int leftBar, int srcBar, bool isHigh, color col, string txt, int kind, int bornBar, int rightBar, int readyBar) =>
    off = bar_index - srcBar
    if off >= 0
        [top_, bot_] = f_candleZone(open[off], close[off], high[off], low[off], isHigh)
        dir_ = f_levelDir(kind, isHigh)
        lv = Level.new(leftBar, rightBar, top_, bot_, col, f_levelDisplayText(kind, dir_, txt), kind, dir_, true, false, true, readyBar, bornBar, na, na, false, false, 0)
        array.push(lvs, lv)

f_deleteLatestTJL1ByLeft(array<Level> lvs, int srcLeftBar) =>
    if array.size(lvs) > 0
        for i = array.size(lvs) - 1 to 0
            lv = array.get(lvs, i)
            if not lv.deleted and lv.active and lv.kind == 1 and lv.left == srcLeftBar
                lv.deleted := true
                lv.active  := false
                if not na(lv.bx)
                    box.delete(lv.bx)
                if not na(lv.lb)
                    label.delete(lv.lb)
                array.set(lvs, i, lv)
                break

f_freezePreviousCHOCHLevels(array<Level> lvs) =>
    if array.size(lvs) > 0
        for i = 0 to array.size(lvs) - 1
            lv = array.get(lvs, i)
            if not lv.deleted and lv.active and lv.kind >= 3 and lv.kind <= 7
                lv.active := false
                array.set(lvs, i, lv)

f_updateLevels(array<Level> lvs, float rClose, float rHigh, float rLow, int barNum, array<int> anaTests, array<int> anaWins, array<int> anaLosses) =>
    if array.size(lvs) > 0
        for i = 0 to array.size(lvs) - 1
            lv = array.get(lvs, i)
            if lv.deleted
                continue
            lv := f_updateLevelAnalyzer(lv, rClose, rHigh, rLow, barNum, anaTests, anaWins, anaLosses)
            if not lv.active
                array.set(lvs, i, lv)
                continue
            lv.right := barNum
            issWickLevel = lv.kind == 30 or lv.kind == 31 or lv.kind == 32 or lv.kind == 33
            if issWickLevel
                if inpStopISS34ByWickTap and barNum > lv.bornBar
                    crossed = lv.dir == 1 ? rClose > lv.top : rClose < lv.bot
                    if not lv.stopReady and crossed
                        lv.stopReady := true
                        lv.stopReadyBar := barNum
                    if lv.stopReady and barNum > lv.stopReadyBar
                        issTapped = rHigh >= lv.bot and rLow <= lv.top
                        if issTapped
                            lv.active := false
                            lv.right := barNum
            else
                if inpStopOnTap and barNum > lv.bornBar
                    stdTapped = f_isTapped(rClose, rHigh, rLow, lv.top, lv.bot)
                    if stdTapped
                        lv.active := false
                        lv.right := barNum
            array.set(lvs, i, lv)

f_trimLevels(array<Level> lvs) =>
    if array.size(lvs) > 0
        kept = 0
        for i = array.size(lvs) - 1 to 0
            lv = array.get(lvs, i)
            if lv.deleted
                continue
            kept += 1
            if kept > inpMaxLiveLevels
                lv.deleted := true
                if not na(lv.bx)
                    box.delete(lv.bx)
                if not na(lv.lb)
                    label.delete(lv.lb)
                array.set(lvs, i, lv)

f_pushLine(array<line> arr, line ln) =>
    array.push(arr, ln)
    if array.size(arr) > inpMaxLines
        old = array.shift(arr)
        line.delete(old)

f_pushLabel(array<label> arr, label lb) =>
    array.push(arr, lb)
    if array.size(arr) > inpMaxLabels
        old = array.shift(arr)
        label.delete(old)

f_shouldShowLevel(int kind) =>
    if kind == 1
        inpShowTJL1
    else if kind == 2
        inpShowTJL2
    else if kind == 3
        inpShowSBR
    else if kind == 4
        inpShowRBS
    else if kind == 5
        inpShowDT
    else if kind == 6
        inpShowDB
    else if kind == 7
        inpShowQML
    else if kind == 8
        inpShowBestQML
    else if kind == 29
        inpShowISS1
    else if kind == 30 or kind == 32
        inpShowISS3
    else if kind == 31 or kind == 33
        inpShowISS4
    else
        true

f_mtfTrendCalc() =>
    var int mtfTrend = 0
    var int mtfStructureTrend = 0
    var int mtfPhase = 1
    var int mtfStartBarIndex = na
    var float mtfRunHigh = na
    var int mtfRunHighBar = na
    var float mtfRunLow = na
    var int mtfRunLowBar = na
    var float mtfLastCH = na
    var bool mtfLastCHSet = false
    var float mtfLastCL = na
    var bool mtfLastCLSet = false
    var int mtfBullIssState = 0
    var bool mtfBullIssBaseConfirmed = false
    var float mtfBullIssBaseLow = na
    var int mtfBullIssBaseLowBar = na
    var float mtfBullIssRunHigh = na
    var int mtfBullIssRunHighBar = na
    var float mtfBullIss1Level = na
    var int mtfBullIss1Bar = na
    var float mtfBullIssAfterBreakRunHigh = na
    var int mtfBullIssAfterBreakRunHighBar = na
    var float mtfBullIssAfterBreakRunLow = na
    var int mtfBullIssAfterBreakRunLowBar = na
    var int mtfBearIssState = 0
    var bool mtfBearIssBaseConfirmed = false
    var float mtfBearIssBaseHigh = na
    var int mtfBearIssBaseHighBar = na
    var float mtfBearIssRunLow = na
    var int mtfBearIssRunLowBar = na
    var float mtfBearIss1Level = na
    var int mtfBearIss1Bar = na
    var float mtfBearIssAfterBreakRunLow = na
    var int mtfBearIssAfterBreakRunLowBar = na
    var float mtfBearIssAfterBreakRunHigh = na
    var int mtfBearIssAfterBreakRunHighBar = na

    if na(mtfStartBarIndex) and time >= inpStartTime
        mtfStartBarIndex := bar_index

    mtfInWindow = not na(mtfStartBarIndex) and bar_index >= mtfStartBarIndex and (bar_index - mtfStartBarIndex) <= inpMaxBars
    mtfEnoughBars = bar_index >= 2

    if mtfInWindow and mtfEnoughBars
        if na(mtfRunHigh) or high > mtfRunHigh
            mtfRunHigh := high
            mtfRunHighBar := bar_index
        if na(mtfRunLow) or low < mtfRunLow
            mtfRunLow := low
            mtfRunLowBar := bar_index

        mtfRedP = close[1] < open[1]
        mtfGreenP = close[1] > open[1]
        mtfRedC = close < open
        mtfGreenC = close > open

        mtfBearishIssShift = mtfRedP and mtfRedC and close < low[1]
        mtfBullishIssShift = mtfGreenP and mtfGreenC and close > high[1]

        mtfBullRetracement = mtfBearishIssShift
        mtfBearRetracement = mtfBullishIssShift

        mtfBearChoch = mtfTrend == 1 and mtfLastCLSet and mtfRedP and close[1] < mtfLastCL and close < mtfLastCL
        mtfBullChoch = mtfTrend == -1 and mtfLastCHSet and mtfGreenP and close[1] > mtfLastCH and close > mtfLastCH

        if mtfBearChoch
            mtfTrend := -1
            mtfStructureTrend := -1
            mtfPhase := 1
            mtfLastCH := mtfRunHigh
            mtfLastCHSet := true
            mtfRunHigh := high
            mtfRunHighBar := bar_index
            mtfRunLow := low
            mtfRunLowBar := bar_index
            mtfBullIssState := 1
            mtfBullIssBaseConfirmed := false
            mtfBullIssBaseLow := low
            mtfBullIssBaseLowBar := bar_index
            mtfBullIssRunHigh := high
            mtfBullIssRunHighBar := bar_index
            mtfBullIss1Level := na
            mtfBullIss1Bar := na
            mtfBullIssAfterBreakRunHigh := na
            mtfBullIssAfterBreakRunHighBar := na
            mtfBullIssAfterBreakRunLow := na
            mtfBullIssAfterBreakRunLowBar := na
            mtfBearIssState := 0
            mtfBearIssBaseConfirmed := false
            mtfBearIssBaseHigh := na
            mtfBearIssBaseHighBar := na
            mtfBearIssRunLow := na
            mtfBearIssRunLowBar := na
            mtfBearIss1Level := na
            mtfBearIss1Bar := na
            mtfBearIssAfterBreakRunLow := na
            mtfBearIssAfterBreakRunLowBar := na
            mtfBearIssAfterBreakRunHigh := na
            mtfBearIssAfterBreakRunHighBar := na
        else if mtfBullChoch
            mtfTrend := 1
            mtfStructureTrend := 1
            mtfPhase := 1
            mtfLastCL := mtfRunLow
            mtfLastCLSet := true
            mtfRunHigh := high
            mtfRunHighBar := bar_index
            mtfRunLow := low
            mtfRunLowBar := bar_index
            mtfBearIssState := 1
            mtfBearIssBaseConfirmed := false
            mtfBearIssBaseHigh := high
            mtfBearIssBaseHighBar := bar_index
            mtfBearIssRunLow := low
            mtfBearIssRunLowBar := bar_index
            mtfBearIss1Level := na
            mtfBearIss1Bar := na
            mtfBearIssAfterBreakRunLow := na
            mtfBearIssAfterBreakRunLowBar := na
            mtfBearIssAfterBreakRunHigh := na
            mtfBearIssAfterBreakRunHighBar := na
            mtfBullIssState := 0
            mtfBullIssBaseConfirmed := false
            mtfBullIssBaseLow := na
            mtfBullIssBaseLowBar := na
            mtfBullIssRunHigh := na
            mtfBullIssRunHighBar := na
            mtfBullIss1Level := na
            mtfBullIss1Bar := na
            mtfBullIssAfterBreakRunHigh := na
            mtfBullIssAfterBreakRunHighBar := na
            mtfBullIssAfterBreakRunLow := na
            mtfBullIssAfterBreakRunLowBar := na
        else
            if mtfTrend == 1 and mtfPhase == 2 and mtfLastCHSet and close > mtfLastCH
                mtfLastCL := mtfRunLow
                mtfLastCLSet := true
                mtfStructureTrend := 1
                mtfPhase := 1
                mtfRunHigh := high
                mtfRunHighBar := bar_index
                mtfRunLow := low
                mtfRunLowBar := bar_index
                mtfBearIssState := 1
                mtfBearIssBaseConfirmed := false
                mtfBearIssBaseHigh := high
                mtfBearIssBaseHighBar := bar_index
                mtfBearIssRunLow := low
                mtfBearIssRunLowBar := bar_index
                mtfBearIss1Level := na
                mtfBearIss1Bar := na
                mtfBearIssAfterBreakRunLow := na
                mtfBearIssAfterBreakRunLowBar := na
                mtfBearIssAfterBreakRunHigh := na
                mtfBearIssAfterBreakRunHighBar := na
                mtfBullIssState := 0
                mtfBullIssBaseConfirmed := false
                mtfBullIssBaseLow := na
                mtfBullIssBaseLowBar := na
                mtfBullIssRunHigh := na
                mtfBullIssRunHighBar := na
                mtfBullIss1Level := na
                mtfBullIss1Bar := na
                mtfBullIssAfterBreakRunHigh := na
                mtfBullIssAfterBreakRunHighBar := na
                mtfBullIssAfterBreakRunLow := na
                mtfBullIssAfterBreakRunLowBar := na
            else if mtfTrend == -1 and mtfPhase == 2 and mtfLastCLSet and close < mtfLastCL
                mtfLastCH := mtfRunHigh
                mtfLastCHSet := true
                mtfStructureTrend := -1
                mtfPhase := 1
                mtfRunHigh := high
                mtfRunHighBar := bar_index
                mtfRunLow := low
                mtfRunLowBar := bar_index
                mtfBullIssState := 1
                mtfBullIssBaseConfirmed := false
                mtfBullIssBaseLow := low
                mtfBullIssBaseLowBar := bar_index
                mtfBullIssRunHigh := high
                mtfBullIssRunHighBar := bar_index
                mtfBullIss1Level := na
                mtfBullIss1Bar := na
                mtfBullIssAfterBreakRunHigh := na
                mtfBullIssAfterBreakRunHighBar := na
                mtfBullIssAfterBreakRunLow := na
                mtfBullIssAfterBreakRunLowBar := na
                mtfBearIssState := 0
                mtfBearIssBaseConfirmed := false
                mtfBearIssBaseHigh := na
                mtfBearIssBaseHighBar := na
                mtfBearIssRunLow := na
                mtfBearIssRunLowBar := na
                mtfBearIss1Level := na
                mtfBearIss1Bar := na
                mtfBearIssAfterBreakRunLow := na
                mtfBearIssAfterBreakRunLowBar := na
                mtfBearIssAfterBreakRunHigh := na
                mtfBearIssAfterBreakRunHighBar := na
            else if mtfPhase == 1
                if mtfTrend != -1 and mtfBullRetracement
                    mtfLastCH := mtfRunHigh
                    mtfLastCHSet := true
                    mtfTrend := 1
                    mtfPhase := 2
                    if low < low[1]
                        mtfRunLow := low
                        mtfRunLowBar := bar_index
                    else
                        mtfRunLow := low[1]
                        mtfRunLowBar := bar_index - 1
                else if mtfTrend != 1 and mtfBearRetracement
                    mtfLastCL := mtfRunLow
                    mtfLastCLSet := true
                    mtfTrend := -1
                    mtfPhase := 2
                    if high > high[1]
                        mtfRunHigh := high
                        mtfRunHighBar := bar_index
                    else
                        mtfRunHigh := high[1]
                        mtfRunHighBar := bar_index - 1

        if inpEnableISS
            mtfBullIssInvalidated = mtfBullIssState >= 2 and not na(mtfBullIssBaseLow) and close < mtfBullIssBaseLow
            mtfBearIssInvalidated = mtfBearIssState >= 2 and not na(mtfBearIssBaseHigh) and close > mtfBearIssBaseHigh

            if mtfBullIssInvalidated
                mtfBullIssState := 0
                mtfBullIssBaseConfirmed := false
                mtfBullIssBaseLow := na
                mtfBullIssBaseLowBar := na
                mtfBullIssRunHigh := na
                mtfBullIssRunHighBar := na
                mtfBullIss1Level := na
                mtfBullIss1Bar := na
                mtfBullIssAfterBreakRunHigh := na
                mtfBullIssAfterBreakRunHighBar := na
                mtfBullIssAfterBreakRunLow := na
                mtfBullIssAfterBreakRunLowBar := na
            else if mtfBullIssState == 1
                if na(mtfBullIssBaseLow) or low < mtfBullIssBaseLow
                    mtfBullIssBaseLow := low
                    mtfBullIssBaseLowBar := bar_index
                    mtfBullIssRunHigh := high
                    mtfBullIssRunHighBar := bar_index
                    mtfBullIssBaseConfirmed := false
                if not mtfBullIssBaseConfirmed
                    if mtfBullishIssShift
                        mtfBullIssBaseConfirmed := true
                        mtfBullIssRunHigh := high
                        mtfBullIssRunHighBar := bar_index
                else
                    if na(mtfBullIssRunHigh) or high > mtfBullIssRunHigh
                        mtfBullIssRunHigh := high
                        mtfBullIssRunHighBar := bar_index
                    if mtfBearishIssShift and not na(mtfBullIssRunHighBar) and mtfBullIssRunHighBar < bar_index
                        mtfBullIss1Level := mtfBullIssRunHigh
                        mtfBullIss1Bar := mtfBullIssRunHighBar
                        mtfBullIssState := 2
            else if mtfBullIssState == 2
                if not na(mtfBullIss1Level) and close > mtfBullIss1Level
                    mtfBullIssAfterBreakRunHigh := high
                    mtfBullIssAfterBreakRunHighBar := bar_index
                    mtfBullIssAfterBreakRunLow := low
                    mtfBullIssAfterBreakRunLowBar := bar_index
                    mtfBullIssState := 3
            else if mtfBullIssState == 3
                if na(mtfBullIssAfterBreakRunHigh) or high > mtfBullIssAfterBreakRunHigh
                    mtfBullIssAfterBreakRunHigh := high
                    mtfBullIssAfterBreakRunHighBar := bar_index
                    mtfBullIssAfterBreakRunLow := low
                    mtfBullIssAfterBreakRunLowBar := bar_index
                else if na(mtfBullIssAfterBreakRunLow) or low < mtfBullIssAfterBreakRunLow
                    mtfBullIssAfterBreakRunLow := low
                    mtfBullIssAfterBreakRunLowBar := bar_index
                if mtfBearishIssShift and not na(mtfBullIssAfterBreakRunHighBar) and not na(mtfBullIssAfterBreakRunLowBar)
                    mtfBullIssState := 4
            else if mtfBullIssState == 4
                if na(mtfBullIssAfterBreakRunLow) or low < mtfBullIssAfterBreakRunLow
                    mtfBullIssAfterBreakRunLow := low
                    mtfBullIssAfterBreakRunLowBar := bar_index
                if not na(mtfBullIssAfterBreakRunHigh) and not na(mtfBullIssAfterBreakRunLowBar) and close > mtfBullIssAfterBreakRunHigh
                    mtfTrend := 1
                    mtfStructureTrend := 1
                    mtfPhase := 1
                    mtfBullIssState := 0
                    mtfBullIssBaseConfirmed := false
                    mtfBullIssBaseLow := na
                    mtfBullIssBaseLowBar := na
                    mtfBullIssRunHigh := na
                    mtfBullIssRunHighBar := na
                    mtfBullIss1Level := na
                    mtfBullIss1Bar := na
                    mtfBullIssAfterBreakRunHigh := na
                    mtfBullIssAfterBreakRunHighBar := na
                    mtfBullIssAfterBreakRunLow := na
                    mtfBullIssAfterBreakRunLowBar := na
                    mtfBearIssState := 0
                    mtfBearIssBaseConfirmed := false
                    mtfBearIssBaseHigh := na
                    mtfBearIssBaseHighBar := na
                    mtfBearIssRunLow := na
                    mtfBearIssRunLowBar := na
                    mtfBearIss1Level := na
                    mtfBearIss1Bar := na
                    mtfBearIssAfterBreakRunLow := na
                    mtfBearIssAfterBreakRunLowBar := na
                    mtfBearIssAfterBreakRunHigh := na
                    mtfBearIssAfterBreakRunHighBar := na

            if mtfBearIssInvalidated
                mtfBearIssState := 0
                mtfBearIssBaseConfirmed := false
                mtfBearIssBaseHigh := na
                mtfBearIssBaseHighBar := na
                mtfBearIssRunLow := na
                mtfBearIssRunLowBar := na
                mtfBearIss1Level := na
                mtfBearIss1Bar := na
                mtfBearIssAfterBreakRunLow := na
                mtfBearIssAfterBreakRunLowBar := na
                mtfBearIssAfterBreakRunHigh := na
                mtfBearIssAfterBreakRunHighBar := na
            else if mtfBearIssState == 1
                if na(mtfBearIssBaseHigh) or high > mtfBearIssBaseHigh
                    mtfBearIssBaseHigh := high
                    mtfBearIssBaseHighBar := bar_index
                    mtfBearIssRunLow := low
                    mtfBearIssRunLowBar := bar_index
                    mtfBearIssBaseConfirmed := false
                if not mtfBearIssBaseConfirmed
                    if mtfBearishIssShift
                        mtfBearIssBaseConfirmed := true
                        mtfBearIssRunLow := low
                        mtfBearIssRunLowBar := bar_index
                else
                    if na(mtfBearIssRunLow) or low < mtfBearIssRunLow
                        mtfBearIssRunLow := low
                        mtfBearIssRunLowBar := bar_index
                    if mtfBullishIssShift and not na(mtfBearIssRunLowBar) and mtfBearIssRunLowBar < bar_index
                        mtfBearIss1Level := mtfBearIssRunLow
                        mtfBearIss1Bar := mtfBearIssRunLowBar
                        mtfBearIssState := 2
            else if mtfBearIssState == 2
                if not na(mtfBearIss1Level) and close < mtfBearIss1Level
                    mtfBearIssAfterBreakRunLow := low
                    mtfBearIssAfterBreakRunLowBar := bar_index
                    mtfBearIssAfterBreakRunHigh := high
                    mtfBearIssAfterBreakRunHighBar := bar_index
                    mtfBearIssState := 3
            else if mtfBearIssState == 3
                if na(mtfBearIssAfterBreakRunLow) or low < mtfBearIssAfterBreakRunLow
                    mtfBearIssAfterBreakRunLow := low
                    mtfBearIssAfterBreakRunLowBar := bar_index
                    mtfBearIssAfterBreakRunHigh := high
                    mtfBearIssAfterBreakRunHighBar := bar_index
                else if na(mtfBearIssAfterBreakRunHigh) or high > mtfBearIssAfterBreakRunHigh
                    mtfBearIssAfterBreakRunHigh := high
                    mtfBearIssAfterBreakRunHighBar := bar_index
                if mtfBullishIssShift and not na(mtfBearIssAfterBreakRunLowBar) and not na(mtfBearIssAfterBreakRunHighBar)
                    mtfBearIssState := 4
            else if mtfBearIssState == 4
                if na(mtfBearIssAfterBreakRunHigh) or high > mtfBearIssAfterBreakRunHigh
                    mtfBearIssAfterBreakRunHigh := high
                    mtfBearIssAfterBreakRunHighBar := bar_index
                if not na(mtfBearIssAfterBreakRunLow) and not na(mtfBearIssAfterBreakRunHighBar) and close < mtfBearIssAfterBreakRunLow
                    mtfTrend := -1
                    mtfStructureTrend := -1
                    mtfPhase := 1
                    mtfBearIssState := 0
                    mtfBearIssBaseConfirmed := false
                    mtfBearIssBaseHigh := na
                    mtfBearIssBaseHighBar := na
                    mtfBearIssRunLow := na
                    mtfBearIssRunLowBar := na
                    mtfBearIss1Level := na
                    mtfBearIss1Bar := na
                    mtfBearIssAfterBreakRunLow := na
                    mtfBearIssAfterBreakRunLowBar := na
                    mtfBearIssAfterBreakRunHigh := na
                    mtfBearIssAfterBreakRunHighBar := na
                    mtfBullIssState := 0
                    mtfBullIssBaseConfirmed := false
                    mtfBullIssBaseLow := na
                    mtfBullIssBaseLowBar := na
                    mtfBullIssRunHigh := na
                    mtfBullIssRunHighBar := na
                    mtfBullIss1Level := na
                    mtfBullIss1Bar := na
                    mtfBullIssAfterBreakRunHigh := na
                    mtfBullIssAfterBreakRunHighBar := na
                    mtfBullIssAfterBreakRunLow := na
                    mtfBullIssAfterBreakRunLowBar := na

    mtfStructureTrend

f_dashEmaTrendCalc() =>
    dashEma = ta.ema(emaSrc, emaLen)
    close > dashEma ? 1 : close < dashEma ? -1 : 0

f_dashTfLabel(string tf) =>
    switch tf
        "1" => "1m"
        "3" => "3m"
        "5" => "5m"
        "15" => "15m"
        "30" => "30m"
        "45" => "45m"
        "60" => "1H"
        "120" => "2H"
        "180" => "3H"
        "240" => "4H"
        "D" => "1D"
        "1D" => "1D"
        "W" => "1W"
        "1W" => "1W"
        "M" => "1M"
        "1M" => "1M"
        => tf

f_dashTrendText(int dir) =>
    dir == 1 ? "BULLISH" : dir == -1 ? "BEARISH" : "NEUTRAL"

f_dashTrendColor(int dir) =>
    dir == 1 ? color.green : dir == -1 ? color.red : color.gray

// ==================================================================
// PERSISTENT STATE
// ==================================================================
var array<Level>    levels      = array.new<Level>()
var array<line>     drawnLines  = array.new<line>()
var array<label>    drawnLabels = array.new<label>()
var array<FVGLevel> fvgLevels   = array.new<FVGLevel>()
var array<OBLevel>  obLevels    = array.new<OBLevel>()
var line bullIssBos1Line = na
var line bearIssBos1Line = na

var int   trend = 0
var int   phase = 1
var table tfDashboard = table.new(position.top_right, 2, 14, border_width=1)

// FIX 2 & 3: Table rows increased from 16 → 19 (1 header + 17 data slots + 1 spare).
// Previously only 16 rows were allocated, but slots 0–16 need up to 18 rows.
var table levelAnalyzerTable = table.new(position.bottom_right, 5, 19, border_width=1)

// FIX 4, 5, 6: Arrays resized from 15 → 17 elements to cover all slots 0–16.
// Slots 15 ("BEST BUY QML") and 16 ("BEST SELL QML") previously caused
// "Index N is out of bounds, array size is 15" at runtime.
var array<int> levelAnalyzerTests  = array.new<int>(17, 0)
var array<int> levelAnalyzerWins   = array.new<int>(17, 0)
var array<int> levelAnalyzerLosses = array.new<int>(17, 0)

var Snap runHigh = f_initSnap()
var Snap runLow  = f_initSnap()
var Snap lastCH  = f_initSnap()
var Snap lastCL  = f_initSnap()
var Snap tjl1    = f_initSnap()
var Snap tjl2    = f_initSnap()
var bool runHighSet = false
var bool runLowSet  = false
var bool lastCHSet  = false
var bool lastCLSet  = false
var bool tjl1Set    = false

var int bullIssState = 0
var bool bullIssBaseConfirmed = false
var float bullIssBaseLow = na
var int bullIssBaseLowBar = na
var float bullIssRunHigh = na
var int bullIssRunHighBar = na
var float bullIss1Level = na
var int bullIss1Bar = na
var float bullIssAfterBreakRunHigh = na
var int bullIssAfterBreakRunHighBar = na
var float bullIssAfterBreakRunLow = na
var int bullIssAfterBreakRunLowBar = na
var array<int> bullIssBosBars = array.new<int>()
var array<float> bullIssBosLvls = array.new<float>()

var int bearIssState = 0
var bool bearIssBaseConfirmed = false
var float bearIssBaseHigh = na
var int bearIssBaseHighBar = na
var float bearIssRunLow = na
var int bearIssRunLowBar = na
var float bearIss1Level = na
var int bearIss1Bar = na
var float bearIssAfterBreakRunLow = na
var int bearIssAfterBreakRunLowBar = na
var float bearIssAfterBreakRunHigh = na
var int bearIssAfterBreakRunHighBar = na
var array<int> bearIssBosBars = array.new<int>()
var array<float> bearIssBosLvls = array.new<float>()

var int lastChochSide = 0
var bool issOrTjlSinceChoch = false
var int lastQmlLeft = na
var float lastQmlTop = na
var float lastQmlBot = na
var color lastQmlCol = na

var int startBarIndex = na
if na(startBarIndex) and time >= inpStartTime
    startBarIndex := bar_index
inWindow   = not na(startBarIndex) and bar_index >= startBarIndex and (bar_index - startBarIndex) <= inpMaxBars
enoughBars = bar_index >= 2

// ==================================================================
// KILL ZONES
// ==================================================================
utcH   = hour(time,   "UTC")
utcM   = minute(time, "UTC")
utcTot = utcH * 60 + utcM
isLondonKZ = utcTot >= 390 and utcTot < 480
isNYKZ     = utcTot >= 750 and utcTot < 870
bgcolor(inpShowKZ and isLondonKZ ? inpLondonColor : na, title="London Kill Zone")
bgcolor(inpShowKZ and isNYKZ     ? inpNYColor     : na, title="New York Kill Zone")

// ==================================================================
// MAIN LOGIC
// ==================================================================
if inWindow and enoughBars
    f_updateLevels(levels, close, high, low, bar_index, levelAnalyzerTests, levelAnalyzerWins, levelAnalyzerLosses)

    if inpShowFVG and array.size(fvgLevels) > 0
        for i = 0 to array.size(fvgLevels) - 1
            fv = array.get(fvgLevels, i)
            if fv.deleted
                continue
            fv.right := bar_index
            if inpFVGDeleteOnTap and bar_index > fv.left
                fvTapped = inpTapSource == tapByClose ? (close >= fv.bot and close <= fv.top) : (low <= fv.top and high >= fv.bot)
                if fvTapped
                    fv.active  := false
                    fv.deleted := true
                    if not na(fv.bx)
                        box.delete(fv.bx)
                    array.set(fvgLevels, i, fv)
                    continue
            if not na(fv.bx)
                box.set_right(fv.bx, bar_index)
            array.set(fvgLevels, i, fv)

    if inpShowOB and array.size(obLevels) > 0
        for i = 0 to array.size(obLevels) - 1
            ob = array.get(obLevels, i)
            if ob.deleted
                continue
            ob.right := bar_index
            if inpOBDeleteOnTap and bar_index > ob.left
                obTapped = inpTapSource == tapByClose ? (close >= ob.bot and close <= ob.top) : (low <= ob.top and high >= ob.bot)
                if obTapped
                    ob.active  := false
                    ob.deleted := true
                    if not na(ob.bx)
                        box.delete(ob.bx)
                    array.set(obLevels, i, ob)
                    continue
            if not na(ob.bx)
                box.set_right(ob.bx, bar_index)
            array.set(obLevels, i, ob)

    if not runHighSet or high > runHigh.lvl
        runHigh    := f_makeSnapCurrent(high)
        runHighSet := true
    if not runLowSet or low < runLow.lvl
        runLow    := f_makeSnapCurrent(low)
        runLowSet := true

    redP   = close[1] < open[1]
    greenP = close[1] > open[1]
    redC   = close < open
    greenC = close > open

    // ISS confirmation uses two same-direction candles. The second candle must
    // close through the first candle's wick.
    bearishIssShift = redP and redC and close < low[1]
    bullishIssShift = greenP and greenC and close > high[1]

    bullRetracement = bearishIssShift
    bearRetracement = bullishIssShift

    bearChoch = trend ==  1 and lastCLSet and redP   and close[1] < lastCL.lvl and close < lastCL.lvl
    bullChoch = trend == -1 and lastCHSet and greenP and close[1] > lastCH.lvl and close > lastCH.lvl

    if bearChoch
        dualChochHit = lastChochSide == -1 and not issOrTjlSinceChoch
        if inpShowCHOCH
            ln = line.new(lastCL.bar, lastCL.lvl, bar_index, lastCL.lvl, xloc=xloc.bar_index, extend=extend.none, color=inpCHColor, style=line.style_dashed, width=inpLineWidth)
            f_pushLine(drawnLines, ln)
        if tjl1Set
            f_deleteLatestTJL1ByLeft(levels, tjl1.bar)
        if dualChochHit
            f_promoteLastChochLevelsToBest(levels, lastQmlLeft)
        else
            if inpKeepOnlyLastCHOCH
                f_freezePreviousCHOCHLevels(levels)
            if inpShowLevels
                clOffset = bar_index - lastCL.bar
                rhOffset = bar_index - runHigh.bar
                f_addLevel(levels, lastCL.bar, open[clOffset], close[clOffset], high[clOffset], low[clOffset], false, inpSBRColor, "SBR", 3, bar_index, bar_index)
                if runHigh.bar != tjl1.bar
                    f_addLevel(levels, runHigh.bar, open[rhOffset], close[rhOffset], high[rhOffset], low[rhOffset], true, inpDTDBColor, "DT", 5, bar_index, bar_index)
                if tjl1Set
                    tjOffset = bar_index - tjl1.bar
                    [tjTop, tjBot] = f_candleZone(open[tjOffset], close[tjOffset], high[tjOffset], low[tjOffset], true)
                    f_addLevel(levels, tjl1.bar, open[tjOffset], close[tjOffset], high[tjOffset], low[tjOffset], true, inpQMLColor, "SELL QML", 7, bar_index, bar_index)
                    lastQmlLeft := tjl1.bar
                    lastQmlTop := tjTop
                    lastQmlBot := tjBot
                    lastQmlCol := inpQMLColor
        if inpShowOB
            obOff = -1
            for i = 1 to 10
                if close[i] > open[i]
                    obOff := i
                    break
            if obOff != -1
                obBar = bar_index - obOff
                obTop = high[obOff]
                obBot = open[obOff]
                if obTop > obBot
                    bx = box.new(obBar, obTop, bar_index, obBot, xloc=xloc.bar_index, border_color=inpBearOBColor, bgcolor=inpBearOBColor, text="S.OB", text_color=color.white, text_size=size.tiny, text_halign=text.align_right, text_valign=text.align_center)
                    ob = OBLevel.new(obBar, bar_index, obTop, obBot, false, true, false, bx)
                    array.push(obLevels, ob)
        trend     := -1
        phase     := 1
        lastCH    := f_makeSnapAtBar(runHigh.bar, runHigh.lvl)
        lastCHSet := true
        runHigh   := f_makeSnapCurrent(high)
        runLow    := f_makeSnapCurrent(low)
        lastChochSide := 1
        issOrTjlSinceChoch := false

        // Bearish external structure: arm bullish ISS from a candidate low.
        if not na(bullIssBos1Line)
            line.delete(bullIssBos1Line)
            bullIssBos1Line := na
        if not na(bearIssBos1Line)
            line.delete(bearIssBos1Line)
            bearIssBos1Line := na
        bullIssState := 1
        bullIssBaseConfirmed := false
        bullIssBaseLow := low
        bullIssBaseLowBar := bar_index
        bullIssRunHigh := high
        bullIssRunHighBar := bar_index
        bullIss1Level := na
        bullIss1Bar := na
        bullIssAfterBreakRunHigh := na
        bullIssAfterBreakRunHighBar := na
        bullIssAfterBreakRunLow := na
        bullIssAfterBreakRunLowBar := na
        array.clear(bullIssBosBars)
        array.clear(bullIssBosLvls)
        bearIssState := 0
        bearIssBaseConfirmed := false
        bearIssBaseHigh := na
        bearIssBaseHighBar := na
        bearIssRunLow := na
        bearIssRunLowBar := na
        bearIss1Level := na
        bearIss1Bar := na
        bearIssAfterBreakRunLow := na
        bearIssAfterBreakRunLowBar := na
        bearIssAfterBreakRunHigh := na
        bearIssAfterBreakRunHighBar := na
        array.clear(bearIssBosBars)
        array.clear(bearIssBosLvls)

    else if bullChoch
        dualChochHit = lastChochSide == 1 and not issOrTjlSinceChoch
        if inpShowCHOCH
            ln = line.new(lastCH.bar, lastCH.lvl, bar_index, lastCH.lvl, xloc=xloc.bar_index, extend=extend.none, color=inpCHColor, style=line.style_dashed, width=inpLineWidth)
            f_pushLine(drawnLines, ln)
        if tjl1Set
            f_deleteLatestTJL1ByLeft(levels, tjl1.bar)
        if dualChochHit
            f_promoteLastChochLevelsToBest(levels, lastQmlLeft)
        else
            if inpKeepOnlyLastCHOCH
                f_freezePreviousCHOCHLevels(levels)
            if inpShowLevels
                chOffset = bar_index - lastCH.bar
                rlOffset = bar_index - runLow.bar
                f_addLevel(levels, lastCH.bar, open[chOffset], close[chOffset], high[chOffset], low[chOffset], true, inpRBSColor, "RBS", 4, bar_index, bar_index)
                if runLow.bar != tjl1.bar
                    f_addLevel(levels, runLow.bar, open[rlOffset], close[rlOffset], high[rlOffset], low[rlOffset], false, inpDTDBColor, "DB", 6, bar_index, bar_index)
                if tjl1Set
                    tjOffset = bar_index - tjl1.bar
                    [tjTop, tjBot] = f_candleZone(open[tjOffset], close[tjOffset], high[tjOffset], low[tjOffset], false)
                    f_addLevel(levels, tjl1.bar, open[tjOffset], close[tjOffset], high[tjOffset], low[tjOffset], false, inpQMLColor, "BUY QML", 7, bar_index, bar_index)
                    lastQmlLeft := tjl1.bar
                    lastQmlTop := tjTop
                    lastQmlBot := tjBot
                    lastQmlCol := inpQMLColor
        if inpShowOB
            obOff = -1
            for i = 1 to 10
                if close[i] < open[i]
                    obOff := i
                    break
            if obOff != -1
                obBar = bar_index - obOff
                obTop = open[obOff]
                obBot = low[obOff]
                if obTop > obBot
                    bx = box.new(obBar, obTop, bar_index, obBot, xloc=xloc.bar_index, border_color=inpBullOBColor, bgcolor=inpBullOBColor, text="D.OB", text_color=color.white, text_size=size.tiny, text_halign=text.align_right, text_valign=text.align_center)
                    ob = OBLevel.new(obBar, bar_index, obTop, obBot, true, true, false, bx)
                    array.push(obLevels, ob)
        trend     := 1
        phase     := 1
        lastCL    := f_makeSnapAtBar(runLow.bar, runLow.lvl)
        lastCLSet := true
        runHigh   := f_makeSnapCurrent(high)
        runLow    := f_makeSnapCurrent(low)
        lastChochSide := -1
        issOrTjlSinceChoch := false

        // Bullish external structure: arm bearish ISS from a candidate high.
        if not na(bullIssBos1Line)
            line.delete(bullIssBos1Line)
            bullIssBos1Line := na
        if not na(bearIssBos1Line)
            line.delete(bearIssBos1Line)
            bearIssBos1Line := na
        bearIssState := 1
        bearIssBaseConfirmed := false
        bearIssBaseHigh := high
        bearIssBaseHighBar := bar_index
        bearIssRunLow := low
        bearIssRunLowBar := bar_index
        bearIss1Level := na
        bearIss1Bar := na
        bearIssAfterBreakRunLow := na
        bearIssAfterBreakRunLowBar := na
        bearIssAfterBreakRunHigh := na
        bearIssAfterBreakRunHighBar := na
        array.clear(bearIssBosBars)
        array.clear(bearIssBosLvls)
        bullIssState := 0
        bullIssBaseConfirmed := false
        bullIssBaseLow := na
        bullIssBaseLowBar := na
        bullIssRunHigh := na
        bullIssRunHighBar := na
        bullIss1Level := na
        bullIss1Bar := na
        bullIssAfterBreakRunHigh := na
        bullIssAfterBreakRunHighBar := na
        bullIssAfterBreakRunLow := na
        bullIssAfterBreakRunLowBar := na
        array.clear(bullIssBosBars)
        array.clear(bullIssBosLvls)

    else
        if trend == 1 and phase == 2 and lastCHSet and close > lastCH.lvl
            if inpShowBOS
                ln = line.new(lastCH.bar, lastCH.lvl, bar_index, lastCH.lvl, xloc=xloc.bar_index, extend=extend.none, color=inpBullBOSColor, style=line.style_solid, width=inpLineWidth)
                f_pushLine(drawnLines, ln)
            lastCL := f_makeSnapAtBar(runLow.bar, runLow.lvl)
            lastCLSet := true
            chOff2 = bar_index - lastCH.bar
            tjl1 := f_makeSnapAtBar(lastCH.bar, lastCH.lvl)
            tjl2 := f_makeSnapAtBar(lastCL.bar, lastCL.lvl)
            tjl1Set := true
            if inpShowTJL
                f_addLevel(levels, tjl1.bar, open[chOff2], close[chOff2], high[chOff2], low[chOff2], true, inpBullTJLColor, "TJL1", 1, bar_index, bar_index)
                clOff2 = bar_index - lastCL.bar
                f_addLevel(levels, tjl2.bar, open[clOff2], close[clOff2], high[clOff2], low[clOff2], false, inpBullTJLColor, "TJL2", 2, bar_index, bar_index)
                issOrTjlSinceChoch := true
            if inpShowOB
                obOff = -1
                for i = 1 to 10
                    if close[i] < open[i]
                        obOff := i
                        break
                if obOff != -1
                    obBar = bar_index - obOff
                    obTop = open[obOff]
                    obBot = low[obOff]
                    if obTop > obBot
                        bx = box.new(obBar, obTop, bar_index, obBot, xloc=xloc.bar_index, border_color=inpBullOBColor, bgcolor=inpBullOBColor, text="D.OB", text_color=color.white, text_size=size.tiny, text_halign=text.align_right, text_valign=text.align_center)
                        ob = OBLevel.new(obBar, bar_index, obTop, obBot, true, true, false, bx)
                        array.push(obLevels, ob)
            phase   := 1
            runHigh := f_makeSnapCurrent(high)
            runLow  := f_makeSnapCurrent(low)

            if not na(bullIssBos1Line)
                line.delete(bullIssBos1Line)
                bullIssBos1Line := na
            if not na(bearIssBos1Line)
                line.delete(bearIssBos1Line)
                bearIssBos1Line := na
            bearIssState := 1
            bearIssBaseConfirmed := false
            bearIssBaseHigh := high
            bearIssBaseHighBar := bar_index
            bearIssRunLow := low
            bearIssRunLowBar := bar_index
            bearIss1Level := na
            bearIss1Bar := na
            bearIssAfterBreakRunLow := na
            bearIssAfterBreakRunLowBar := na
            bearIssAfterBreakRunHigh := na
            bearIssAfterBreakRunHighBar := na
            array.clear(bearIssBosBars)
            array.clear(bearIssBosLvls)
            bullIssState := 0
            bullIssBaseConfirmed := false
            bullIssBaseLow := na
            bullIssBaseLowBar := na
            bullIssRunHigh := na
            bullIssRunHighBar := na
            bullIss1Level := na
            bullIss1Bar := na
            bullIssAfterBreakRunHigh := na
            bullIssAfterBreakRunHighBar := na
            bullIssAfterBreakRunLow := na
            bullIssAfterBreakRunLowBar := na
            array.clear(bullIssBosBars)
            array.clear(bullIssBosLvls)

        else if trend == -1 and phase == 2 and lastCLSet and close < lastCL.lvl
            if inpShowBOS
                ln = line.new(lastCL.bar, lastCL.lvl, bar_index, lastCL.lvl, xloc=xloc.bar_index, extend=extend.none, color=inpBearBOSColor, style=line.style_solid, width=inpLineWidth)
                f_pushLine(drawnLines, ln)
            lastCH := f_makeSnapAtBar(runHigh.bar, runHigh.lvl)
            lastCHSet := true
            clOff2 = bar_index - lastCL.bar
            tjl1 := f_makeSnapAtBar(lastCL.bar, lastCL.lvl)
            tjl2 := f_makeSnapAtBar(lastCH.bar, lastCH.lvl)
            tjl1Set := true
            if inpShowTJL
                f_addLevel(levels, tjl1.bar, open[clOff2], close[clOff2], high[clOff2], low[clOff2], false, inpBearTJLColor, "TJL1", 1, bar_index, bar_index)
                chOff2 = bar_index - lastCH.bar
                f_addLevel(levels, tjl2.bar, open[chOff2], close[chOff2], high[chOff2], low[chOff2], true, inpBearTJLColor, "TJL2", 2, bar_index, bar_index)
                issOrTjlSinceChoch := true
            if inpShowOB
                obOff = -1
                for i = 1 to 10
                    if close[i] > open[i]
                        obOff := i
                        break
                if obOff != -1
                    obBar = bar_index - obOff
                    obTop = high[obOff]
                    obBot = open[obOff]
                    if obTop > obBot
                        bx = box.new(obBar, obTop, bar_index, obBot, xloc=xloc.bar_index, border_color=inpBearOBColor, bgcolor=inpBearOBColor, text="S.OB", text_color=color.white, text_size=size.tiny, text_halign=text.align_right, text_valign=text.align_center)
                        ob = OBLevel.new(obBar, bar_index, obTop, obBot, false, true, false, bx)
                        array.push(obLevels, ob)
            phase   := 1
            runHigh := f_makeSnapCurrent(high)
            runLow  := f_makeSnapCurrent(low)

            if not na(bullIssBos1Line)
                line.delete(bullIssBos1Line)
                bullIssBos1Line := na
            if not na(bearIssBos1Line)
                line.delete(bearIssBos1Line)
                bearIssBos1Line := na
            bullIssState := 1
            bullIssBaseConfirmed := false
            bullIssBaseLow := low
            bullIssBaseLowBar := bar_index
            bullIssRunHigh := high
            bullIssRunHighBar := bar_index
            bullIss1Level := na
            bullIss1Bar := na
            bullIssAfterBreakRunHigh := na
            bullIssAfterBreakRunHighBar := na
            bullIssAfterBreakRunLow := na
            bullIssAfterBreakRunLowBar := na
            array.clear(bullIssBosBars)
            array.clear(bullIssBosLvls)
            bearIssState := 0
            bearIssBaseConfirmed := false
            bearIssBaseHigh := na
            bearIssBaseHighBar := na
            bearIssRunLow := na
            bearIssRunLowBar := na
            bearIss1Level := na
            bearIss1Bar := na
            bearIssAfterBreakRunLow := na
            bearIssAfterBreakRunLowBar := na
            bearIssAfterBreakRunHigh := na
            bearIssAfterBreakRunHighBar := na
            array.clear(bearIssBosBars)
            array.clear(bearIssBosLvls)

        else if phase == 1
            if trend != -1 and bullRetracement
                lastCH := f_makeSnapAtBar(runHigh.bar, runHigh.lvl)
                lastCHSet := true
                trend := 1
                phase := 2
                if inpShowSwings
                    lb = label.new(lastCH.bar, lastCH.lvl, "CH", xloc=xloc.bar_index, style=label.style_none, textcolor=inpCHColor, size=size.small)
                    f_pushLabel(drawnLabels, lb)
                runLow := low < low[1] ? f_makeSnapCurrent(low) : f_makeSnapAtBar(bar_index - 1, low[1])
            else if trend != 1 and bearRetracement
                lastCL := f_makeSnapAtBar(runLow.bar, runLow.lvl)
                lastCLSet := true
                trend := -1
                phase := 2
                if inpShowSwings
                    lb = label.new(lastCL.bar, lastCL.lvl, "CL", xloc=xloc.bar_index, style=label.style_none, textcolor=inpCLColor, size=size.small)
                    f_pushLabel(drawnLabels, lb)
                runHigh := high > high[1] ? f_makeSnapCurrent(high) : f_makeSnapAtBar(bar_index - 1, high[1])

    // ==================================================================
    // ISS STATE MACHINE
    // ==================================================================
    if inpEnableISS
        bullIssInvalidated = bullIssState >= 2 and not na(bullIssBaseLow) and close < bullIssBaseLow
        bearIssInvalidated = bearIssState >= 2 and not na(bearIssBaseHigh) and close > bearIssBaseHigh

        if bullIssInvalidated
            if not na(bullIssBos1Line)
                line.delete(bullIssBos1Line)
                bullIssBos1Line := na
            bullIssState := 0
            bullIssBaseConfirmed := false
            bullIssBaseLow := na
            bullIssBaseLowBar := na
            bullIssRunHigh := na
            bullIssRunHighBar := na
            bullIss1Level := na
            bullIss1Bar := na
            bullIssAfterBreakRunHigh := na
            bullIssAfterBreakRunHighBar := na
            bullIssAfterBreakRunLow := na
            bullIssAfterBreakRunLowBar := na
            array.clear(bullIssBosBars)
            array.clear(bullIssBosLvls)
        else if bullIssState == 1
            if na(bullIssBaseLow) or low < bullIssBaseLow
                bullIssBaseLow := low
                bullIssBaseLowBar := bar_index
                bullIssRunHigh := high
                bullIssRunHighBar := bar_index
                bullIssBaseConfirmed := false
            if not bullIssBaseConfirmed
                if bullishIssShift
                    bullIssBaseConfirmed := true
                    bullIssRunHigh := high
                    bullIssRunHighBar := bar_index
            else
                if na(bullIssRunHigh) or high > bullIssRunHigh
                    bullIssRunHigh := high
                    bullIssRunHighBar := bar_index
                if bearishIssShift and not na(bullIssRunHighBar) and bullIssRunHighBar < bar_index
                    bullIss1Level := bullIssRunHigh
                    bullIss1Bar := bullIssRunHighBar
                    bullIssState := 2
        else if bullIssState == 2
            if not na(bullIss1Level) and close > bullIss1Level
                array.push(bullIssBosBars, bullIss1Bar)
                array.push(bullIssBosLvls, bullIss1Level)
                if inpShowISSBOS
                    bullIssBos1Line := line.new(bullIss1Bar, bullIss1Level, bar_index, bullIss1Level, xloc=xloc.bar_index, extend=extend.none, color=inpISSColor, style=line.style_solid, width=inpLineWidth)
                    f_pushLine(drawnLines, bullIssBos1Line)
                bullIssAfterBreakRunHigh := high
                bullIssAfterBreakRunHighBar := bar_index
                bullIssAfterBreakRunLow := low
                bullIssAfterBreakRunLowBar := bar_index
                bullIssState := 3
        else if bullIssState == 3
            if na(bullIssAfterBreakRunHigh) or high > bullIssAfterBreakRunHigh
                bullIssAfterBreakRunHigh := high
                bullIssAfterBreakRunHighBar := bar_index
                bullIssAfterBreakRunLow := low
                bullIssAfterBreakRunLowBar := bar_index
            else if na(bullIssAfterBreakRunLow) or low < bullIssAfterBreakRunLow
                bullIssAfterBreakRunLow := low
                bullIssAfterBreakRunLowBar := bar_index
            if bearishIssShift and not na(bullIssAfterBreakRunHighBar) and not na(bullIssAfterBreakRunLowBar)
                bullIssState := 4
        else if bullIssState == 4
            if na(bullIssAfterBreakRunLow) or low < bullIssAfterBreakRunLow
                bullIssAfterBreakRunLow := low
                bullIssAfterBreakRunLowBar := bar_index
            if not na(bullIssAfterBreakRunHigh) and not na(bullIssAfterBreakRunLowBar) and close > bullIssAfterBreakRunHigh
                array.push(bullIssBosBars, bullIssAfterBreakRunHighBar)
                array.push(bullIssBosLvls, bullIssAfterBreakRunHigh)
                if inpShowISSBOS
                    ln = line.new(bullIssAfterBreakRunHighBar, bullIssAfterBreakRunHigh, bar_index, bullIssAfterBreakRunHigh, xloc=xloc.bar_index, extend=extend.none, color=inpISSColor, style=line.style_solid, width=inpLineWidth)
                    f_pushLine(drawnLines, ln)
                if inpShowISS and inpShowISSLabel
                    lb = label.new(bullIssBaseLowBar, bullIssBaseLow, "ISS", xloc=xloc.bar_index, style=label.style_none, textcolor=inpISSColor, size=size.normal)
                    f_pushLabel(drawnLabels, lb)
                    issOrTjlSinceChoch := true
                if inpShowLevels and inpShowISS1
                    f_addLevelFromBarReady(levels, bullIss1Bar, bullIss1Bar, true, inpISSColor, "ISS 1", 29, bar_index, bar_index, bar_index)
                if inpShowLevels and inpShowISS3
                    f_addLevelFromBarReady(levels, bullIssAfterBreakRunHighBar, bullIssAfterBreakRunHighBar, true, inpISSColor, "ISS 3", 30, bar_index, bar_index, bar_index)
                if inpShowLevels and inpShowISS4
                    f_addLevelFromBarReady(levels, bullIssAfterBreakRunLowBar, bullIssAfterBreakRunLowBar, false, inpISSColor, "ISS 4", 31, bar_index, bar_index, bar_index)
                // Promote the confirmed bullish ISS swing into the main structure.
                // This makes the next CHOCH use the ISS internal pivots for QML.
                trend := 1
                phase := 1
                lastCH := f_makeSnapAtBar(bullIssAfterBreakRunHighBar, bullIssAfterBreakRunHigh)
                lastCL := f_makeSnapAtBar(bullIssAfterBreakRunLowBar, bullIssAfterBreakRunLow)
                lastCHSet := true
                lastCLSet := true
                tjl1 := f_makeSnapAtBar(bullIssAfterBreakRunHighBar, bullIssAfterBreakRunHigh)
                tjl2 := f_makeSnapAtBar(bullIssAfterBreakRunLowBar, bullIssAfterBreakRunLow)
                tjl1Set := true
                runHigh := f_makeSnapCurrent(high)
                runLow := f_makeSnapCurrent(low)
                issOrTjlSinceChoch := true
                bullIssState := 0
                bullIssBaseConfirmed := false
                bullIssBaseLow := na
                bullIssBaseLowBar := na
                bullIssRunHigh := na
                bullIssRunHighBar := na
                bullIss1Level := na
                bullIss1Bar := na
                bullIssAfterBreakRunHigh := na
                bullIssAfterBreakRunHighBar := na
                bullIssAfterBreakRunLow := na
                bullIssAfterBreakRunLowBar := na
                array.clear(bullIssBosBars)
                array.clear(bullIssBosLvls)
                bullIssBos1Line := na
                bearIssState := 0
                bearIssBaseConfirmed := false
                bearIssBaseHigh := na
                bearIssBaseHighBar := na
                bearIssRunLow := na
                bearIssRunLowBar := na
                bearIss1Level := na
                bearIss1Bar := na
                bearIssAfterBreakRunLow := na
                bearIssAfterBreakRunLowBar := na
                bearIssAfterBreakRunHigh := na
                bearIssAfterBreakRunHighBar := na
                array.clear(bearIssBosBars)
                array.clear(bearIssBosLvls)

        if bearIssInvalidated
            if not na(bearIssBos1Line)
                line.delete(bearIssBos1Line)
                bearIssBos1Line := na
            bearIssState := 0
            bearIssBaseConfirmed := false
            bearIssBaseHigh := na
            bearIssBaseHighBar := na
            bearIssRunLow := na
            bearIssRunLowBar := na
            bearIss1Level := na
            bearIss1Bar := na
            bearIssAfterBreakRunLow := na
            bearIssAfterBreakRunLowBar := na
            bearIssAfterBreakRunHigh := na
            bearIssAfterBreakRunHighBar := na
            array.clear(bearIssBosBars)
            array.clear(bearIssBosLvls)
        else if bearIssState == 1
            if na(bearIssBaseHigh) or high > bearIssBaseHigh
                bearIssBaseHigh := high
                bearIssBaseHighBar := bar_index
                bearIssRunLow := low
                bearIssRunLowBar := bar_index
                bearIssBaseConfirmed := false
            if not bearIssBaseConfirmed
                if bearishIssShift
                    bearIssBaseConfirmed := true
                    bearIssRunLow := low
                    bearIssRunLowBar := bar_index
            else
                if na(bearIssRunLow) or low < bearIssRunLow
                    bearIssRunLow := low
                    bearIssRunLowBar := bar_index
                if bullishIssShift and not na(bearIssRunLowBar) and bearIssRunLowBar < bar_index
                    bearIss1Level := bearIssRunLow
                    bearIss1Bar := bearIssRunLowBar
                    bearIssState := 2
        else if bearIssState == 2
            if not na(bearIss1Level) and close < bearIss1Level
                array.push(bearIssBosBars, bearIss1Bar)
                array.push(bearIssBosLvls, bearIss1Level)
                if inpShowISSBOS
                    bearIssBos1Line := line.new(bearIss1Bar, bearIss1Level, bar_index, bearIss1Level, xloc=xloc.bar_index, extend=extend.none, color=inpISSColor, style=line.style_solid, width=inpLineWidth)
                    f_pushLine(drawnLines, bearIssBos1Line)
                bearIssAfterBreakRunLow := low
                bearIssAfterBreakRunLowBar := bar_index
                bearIssAfterBreakRunHigh := high
                bearIssAfterBreakRunHighBar := bar_index
                bearIssState := 3
        else if bearIssState == 3
            if na(bearIssAfterBreakRunLow) or low < bearIssAfterBreakRunLow
                bearIssAfterBreakRunLow := low
                bearIssAfterBreakRunLowBar := bar_index
                bearIssAfterBreakRunHigh := high
                bearIssAfterBreakRunHighBar := bar_index
            else if na(bearIssAfterBreakRunHigh) or high > bearIssAfterBreakRunHigh
                bearIssAfterBreakRunHigh := high
                bearIssAfterBreakRunHighBar := bar_index
            if bullishIssShift and not na(bearIssAfterBreakRunLowBar) and not na(bearIssAfterBreakRunHighBar)
                bearIssState := 4
        else if bearIssState == 4
            if na(bearIssAfterBreakRunHigh) or high > bearIssAfterBreakRunHigh
                bearIssAfterBreakRunHigh := high
                bearIssAfterBreakRunHighBar := bar_index
            if not na(bearIssAfterBreakRunLow) and not na(bearIssAfterBreakRunHighBar) and close < bearIssAfterBreakRunLow
                array.push(bearIssBosBars, bearIssAfterBreakRunLowBar)
                array.push(bearIssBosLvls, bearIssAfterBreakRunLow)
                if inpShowISSBOS
                    ln = line.new(bearIssAfterBreakRunLowBar, bearIssAfterBreakRunLow, bar_index, bearIssAfterBreakRunLow, xloc=xloc.bar_index, extend=extend.none, color=inpISSColor, style=line.style_solid, width=inpLineWidth)
                    f_pushLine(drawnLines, ln)
                if inpShowISS and inpShowISSLabel
                    lb = label.new(bearIssBaseHighBar, bearIssBaseHigh, "ISS", xloc=xloc.bar_index, style=label.style_none, textcolor=inpISSColor, size=size.normal)
                    f_pushLabel(drawnLabels, lb)
                    issOrTjlSinceChoch := true
                if inpShowLevels and inpShowISS1
                    f_addLevelFromBarReady(levels, bearIss1Bar, bearIss1Bar, false, inpISSColor, "ISS 1", 29, bar_index, bar_index, bar_index)
                if inpShowLevels and inpShowISS3
                    f_addLevelFromBarReady(levels, bearIssAfterBreakRunLowBar, bearIssAfterBreakRunLowBar, false, inpISSColor, "ISS 3", 32, bar_index, bar_index, bar_index)
                if inpShowLevels and inpShowISS4
                    f_addLevelFromBarReady(levels, bearIssAfterBreakRunHighBar, bearIssAfterBreakRunHighBar, true, inpISSColor, "ISS 4", 33, bar_index, bar_index, bar_index)
                // Promote the confirmed bearish ISS swing into the main structure.
                // This makes the next CHOCH use the ISS internal pivots for QML.
                trend := -1
                phase := 1
                lastCH := f_makeSnapAtBar(bearIssAfterBreakRunHighBar, bearIssAfterBreakRunHigh)
                lastCL := f_makeSnapAtBar(bearIssAfterBreakRunLowBar, bearIssAfterBreakRunLow)
                lastCHSet := true
                lastCLSet := true
                tjl1 := f_makeSnapAtBar(bearIssAfterBreakRunLowBar, bearIssAfterBreakRunLow)
                tjl2 := f_makeSnapAtBar(bearIssAfterBreakRunHighBar, bearIssAfterBreakRunHigh)
                tjl1Set := true
                runHigh := f_makeSnapCurrent(high)
                runLow := f_makeSnapCurrent(low)
                issOrTjlSinceChoch := true
                bearIssState := 0
                bearIssBaseConfirmed := false
                bearIssBaseHigh := na
                bearIssBaseHighBar := na
                bearIssRunLow := na
                bearIssRunLowBar := na
                bearIss1Level := na
                bearIss1Bar := na
                bearIssAfterBreakRunLow := na
                bearIssAfterBreakRunLowBar := na
                bearIssAfterBreakRunHigh := na
                bearIssAfterBreakRunHighBar := na
                array.clear(bearIssBosBars)
                array.clear(bearIssBosLvls)
                bearIssBos1Line := na
                bullIssState := 0
                bullIssBaseConfirmed := false
                bullIssBaseLow := na
                bullIssBaseLowBar := na
                bullIssRunHigh := na
                bullIssRunHighBar := na
                bullIss1Level := na
                bullIss1Bar := na
                bullIssAfterBreakRunHigh := na
                bullIssAfterBreakRunHighBar := na
                bullIssAfterBreakRunLow := na
                bullIssAfterBreakRunLowBar := na
                array.clear(bullIssBosBars)
                array.clear(bullIssBosLvls)

    if inpShowFVG
        bullFVGForm = low > high[2]
        bearFVGForm = high < low[2]
        if bullFVGForm
            fvgTop = low
            fvgBot = high[2]
            if fvgTop > fvgBot
                bx = box.new(bar_index - 2, fvgTop, bar_index, fvgBot, xloc=xloc.bar_index, border_color=inpBullFVGColor, bgcolor=inpBullFVGColor, text="FVG", text_color=color.white, text_size=size.tiny, text_halign=text.align_right, text_valign=text.align_center)
                fv = FVGLevel.new(bar_index - 2, bar_index, fvgTop, fvgBot, true, true, false, bx)
                array.push(fvgLevels, fv)
        if bearFVGForm
            fvgTop = low[2]
            fvgBot = high
            if fvgTop > fvgBot
                bx = box.new(bar_index - 2, fvgTop, bar_index, fvgBot, xloc=xloc.bar_index, border_color=inpBearFVGColor, bgcolor=inpBearFVGColor, text="FVG", text_color=color.white, text_size=size.tiny, text_halign=text.align_right, text_valign=text.align_center)
                fv = FVGLevel.new(bar_index - 2, bar_index, fvgTop, fvgBot, false, true, false, bx)
                array.push(fvgLevels, fv)

    f_trimLevels(levels)

    if inpShowFVG and array.size(fvgLevels) > 0
        kept = 0
        for i = array.size(fvgLevels) - 1 to 0
            fv = array.get(fvgLevels, i)
            if fv.deleted
                continue
            kept += 1
            if kept > inpMaxFVG
                fv.deleted := true
                fv.active  := false
                if not na(fv.bx)
                    box.delete(fv.bx)
                array.set(fvgLevels, i, fv)

    if inpShowOB and array.size(obLevels) > 0
        kept = 0
        for i = array.size(obLevels) - 1 to 0
            ob = array.get(obLevels, i)
            if ob.deleted
                continue
            kept += 1
            if kept > inpMaxOB
                ob.deleted := true
                ob.active  := false
                if not na(ob.bx)
                    box.delete(ob.bx)
                array.set(obLevels, i, ob)

    drawn = 0
    if array.size(levels) > 0
        for j = array.size(levels) - 1 to 0
            if drawn >= inpMaxLiveLevels
                break
            lv = array.get(levels, j)
            if lv.deleted
                continue
            if not f_shouldShowLevel(lv.kind)
                continue
            if na(lv.bx)
                lv.bx := box.new(lv.left, lv.top, lv.right, lv.bot, xloc=xloc.bar_index, border_color=lv.col, bgcolor=color.new(lv.col, 75), text=lv.txt, text_color=lv.col, text_size=size.small, text_halign=f_levelTextHAlign(), text_valign=f_levelTextVAlign())
            else
                box.set_lefttop(lv.bx, lv.left, lv.top)
                box.set_rightbottom(lv.bx, lv.right, lv.bot)
                box.set_border_color(lv.bx, lv.col)
                box.set_bgcolor(lv.bx, color.new(lv.col, 75))
            f_applyLevelText(lv.bx, lv.txt, lv.col)
            if not na(lv.lb)
                label.delete(lv.lb)
                lv.lb := na
            array.set(levels, j, lv)
            drawn += 1

dashTrend1 = request.security(syminfo.tickerid, inpDashTf1, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend2 = request.security(syminfo.tickerid, inpDashTf2, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend3 = request.security(syminfo.tickerid, inpDashTf3, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend4 = request.security(syminfo.tickerid, inpDashTf4, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend5 = request.security(syminfo.tickerid, inpDashTf5, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend6 = request.security(syminfo.tickerid, inpDashTf6, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend7 = request.security(syminfo.tickerid, inpDashTf7, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend8 = request.security(syminfo.tickerid, inpDashTf8, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend9 = request.security(syminfo.tickerid, inpDashTf9, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend10 = request.security(syminfo.tickerid, inpDashTf10, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend11 = request.security(syminfo.tickerid, inpDashTf11, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend12 = request.security(syminfo.tickerid, inpDashTf12, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)
dashTrend13 = request.security(syminfo.tickerid, inpDashTf13, f_dashEmaTrendCalc(), lookahead=barmerge.lookahead_off)

if barstate.islast
    table.clear(tfDashboard, 0, 0, 1, 13)
    if inpShowTrendDash
        headerBg = color.rgb(30, 30, 30)
        tfCellBg = color.rgb(18, 18, 18)
        table.cell(tfDashboard, 0, 0, "TIMEFRAME", text_color=color.white, bgcolor=headerBg, text_size=size.small)
        table.cell(tfDashboard, 1, 0, "TREND", text_color=color.white, bgcolor=headerBg, text_size=size.small)
        dashRow = 1
        if inpDashShowTf1
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf1), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend1), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend1), text_size=size.small)
            dashRow += 1
        if inpDashShowTf2
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf2), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend2), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend2), text_size=size.small)
            dashRow += 1
        if inpDashShowTf3
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf3), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend3), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend3), text_size=size.small)
            dashRow += 1
        if inpDashShowTf4
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf4), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend4), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend4), text_size=size.small)
            dashRow += 1
        if inpDashShowTf5
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf5), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend5), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend5), text_size=size.small)
            dashRow += 1
        if inpDashShowTf6
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf6), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend6), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend6), text_size=size.small)
            dashRow += 1
        if inpDashShowTf7
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf7), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend7), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend7), text_size=size.small)
            dashRow += 1
        if inpDashShowTf8
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf8), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend8), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend8), text_size=size.small)
            dashRow += 1
        if inpDashShowTf9
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf9), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend9), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend9), text_size=size.small)
            dashRow += 1
        if inpDashShowTf10
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf10), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend10), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend10), text_size=size.small)
            dashRow += 1
        if inpDashShowTf11
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf11), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend11), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend11), text_size=size.small)
            dashRow += 1
        if inpDashShowTf12
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf12), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend12), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend12), text_size=size.small)
            dashRow += 1
        if inpDashShowTf13
            table.cell(tfDashboard, 0, dashRow, f_dashTfLabel(inpDashTf13), text_color=color.white, bgcolor=tfCellBg, text_size=size.small)
            table.cell(tfDashboard, 1, dashRow, f_dashTrendText(dashTrend13), text_color=color.white, bgcolor=f_dashTrendColor(dashTrend13), text_size=size.small)

    // FIX 7: table.clear end row updated from 15 → 18 to match the expanded table (19 rows, 0-indexed 0–18).
    table.clear(levelAnalyzerTable, 0, 0, 1, 13)
    if inpShowLevelAnalyzer
        anaHeaderBg = color.rgb(30, 30, 30)
        anaCellBg = color.rgb(18, 18, 18)
        anaBestBg = color.rgb(0, 100, 0)
        bestSlot = f_bestAnalyzerSlot(levelAnalyzerWins, levelAnalyzerLosses)
        table.cell(levelAnalyzerTable, 0, 0, "LEVEL", text_color=color.white, bgcolor=anaHeaderBg, text_size=size.small)
        table.cell(levelAnalyzerTable, 1, 0, "TESTS", text_color=color.white, bgcolor=anaHeaderBg, text_size=size.small)
        table.cell(levelAnalyzerTable, 2, 0, "WINS", text_color=color.white, bgcolor=anaHeaderBg, text_size=size.small)
        table.cell(levelAnalyzerTable, 3, 0, "LOSS", text_color=color.white, bgcolor=anaHeaderBg, text_size=size.small)
        table.cell(levelAnalyzerTable, 4, 0, "ACC", text_color=color.white, bgcolor=anaHeaderBg, text_size=size.small)
        anaRow = 1
        // FIX 8: Loop extended from 14 → 16 so all 17 slots (0–16) are rendered in the table.
        for anaSlot = 0 to 16
            if f_analyzerShowSlot(anaSlot)
                tests = array.get(levelAnalyzerTests, anaSlot)
                wins = array.get(levelAnalyzerWins, anaSlot)
                losses = array.get(levelAnalyzerLosses, anaSlot)
                rowBg = anaSlot == bestSlot ? anaBestBg : anaCellBg
                table.cell(levelAnalyzerTable, 0, anaRow, f_analyzerLabel(anaSlot), text_color=color.white, bgcolor=rowBg, text_size=size.small)
                table.cell(levelAnalyzerTable, 1, anaRow, str.tostring(tests), text_color=color.white, bgcolor=rowBg, text_size=size.small)
                table.cell(levelAnalyzerTable, 2, anaRow, str.tostring(wins), text_color=color.white, bgcolor=rowBg, text_size=size.small)
                table.cell(levelAnalyzerTable, 3, anaRow, str.tostring(losses), text_color=color.white, bgcolor=rowBg, text_size=size.small)
                table.cell(levelAnalyzerTable, 4, anaRow, f_analyzerRateText(wins, losses), text_color=color.white, bgcolor=rowBg, text_size=size.small)
                anaRow += 1

Post a Comment

Please Select Embedded Mode To Show The Comment System.*

Previous Post Next Post

Contact Form