Karlos Alpha V11 Gentle - Ultimate Auto Trading Bot By Aihan Daniyen

 //@version=5

indicator('πŸ”₯ Karlos Algo Black V8 Sharp —mix version', overlay=true)


// === INPUTS ===

show_tp_sl = input.bool(true, 'Display TP & SL')

rrr = input.string('1:2', 'Risk to Reward Ratio', options=['1:1','1:2','1:3','1:4'])

tp_sl_mult = input.float(1.0, 'TP/SL Multiplier')

tp_sl_prec = input.int(2, 'TP/SL Precision')

disable_repeating = input.bool(true, 'Disable Repeating Signals')


rsi_threshold = input.int(80, 'RSI Threshold')

candle_delta_len = input.int(10, 'Candle Delta Length')


// === LABEL STYLE ===

label_style = input.string('text bubble', 'Label Style', options=['text bubble','triangle','arrow'])

buy_label_color = input.color(color.green, 'BUY Label Color')

sell_label_color = input.color(color.red, 'SELL Label Color')

label_text_color = input.color(color.white, 'Label Text Color')


// === INDICATORS ===

rsi = ta.rsi(close, 14)

atr = ta.atr(14)

stable_candle = math.abs(close - open) / ta.tr > 0.7


// === CONDITIONS ===

bullish_engulfing = close[1] < open[1] and close > open and close > open[1]

bearish_engulfing = close[1] > open[1] and close < open and close < open[1]


rsi_below = rsi < rsi_threshold

rsi_above = rsi > 100 - rsi_threshold

price_decrease = close < close[candle_delta_len]

price_increase = close > close[candle_delta_len]


var string last_signal = ''

var float tp = na

var float sl = na


buy_condition = bullish_engulfing and stable_candle and rsi_below and price_decrease

sell_condition = bearish_engulfing and stable_candle and rsi_above and price_increase


can_buy = buy_condition and (disable_repeating ? last_signal != 'buy' : true)

can_sell = sell_condition and (disable_repeating ? last_signal != 'sell' : true)


// === ROUND FUNCTION ===

round_up(val, dec) =>

    factor = math.pow(10, dec)

    math.ceil(val * factor) / factor


// === BUY EXECUTION ===

if can_buy

    last_signal := 'buy'

    dist = atr * tp_sl_mult

    tp_val = rrr == '1:1' ? dist : rrr == '1:2' ? dist * 2 : rrr == '1:3' ? dist * 3 : dist * 4

    tp := round_up(close + tp_val, tp_sl_prec)

    sl := round_up(close - dist, tp_sl_prec)


    // Labels

    if label_style == 'text bubble'

        label.new(bar_index, low, 'BUY', style=label.style_label_up, color=buy_label_color, textcolor=label_text_color)

    else if label_style == 'triangle'

        label.new(bar_index, low, 'BUY', yloc=yloc.belowbar, style=label.style_triangleup, color=buy_label_color, textcolor=label_text_color)

    else

        label.new(bar_index, low, 'BUY', yloc=yloc.belowbar, style=label.style_arrowup, color=buy_label_color, textcolor=label_text_color)


    if show_tp_sl

        label.new(bar_index, low, 'TP: ' + str.tostring(tp) + '\nSL: ' + str.tostring(sl), textcolor=label_text_color)


// === SELL EXECUTION ===

if can_sell

    last_signal := 'sell'

    dist = atr * tp_sl_mult

    tp_val = rrr == '1:1' ? dist : rrr == '1:2' ? dist * 2 : rrr == '1:3' ? dist * 3 : dist * 4

    tp := round_up(close - tp_val, tp_sl_prec)

    sl := round_up(close + dist, tp_sl_prec)


    // Labels

    if label_style == 'text bubble'

        label.new(bar_index, high, 'SELL', style=label.style_label_down, color=sell_label_color, textcolor=label_text_color)

    else if label_style == 'triangle'

        label.new(bar_index, high, 'SELL', yloc=yloc.abovebar, style=label.style_triangledown, color=sell_label_color, textcolor=label_text_color)

    else

        label.new(bar_index, high, 'SELL', yloc=yloc.abovebar, style=label.style_arrowdown, color=sell_label_color, textcolor=label_text_color)


    if show_tp_sl

        label.new(bar_index, high, 'TP: ' + str.tostring(tp) + '\nSL: ' + str.tostring(sl), textcolor=label_text_color)


// === PLOTS FOR TP & SL ===

plotshape(can_buy, title='Buy Signal', location=location.belowbar, color=color.green, style=shape.labelup, text='BUY')

plotshape(can_sell, title='Sell Signal', location=location.abovebar, color=color.red, style=shape.labeldown, text='SELL')

plot(tp, 'TP', color=color.green, style=plot.style_circles)

plot(sl, 'SL', color=color.red, style=plot.style_circles)


// === ALERTS ===

alertcondition(can_buy, title='BUY Signal', message='GainzAlgo Indicator: BUY Signal')

alertcondition(can_sell, title='SELL Signal', message='GainzAlgo Indicator: SELL Signal')



//---------------------------------------------------------------------------------------------------------------------{

BULLISH_LEG                     = 1

BEARISH_LEG                     = 0


BULLISH                         = +1

BEARISH                         = -1


GREEN                           = #089981

RED                             = #F23645

BLUE                            = #2157f3

GRAY                            = #878b94

MONO_BULLISH                    = #b2b5be

MONO_BEARISH                    = #5d606b


HISTORICAL                      = 'Historical'

PRESENT                         = 'Present'


COLORED                         = 'Colored'

MONOCHROME                      = 'Monochrome'


ALL                             = 'All'

BOS                             = 'BOS'

CHOCH                           = 'CHoCH'


TINY                            = size.tiny

SMALL                           = size.small

NORMAL                          = size.normal


ATR                             = 'Atr'

RANGE                           = 'Cumulative Mean Range'


CLOSE                           = 'Close'

HIGHLOW                         = 'High/Low'


SOLID                           = '⎯⎯⎯'

DASHED                          = '----'

DOTTED                          = '····'


SMART_GROUP                     = 'Smart Money Concepts'

INTERNAL_GROUP                  = 'Real Time Internal Structure'

SWING_GROUP                     = 'Real Time Swing Structure'

BLOCKS_GROUP                    = 'Order Blocks'

EQUAL_GROUP                     = 'EQH/EQL'

GAPS_GROUP                      = 'Fair Value Gaps'

LEVELS_GROUP                    = 'Highs & Lows MTF'

ZONES_GROUP                     = 'Premium & Discount Zones'


modeTooltip                     = 'Allows to display historical Structure or only the recent ones'

styleTooltip                    = 'Indicator color theme'

showTrendTooltip                = 'Display additional candles with a color reflecting the current trend detected by structure'

showInternalsTooltip            = 'Display internal market structure'

internalFilterConfluenceTooltip = 'Filter non significant internal structure breakouts'

showStructureTooltip            = 'Display swing market Structure'

showSwingsTooltip               = 'Display swing point as labels on the chart'

showHighLowSwingsTooltip        = 'Highlight most recent strong and weak high/low points on the chart'

showInternalOrderBlocksTooltip  = 'Display internal order blocks on the chart\n\nNumber of internal order blocks to display on the chart'

showSwingOrderBlocksTooltip     = 'Display swing order blocks on the chart\n\nNumber of internal swing blocks to display on the chart'

orderBlockFilterTooltip         = 'Method used to filter out volatile order blocks \n\nIt is recommended to use the cumulative mean range method when a low amount of data is available'

orderBlockMitigationTooltip     = 'Select what values to use for order block mitigation'

showEqualHighsLowsTooltip       = 'Display equal highs and equal lows on the chart'

equalHighsLowsLengthTooltip     = 'Number of bars used to confirm equal highs and equal lows'

equalHighsLowsThresholdTooltip  = 'Sensitivity threshold in a range (0, 1) used for the detection of equal highs & lows\n\nLower values will return fewer but more pertinent results'

showFairValueGapsTooltip        = 'Display fair values gaps on the chart'

fairValueGapsThresholdTooltip   = 'Filter out non significant fair value gaps'

fairValueGapsTimeframeTooltip   = 'Fair value gaps timeframe'

fairValueGapsExtendTooltip      = 'Determine how many bars to extend the Fair Value Gap boxes on chart'

showPremiumDiscountZonesTooltip = 'Display premium, discount, and equilibrium zones on chart'


modeInput                       = input.string( HISTORICAL, 'Mode',                     group = SMART_GROUP,    tooltip = modeTooltip, options = [HISTORICAL, PRESENT])

styleInput                      = input.string( COLORED,    'Style',                    group = SMART_GROUP,    tooltip = styleTooltip,options = [COLORED, MONOCHROME])

showTrendInput                  = input(        false,      'Color Candles',            group = SMART_GROUP,    tooltip = showTrendTooltip)


showInternalsInput              = input(        true,       'Show Internal Structure',  group = INTERNAL_GROUP, tooltip = showInternalsTooltip)

showInternalBullInput           = input.string( ALL,        'Bullish Structure',        group = INTERNAL_GROUP, inline = 'ibull', options = [ALL,BOS,CHOCH])

internalBullColorInput          = input(        GREEN,      '',                         group = INTERNAL_GROUP, inline = 'ibull')

showInternalBearInput           = input.string( ALL,        'Bearish Structure' ,       group = INTERNAL_GROUP, inline = 'ibear', options = [ALL,BOS,CHOCH])

internalBearColorInput          = input(        RED,        '',                         group = INTERNAL_GROUP, inline = 'ibear')

internalFilterConfluenceInput   = input(        false,      'Confluence Filter',        group = INTERNAL_GROUP, tooltip = internalFilterConfluenceTooltip)

internalStructureSize           = input.string( TINY,       'Internal Label Size',      group = INTERNAL_GROUP, options = [TINY,SMALL,NORMAL])


showStructureInput              = input(        true,       'Show Swing Structure',     group = SWING_GROUP,    tooltip = showStructureTooltip)

showSwingBullInput              = input.string( ALL,        'Bullish Structure',        group = SWING_GROUP,    inline = 'bull',    options = [ALL,BOS,CHOCH])

swingBullColorInput             = input(        GREEN,      '',                         group = SWING_GROUP,    inline = 'bull')

showSwingBearInput              = input.string( ALL,        'Bearish Structure',        group = SWING_GROUP,    inline = 'bear',    options = [ALL,BOS,CHOCH])

swingBearColorInput             = input(        RED,        '',                         group = SWING_GROUP,    inline = 'bear')

swingStructureSize              = input.string( SMALL,      'Swing Label Size',         group = SWING_GROUP,    options = [TINY,SMALL,NORMAL])

showSwingsInput                 = input(        false,      'Show Swings Points',       group = SWING_GROUP,    tooltip = showSwingsTooltip,inline = 'swings')

swingsLengthInput               = input.int(    50,         '',                         group = SWING_GROUP,    minval = 10,                inline = 'swings')

showHighLowSwingsInput          = input(        true,       'Show Strong/Weak High/Low',group = SWING_GROUP,    tooltip = showHighLowSwingsTooltip)


showInternalOrderBlocksInput    = input(        true,       'Internal Order Blocks' ,   group = BLOCKS_GROUP,   tooltip = showInternalOrderBlocksTooltip,   inline = 'iob')

internalOrderBlocksSizeInput    = input.int(    5,          '',                         group = BLOCKS_GROUP,   minval = 1, maxval = 20,                    inline = 'iob')

showSwingOrderBlocksInput       = input(        false,      'Swing Order Blocks',       group = BLOCKS_GROUP,   tooltip = showSwingOrderBlocksTooltip,      inline = 'ob')

swingOrderBlocksSizeInput       = input.int(    5,          '',                         group = BLOCKS_GROUP,   minval = 1, maxval = 20,                    inline = 'ob') 

orderBlockFilterInput           = input.string( 'Atr',      'Order Block Filter',       group = BLOCKS_GROUP,   tooltip = orderBlockFilterTooltip,          options = [ATR, RANGE])

orderBlockMitigationInput       = input.string( HIGHLOW,    'Order Block Mitigation',   group = BLOCKS_GROUP,   tooltip = orderBlockMitigationTooltip,      options = [CLOSE,HIGHLOW])

internalBullishOrderBlockColor  = input.color(color.new(#3179f5, 80), 'Internal Bullish OB',    group = BLOCKS_GROUP)

internalBearishOrderBlockColor  = input.color(color.new(#f77c80, 80), 'Internal Bearish OB',    group = BLOCKS_GROUP)

swingBullishOrderBlockColor     = input.color(color.new(#1848cc, 80), 'Bullish OB',             group = BLOCKS_GROUP)

swingBearishOrderBlockColor     = input.color(color.new(#b22833, 80), 'Bearish OB',             group = BLOCKS_GROUP)


showEqualHighsLowsInput         = input(        true,       'Equal High/Low',           group = EQUAL_GROUP,    tooltip = showEqualHighsLowsTooltip)

equalHighsLowsLengthInput       = input.int(    3,          'Bars Confirmation',        group = EQUAL_GROUP,    tooltip = equalHighsLowsLengthTooltip,      minval = 1)

equalHighsLowsThresholdInput    = input.float(  0.1,        'Threshold',                group = EQUAL_GROUP,    tooltip = equalHighsLowsThresholdTooltip,   minval = 0, maxval = 0.5, step = 0.1)

equalHighsLowsSizeInput         = input.string( TINY,       'Label Size',               group = EQUAL_GROUP,    options = [TINY,SMALL,NORMAL])


showFairValueGapsInput          = input(        false,      'Fair Value Gaps',          group = GAPS_GROUP,     tooltip = showFairValueGapsTooltip)

fairValueGapsThresholdInput     = input(        true,       'Auto Threshold',           group = GAPS_GROUP,     tooltip = fairValueGapsThresholdTooltip)

fairValueGapsTimeframeInput     = input.timeframe('',       'Timeframe',                group = GAPS_GROUP,     tooltip = fairValueGapsTimeframeTooltip)

fairValueGapsBullColorInput     = input.color(color.new(#00ff68, 70), 'Bullish FVG' , group = GAPS_GROUP)

fairValueGapsBearColorInput     = input.color(color.new(#ff0008, 70), 'Bearish FVG' , group = GAPS_GROUP)

fairValueGapsExtendInput        = input.int(    1,          'Extend FVG',               group = GAPS_GROUP,     tooltip = fairValueGapsExtendTooltip,       minval = 0)


showDailyLevelsInput            = input(        false,      'Daily',    group = LEVELS_GROUP,   inline = 'daily')

dailyLevelsStyleInput           = input.string( SOLID,      '',         group = LEVELS_GROUP,   inline = 'daily',   options = [SOLID,DASHED,DOTTED])

dailyLevelsColorInput           = input(        BLUE,       '',         group = LEVELS_GROUP,   inline = 'daily')

showWeeklyLevelsInput           = input(        false,      'Weekly',   group = LEVELS_GROUP,   inline = 'weekly')

weeklyLevelsStyleInput          = input.string( SOLID,      '',         group = LEVELS_GROUP,   inline = 'weekly',  options = [SOLID,DASHED,DOTTED])

weeklyLevelsColorInput          = input(        BLUE,       '',         group = LEVELS_GROUP,   inline = 'weekly')

showMonthlyLevelsInput          = input(        false,      'Monthly',   group = LEVELS_GROUP,   inline = 'monthly')

monthlyLevelsStyleInput         = input.string( SOLID,      '',         group = LEVELS_GROUP,   inline = 'monthly', options = [SOLID,DASHED,DOTTED])

monthlyLevelsColorInput         = input(        BLUE,       '',         group = LEVELS_GROUP,   inline = 'monthly')


showPremiumDiscountZonesInput   = input(        false,      'Premium/Discount Zones',   group = ZONES_GROUP , tooltip = showPremiumDiscountZonesTooltip)

premiumZoneColorInput           = input.color(  RED,        'Premium Zone',             group = ZONES_GROUP)

equilibriumZoneColorInput       = input.color(  GRAY,       'Equilibrium Zone',         group = ZONES_GROUP)

discountZoneColorInput          = input.color(  GREEN,      'Discount Zone',            group = ZONES_GROUP)


//---------------------------------------------------------------------------------------------------------------------}

//DATA STRUCTURES & VARIABLES

//---------------------------------------------------------------------------------------------------------------------{

// @type                            UDT representing alerts as bool fields

// @field internalBullishBOS        internal structure custom alert

// @field internalBearishBOS        internal structure custom alert

// @field internalBullishCHoCH      internal structure custom alert

// @field internalBearishCHoCH      internal structure custom alert

// @field swingBullishBOS           swing structure custom alert

// @field swingBearishBOS           swing structure custom alert

// @field swingBullishCHoCH         swing structure custom alert

// @field swingBearishCHoCH         swing structure custom alert

// @field internalBullishOrderBlock internal order block custom alert

// @field internalBearishOrderBlock internal order block custom alert

// @field swingBullishOrderBlock    swing order block custom alert

// @field swingBearishOrderBlock    swing order block custom alert

// @field equalHighs                equal high low custom alert

// @field equalLows                 equal high low custom alert

// @field bullishFairValueGap       fair value gap custom alert

// @field bearishFairValueGap       fair value gap custom alert

type alerts

    bool internalBullishBOS         = false

    bool internalBearishBOS         = false

    bool internalBullishCHoCH       = false

    bool internalBearishCHoCH       = false

    bool swingBullishBOS            = false

    bool swingBearishBOS            = false

    bool swingBullishCHoCH          = false

    bool swingBearishCHoCH          = false

    bool internalBullishOrderBlock  = false

    bool internalBearishOrderBlock  = false

    bool swingBullishOrderBlock     = false

    bool swingBearishOrderBlock     = false

    bool equalHighs                 = false

    bool equalLows                  = false

    bool bullishFairValueGap        = false

    bool bearishFairValueGap        = false


// @type                            UDT representing last swing extremes (top & bottom)

// @field top                       last top swing price

// @field bottom                    last bottom swing price

// @field barTime                   last swing bar time

// @field barIndex                  last swing bar index

// @field lastTopTime               last top swing time

// @field lastBottomTime            last bottom swing time

type trailingExtremes

    float top

    float bottom

    int barTime

    int barIndex

    int lastTopTime

    int lastBottomTime


// @type                            UDT representing Fair Value Gaps

// @field top                       top price

// @field bottom                    bottom price

// @field bias                      bias (BULLISH or BEARISH)

// @field topBox                    top box

// @field bottomBox                 bottom box

type fairValueGap

    float top

    float bottom

    int bias

    box topBox

    box bottomBox


// @type                            UDT representing trend bias

// @field bias                      BULLISH or BEARISH

type trend

    int bias    


// @type                            UDT representing Equal Highs Lows display

// @field l_ine                     displayed line

// @field l_abel                    displayed label

type equalDisplay

    line l_ine      = na

    label l_abel    = na


// @type                            UDT representing a pivot point (swing point) 

// @field currentLevel              current price level

// @field lastLevel                 last price level

// @field crossed                   true if price level is crossed

// @field barTime                   bar time

// @field barIndex                  bar index    

type pivot

    float currentLevel

    float lastLevel

    bool crossed

    int barTime     = time

    int barIndex    = bar_index


// @type                            UDT representing an order block

// @field barHigh                   bar high

// @field barLow                    bar low

// @field barTime                   bar time

// @field bias                      BULLISH or BEARISH

type orderBlock

    float barHigh

    float barLow

    int barTime    

    int bias


// @variable                        current swing pivot high    

var pivot swingHigh                 = pivot.new(na,na,false)

// @variable                        current swing pivot low

var pivot swingLow                  = pivot.new(na,na,false)

// @variable                        current internal pivot high

var pivot internalHigh              = pivot.new(na,na,false)

// @variable                        current internal pivot low

var pivot internalLow               = pivot.new(na,na,false)

// @variable                        current equal high pivot

var pivot equalHigh                 = pivot.new(na,na,false)

// @variable                        current equal low pivot

var pivot equalLow                  = pivot.new(na,na,false)

// @variable                        swing trend bias

var trend swingTrend                = trend.new(0)

// @variable                        internal trend bias

var trend internalTrend             = trend.new(0)

// @variable                        equal high display

var equalDisplay equalHighDisplay   = equalDisplay.new()

// @variable                        equal low display

var equalDisplay equalLowDisplay    = equalDisplay.new()

// @variable                        storage for fairValueGap UDTs

var array<fairValueGap> fairValueGaps = array.new<fairValueGap>()

// @variable                        storage for parsed highs

var array<float> parsedHighs        = array.new<float>()

// @variable                        storage for parsed lows

var array<float> parsedLows         = array.new<float>()

// @variable                        storage for raw highs

var array<float> highs              = array.new<float>()

// @variable                        storage for raw lows

var array<float> lows               = array.new<float>()

// @variable                        storage for bar time values

var array<int> times                = array.new<int>()

// @variable                        last trailing swing high and low

var trailingExtremes trailing       = trailingExtremes.new()

// @variable                                storage for orderBlock UDTs (swing order blocks)

var array<orderBlock> swingOrderBlocks      = array.new<orderBlock>()

// @variable                                storage for orderBlock UDTs (internal order blocks)

var array<orderBlock> internalOrderBlocks   = array.new<orderBlock>()

// @variable                                storage for swing order blocks boxes

var array<box> swingOrderBlocksBoxes        = array.new<box>()

// @variable                                storage for internal order blocks boxes

var array<box> internalOrderBlocksBoxes     = array.new<box>()

// @variable                        color for swing bullish structures

var swingBullishColor               = styleInput == MONOCHROME ? MONO_BULLISH : swingBullColorInput

// @variable                        color for swing bearish structures

var swingBearishColor               = styleInput == MONOCHROME ? MONO_BEARISH : swingBearColorInput

// @variable                        color for bullish fair value gaps

var fairValueGapBullishColor        = styleInput == MONOCHROME ? color.new(MONO_BULLISH,70) : fairValueGapsBullColorInput

// @variable                        color for bearish fair value gaps

var fairValueGapBearishColor        = styleInput == MONOCHROME ? color.new(MONO_BEARISH,70) : fairValueGapsBearColorInput

// @variable                        color for premium zone

var premiumZoneColor                = styleInput == MONOCHROME ? MONO_BEARISH : premiumZoneColorInput

// @variable                        color for discount zone

var discountZoneColor               = styleInput == MONOCHROME ? MONO_BULLISH : discountZoneColorInput 

// @variable                        bar index on current script iteration

varip int currentBarIndex           = bar_index

// @variable                        bar index on last script iteration

varip int lastBarIndex              = bar_index

// @variable                        alerts in current bar

alerts currentAlerts                = alerts.new()

// @variable                        time at start of chart

var initialTime                     = time


// we create the needed boxes for displaying order blocks at the first execution

if barstate.isfirst

    if showSwingOrderBlocksInput

        for index = 1 to swingOrderBlocksSizeInput

            swingOrderBlocksBoxes.push(box.new(na,na,na,na,xloc = xloc.bar_time,extend = extend.right))

    if showInternalOrderBlocksInput

        for index = 1 to internalOrderBlocksSizeInput

            internalOrderBlocksBoxes.push(box.new(na,na,na,na,xloc = xloc.bar_time,extend = extend.right))


// @variable                        source to use in bearish order blocks mitigation

bearishOrderBlockMitigationSource   = orderBlockMitigationInput == CLOSE ? close : high

// @variable                        source to use in bullish order blocks mitigation

bullishOrderBlockMitigationSource   = orderBlockMitigationInput == CLOSE ? close : low

// @variable                        default volatility measure

atrMeasure                          = ta.atr(200)

// @variable                        parsed volatility measure by user settings

volatilityMeasure                   = orderBlockFilterInput == ATR ? atrMeasure : ta.cum(ta.tr)/bar_index

// @variable                        true if current bar is a high volatility bar

highVolatilityBar                   = (high - low) >= (2 * volatilityMeasure)

// @variable                        parsed high

parsedHigh                          = highVolatilityBar ? low : high

// @variable                        parsed low

parsedLow                           = highVolatilityBar ? high : low


// we store current values into the arrays at each bar

parsedHighs.push(parsedHigh)

parsedLows.push(parsedLow)

highs.push(high)

lows.push(low)

times.push(time)


//---------------------------------------------------------------------------------------------------------------------}

//USER-DEFINED FUNCTIONS

//---------------------------------------------------------------------------------------------------------------------{

// @function            Get the value of the current leg, it can be 0 (bearish) or 1 (bullish)

// @returns             int

leg(int size) =>

    var leg     = 0    

    newLegHigh  = high[size] > ta.highest( size)

    newLegLow   = low[size]  < ta.lowest(  size)

    

    if newLegHigh

        leg := BEARISH_LEG

    else if newLegLow

        leg := BULLISH_LEG

    leg


// @function            Identify whether the current value is the start of a new leg (swing)

// @param leg           (int) Current leg value

// @returns             bool

startOfNewLeg(int leg)      => ta.change(leg) != 0


// @function            Identify whether the current level is the start of a new bearish leg (swing)

// @param leg           (int) Current leg value

// @returns             bool

startOfBearishLeg(int leg)  => ta.change(leg) == -1


// @function            Identify whether the current level is the start of a new bullish leg (swing)

// @param leg           (int) Current leg value

// @returns             bool

startOfBullishLeg(int leg)  => ta.change(leg) == +1


// @function            create a new label

// @param labelTime     bar time coordinate

// @param labelPrice    price coordinate

// @param tag           text to display

// @param labelColor    text color

// @param labelStyle    label style

// @returns             label ID

drawLabel(int labelTime, float labelPrice, string tag, color labelColor, string labelStyle) =>    

    var label l_abel = na


    if modeInput == PRESENT

        l_abel.delete()


    l_abel := label.new(chart.point.new(labelTime,na,labelPrice),tag,xloc.bar_time,color=color(na),textcolor=labelColor,style = labelStyle,size = size.small)


// @function            create a new line and label representing an EQH or EQL

// @param p_ivot        starting pivot

// @param level         price level of current pivot

// @param size          how many bars ago was the current pivot detected

// @param equalHigh     true for EQH, false for EQL

// @returns             label ID

drawEqualHighLow(pivot p_ivot, float level, int size, bool equalHigh) =>

    equalDisplay e_qualDisplay = equalHigh ? equalHighDisplay : equalLowDisplay

    

    string tag          = 'EQL'

    color equalColor    = swingBullishColor

    string labelStyle   = label.style_label_up


    if equalHigh

        tag         := 'EQH'

        equalColor  := swingBearishColor

        labelStyle  := label.style_label_down


    if modeInput == PRESENT

        line.delete(    e_qualDisplay.l_ine)

        label.delete(   e_qualDisplay.l_abel)

        

    e_qualDisplay.l_ine     := line.new(chart.point.new(p_ivot.barTime,na,p_ivot.currentLevel), chart.point.new(time[size],na,level), xloc = xloc.bar_time, color = equalColor, style = line.style_dotted)

    labelPosition           = math.round(0.5*(p_ivot.barIndex + bar_index - size))

    e_qualDisplay.l_abel    := label.new(chart.point.new(na,labelPosition,level), tag, xloc.bar_index, color = color(na), textcolor = equalColor, style = labelStyle, size = equalHighsLowsSizeInput)


// @function            store current structure and trailing swing points, and also display swing points and equal highs/lows

// @param size          (int) structure size

// @param equalHighLow  (bool) true for displaying current highs/lows

// @param internal      (bool) true for getting internal structures

// @returns             label ID

getCurrentStructure(int size,bool equalHighLow = false, bool internal = false) =>        

    currentLeg              = leg(size)

    newPivot                = startOfNewLeg(currentLeg)

    pivotLow                = startOfBullishLeg(currentLeg)

    pivotHigh               = startOfBearishLeg(currentLeg)


    if newPivot

        if pivotLow

            pivot p_ivot    = equalHighLow ? equalLow : internal ? internalLow : swingLow    


            if equalHighLow and math.abs(p_ivot.currentLevel - low[size]) < equalHighsLowsThresholdInput * atrMeasure                

                drawEqualHighLow(p_ivot, low[size], size, false)

                currentAlerts.equalLows := true


            p_ivot.lastLevel    := p_ivot.currentLevel

            p_ivot.currentLevel := low[size]

            p_ivot.crossed      := false

            p_ivot.barTime      := time[size]

            p_ivot.barIndex     := bar_index[size]


            if not equalHighLow and not internal

                trailing.bottom         := p_ivot.currentLevel

                trailing.barTime        := p_ivot.barTime

                trailing.barIndex       := p_ivot.barIndex

                trailing.lastBottomTime := p_ivot.barTime


            if showSwingsInput and not internal and not equalHighLow

                drawLabel(time[size], p_ivot.currentLevel, p_ivot.currentLevel < p_ivot.lastLevel ? 'LL' : 'HL', swingBullishColor, label.style_label_up)            

        else

            pivot p_ivot = equalHighLow ? equalHigh : internal ? internalHigh : swingHigh


            if equalHighLow and math.abs(p_ivot.currentLevel - high[size]) < equalHighsLowsThresholdInput * atrMeasure

                drawEqualHighLow(p_ivot,high[size],size,true)

                currentAlerts.equalHighs := true               


            p_ivot.lastLevel    := p_ivot.currentLevel

            p_ivot.currentLevel := high[size]

            p_ivot.crossed      := false

            p_ivot.barTime      := time[size]

            p_ivot.barIndex     := bar_index[size]


            if not equalHighLow and not internal

                trailing.top            := p_ivot.currentLevel

                trailing.barTime        := p_ivot.barTime

                trailing.barIndex       := p_ivot.barIndex

                trailing.lastTopTime    := p_ivot.barTime


            if showSwingsInput and not internal and not equalHighLow

                drawLabel(time[size], p_ivot.currentLevel, p_ivot.currentLevel > p_ivot.lastLevel ? 'HH' : 'LH', swingBearishColor, label.style_label_down)

                

// @function                draw line and label representing a structure

// @param p_ivot            base pivot point

// @param tag               test to display

// @param structureColor    base color

// @param lineStyle         line style

// @param labelStyle        label style

// @param labelSize         text size

// @returns                 label ID

drawStructure(pivot p_ivot, string tag, color structureColor, string lineStyle, string labelStyle, string labelSize) =>    

    var line l_ine      = line.new(na,na,na,na,xloc = xloc.bar_time)

    var label l_abel    = label.new(na,na)


    if modeInput == PRESENT

        l_ine.delete()

        l_abel.delete()


    l_ine   := line.new(chart.point.new(p_ivot.barTime,na,p_ivot.currentLevel), chart.point.new(time,na,p_ivot.currentLevel), xloc.bar_time, color=structureColor, style=lineStyle)

    l_abel  := label.new(chart.point.new(na,math.round(0.5*(p_ivot.barIndex+bar_index)),p_ivot.currentLevel), tag, xloc.bar_index, color=color(na), textcolor=structureColor, style=labelStyle, size = labelSize)


// @function            delete order blocks

// @param internal      true for internal order blocks

// @returns             orderBlock ID

deleteOrderBlocks(bool internal = false) =>

    array<orderBlock> orderBlocks = internal ? internalOrderBlocks : swingOrderBlocks


    for [index,eachOrderBlock] in orderBlocks

        bool crossedOderBlock = false

        

        if bearishOrderBlockMitigationSource > eachOrderBlock.barHigh and eachOrderBlock.bias == BEARISH

            crossedOderBlock := true

            if internal

                currentAlerts.internalBearishOrderBlock := true

            else

                currentAlerts.swingBearishOrderBlock    := true

        else if bullishOrderBlockMitigationSource < eachOrderBlock.barLow and eachOrderBlock.bias == BULLISH

            crossedOderBlock := true

            if internal

                currentAlerts.internalBullishOrderBlock := true

            else

                currentAlerts.swingBullishOrderBlock    := true

        if crossedOderBlock                    

            orderBlocks.remove(index)            


// @function            fetch and store order blocks

// @param p_ivot        base pivot point

// @param internal      true for internal order blocks

// @param bias          BULLISH or BEARISH

// @returns             void

storeOrdeBlock(pivot p_ivot,bool internal = false,int bias) =>

    if (not internal and showSwingOrderBlocksInput) or (internal and showInternalOrderBlocksInput)


        array<float> a_rray = na

        int parsedIndex = na


        if bias == BEARISH

            a_rray      := parsedHighs.slice(p_ivot.barIndex,bar_index)

            parsedIndex := p_ivot.barIndex + a_rray.indexof(a_rray.max())  

        else

            a_rray      := parsedLows.slice(p_ivot.barIndex,bar_index)

            parsedIndex := p_ivot.barIndex + a_rray.indexof(a_rray.min())                        


        orderBlock o_rderBlock          = orderBlock.new(parsedHighs.get(parsedIndex), parsedLows.get(parsedIndex), times.get(parsedIndex),bias)

        array<orderBlock> orderBlocks   = internal ? internalOrderBlocks : swingOrderBlocks

        

        if orderBlocks.size() >= 100

            orderBlocks.pop()

        orderBlocks.unshift(o_rderBlock)


// @function            draw order blocks as boxes

// @param internal      true for internal order blocks

// @returns             void

drawOrderBlocks(bool internal = false) =>        

    array<orderBlock> orderBlocks = internal ? internalOrderBlocks : swingOrderBlocks

    orderBlocksSize = orderBlocks.size()


    if orderBlocksSize > 0        

        maxOrderBlocks                      = internal ? internalOrderBlocksSizeInput : swingOrderBlocksSizeInput

        array<orderBlock> parsedOrdeBlocks  = orderBlocks.slice(0, math.min(maxOrderBlocks,orderBlocksSize))

        array<box> b_oxes                   = internal ? internalOrderBlocksBoxes : swingOrderBlocksBoxes        


        for [index,eachOrderBlock] in parsedOrdeBlocks

            orderBlockColor = styleInput == MONOCHROME ? (eachOrderBlock.bias == BEARISH ? color.new(MONO_BEARISH,80) : color.new(MONO_BULLISH,80)) : internal ? (eachOrderBlock.bias == BEARISH ? internalBearishOrderBlockColor : internalBullishOrderBlockColor) : (eachOrderBlock.bias == BEARISH ? swingBearishOrderBlockColor : swingBullishOrderBlockColor)


            box b_ox        = b_oxes.get(index)

            b_ox.set_top_left_point(    chart.point.new(eachOrderBlock.barTime,na,eachOrderBlock.barHigh))

            b_ox.set_bottom_right_point(chart.point.new(last_bar_time,na,eachOrderBlock.barLow))        

            b_ox.set_border_color(      internal ? na : orderBlockColor)

            b_ox.set_bgcolor(           orderBlockColor)


// @function            detect and draw structures, also detect and store order blocks

// @param internal      true for internal structures or order blocks

// @returns             void

displayStructure(bool internal = false) =>

    var bullishBar = true

    var bearishBar = true


    if internalFilterConfluenceInput

        bullishBar := high - math.max(close, open) > math.min(close, open - low)

        bearishBar := high - math.max(close, open) < math.min(close, open - low)

    

    pivot p_ivot    = internal ? internalHigh : swingHigh

    trend t_rend    = internal ? internalTrend : swingTrend


    lineStyle       = internal ? line.style_dashed : line.style_solid

    labelSize       = internal ? internalStructureSize : swingStructureSize


    extraCondition  = internal ? internalHigh.currentLevel != swingHigh.currentLevel and bullishBar : true

    bullishColor    = styleInput == MONOCHROME ? MONO_BULLISH : internal ? internalBullColorInput : swingBullColorInput


    if ta.crossover(close,p_ivot.currentLevel) and not p_ivot.crossed and extraCondition

        string tag = t_rend.bias == BEARISH ? CHOCH : BOS


        if internal

            currentAlerts.internalBullishCHoCH  := tag == CHOCH

            currentAlerts.internalBullishBOS    := tag == BOS

        else

            currentAlerts.swingBullishCHoCH     := tag == CHOCH

            currentAlerts.swingBullishBOS       := tag == BOS


        p_ivot.crossed  := true

        t_rend.bias     := BULLISH


        displayCondition = internal ? showInternalsInput and (showInternalBullInput == ALL or (showInternalBullInput == BOS and tag != CHOCH) or (showInternalBullInput == CHOCH and tag == CHOCH)) : showStructureInput and (showSwingBullInput == ALL or (showSwingBullInput == BOS and tag != CHOCH) or (showSwingBullInput == CHOCH and tag == CHOCH))


        if displayCondition                        

            drawStructure(p_ivot,tag,bullishColor,lineStyle,label.style_label_down,labelSize)


        if (internal and showInternalOrderBlocksInput) or (not internal and showSwingOrderBlocksInput)

            storeOrdeBlock(p_ivot,internal,BULLISH)


    p_ivot          := internal ? internalLow : swingLow    

    extraCondition  := internal ? internalLow.currentLevel != swingLow.currentLevel and bearishBar : true

    bearishColor    = styleInput == MONOCHROME ? MONO_BEARISH : internal ? internalBearColorInput : swingBearColorInput


    if ta.crossunder(close,p_ivot.currentLevel) and not p_ivot.crossed and extraCondition

        string tag = t_rend.bias == BULLISH ? CHOCH : BOS


        if internal

            currentAlerts.internalBearishCHoCH  := tag == CHOCH

            currentAlerts.internalBearishBOS    := tag == BOS

        else

            currentAlerts.swingBearishCHoCH     := tag == CHOCH

            currentAlerts.swingBearishBOS       := tag == BOS


        p_ivot.crossed := true

        t_rend.bias := BEARISH


        displayCondition = internal ? showInternalsInput and (showInternalBearInput == ALL or (showInternalBearInput == BOS and tag != CHOCH) or (showInternalBearInput == CHOCH and tag == CHOCH)) : showStructureInput and (showSwingBearInput == ALL or (showSwingBearInput == BOS and tag != CHOCH) or (showSwingBearInput == CHOCH and tag == CHOCH))

        

        if displayCondition                        

            drawStructure(p_ivot,tag,bearishColor,lineStyle,label.style_label_up,labelSize)


        if (internal and showInternalOrderBlocksInput) or (not internal and showSwingOrderBlocksInput)

            storeOrdeBlock(p_ivot,internal,BEARISH)


// @function            draw one fair value gap box (each fair value gap has two boxes)

// @param leftTime      left time coordinate

// @param rightTime     right time coordinate

// @param topPrice      top price level

// @param bottomPrice   bottom price level

// @param boxColor      box color

// @returns             box ID

fairValueGapBox(leftTime,rightTime,topPrice,bottomPrice,boxColor) => box.new(chart.point.new(leftTime,na,topPrice),chart.point.new(rightTime + fairValueGapsExtendInput * (time-time[1]),na,bottomPrice), xloc=xloc.bar_time, border_color = boxColor, bgcolor = boxColor)


// @function            delete fair value gaps

// @returns             fairValueGap ID

deleteFairValueGaps() =>

    for [index,eachFairValueGap] in fairValueGaps

        if (low < eachFairValueGap.bottom and eachFairValueGap.bias == BULLISH) or (high > eachFairValueGap.top and eachFairValueGap.bias == BEARISH)

            eachFairValueGap.topBox.delete()

            eachFairValueGap.bottomBox.delete()

            fairValueGaps.remove(index)

    

// @function            draw fair value gaps

// @returns             fairValueGap ID

drawFairValueGaps() => 

    [lastClose, lastOpen, lastTime, currentHigh, currentLow, currentTime, last2High, last2Low] = request.security(syminfo.tickerid, fairValueGapsTimeframeInput, [close[1], open[1], time[1], high[0], low[0], time[0], high[2], low[2]],lookahead = barmerge.lookahead_on)


    barDeltaPercent     = (lastClose - lastOpen) / (lastOpen * 100)

    newTimeframe        = timeframe.change(fairValueGapsTimeframeInput)

    threshold           = fairValueGapsThresholdInput ? ta.cum(math.abs(newTimeframe ? barDeltaPercent : 0)) / bar_index * 2 : 0


    bullishFairValueGap = currentLow > last2High and lastClose > last2High and barDeltaPercent > threshold and newTimeframe

    bearishFairValueGap = currentHigh < last2Low and lastClose < last2Low and -barDeltaPercent > threshold and newTimeframe


    if bullishFairValueGap

        currentAlerts.bullishFairValueGap := true

        fairValueGaps.unshift(fairValueGap.new(currentLow,last2High,BULLISH,fairValueGapBox(lastTime,currentTime,currentLow,math.avg(currentLow,last2High),fairValueGapBullishColor),fairValueGapBox(lastTime,currentTime,math.avg(currentLow,last2High),last2High,fairValueGapBullishColor)))

    if bearishFairValueGap

        currentAlerts.bearishFairValueGap := true

        fairValueGaps.unshift(fairValueGap.new(currentHigh,last2Low,BEARISH,fairValueGapBox(lastTime,currentTime,currentHigh,math.avg(currentHigh,last2Low),fairValueGapBearishColor),fairValueGapBox(lastTime,currentTime,math.avg(currentHigh,last2Low),last2Low,fairValueGapBearishColor)))


// @function            get line style from string

// @param style         line style

// @returns             string

getStyle(string style) =>

    switch style

        SOLID => line.style_solid

        DASHED => line.style_dashed

        DOTTED => line.style_dotted


// @function            draw MultiTimeFrame levels

// @param timeframe     base timeframe

// @param sameTimeframe true if chart timeframe is same as base timeframe

// @param style         line style

// @param levelColor    line and text color

// @returns             void

drawLevels(string timeframe, bool sameTimeframe, string style, color levelColor) =>

    [topLevel, bottomLevel, leftTime, rightTime] = request.security(syminfo.tickerid, timeframe, [high[1], low[1], time[1], time],lookahead = barmerge.lookahead_on)


    float parsedTop         = sameTimeframe ? high : topLevel

    float parsedBottom      = sameTimeframe ? low : bottomLevel    


    int parsedLeftTime      = sameTimeframe ? time : leftTime

    int parsedRightTime     = sameTimeframe ? time : rightTime


    int parsedTopTime       = time

    int parsedBottomTime    = time


    if not sameTimeframe

        int leftIndex               = times.binary_search_rightmost(parsedLeftTime)

        int rightIndex              = times.binary_search_rightmost(parsedRightTime)


        array<int> timeArray        = times.slice(leftIndex,rightIndex)

        array<float> topArray       = highs.slice(leftIndex,rightIndex)

        array<float> bottomArray    = lows.slice(leftIndex,rightIndex)


        parsedTopTime               := timeArray.size() > 0 ? timeArray.get(topArray.indexof(topArray.max())) : initialTime

        parsedBottomTime            := timeArray.size() > 0 ? timeArray.get(bottomArray.indexof(bottomArray.min())) : initialTime


    var line topLine        = line.new(na, na, na, na, xloc = xloc.bar_time, color = levelColor, style = getStyle(style))

    var line bottomLine     = line.new(na, na, na, na, xloc = xloc.bar_time, color = levelColor, style = getStyle(style))

    var label topLabel      = label.new(na, na, xloc = xloc.bar_time, text = str.format('P{0}H',timeframe), color=color(na), textcolor = levelColor, size = size.small, style = label.style_label_left)

    var label bottomLabel   = label.new(na, na, xloc = xloc.bar_time, text = str.format('P{0}L',timeframe), color=color(na), textcolor = levelColor, size = size.small, style = label.style_label_left)


    topLine.set_first_point(    chart.point.new(parsedTopTime,na,parsedTop))

    topLine.set_second_point(   chart.point.new(last_bar_time + 20 * (time-time[1]),na,parsedTop))   

    topLabel.set_point(         chart.point.new(last_bar_time + 20 * (time-time[1]),na,parsedTop))


    bottomLine.set_first_point( chart.point.new(parsedBottomTime,na,parsedBottom))    

    bottomLine.set_second_point(chart.point.new(last_bar_time + 20 * (time-time[1]),na,parsedBottom))

    bottomLabel.set_point(      chart.point.new(last_bar_time + 20 * (time-time[1]),na,parsedBottom))


// @function            true if chart timeframe is higher than provided timeframe

// @param timeframe     timeframe to check

// @returns             bool

higherTimeframe(string timeframe) => timeframe.in_seconds() > timeframe.in_seconds(timeframe)


// @function            update trailing swing points

// @returns             int

updateTrailingExtremes() =>

    trailing.top            := math.max(high,trailing.top)

    trailing.lastTopTime    := trailing.top == high ? time : trailing.lastTopTime

    trailing.bottom         := math.min(low,trailing.bottom)

    trailing.lastBottomTime := trailing.bottom == low ? time : trailing.lastBottomTime


// @function            draw trailing swing points

// @returns             void

drawHighLowSwings() =>

    var line topLine        = line.new(na, na, na, na, color = swingBearishColor, xloc = xloc.bar_time)

    var line bottomLine     = line.new(na, na, na, na, color = swingBullishColor, xloc = xloc.bar_time)

    var label topLabel      = label.new(na, na, color=color(na), textcolor = swingBearishColor, xloc = xloc.bar_time, style = label.style_label_down, size = size.tiny)

    var label bottomLabel   = label.new(na, na, color=color(na), textcolor = swingBullishColor, xloc = xloc.bar_time, style = label.style_label_up, size = size.tiny)


    rightTimeBar            = last_bar_time + 20 * (time - time[1])


    topLine.set_first_point(    chart.point.new(trailing.lastTopTime, na, trailing.top))

    topLine.set_second_point(   chart.point.new(rightTimeBar, na, trailing.top))

    topLabel.set_point(         chart.point.new(rightTimeBar, na, trailing.top))

    topLabel.set_text(          swingTrend.bias == BEARISH ? 'Strong High' : 'Weak High')


    bottomLine.set_first_point( chart.point.new(trailing.lastBottomTime, na, trailing.bottom))

    bottomLine.set_second_point(chart.point.new(rightTimeBar, na, trailing.bottom))

    bottomLabel.set_point(      chart.point.new(rightTimeBar, na, trailing.bottom))

    bottomLabel.set_text(       swingTrend.bias == BULLISH ? 'Strong Low' : 'Weak Low')


// @function            draw a zone with a label and a box

// @param labelLevel    price level for label

// @param labelIndex    bar index for label

// @param top           top price level for box

// @param bottom        bottom price level for box

// @param tag           text to display

// @param zoneColor     base color

// @param style         label style

// @returns             void

drawZone(float labelLevel, int labelIndex, float top, float bottom, string tag, color zoneColor, string style) =>

    var label l_abel    = label.new(na,na,text = tag, color=color(na),textcolor = zoneColor, style = style, size = size.small)

    var box b_ox        = box.new(na,na,na,na,bgcolor = color.new(zoneColor,80),border_color = color(na), xloc = xloc.bar_time)


    b_ox.set_top_left_point(    chart.point.new(trailing.barTime,na,top))

    b_ox.set_bottom_right_point(chart.point.new(last_bar_time,na,bottom))


    l_abel.set_point(           chart.point.new(na,labelIndex,labelLevel))


// @function            draw premium/discount zones

// @returns             void

drawPremiumDiscountZones() =>

    drawZone(trailing.top, math.round(0.5*(trailing.barIndex + last_bar_index)), trailing.top, 0.95*trailing.top + 0.05*trailing.bottom, 'Premium', premiumZoneColor, label.style_label_down)


    equilibriumLevel = math.avg(trailing.top, trailing.bottom)

    drawZone(equilibriumLevel, last_bar_index, 0.525*trailing.top + 0.475*trailing.bottom, 0.525*trailing.bottom + 0.475*trailing.top, 'Equilibrium', equilibriumZoneColorInput, label.style_label_left)


    drawZone(trailing.bottom, math.round(0.5*(trailing.barIndex + last_bar_index)), 0.95*trailing.bottom + 0.05*trailing.top, trailing.bottom, 'Discount', discountZoneColor, label.style_label_up)


//---------------------------------------------------------------------------------------------------------------------}

//MUTABLE VARIABLES & EXECUTION

//---------------------------------------------------------------------------------------------------------------------{

parsedOpen  = showTrendInput ? open : na

candleColor = internalTrend.bias == BULLISH ? swingBullishColor : swingBearishColor

plotcandle(parsedOpen,high,low,close,color = candleColor, wickcolor = candleColor, bordercolor = candleColor)


if showHighLowSwingsInput or showPremiumDiscountZonesInput

    updateTrailingExtremes()


    if showHighLowSwingsInput

        drawHighLowSwings()


    if showPremiumDiscountZonesInput

        drawPremiumDiscountZones()


if showFairValueGapsInput

    deleteFairValueGaps()


getCurrentStructure(swingsLengthInput,false)

getCurrentStructure(5,false,true)


if showEqualHighsLowsInput

    getCurrentStructure(equalHighsLowsLengthInput,true)


if showInternalsInput or showInternalOrderBlocksInput or showTrendInput

    displayStructure(true)


if showStructureInput or showSwingOrderBlocksInput or showHighLowSwingsInput

    displayStructure()


if showInternalOrderBlocksInput

    deleteOrderBlocks(true)


if showSwingOrderBlocksInput

    deleteOrderBlocks()


if showFairValueGapsInput

    drawFairValueGaps()


if barstate.islastconfirmedhistory or barstate.islast

    if showInternalOrderBlocksInput        

        drawOrderBlocks(true)

        

    if showSwingOrderBlocksInput        

        drawOrderBlocks()


lastBarIndex    := currentBarIndex

currentBarIndex := bar_index

newBar          = currentBarIndex != lastBarIndex


if barstate.islastconfirmedhistory or (barstate.isrealtime and newBar)

    if showDailyLevelsInput and not higherTimeframe('D')

        drawLevels('D',timeframe.isdaily,dailyLevelsStyleInput,dailyLevelsColorInput)


    if showWeeklyLevelsInput and not higherTimeframe('W')

        drawLevels('W',timeframe.isweekly,weeklyLevelsStyleInput,weeklyLevelsColorInput)


    if showMonthlyLevelsInput and not higherTimeframe('M')

        drawLevels('M',timeframe.ismonthly,monthlyLevelsStyleInput,monthlyLevelsColorInput)


//---------------------------------------------------------------------------------------------------------------------}

//ALERTS

//---------------------------------------------------------------------------------------------------------------------{

alertcondition(currentAlerts.internalBullishBOS,        'Internal Bullish BOS',         'Internal Bullish BOS formed')

alertcondition(currentAlerts.internalBullishCHoCH,      'Internal Bullish CHoCH',       'Internal Bullish CHoCH formed')

alertcondition(currentAlerts.internalBearishBOS,        'Internal Bearish BOS',         'Internal Bearish BOS formed')

alertcondition(currentAlerts.internalBearishCHoCH,      'Internal Bearish CHoCH',       'Internal Bearish CHoCH formed')


alertcondition(currentAlerts.swingBullishBOS,           'Bullish BOS',                  'Internal Bullish BOS formed')

alertcondition(currentAlerts.swingBullishCHoCH,         'Bullish CHoCH',                'Internal Bullish CHoCH formed')

alertcondition(currentAlerts.swingBearishBOS,           'Bearish BOS',                  'Bearish BOS formed')

alertcondition(currentAlerts.swingBearishCHoCH,         'Bearish CHoCH',                'Bearish CHoCH formed')


alertcondition(currentAlerts.internalBullishOrderBlock, 'Bullish Internal OB Breakout', 'Price broke bullish internal OB')

alertcondition(currentAlerts.internalBearishOrderBlock, 'Bearish Internal OB Breakout', 'Price broke bearish internal OB')

alertcondition(currentAlerts.swingBullishOrderBlock,    'Bullish Swing OB Breakout',    'Price broke bullish swing OB')

alertcondition(currentAlerts.swingBearishOrderBlock,    'Bearish Swing OB Breakout',    'Price broke bearish swing OB')


alertcondition(currentAlerts.equalHighs,                'Equal Highs',                  'Equal highs detected')

alertcondition(currentAlerts.equalLows,                 'Equal Lows',                   'Equal lows detected')


alertcondition(currentAlerts.bullishFairValueGap,       'Bullish FVG',                  'Bullish FVG formed')

alertcondition(currentAlerts.bearishFairValueGap,       'Bearish FVG',                  'Bearish FVG formed')










//---------------------------------------------------------------------------------------------------------------------}




//Strings

//-----------------------------------------------------------------------------{

o          = 'Options'

sp1        = '       '

sp2        = '              '

hl         = 'High / Low    ' + sp1

ny_        = 'New York'       + sp1

lo_        = 'London Open'

lc_        = 'London Close'

as_        = 'Asian'      


//-----------------------------------------------------------------------------}

//Settings

//-----------------------------------------------------------------------------{

i_mode     = input.string(         'Present'      , title = 'Mode'                   , options =['Present', 'Historical']                                              )


//Market Structure Shift

showMS     = input.bool  (           true         , title = ''                       ,   group = 'Market Structures', inline = 'MS'                                    )

len        = input.int   (             5          , title = '     Length   ' +sp2    ,   group = 'Market Structures', inline = 'MS'       , minval = 3, maxval =  10   )


iMSS       = input.bool  (           true         , title = '       MSS'     +sp1    ,   group = 'Market Structures', inline = 'M1'                                    )

cMSSbl     = input.color (color.new(#00e6a1,  0), title = 'bullish'                ,   group = 'Market Structures', inline = 'M1'                                    )

cMSSbr     = input.color (color.new(#e60400,  0), title = 'bearish'                ,   group = 'Market Structures', inline = 'M1'                                    )


iBOS       = input.bool  (           true         , title = '       BOS'     +sp1    ,   group = 'Market Structures', inline = 'BS'                                    )

cBOSbl     = input.color (color.new(#00e6a1,  0), title = 'bullish'                ,   group = 'Market Structures', inline = 'BS'                                    )

cBOSbr     = input.color (color.new(#e60400,  0), title = 'bearish'                ,   group = 'Market Structures', inline = 'BS'                                    )


//Displacement

sDispl     = input.bool  (           false        , title = 'Show Displacement'      ,   group = 'Displacement'                                                        )


perc_Body  = 0.36 // input.int(   36, minval=1, maxval=36) / 100

bxBack     = 10   // input.int(   10, minval=0, maxval=10)


sVimbl     = input.bool  (           true         , title = ''                       ,   group = 'Volume Imbalance' , inline = 'VI'                                    )

visVim     = input.int   (             2          , title = "   # Visible VI's  "+sp1,   group = 'Volume Imbalance' , inline = 'VI'      , minval = 2, maxval = 100    ) 

cVimbl     = input.color (color.new(#06b2d0,  0), title = ''                       ,   group = 'Volume Imbalance' , inline = 'VI'                                    )


//Order Blocks  

showOB     = input.bool  (           true         , title = 'Show Order Blocks'      ,   group = 'Order Blocks'                                                        )

length     = input.int   (            10          , title = 'Swing Lookback'         ,   group = 'Order Blocks'                          , minval = 3                  )

showBull   = input.int   (             1          , title = 'Show Last Bullish OB'   ,   group = 'Order Blocks'                          , minval = 0                  )

showBear   = input.int   (             1          , title = 'Show Last Bearish OB'   ,   group = 'Order Blocks'                          , minval = 0                  )

useBody    = input.bool  (           true         , title = 'Use Candle Body'                                                                                          )


//OB Style

bullCss    = input.color (color.new(#3e89fa,  0), title = 'Bullish OB  '           ,   group = 'Order Blocks'     , inline = 'bullcss'                               )

bullBrkCss = input.color (color.new(#4785f9, 85), title = 'Bullish Break  '        ,   group = 'Order Blocks'     , inline = 'bullcss'                               )


bearCss    = input.color (color.new(#FF3131,  0), title = 'Bearish OB'             ,   group = 'Order Blocks'     , inline = 'bearcss'                               )

bearBrkCss = input.color (color.new(#f9ff57, 85), title = 'Bearish Break'          ,   group = 'Order Blocks'     , inline = 'bearcss'                               )


showLabels = input.bool  (          false, title = 'Show Historical Polarity Changes',   group = 'Order Blocks'                                                        )


//Liquidity   

showLq     = input.bool  (           true         , title = 'Show Liquidity'         ,   group = 'Liquidity'                                                           )

a     = 10 / input.float (             4          , title = 'margin'                 ,   group = 'Liquidity'   , step = 0.1, minval = 2, maxval =   7                  )

visLiq     = input.int   (             2          , title = '# Visible Liq. boxes'   ,   group = 'Liquidity'

           ,                                       minval = 1         , maxval = 50  , tooltip = 'In the same direction'                                               )

cLIQ_B     = input.color (color.new(#fa451c,  0), title = 'Buyside Liquidity  '    ,   group = 'Liquidity'                                                           )

cLIQ_S     = input.color (color.new(#1ce4fa,  0), title = 'Sellside Liquidity'     ,   group = 'Liquidity'                                                           )


//FVG      

shwFVG     = input.bool  (           true         , title = 'Show FVGs'              ,   group = 'Fair Value Gaps'                                                     )

i_BPR      = input.bool  (           false        , title = 'Balance Price Range'    ,   group = 'Fair Value Gaps'                                                     )

i_FVG      = input.string(           'FVG'        , title = o                        ,   group = 'Fair Value Gaps'  , options=['FVG', 'IFVG']                           

           ,                                                                           tooltip = 'Fair Value Gaps\nor\nImplied Fair Value Gaps'                        )

visBxs     = input.int   (             2          , title = '# Visible FVG\'s'       ,   group = 'Fair Value Gaps'

           ,                                       minval = 1         , maxval = 20  , tooltip = 'In the same direction'                                               )


//FVG Style

cFVGbl     = input.color (color.new(#00e676,  0), title = 'Bullish FVG  '          ,   group = 'Fair Value Gaps'  , inline = 'FVGbl'                                 )

cFVGblBR   = input.color (color.new(#808000,  0), title = 'Break'                  ,   group = 'Fair Value Gaps'  , inline = 'FVGbl'                                 )

cFVGbr     = input.color (color.new(#ff5252,  0), title = 'Bearish FVG '           ,   group = 'Fair Value Gaps'  , inline = 'FVGbr'                                 )

cFVGbrBR   = input.color (color.new(#FF0000,  0), title = 'Break'                  ,   group = 'Fair Value Gaps'  , inline = 'FVGbr'                                 )


//NWOG/NDOG 

iNWOG      = input.bool  (           true         , title = ''        , inline='NWOG',   group = 'NWOG/NDOG'                                                           )

cNWOG1     = input.color (color.new(#ff5252, 28), title = 'NWOG    ', inline='NWOG',   group = 'NWOG/NDOG'                                                           )

cNWOG2     = input.color (color.new(#b2b5be, 50), title = ''        , inline='NWOG',   group = 'NWOG/NDOG'                                                           )

maxNWOG    = input.int   (             3          , title = 'Show max', inline='NWOG',   group = 'NWOG/NDOG'                , minval = 0, maxval =  50                 )


iNDOG      = input.bool  (           false        , title = ''        , inline='NDOG',   group = 'NWOG/NDOG'                                                           )

cNDOG1     = input.color (color.new(#ff9800, 20), title = 'NDOG    ', inline='NDOG',   group = 'NWOG/NDOG'                                                           )

cNDOG2     = input.color (color.new(#4dd0e1, 65), title =    ''     , inline='NDOG',   group = 'NWOG/NDOG'                                                           )

maxNDOG    = input.int   (             1          , title = 'Show max', inline='NDOG',   group = 'NWOG/NDOG'                , minval = 0, maxval =  50                 )


//Fibonacci 

iFib       = input.string(           'NONE'      , title = 'Fibonacci between last: ',   group = 'Fibonacci', options=['FVG', 'BPR', 'OB', 'Liq', 'VI', 'NWOG', 'NONE'])

iExt       = input.bool  (           false       , title = 'Extend lines'            ,   group = 'Fibonacci'                                                           )


//Killzones 

showKZ     = input.bool  (           false        , title = 'Show Killzones'         ,   group = 'Killzones'                                                           )

//New York

showNy     = input.bool  (           true         , title = ny_      , inline = 'ny' ,   group = 'Killzones'                                                           ) and showKZ

nyCss      = input.color (color.new(#ff5d00, 93), title = ''       , inline = 'ny' ,   group = 'Killzones'                                                           )

//London Open

showLdno   = input.bool  (           true         , title = lo_      , inline = 'lo' ,   group = 'Killzones'                                                           ) and showKZ

ldnoCss    = input.color (color.new(#00bcd4, 93), title = ''       , inline = 'lo' ,   group = 'Killzones'                                                           )

//London Close

showLdnc   = input.bool  (           true         , title = lc_      , inline = 'lc' ,   group = 'Killzones'                                                           ) and showKZ

ldncCss    = input.color (color.new(#2157f3, 93), title = ''       , inline = 'lc' ,   group = 'Killzones'                                                           )

//Asian

showAsia   = input.bool  (           true         , title = as_ + sp2, inline = 'as' ,   group = 'Killzones'                                                           ) and showKZ

asiaCss    = input.color (color.new(#e91e63, 93), title = ''       , inline = 'as' ,   group = 'Killzones'                                                           )


//-----------------------------------------------------------------------------}

//General Calculations

//-----------------------------------------------------------------------------{

n          =                      bar_index

hi         =                      high  

lo         =                      low   

tf_msec    = timeframe.in_seconds(timeframe.period) * 1000

maxSize    =        50

per        = i_mode == 'Present' ? last_bar_index - bar_index <=  500 : true

perB       = last_bar_index - bar_index <= 1000  ? true : false

xloc       = iFib   ==   'OB'    ? xloc.bar_time : xloc.bar_index

ext        = iExt                ?  extend.right : extend.none

plus       = iFib   ==   'OB'    ?  tf_msec * 50 : 50

mx         = math.max(close , open)

mn         = math.min(close , open)

body       = math.abs(close - open)

meanBody   = ta.sma  (body  ,  len)

max        = useBody ?  mx  : high

min        = useBody ?  mn  : low

blBrkConf  = 0

brBrkConf  = 0

r          = color.r(chart.bg_color)

g          = color.g(chart.bg_color)

b          = color.b(chart.bg_color)

isDark     = r < 80 and g < 80 and b < 80


//-----------------------------------------------------------------------------}

//User Defined Types

//-----------------------------------------------------------------------------{

type ZZ 

    int   [] d

    int   [] x 

    float [] y 

    bool  [] b


type ln_d

    line  l

    int   d


type _2ln_lb

    line  l1

    line  l2

    label lb


type bx_ln

    box   b 

    line  l 


type bx_ln_lb

    box   bx

    line  ln

    label lb 


type mss 

    int     dir

    line [] l_mssBl

    line [] l_mssBr

    line [] l_bosBl

    line [] l_bosBr

    label[] lbMssBl

    label[] lbMssBr

    label[] lbBosBl

    label[] lbBosBr


type liq

    box   bx

    bool  broken

    bool  brokenTop

    bool  brokenBtm

    line  ln


type ob

    float   top       = na

    float   btm       = na

    int     loc       = bar_index

    bool    breaker   = false

    int     break_loc = na


type swing

    float y = na

    int   x = na

    bool  crossed = false


type FVG 

    box box 

    bool active

    int  pos 


var mss MSS = mss.new(

 0

 , array.new < line  >()

 , array.new < line  >() 

 , array.new < line  >()

 , array.new < line  >()

 , array.new < label >() 

 , array.new < label >()

 , array.new < label >()

 , array.new < label >()

 )


//-----------------------------------------------------------------------------}

//Variables

//-----------------------------------------------------------------------------{

maxVimb = 2


var float friCp = na, var int friCi = na // Friday Close price/index

var float monOp = na, var int monOi = na // Monday Open  price/index


var float prDCp = na, var int prDCi = na // Previous Day Open price/index

var float cuDOp = na, var int cuDOi = na // Current  Day Open price/index


var _2ln_lb [] Vimbal     = array.new<  _2ln_lb >() 


var   liq   [] b_liq_B    = array.new<    liq   >(1, liq.new(box(na), false, false, false, line(na)))

var   liq   [] b_liq_S    = array.new<    liq   >(1, liq.new(box(na), false, false, false, line(na)))


var    ob   [] bullish_ob = array.new<    ob    >()

var    ob   [] bearish_ob = array.new<    ob    >()


var bx_ln   [] bl_NWOG    = array.new<   bx_ln  >()

var bx_ln   [] bl_NDOG    = array.new<   bx_ln  >()


var bx_ln_lb[] a_bx_ln_lb = array.new< bx_ln_lb >()


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

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


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

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


var  ZZ         aZZ       = 

 ZZ.new(

 array.new < int    >(maxSize,  0), 

 array.new < int    >(maxSize,  0), 

 array.new < float  >(maxSize, na),

 array.new < bool   >(maxSize, na))


var line _diag = line.new(na, na, na, na, color=color.new(color.silver, 50), style=line.style_dashed, xloc= xloc            )

var line _vert = line.new(na, na, na, na, color=color.new(color.silver, 50), style=line.style_dotted, xloc= xloc            )

var line _zero = line.new(na, na, na, na, color=color.new(color.silver,  5), style=line.style_solid , xloc= xloc, extend=ext)

var line _0236 = line.new(na, na, na, na, color=color.new(color.orange, 25), style=line.style_solid , xloc= xloc, extend=ext)

var line _0382 = line.new(na, na, na, na, color=color.new(color.yellow, 25), style=line.style_solid , xloc= xloc, extend=ext)

var line _0500 = line.new(na, na, na, na, color=color.new(color.green , 25), style=line.style_solid , xloc= xloc, extend=ext)

var line _0618 = line.new(na, na, na, na, color=color.new(color.yellow, 25), style=line.style_solid , xloc= xloc, extend=ext)

var line _0786 = line.new(na, na, na, na, color=color.new(color.orange, 25), style=line.style_solid , xloc= xloc, extend=ext)

var line _one_ = line.new(na, na, na, na, color=color.new(color.silver,  5), style=line.style_solid , xloc= xloc, extend=ext)

var line _1618 = line.new(na, na, na, na, color=color.new(color.yellow, 25), style=line.style_solid , xloc= xloc, extend=ext)

 

//-----------------------------------------------------------------------------}

//Functions/methods

//-----------------------------------------------------------------------------{

method in_out(ZZ aZZ, int d, int x1, float y1, int x2, float y2, color col, bool b) =>

    aZZ.d.unshift(d), aZZ.x.unshift(x2), aZZ.y.unshift(y2), aZZ.b.unshift(b), aZZ.d.pop(), aZZ.x.pop(), aZZ.y.pop(), aZZ.b.pop()


method timeinrange(string res, string sess) => not na(time(timeframe.period, res, sess))


method setLine(line ln, int x1, float y1, int x2, float y2) => ln.set_xy1(x1, y1), ln.set_xy2(x2, y2)


method clear_aLine(line[] l) =>

    if l.size() > 0

        for i = l.size() -1 to 0

            l.pop().delete()


method clear_aLabLin(label[] l) =>

    if l.size() > 0

        for i = l.size() -1 to 0

            l.pop().delete()


method clear_aLabLin(line[] l) =>

    if l.size() > 0

        for i = l.size() -1 to 0

            l.pop().delete()


method notransp(color css) => color.rgb(color.r(css), color.g(css), color.b(css))


method display(ob id, css, break_css, str)=>

    if showOB

        if id.breaker

            a_bx_ln_lb.unshift(

             bx_ln_lb.new(

               box.new(id.loc, id.top, timenow + (tf_msec * 10), id.btm, na 

             , bgcolor = break_css

             , extend  = extend.none

             , xloc    = xloc.bar_time)

             , line (na)

             , label(na))

             )

        else

            y  = str == 'bl' ? id.btm : id.top

            s  = str == 'bl' ? label.style_label_up : label.style_label_down

            a_bx_ln_lb.unshift(

             bx_ln_lb.new(

               box(na)

             , line.new(id.loc,   y  , id.loc  + (tf_msec * 10),    y  

             , xloc    = xloc.bar_time, color=css, width=2)

             , label.new(              id.loc  + (tf_msec * 10),    y

             , text  = str == 'bl' ? '+OB' : '-OB'

             , xloc  = xloc.bar_time

             , style = s    , color = color(na)

             , textcolor=css, size  = size.small))

             )


swings(len)=>

    var os = 0

    var swing top = swing.new(na, na)

    var swing btm = swing.new(na, na)

    

    upper = ta.highest(len)

    lower = ta.lowest(len)


    os := high[len] > upper ? 0 

       :  low [len] < lower ? 1 : os


    if os == 0 and os[1] != 0

        top := swing.new(high[length], bar_index[length])

    

    if os == 1 and os[1] != 1

        btm := swing.new(low[length], bar_index[length])


    [top, btm]

            

set_lab(i, str) =>

    style = str == 'Bl' ? label.style_label_down : label.style_label_up

    txcol = str == 'Bl' ? color.lime : color.red

    label.new(math.round(math.avg(aZZ.x.get(i), n)), aZZ.y.get(i), text='BOS'

     , style=style, color=color(na), textcolor=txcol, size=size.tiny)

set_lin(i, str) =>

    color = str == 'Bl' ? color.lime : color.red

    line.new(aZZ.x.get(i), aZZ.y.get(i), n, aZZ.y.get(i), color=color, style=line.style_dotted)


draw(left, col) =>

    //

    max_bars_back(time, 1000)

    var int dir= na, var int x1= na, var float y1= na, var int x2= na, var float y2= na

    //

    sz       = aZZ.d.size( )

    x2      := bar_index -1

    ph       = ta.pivothigh(hi, left, 1)

    pl       = ta.pivotlow (lo, left, 1)

    if ph   

        dir := aZZ.d.get (0) 

        x1  := aZZ.x.get (0) 

        y1  := aZZ.y.get (0) 

        y2  :=      nz(hi[1])

        //

        if dir <  1  // if previous point was a pl, add, and change direction ( 1)

            aZZ.in_out( 1, x1, y1, x2, y2, col, true)

        else

            if dir ==  1 and ph > y1 

                aZZ.x.set(0, x2), aZZ.y.set(0, y2)

        //

        // liquidity

        if showLq and per and sz > 0

            count = 0

            st_P  = 0.

            st_B  = 0

            minP  = 0.

            maxP  = 10e6

            for i = 0 to math.min(sz, 50) -1

                if aZZ.d.get(i) ==  1 

                    if aZZ.y.get(i) > ph + (atr/a)

                        break

                    else

                        if aZZ.y.get(i) > ph - (atr/a) and aZZ.y.get(i) < ph + (atr/a)

                            count += 1

                            st_B := aZZ.x.get(i)

                            st_P := aZZ.y.get(i)

                            if aZZ.y.get(i) > minP

                                minP := aZZ.y.get(i)

                            if aZZ.y.get(i) < maxP 

                                maxP := aZZ.y.get(i)

            if count > 2

                getB = b_liq_B.get(0)

                if st_B == getB.bx.get_left()

                    getB.bx.set_top(math.avg(minP, maxP) + (atr/a))

                    getB.bx.set_rightbottom(n +10, math.avg(minP, maxP) - (atr/a))

                else

                    b_liq_B.unshift(liq.new(

                     box.new(

                       st_B, math.avg(minP, maxP) + (atr/a), n +10, math.avg(minP, maxP) - (atr/a)

                     , text = 'Buyside liquidity', text_size = size.tiny, text_halign = text.align_left

                     , text_valign = text.align_bottom, text_color = color.new(cLIQ_B, 25)

                     , bgcolor=color(na), border_color=color(na)

                      )

                     , false

                     , false

                     , false

                     , line.new(st_B, st_P, n -1, st_P, color = color.new(cLIQ_B, 0))

                      )

                     )      

                if b_liq_B.size() > visLiq

                    getLast = b_liq_B.pop()

                    getLast.bx.delete()

                    getLast.ln.delete()               

    //

    if pl

        dir := aZZ.d.get (0) 

        x1  := aZZ.x.get (0) 

        y1  := aZZ.y.get (0) 

        y2  :=      nz(lo[1])

        //

        if dir > -1  // if previous point was a ph, add, and change direction (-1)

            aZZ.in_out(-1, x1, y1, x2, y2, col, true)

        else

            if dir == -1 and pl < y1 

                aZZ.x.set(0, x2), aZZ.y.set(0, y2)

        //

        //Liquidity

        if showLq and per and sz > 0

            count = 0

            st_P  = 0.

            st_B  = 0

            minP  = 0.

            maxP  = 10e6

            for i = 0 to math.min(sz, 50) -1

                if aZZ.d.get(i) == -1 

                    if aZZ.y.get(i) < pl - (atr/a)

                        break

                    else

                        if aZZ.y.get(i) > pl - (atr/a) and aZZ.y.get(i) < pl + (atr/a)

                            count += 1

                            st_B := aZZ.x.get(i)

                            st_P := aZZ.y.get(i)

                            if aZZ.y.get(i) > minP

                                minP := aZZ.y.get(i)

                            if aZZ.y.get(i) < maxP 

                                maxP := aZZ.y.get(i)

            if count > 2

                getB = b_liq_S.get(0)

                if st_B == getB.bx.get_left()

                    getB.bx.set_top(math.avg(minP, maxP) + (atr/a))

                    getB.bx.set_rightbottom(n +10, math.avg(minP, maxP) - (atr/a))

                else

                    b_liq_S.unshift(liq.new(

                      box.new(

                       st_B, math.avg(minP, maxP) + (atr/a), n +10, math.avg(minP, maxP) - (atr/a)

                     , text = 'Sellside liquidity', text_size = size.tiny, text_halign = text.align_left

                     , text_valign = text.align_bottom, text_color = color.new(cLIQ_S, 25)

                     , bgcolor=color(na), border_color=color(na)

                      )

                     , false

                     , false

                     , false

                     , line.new(st_B, st_P, n -1, st_P, color = color.new(cLIQ_S, 0))

                      )

                     )  

                if b_liq_S.size() > visLiq

                    getLast = b_liq_S.pop()

                    getLast.bx.delete()

                    getLast.ln.delete()            

    //

    //Market Structure Shift 

    if showMS 

        //

        iH = aZZ.d.get(2) ==  1 ? 2 : 1

        iL = aZZ.d.get(2) == -1 ? 2 : 1

        //

        switch

            // MSS Bullish

            close > aZZ.y.get(iH) and aZZ.d.get(iH) ==  1 and MSS.dir <  1 =>

                MSS.dir :=  1 

                if i_mode == 'Present'

                    MSS.l_bosBl.clear_aLabLin(), MSS.l_bosBr.clear_aLabLin()   

                    MSS.lbBosBl.clear_aLabLin(), MSS.lbBosBr.clear_aLabLin()  

                    MSS.l_mssBl.clear_aLabLin(), MSS.l_mssBr.clear_aLabLin() 

                    MSS.lbMssBl.clear_aLabLin(), MSS.lbMssBr.clear_aLabLin() 

                //      

                MSS.l_mssBl.unshift(line.new (

                  aZZ.x.get(iH), aZZ.y.get(iH), n, aZZ.y.get(iH), color=cMSSbl))

                MSS.lbMssBl.unshift(label.new(

                  math.round(math.avg(aZZ.x.get(iH), n)), aZZ.y.get(iH), text ='MSS'

                  , style=label.style_label_down, size=size.tiny, color=color(na), textcolor=cMSSbl))

            // MSS Bearish

            close < aZZ.y.get(iL) and aZZ.d.get(iL) == -1 and MSS.dir > -1 =>

                MSS.dir := -1 

                if i_mode == 'Present'

                    MSS.l_bosBl.clear_aLabLin(), MSS.l_bosBr.clear_aLabLin()   

                    MSS.lbBosBl.clear_aLabLin(), MSS.lbBosBr.clear_aLabLin()  

                    MSS.l_mssBl.clear_aLabLin(), MSS.l_mssBr.clear_aLabLin() 

                    MSS.lbMssBl.clear_aLabLin(), MSS.lbMssBr.clear_aLabLin()

                // 

                MSS.l_mssBr.unshift(line.new (

                  aZZ.x.get(iL), aZZ.y.get(iL), n, aZZ.y.get(iL), color=cMSSbr))

                MSS.lbMssBr.unshift(label.new(

                  math.round(math.avg(aZZ.x.get(iL), n)), aZZ.y.get(iL), text ='MSS'

                  , style=label.style_label_up  , size=size.tiny, color=color(na), textcolor=cMSSbr))

            // BOS Bullish

            MSS.dir ==  1 and close > aZZ.y.get(iH) and iBOS =>

                if MSS.l_bosBl.size() > 0

                    if aZZ.y.get(iH) != MSS.l_bosBl.get(0).get_y2() and

                       aZZ.y.get(iH) != MSS.l_mssBl.get(0).get_y2()

                        MSS.l_bosBl.unshift(set_lin(iH, 'Bl')), MSS.lbBosBl.unshift(set_lab(iH, 'Bl'))

                else  

                    if aZZ.y.get(iH) != MSS.l_mssBl.get(0).get_y2()                     

                        MSS.l_bosBl.unshift(set_lin(iH, 'Bl')), MSS.lbBosBl.unshift(set_lab(iH, 'Bl'))

            // BOS Bearish

            MSS.dir == -1 and close < aZZ.y.get(iL) and iBOS =>

                if MSS.l_bosBr.size() > 0

                    if aZZ.y.get(iL) != MSS.l_bosBr.get(0).get_y2() and

                       aZZ.y.get(iL) != MSS.l_mssBr.get(0).get_y2()

                        MSS.l_bosBr.unshift(set_lin(iL, 'Br')), MSS.lbBosBr.unshift(set_lab(iL, 'Br'))

                else

                    if aZZ.y.get(iL) != MSS.l_mssBr.get(0).get_y2()                     

                        MSS.l_bosBr.unshift(set_lin(iL, 'Br')), MSS.lbBosBr.unshift(set_lab(iL, 'Br'))

        if not iMSS

            MSS.l_mssBl.get(0).set_color(color(na)), MSS.lbMssBl.get(0).set_textcolor(color(na))

            MSS.l_mssBr.get(0).set_color(color(na)), MSS.lbMssBr.get(0).set_textcolor(color(na))




//-----------------------------------------------------------------------------}

//Calculations

//-----------------------------------------------------------------------------{

draw(len, color.yellow)             


if MSS.l_bosBl.size() > 200

    MSS.l_bosBl.pop().delete()

    MSS.lbBosBl.pop().delete()


if MSS.l_bosBr.size() > 200

    MSS.l_bosBr.pop().delete()

    MSS.lbBosBr.pop().delete()


//Killzones 

ny          = time(timeframe.period, input.session('0700-0900', '', inline = 'ny', group = 'Killzones'), 'America/New_York') and showNy 

ldn_open    = time(timeframe.period, input.session('0700-1000', '', inline = 'lo', group = 'Killzones'), 'Europe/London'   ) and showLdno // 0200-0500 UTC-5

ldn_close   = time(timeframe.period, input.session('1500-1700', '', inline = 'lc', group = 'Killzones'), 'Europe/London'   ) and showLdnc // 1000-1200 UTC-5

asian       = time(timeframe.period, input.session('1000-1400', '', inline = 'as', group = 'Killzones'), 'Asia/Tokyo'      ) and showAsia // 2000-0000 UTC-5


//Pivotpoints 

ph          = ta.pivothigh(3, 1), lPh = fixnan(ph)

pl          = ta.pivotlow (3, 1), lPl = fixnan(pl)


//Candles 

L_body      = 

 high - mx  < body * perc_Body and 

 mn - low   < body * perc_Body


L_bodyUP    =   body > meanBody  and L_body and close > open

L_bodyDN    =   body > meanBody  and L_body and close < open


bsNOTbodyUP = ta.barssince(not L_bodyUP)

bsNOTbodyDN = ta.barssince(not L_bodyDN)


bsIs_bodyUP = ta.barssince(    L_bodyUP)

bsIs_bodyDN = ta.barssince(    L_bodyDN)


lwst        = math.min(lPh [bsNOTbodyUP[1]], low[bsNOTbodyUP[1]])

hgst        = math.max(high[bsNOTbodyDN[1]], lPl[bsNOTbodyDN[1]])


//Imbalance

imbalanceUP = L_bodyUP[1] and (i_FVG == 'FVG' ? low  > high[2] : low  < high[2])

imbalanceDN = L_bodyDN[1] and (i_FVG == 'FVG' ? high < low [2] : high > low [2])


//Volume Imbalance

vImb_Bl     = open > close[1] and high[1] > low  and close > close[1] and open > open[1] and high[1] < mn

vImb_Br     = open < close[1] and low [1] < high and close < close[1] and open < open[1] and low [1] > mx


if sVimbl

    if vImb_Bl

        Vimbal.unshift(

         _2ln_lb.new(

          line.new (n -1, mx[1], n +3, mx[1], color=cVimbl)

         , line.new (n   , mn   , n +3, mn   , color=cVimbl)

          , label.new(n +3, math.avg    (mx[1], mn), text='VI'

         , color=color(na) , textcolor=cVimbl, style=label.style_label_left)

          )

         )

    if vImb_Br

        Vimbal.unshift(

         _2ln_lb.new(

          line.new (n -1, mn[1], n +3, mn[1], color=cVimbl)

         , line.new (n   , mx   , n +3, mx   , color=cVimbl)

          , label.new(n +3, math.avg    (mn[1], mx), text='VI'

         , color=color(na) , textcolor=cVimbl, style=label.style_label_left)

          )

         )

    if Vimbal.size() > visVim 

        pop = Vimbal.pop()

        pop.l1.delete()

        pop.l2.delete()

        pop.lb.delete()


//Fair Value Gap  

if barstate.isfirst

    for i = 0 to visBxs -1

        bFVG_UP.unshift(FVG.new(box(na), false))

        bFVG_DN.unshift(FVG.new(box(na), false))

        if i_BPR

            bBPR_UP.unshift(FVG.new(box(na), false))

            bBPR_DN.unshift(FVG.new(box(na), false))


if imbalanceUP and per and shwFVG 

    if imbalanceUP[1]

        bFVG_UP.get(0).box.set_lefttop    (n -2, low    )

        bFVG_UP.get(0).box.set_rightbottom(n +8, high[2])

    else

        bFVG_UP.unshift(FVG.new(

          box.new(

           n -2

         ,    i_FVG == 'FVG' ? low : high[2]

         , n, i_FVG == 'FVG' ? high[2] : low

         , bgcolor     = i_BPR ? color(na) : color.new(cFVGbl, 90)

         , border_color= i_BPR ? color(na) : color.new(cFVGbl, 65)

         , text_color  = i_BPR ? color(na) : color.new(cFVGbl, 65)

         , text_size=size.small

         , text=i_FVG

         )

         , true)

         )

        bFVG_UP.pop().box.delete()


if imbalanceDN and per and shwFVG 

    if imbalanceDN[1]

        bFVG_DN.get(0).box.set_lefttop    (n -2, low[2])

        bFVG_DN.get(0).box.set_rightbottom(n +8, high  )

    else

        bFVG_DN.unshift(FVG.new(

         box.new(

           n -2

         ,    i_FVG == 'FVG' ? low[2] : high

         , n, i_FVG == 'FVG' ? high   : low[2]

         , bgcolor     = i_BPR ? color(na) : color.new(cFVGbr, 90)

         , border_color= i_BPR ? color(na) : color.new(cFVGbr, 65)

         , text_color  = i_BPR ? color(na) : color.new(cFVGbr, 65)

         , text_size=size.small

         , text=i_FVG

         )

         , true)

         )

        bFVG_DN.pop().box.delete()


//Balance Price Range (overlap of 2 latest FVG bull/bear)

if i_BPR and bFVG_UP.size() > 0 and bFVG_DN.size() > 0

    bxUP    = bFVG_UP.get(0)

    bxDN    = bFVG_DN.get(0)

    bxUPbtm = bxUP.box.get_bottom()

    bxDNbtm = bxDN.box.get_bottom()

    bxUPtop = bxUP.box.get_top()

    bxDNtop = bxDN.box.get_top()

    left    = math.min(bxUP.box.get_left (), bxDN.box.get_left ())

    right   = math.max(bxUP.box.get_right(), bxDN.box.get_right())

    //

    if bxUPbtm < bxDNtop and 

       bxDNbtm < bxUPbtm

        if left == bBPR_UP.get(0).box.get_left() 

            if  bBPR_UP.get(0).active

                bBPR_UP.get(0).box.set_right(right)

        else

            bBPR_UP.unshift(FVG.new(

             box.new(

              left, bxDNtop, right, bxUPbtm

              , bgcolor     = i_BPR ? color.new(cFVGbl, 90) : color(na)

              , border_color= i_BPR ? color.new(cFVGbl, 65) : color(na)

              , text_color  = i_BPR ? color.new(cFVGbl, 65) : color(na)

              , text_size=size.small

              , text= 'BPR'

              ) 

              , true

              , close > bxUPbtm ? 1 : close < bxDNtop ? -1 : 0

              )

             )

            bBPR_UP.pop().box.delete()

    //

    if bxDNbtm < bxUPtop and 

       bxUPbtm < bxDNbtm 

        if left == bBPR_DN.get(0).box.get_left() 

            if  bBPR_DN.get(0).active

                bBPR_DN.get(0).box.set_right(right)

        else

            bBPR_DN.unshift(FVG.new(

             box.new(

              left, bxUPtop, right, bxDNbtm

              , bgcolor     = i_BPR ? color.new(cFVGbr, 90) : color(na)

              , border_color= i_BPR ? color.new(cFVGbr, 65) : color(na)

              , text_color  = i_BPR ? color.new(cFVGbr, 65) : color(na)

              , text_size=size.small

              , text= 'BPR'

              ) 

              , true

              , close > bxDNbtm ? 1 : close < bxUPtop ? -1 : 0

              )

             )

            bBPR_DN.pop().box.delete()


//FVG's breaks

for i = 0 to math.min(bxBack, bFVG_UP.size() -1)

    getUPi = bFVG_UP.get(i)

    if getUPi.active

        getUPi.box.set_right(bar_index +8)

        if low  < getUPi.box.get_top() and not i_BPR

            getUPi.box.set_border_style(line.style_dashed)

        if low  < getUPi.box.get_bottom()

            if not i_BPR

                getUPi.box.set_bgcolor(color.new(cFVGblBR, 95))

                getUPi.box.set_border_style(line.style_dotted)

            getUPi.box.set_right(bar_index)

            getUPi.active := false


for i = 0 to math.min(bxBack, bFVG_DN.size() -1)

    getDNi = bFVG_DN.get(i)

    if getDNi.active

        getDNi.box.set_right(bar_index +8)

        if high > getDNi.box.get_bottom() and not i_BPR

            getDNi.box.set_border_style(line.style_dashed)

        if high > getDNi.box.get_top()

            if not i_BPR

                getDNi.box.set_bgcolor(color.new(cFVGbrBR, 95))

                getDNi.box.set_border_style(line.style_dotted)

            getDNi.box.set_right(bar_index)

            getDNi.active := false


if i_BPR

    for i = 0 to math.min(bxBack, bBPR_UP.size() -1)

        getUPi = bBPR_UP.get(i)

        if getUPi.active

            getUPi.box.set_right(bar_index +8)

            switch getUPi.pos 

                -1 =>

                    if high > getUPi.box.get_bottom()

                        getUPi.box.set_border_style(line.style_dashed)

                    if high > getUPi.box.get_top   ()

                        getUPi.box.set_bgcolor(color.new(cFVGblBR, 95))

                        getUPi.box.set_border_style(line.style_dotted)

                        getUPi.box.set_right(bar_index)

                        getUPi.active := false

                1 =>

                    if low  < getUPi.box.get_top   ()

                        getUPi.box.set_border_style(line.style_dashed)

                    if low  < getUPi.box.get_bottom()

                        getUPi.box.set_bgcolor(color.new(cFVGblBR, 95))

                        getUPi.box.set_border_style(line.style_dotted)

                        getUPi.box.set_right(bar_index)

                        getUPi.active := false

    

    for i = 0 to math.min(bxBack, bBPR_DN.size() -1)

        getDNi = bBPR_DN.get(i)

        if getDNi.active

            getDNi.box.set_right(bar_index +8)

            switch getDNi.pos 

                -1 =>

                    if high > getDNi.box.get_bottom()

                        getDNi.box.set_border_style(line.style_dashed)

                    if high > getDNi.box.get_top   ()

                        getDNi.box.set_bgcolor(color.new(cFVGbrBR, 95))

                        getDNi.box.set_border_style(line.style_dotted)

                        getDNi.box.set_right(bar_index)

                        getDNi.active := false

                1 =>

                    if low  < getDNi.box.get_top   ()

                        getDNi.box.set_border_style(line.style_dashed)

                    if low  < getDNi.box.get_bottom()

                        getDNi.box.set_bgcolor(color.new(cFVGbrBR, 95))

                        getDNi.box.set_border_style(line.style_dotted)

                        getDNi.box.set_right(bar_index)

                        getDNi.active := false


//NWOG/NDOG 

if barstate.isfirst 

    for i = 0 to maxNWOG -1

        bl_NWOG.unshift(bx_ln.new(box(na), line(na)))

    for i = 0 to maxNDOG -1

        bl_NDOG.unshift(bx_ln.new(box(na), line(na)))


if dayofweek == dayofweek.friday

    friCp := close, friCi := n


if ta.change(dayofweek) 

    if  dayofweek == dayofweek.monday and iNWOG

        monOp := open , monOi := n

        bl_NWOG.unshift(bx_ln.new(   

         box.new(

           friCi        ,   math.max (friCp  , monOp  )

         , monOi        ,   math.min (friCp  , monOp  )

         , bgcolor      =   color    ( na             )

         , border_color =             cNWOG2

         , extend       =             extend.right    )

         ,

         line.new(

           monOi        ,   math.avg (friCp  , monOp  ) 

         , monOi +1     ,   math.avg (friCp  , monOp  )

         , color        =             cNWOG1

         , style        =             line.style_dotted

         , extend       =             extend.right    )         

         ))

        bl = bl_NWOG.pop(), bl.b.delete(), bl.l.delete()

    if iNDOG

        cuDOp := open    , cuDOi := n

        prDCp := close[1], prDCi := n -1

        //

        bl_NDOG.unshift(bx_ln.new(   

         box.new(

           prDCi        ,   math.max (prDCp  , cuDOp  )

         , cuDOi        ,   math.min (prDCp  , cuDOp  )

         , bgcolor      =   color    ( na             )

         , border_color =             cNDOG2

         , extend       =             extend.right    )

         ,

         line.new(

           cuDOi        ,   math.avg (prDCp  , cuDOp  ) 

         , cuDOi +1     ,   math.avg (prDCp  , cuDOp  )

         , color        =             cNDOG1

         , style        =             line.style_dotted

         , extend       =             extend.right    )     

         ))

        bl = bl_NDOG.pop(), bl.b.delete(), bl.l.delete()


//Liquidity 

for i = 0 to b_liq_B.size() -1

    x = b_liq_B.get(i)

    if not x.broken

        x.bx.set_right(n +3)

        x.ln.set_x2   (n +3)

        if not x.brokenTop

            if close > x.bx.get_top   ()

                x.brokenTop := true

        if not x.brokenBtm

            if close > x.bx.get_bottom()

                x.brokenBtm := true             

        if x.brokenBtm 

            x.bx.set_bgcolor(color.new(cLIQ_B, 90))

            x.ln.delete()

            if x.brokenTop 

                x.broken := true

                x.bx.set_right(n)


for i = 0 to b_liq_S.size() -1

    x = b_liq_S.get(i)

    if not x.broken

        x.bx.set_right(n +3)

        x.ln.set_x2   (n +3)

        if not x.brokenTop

            if close < x.bx.get_top   ()

                x.brokenTop := true

        if not x.brokenBtm

            if close < x.bx.get_bottom()

                x.brokenBtm := true             

        if x.brokenTop 

            x.bx.set_bgcolor(color.new(cLIQ_S, 90))

            x.ln.delete()

            if x.brokenBtm

                x.broken := true

                x.bx.set_right(n)


//Order Blocks   

[top, btm] = swings(length)


if showOB and per

    if close > top.y and not top.crossed 

        top.crossed := true

        

        minima = max[1]

        maxima = min[1]

        loc = time[1]

        

        for i = 1 to (n - top.x)-1

            minima := math.min(min[i], minima)

            maxima := minima == min[i] ? max[i] : maxima

            loc := minima == min[i] ? time[i] : loc

        bullish_ob.unshift(ob.new(maxima, minima, loc))

    

    if bullish_ob.size() > 0 

        for i = bullish_ob.size()-1 to 0

            element = bullish_ob.get(i)

            

            if not element.breaker 

                if math.min(close, open) < element.btm

                    element.breaker := true

                    element.break_loc := time

            else

                if close > element.top

                    bullish_ob.remove(i)

                else if i < showBull and top.y < element.top and top.y > element.btm 

                    blBrkConf := 1


    //Set label

    if blBrkConf > blBrkConf[1] and showLabels

        label.new(top.x, top.y, '▼', color = na

          , textcolor = bearCss.notransp()

          , style = label.style_label_down

          , size = size.tiny)


if showOB and per

    if close < btm.y and not btm.crossed 

        btm.crossed := true


        minima = min[1]

        maxima = max[1]

        loc = time[1]


        for i = 1 to (n - btm.x)-1

            maxima := math.max(max[i], maxima)

            minima := maxima == max[i] ? min[i] : minima

            loc := maxima == max[i] ? time[i] : loc

        bearish_ob.unshift(ob.new(maxima, minima, loc))


    if bearish_ob.size() > 0 

        for i = bearish_ob.size()-1 to 0

            element = bearish_ob.get(i)


            if not element.breaker 

                if math.max(close, open) > element.top

                    element.breaker := true

                    element.break_loc := time

            else

                if close < element.btm

                    bearish_ob.remove(i)

                else if i < showBear and btm.y > element.btm and btm.y < element.top 

                    brBrkConf := 1


    //Set label

    if brBrkConf > brBrkConf[1] and showLabels 

        label.new(btm.x, btm.y, '▲', color = na

          , textcolor = bullCss.notransp()

          , style = label.style_label_up

          , size = size.tiny)


//-----------------------------------------------------------------------------}

//Set Order Blocks

//-----------------------------------------------------------------------------{

if barstate.islast and showOB 

    if a_bx_ln_lb.size() > 0

        for i = a_bx_ln_lb.size() -1 to 0 

            item = a_bx_ln_lb.remove(i)

            item.bx.delete()

            item.ln.delete()

            item.lb.delete()

    //Bullish

    if showBull > 0

        blSz = bullish_ob.size()

        if blSz > 0

            for i = 0 to math.min(showBull, bullish_ob.size()) -1

                get_ob = bullish_ob.get(i)

                get_ob.display(bullCss, bullBrkCss, 'bl')

    //Bearish

    if showBear > 0

        brSz = bearish_ob.size()

        if brSz > 0

            for i = 0 to math.min(showBear, bearish_ob.size()) -1

                get_ob = bearish_ob.get(i)

                get_ob.display(bearCss, bearBrkCss, 'br')


//-----------------------------------------------------------------------------}

//Fibonacci

//-----------------------------------------------------------------------------{

if barstate.islast

    x1 = 0, y1 = 0., x2 = 0, y2 = 0., box up = na, box dn = na

    switch iFib

        'FVG'   =>

            if bFVG_UP.size() > 0 and bFVG_DN.size() > 0

                up  := bFVG_UP.get(0).box

                dn  := bFVG_DN.get(0).box

                dnFirst = up.get_left() > dn.get_left()

                dnBottm = up.get_top () > dn.get_top ()

                x1  := dnFirst ? dn.get_left  () : up.get_left  ()

                x2  := dnFirst ? up.get_right () : dn.get_right ()

                y1  := dnFirst ? 

                 dnBottm       ? dn.get_bottom() : dn.get_top   () :

                 dnBottm       ? up.get_top   () : up.get_bottom()

                y2  := dnFirst ? 

                 dnBottm       ? up.get_top   () : up.get_bottom() :

                 dnBottm       ? dn.get_bottom() : dn.get_top   ()

        'BPR'   =>

            if bBPR_UP.size() > 0 and bBPR_DN.size() > 0

                up  := bBPR_UP.get(0).box

                dn  := bBPR_DN.get(0).box

                dnFirst = up.get_left() > dn.get_left()

                dnBottm = up.get_top () > dn.get_top ()

                x1  := dnFirst ? dn.get_left  () : up.get_left  ()

                x2  := dnFirst ? up.get_right () : dn.get_right ()

                y1  := dnFirst ? 

                 dnBottm       ? dn.get_bottom() : dn.get_top   () :

                 dnBottm       ? up.get_top   () : up.get_bottom()

                y2  := dnFirst ? 

                 dnBottm       ? up.get_top   () : up.get_bottom() :

                 dnBottm       ? dn.get_bottom() : dn.get_top   ()

        'OB'    =>

            oSz = a_bx_ln_lb.size()

            if oSz > 1

                xA = nz(

                   a_bx_ln_lb.get(oSz -1).ln.get_x1    () 

                 , a_bx_ln_lb.get(oSz -1).bx.get_left  ()

                 )

                xB = nz(

                   a_bx_ln_lb.get(oSz -2).ln.get_x1    () 

                 , a_bx_ln_lb.get(oSz -2).bx.get_left  ()

                 ) 

                AFirst = xB > xA

                //

                yAT = nz(

                   a_bx_ln_lb.get(oSz -1).ln.get_y1    () 

                 , a_bx_ln_lb.get(oSz -1).bx.get_top   ()

                 )

                yAB = nz(

                   a_bx_ln_lb.get(oSz -1).ln.get_y1    () 

                 , a_bx_ln_lb.get(oSz -1).bx.get_bottom()

                 )          

                yBT = nz(

                   a_bx_ln_lb.get(oSz -2).ln.get_y1    () 

                 , a_bx_ln_lb.get(oSz -2).bx.get_top   ()

                 )

                yBB = nz(

                   a_bx_ln_lb.get(oSz -2).ln.get_y1    () 

                 , a_bx_ln_lb.get(oSz -2).bx.get_bottom()

                 ) 

                ABottom = yAB < yBB

                //

                x1  := AFirst ? xA : xB

                x2  := AFirst ? xB : xA

                y1  := AFirst ? 

                 ABottom ? yAB : yAT :

                 ABottom ? yBT : yBB

                y2  := AFirst ? 

                 ABottom ? yBT : yBB :

                 ABottom ? yAB : yAT

        'Liq'   =>

            if b_liq_B.size() > 0 and b_liq_S.size() > 0

                xA = nz(

                   b_liq_B.get(0).ln.get_x1    () 

                 , b_liq_B.get(0).bx.get_left  ()

                 )

                xB = nz(

                   b_liq_S.get(0).ln.get_x1    () 

                 , b_liq_S.get(0).bx.get_left  ()

                 ) 

                AFirst = xB > xA

                //

                yAT = nz(

                   b_liq_B.get(0).ln.get_y1    () 

                 , b_liq_B.get(0).bx.get_top   ()

                 )

                yAB = nz(

                   b_liq_B.get(0).ln.get_y1    () 

                 , b_liq_B.get(0).bx.get_bottom()

                 )          

                yBT = nz(

                   b_liq_S.get(0).ln.get_y1    () 

                 , b_liq_S.get(0).bx.get_top   ()

                 )

                yBB = nz(

                   b_liq_S.get(0).ln.get_y1    () 

                 , b_liq_S.get(0).bx.get_bottom()

                 ) 

                ABottom = yAB < yBB

                //

                x1  := AFirst ? xA : xB

                x2  := AFirst ? xB : xA

                y1  := AFirst ? 

                 ABottom ? yAB : yAT :

                 ABottom ? yBT : yBB

                y2  := AFirst ? 

                 ABottom ? yBT : yBB :

                 ABottom ? yAB : yAT

        'VI'    =>

            if Vimbal.size() > 1

                AxA = Vimbal.get(1).l2.get_x1(), AxB = Vimbal.get(1).l1.get_x1()

                BxA = Vimbal.get(0).l2.get_x1(), BxB = Vimbal.get(0).l1.get_x1()

                AyA = Vimbal.get(1).l2.get_y1(), AyB = Vimbal.get(1).l1.get_y1()

                ByA = Vimbal.get(0).l2.get_y1(), ByB = Vimbal.get(0).l1.get_y1()

                ABt = math.min(ByA, ByB) > math.min(AyA, AyB) 

                x1 := math.max(AxA, AxB) 

                x2 := math.max(BxA, BxB) 

                y1 := ABt ? math.min(AyA, AyB) : math.max(AyA, AyB) 

                y2 := ABt ? math.max(ByA, ByB) : math.min(ByA, ByB)  

        'NWOG'  =>

            if bl_NWOG.size() > 1

                up  := bl_NWOG.get(0).b

                dn  := bl_NWOG.get(1).b

                dnFirst = up.get_left() > dn.get_left()

                dnBottm = up.get_top () > dn.get_top ()

                x1  := dnFirst ? dn.get_left () : up.get_left ()

                x2  := dnFirst ? up.get_right() : dn.get_right()

                y1  := dnFirst ? 

                 dnBottm ? dn.get_bottom() : dn.get_top   () :

                 dnBottm ? up.get_top   () : up.get_bottom()

                y2  := dnFirst ? 

                 dnBottm ? up.get_top   () : up.get_bottom() :

                 dnBottm ? dn.get_bottom() : dn.get_top   ()

    //

    if iFib != 'NONE'

        rt = math.max(x1, x2)

        lt = math.min(x1, x2)

        tp = math.max(y1, y2)

        bt = math.min(y1, y2)

        _0 = rt == x1 ? y1 : y2

        _1 = rt == x1 ? y2 : y1

        //

        df = _1 - _0

        m0236 = df * 0.236 

        m0382 = df * 0.382 

        m0500 = df * 0.500 

        m0618 = df * 0.618 

        m0786 = df * 0.786 

        m1618 = df * 1.618 

        //

        _diag.setLine(x1, y1        , x2       , y2        )

        _vert.setLine(rt, _0        , rt       , _0 + m1618)

        _zero.setLine(rt, _0        , rt + plus, _0        )

        _0236.setLine(rt, _0 + m0236, rt + plus, _0 + m0236)

        _0382.setLine(rt, _0 + m0382, rt + plus, _0 + m0382)

        _0500.setLine(rt, _0 + m0500, rt + plus, _0 + m0500)

        _0618.setLine(rt, _0 + m0618, rt + plus, _0 + m0618)

        _0786.setLine(rt, _0 + m0786, rt + plus, _0 + m0786)

        _one_.setLine(rt, _1        , rt + plus, _1        )

        _1618.setLine(rt, _0 + m1618, rt + plus, _0 + m1618)


//-----------------------------------------------------------------------------}

//Displacement

//-----------------------------------------------------------------------------{

plotshape(sDispl ? per       ? 

     L_bodyUP    ? low  : na : na : na

     , title     = 'Displacement UP'

     , style     = shape.labelup  

     , color     = color.lime

     , location  = location.belowbar)

plotshape(sDispl ? per       ?

     L_bodyDN    ? high : na : na : na

     , title     = 'Displacement DN'

     , style     = shape.labeldown

     , color     = color.red 

     , location  = location.abovebar)


//-----------------------------------------------------------------------------}

//background - Killzones

//-----------------------------------------------------------------------------{

bgcolor  (per    ? ny        ? nyCss   : na : na, editable = false)

bgcolor  (per    ? ldn_open  ? ldnoCss : na : na, editable = false)

bgcolor  (per    ? ldn_close ? ldncCss : na : na, editable = false)

bgcolor  (per    ? asian     ? asiaCss : na : na, editable = false)


//-----------------------------------------------------------------------------}

Comments

Popular posts from this blog

Karlos Algo Black V11 Sharp — Aihan Malik Daniyen— Extra Efficient

Karlos Algo Black V8 Sharp — Aihan Daniyen