MarketStructure
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © SimpleCryptoLife

//@version=5

// @description This library contains functions for identifying Lows and Highs in a rule-based way, and deriving useful information from them.

library("MarketStructure", overlay=true)

string in_showFunction = input.string(title="Show Function", defval="f_localLowHigh", options=["f_simpleLowHigh","f_localLowHigh","f_enhancedSimpleLowHigh", "f_trueLowHigh"])

// Variables derived entirely from inputs
var bool showSimple = in_showFunction == "f_simpleLowHigh"
var bool showLocal = in_showFunction == "f_localLowHigh"
var bool showEnhanced = in_showFunction == "f_enhancedSimpleLowHigh"
var bool showTrue = in_showFunction == "f_trueLowHigh"


import SimpleCryptoLife/Labels/2 as SCL_Label
color labelColour = color.new(color.white,50)



// 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦   FUNCTION 1  🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦

// @function _simpleLowHigh()  // This function finds Local Lows and Highs, but NOT in order. A Local High is any candle that has its Low taken out on close by a subsequent candle (and vice-versa for Local Lows).
// The Local High does NOT have to be the candle with the highest High out of recent candles. It does NOT have to be a Williams High. It is not necessarily a swing high or a reversal or anything else.
// It doesn't have to be "the" high, so don't be confused.
// By the rules, Local Lows and Highs must alternate. In this function they do not, so I'm calling them Simple Lows and Highs.
// Simple Highs and Lows, by the above definition, can be useful for entries and stops. Because I intend to use them for stops, I want them all, not just the ones that alternate in strict order.
// @param - there are no parameters. The function uses the chart OHLC.
// @returns boolean values for whether this bar confirms a Simple Low/High, and ints for the bar_index of that Low/High.

export f_simpleLowHigh() =>
    var float _trailingLow = na, var float _trailingHigh = na  // Trail for the low (which is used to confirm Highs), and the high (used to confirm Lows).
    var int _simpleHighIndex = na, var int _simpleLowIndex = na  // The bar index of the Simple High/Low when confirmed.
    var int _trailingLowIndex = na, var int _trailingHighIndex = na  // The bar index of the last low that changed the trailing low, or high for trailing high.
    // Setup for Highs
    if low > _trailingLow or (na(_trailingLow) and (low > low[1]))
        _trailingLow := low  // Trail the lows up. If higher, reset, otherwise persist.
        _trailingLowIndex := bar_index  // When you change the trailing low, store the bar index.
    // Setup for Lows
    if high < _trailingHigh or (na(_trailingHigh) and (high < high[1]))
        _trailingHigh := high  // Trail the highs down. If lower, reset, otherwise persist.
        _trailingHighIndex := bar_index  // When you change the trailing high, store the bar index.
    // Confirm Highs, Lows
    bool _isSimpleHigh = close < _trailingLow  // Confirm a High on close below the trailing low.
    bool _isSimpleLow = close > _trailingHigh   // Confirm a Low on close above the trailing high.
    // Cleanup
    if _isSimpleHigh
        _trailingLow := na  // When a High is confirmed, unset the trailing low line.
        _simpleHighIndex := _trailingLowIndex  // And store the bar index of the High.
    if _isSimpleLow
        _trailingHigh := na  // When a Low is confirmed, unset the trailing high line.
        _simpleLowIndex := _trailingHighIndex  // And store the bar index of the Low.
    [_isSimpleHigh, _isSimpleLow, _simpleHighIndex, _simpleLowIndex]


// Example usage

[isSimpleHigh, isSimpleLow, simpleHighIndex, simpleLowIndex] = f_simpleLowHigh()

plotshape(showSimple ? isSimpleHigh : na, title="Simple High Confirmed", style=shape.arrowdown, color=color.red, location=location.abovebar, size=size.small)
plotshape(showSimple ? isSimpleLow : na, title="Simple Low Confirmed", style=shape.arrowup, color=color.green, location=location.belowbar, size=size.small)

int offsetHighSimple = simpleHighIndex - bar_index, int offsetLowSimple = simpleLowIndex - bar_index  // Offset for the label must be negative to offset to the left.
int historyHighSimple = bar_index - simpleHighIndex, int historyLowSimple = bar_index - simpleLowIndex   // Offset for the historical operator must be the other way round.

// We have to use a label because plotshape and plotchar don't work for some reason with series offsets even though they're supposed to.
if showSimple and isSimpleLow
    SCL_Label.labelLast(_text="Simple\nLow", _keepLast = false, _offset=offsetLowSimple, _y=low[historyLowSimple], _textAlign=text.align_left, _style=label.style_label_up, _color=labelColour)
if showSimple and isSimpleHigh
    SCL_Label.labelLast(_text="Simple\nHigh", _keepLast = false, _offset=offsetHighSimple, _y=high[historyHighSimple], _textAlign=text.align_left, _style=label.style_label_down, _color=labelColour)



// 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦   FUNCTION 2  🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦

// @function f_localLowHigh()  // This function finds Local Lows and Highs, in order. A Local High is any candle that has its Low taken out on close by a subsequent candle (and vice-versa for Local Lows).
// The Local High does NOT have to be the candle with the highest High out of recent candles. It does NOT have to be a Williams High. It is not necessarily a swing high or a reversal or anything else.
// By the rules, Local Lows and Highs must alternate, and in this function they do.
// @param - there are no parameters. The function uses the chart OHLC.
// @returns boolean values for whether this bar confirms a Local Low/High, and ints for the bar_index of that Low/High.

export f_localLowHigh() =>
    var float _trailingLow = na, var float _trailingHigh = na  // Trail for the low (which is used to confirm Highs), and the high (used to confirm Lows).
    var int _simpleHighIndex = na, var int _simpleLowIndex = na  // The bar index of the Simple High/Low when confirmed.
    var int _trailingLowIndex = na, var int _trailingHighIndex = na  // The bar index of the last low that changed the trailing low, or high for trailing high.
    var string _lastPivot = na  // Store whether the most recent pivot was a High or Low. 
    var bool _isStrictLocalHigh = na, var bool _isStrictLocalLow = na  // Whether the Local High/Low counts, because it's in order.
    // Setup for Highs
    if low > _trailingLow or (na(_trailingLow) and (low > low[1]))
        _trailingLow := low  // Trail the lows up. If higher, reset, otherwise persist.
        _trailingLowIndex := bar_index  // When you change the trailing low, store the bar index.
    // Setup for Lows
    if high < _trailingHigh or (na(_trailingHigh) and (high < high[1]))
        _trailingHigh := high  // Trail the highs down. If lower, reset, otherwise persist.
        _trailingHighIndex :=  bar_index  // When you change the trailing high, store the bar index.
    // Confirm Highs, Lows
    bool _isLocalHigh = (close < _trailingLow)  // Confirm a High on close below the trailing low.
    bool _isLocalLow = (close > _trailingHigh)   // Confirm a Low on close above the trailing high.
    // Cleanup
    if _isLocalHigh
        _trailingLow := na  // When a High is confirmed, unset the trailing low line.
        _simpleHighIndex := _trailingLowIndex  // And store the bar index of the High.
    if _isLocalLow
        _trailingHigh := na  // When a Low is confirmed, unset the trailing high line.
        _simpleLowIndex := _trailingHighIndex  // And store the bar index of the Low.
    // Promote Highs, Lows only in strict order
    if _isLocalHigh and _lastPivot != "High"
        _isStrictLocalHigh := true
        _lastPivot := "High"
    else
        _isStrictLocalHigh := false
    if _isLocalLow and _lastPivot != "Low"
        _isStrictLocalLow := true
        _lastPivot := "Low"
    else
        _isStrictLocalLow := false

    [_isStrictLocalHigh, _isStrictLocalLow, _simpleHighIndex, _simpleLowIndex, _trailingHigh, _trailingLow]


// Example usage
[isLocalHigh, isLocalLow, localHighIndex, localLowIndex, trailingHigh, trailingLow] = f_localLowHigh()

plotshape(showLocal ? isLocalHigh : na, title="Local High Confirmed", style=shape.arrowdown, color=color.red, location=location.abovebar, size=size.small)
plotshape(showLocal ? isLocalLow : na, title="Local Low Confirmed", style=shape.arrowup, color=color.green, location=location.belowbar, size=size.small)

int offsetHighLocal = localHighIndex - bar_index, int offsetLowLocal = localLowIndex - bar_index  // Offset for the label must be negative to offset to the left.
int historyHighLocal = bar_index - localHighIndex, int historyLowLocal = bar_index - localLowIndex   // Offset for the historical operator must be the other way round.

if showLocal and isLocalLow
    SCL_Label.labelLast(_text="Local\nLow", _keepLast = false, _offset=offsetLowLocal, _y=low[historyLowLocal], _textAlign=text.align_left, _style=label.style_label_up, _color=labelColour)
if showLocal and isLocalHigh
    SCL_Label.labelLast(_text="Local\nHigh", _keepLast = false, _offset=offsetHighLocal, _y=high[historyHighLocal], _textAlign=text.align_left, _style=label.style_label_down, _color=labelColour)



// 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦   FUNCTION 3  🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦

// @function f_enhancedSimpleLowHigh()  // This function finds Local Lows and Highs, but NOT in order. A Local High is any candle that has its Low taken out on close by a subsequent candle (and vice-versa for Local Lows).
// The Local High does NOT have to be the candle with the highest High out of recent candles. It does NOT have to be a Williams High. It is not necessarily a swing high or a reversal or anything else.
// By the rules, Local Lows and Highs must alternate. In this function they do not, so I'm calling them Simple Lows and Highs.
// Simple Highs and Lows, by the above definition, can be useful for entries and stops. Because I intend to use them for trailing stops, I want them all, not just the ones that alternate in strict order.
// The difference between this function and f_simpleLowHigh() is that it also tracks the lowest/highest recent level. This level can be useful for trailing stops.
// In effect, these are like more "normal" highs and lows that you would pick by eye, but confirmed faster in many cases than by waiting for the low/high of that particular candle to be taken out on close, 
// because they are instead confirmed by ANY subsequent candle having its low/high exceeded. Hence, I call these Enhanced Simple Lows/Highs.
// The levels are taken from the extreme highs/lows, but the bar indexes are given for the candles that were actually used to confirm the Low/High. 
// This is by design, because it might be misleading to label the extreme, since we didn't use that candle to confirm the Low/High..
// @param - there are no parameters. The function uses the chart OHLC.
// @returns - boolean values for whether this bar confirms an Enhanced Simple Low/High
//      ints for the bar_index of that Low/High
//      floats for the values of the recent high/low levels
//      floats for the trailing high/low levels (for debug/post-processing)
//      bools for market structure bias


export f_enhancedSimpleLowHigh() =>
    var float _trailingLow = na, var float _trailingHigh = na  // Trail for the low (which is used to confirm Highs), and the high (used to confirm Lows).
    var int _enhancedHighIndex = na, var int _enhancedLowIndex = na  // The bar index of the Simple High/Low when confirmed.
    var int _trailingLowIndex = na, var int _trailingHighIndex = na  // The bar index of the last low that changed the trailing low, or high for trailing high.
    var bool _pivotHighModeUp = na, var bool _pivotLowModeDown = na  // Whether we are trailing the pivot high line up/low line down or not.
    var float _pivotHighTrail = na, var float _pivotLowTrail = na  // Levels used only to track recent highest/lowest levels to plot. They're NOT used to confirm highs/lows.
    var float _pivotHigh = na, var float _pivotLow = na  // The levels of the most recent confirmed Enhanced High/Low.
    
    // Setup for calculating Highs
    if low > _trailingLow or (na(_trailingLow) and (low > low[1]))
        _trailingLow := low  // Trail the lows up. If higher, reset, otherwise persist.
        _trailingLowIndex := bar_index  // When you change the trailing low, store the bar index.
    // Setup for calculating Lows
    if high < _trailingHigh or (na(_trailingHigh) and (high < high[1]))
        _trailingHigh := high  // Trail the highs down. If lower, reset, otherwise persist.
        _trailingHighIndex := bar_index  // When you change the trailing high, store the bar index.
    // Confirm Highs, Lows
    bool _isEnhancedHigh = close < _trailingLow  // Confirm a High on close below the trailing low.
    bool _isEnhancedLow = close > _trailingHigh   // Confirm a Low on close above the trailing high.
    
    // Track pivot levels
    _pivotHighModeUp := na(_pivotHighTrail) and high > high[1] ? true : _isEnhancedHigh ? false : _pivotHighModeUp
    _pivotHighTrail := _pivotHighModeUp and high > _pivotHighTrail ? high : _pivotHighModeUp and na(_pivotHighTrail) ? high : _pivotHighTrail
    _pivotLowModeDown := na(_pivotLowTrail) and low < low[1] ? true : _isEnhancedLow ? false : _pivotLowModeDown
    _pivotLowTrail := _pivotLowModeDown and low < _pivotLowTrail ? low : _pivotLowModeDown and na(_pivotLowTrail) ? low : _pivotLowTrail

    // Cleanup
    if _isEnhancedHigh
        _trailingLow := na  // When a High is confirmed, unset the trailing low line.
        _enhancedHighIndex := _trailingLowIndex  // And store the bar index of the High.
        _pivotHigh := na(_pivotHighTrail) ? math.max(high, high[1]) : math.max(_pivotHighTrail,high)  // Reset the pivot high line
        _pivotHighTrail := na  // Unset the pivot high trail
    if _isEnhancedLow
        _trailingHigh := na  // When a Low is confirmed, unset the trailing high line.
        _enhancedLowIndex := _trailingHighIndex  // And store the bar index of the Low.
        _pivotLow := na(_pivotLowTrail) ? math.min(low, low[1]) : math.min(_pivotLowTrail, low)  // Reset the pivot low line
        _pivotLowTrail := na  // Unset the pivot high trail

    // Market Structure bias
    var bool _isBullish = na, var bool _isBearish = na  // Market structure bias
    _isBullish := close > _pivotHigh ? true : _isBearish ? false : _isBullish
    _isBearish := close < _pivotLow ? true : _isBullish ? false : _isBearish
    if na(_isBullish) and na(_isBearish)  // Approximate bias on first pivot
        _isBullish := _isEnhancedLow ? true : _isBullish
        _isBearish := _isEnhancedHigh ? true : _isBearish

    [_isEnhancedHigh, _isEnhancedLow, _enhancedHighIndex, _enhancedLowIndex, _pivotHighTrail, _pivotHigh, _pivotLowTrail, _pivotLow, _isBullish, _isBearish]


// Example usage

[isEnhancedHigh, isEnhancedLow, enhancedHighIndex, enhancedLowIndex, pivotHighTrail, pivotHigh, pivotLowTrail, pivotLow, enhancedBullish, enhancedBearish] = f_enhancedSimpleLowHigh()

plotshape(showEnhanced ? isEnhancedHigh : na, title="Enhanced Simple High Confirmed", style=shape.arrowdown, color=color.red, location=location.abovebar, size=size.small)
plotshape(showEnhanced ? isEnhancedLow : na, title="Enhanced Simple Low Confirmed", style=shape.arrowup, color=color.green, location=location.belowbar, size=size.small)

int offsetHighEnhanced = enhancedHighIndex - bar_index, int offsetLowEnhanced = enhancedLowIndex - bar_index  // Offset for the label must be negative to offset to the left.
int historyHighEnhanced = bar_index - enhancedHighIndex, int historyLowEnhanced = bar_index - enhancedLowIndex   // Offset for the historical operator must be the other way round.

// We have to use a label because plotshape and plotchar don't work for some reason with series offsets even though they're supposed to.
if showEnhanced and isEnhancedLow
    SCL_Label.labelLast(_text="Enhanced\nLow", _keepLast = false, _offset=offsetLowEnhanced, _y=low[historyLowEnhanced], _textAlign=text.align_left, _style=label.style_label_up, _color=labelColour)
if showEnhanced and isEnhancedHigh
    SCL_Label.labelLast(_text="Enhanced\nHigh", _keepLast = false, _offset=offsetHighEnhanced, _y=high[historyHighEnhanced], _textAlign=text.align_left, _style=label.style_label_down, _color=labelColour)

plot(showEnhanced ? pivotHighTrail : na, title="Recent High Level", linewidth=1, color=color.green, style=plot.style_linebr)
plot(showEnhanced ? pivotHigh : na, title="Enhanced High Level", linewidth=4, color=color.new(color.green,50), style=plot.style_linebr)

plot(showEnhanced ? pivotLowTrail : na, title="Recent Low Level", linewidth=1, color=color.red, style=plot.style_linebr)
plot(showEnhanced ? pivotLow : na, title="Enhanced Low Level", linewidth=4, color=color.new(color.red,50), style=plot.style_linebr)

enhancedBackGroundColour = not showEnhanced ? na : enhancedBullish ? color.new(color.green,80) : enhancedBearish ? color.new(color.red,80) : na
bgcolor(enhancedBackGroundColour)



// 🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦   FUNCTION 4  🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦🟦

// @function f_trueLowHigh()  // This function finds True Lows and Highs.
// A True High is the candle with the highest recent high, which then has its low taken out on close by a subsequent candle (and vice-versa for True Lows).
// The difference between this and an Enhanced High is that confirmation requires not just any Simple High, but confirmation of the very candle that has the highest high.
// Because of this, confirmation is often later, and multiple Simple Highs and Lows can develop within ranges formed by a single big candle without any of them being confirmed. This is by design.
// A True High looks like the intuitive "real high" when you look at the chart. True Lows and Highs must alternate.
// @param - there are no parameters. The function uses the chart OHLC.
// @returns - boolean values for whether this bar confirms an Enhanced Simple Low/High
//      ints for the bar_index of that Low/High
//      floats for the values of the recent high/low levels
//      floats for the trailing high/low levels (for debug/post-processing)
//      bools for market structure bias


export f_trueLowHigh() =>
    var float _trailingLow = na, var float _trailingHigh = na  // Trail for the low (which is used to confirm Highs), and the high (used to confirm Lows).
    var int _trueHighIndex = na, var int _trueLowIndex = na  // The bar index of the True High/Low when confirmed.
    var int _trailingLowIndex = na, var int _trailingHighIndex = na  // The bar index of the last low that changed the trailing low, or high for trailing high.
    var string _lastPivot = na  // Store whether the most recent pivot was a High or Low. 
    var bool _isTrueHigh = na, var bool _isTrueLow = na  // Whether the Local High/Low counts, because it's in order.
    var bool _pivotHighModeUp = na, var bool _pivotLowModeDown = na  // Whether we are trailing the pivot high line up/low line down or not.
    var float _pivotHighTrail = na, var float _pivotLowTrail = na  // Levels used only to track recent highest/lowest levels to plot. Here, they ARE used to identify the candle from which to confirm highs/lows.
    var float _pivotHigh = na, var float _pivotLow = na  // The levels of the most recent confirmed Enhanced High/Low.

    // Track pivot levels
    _pivotHighModeUp := na(_pivotHighTrail) and high > high[1] ? true : _isTrueHigh ? false : _pivotHighModeUp
    _pivotHighTrail := _pivotHighModeUp and high > _pivotHighTrail ? high : _pivotHighModeUp and na(_pivotHighTrail) ? high : _pivotHighTrail
    _pivotLowModeDown := na(_pivotLowTrail) and low < low[1] ? true : _isTrueLow ? false : _pivotLowModeDown
    _pivotLowTrail := _pivotLowModeDown and low < _pivotLowTrail ? low : _pivotLowModeDown and na(_pivotLowTrail) ? low : _pivotLowTrail

    // Setup for Highs
    if high > _pivotHighTrail[1] or na(_pivotHighTrail[1]) and not na(_pivotHighTrail)
        _trailingLow := low  // Trail the lows up. If higher, reset, otherwise persist.
        _trailingLowIndex := bar_index  // When you change the trailing low, store the bar index.
   
    // Setup for Lows
    var bool _debug1 = na 
    if low < _pivotLowTrail[1] or na(_pivotLowTrail[1]) and not na(_pivotLowTrail)
        _trailingHigh := high  // Trail the highs down and stop when we reach a low. If lower, reset, otherwise persist.
        _trailingHighIndex :=  bar_index  // When you change the trailing high, store the bar index.

    // Confirm Highs, Lows
    bool _isLocalHigh = (close < _trailingLow)  // Confirm a High on close below the trailing low.
    bool _isLocalLow = (close > _trailingHigh)   // Confirm a Low on close above the trailing high.

    // Cleanup
    if _isLocalHigh
        _trailingLow := na  // When a High is confirmed, unset the trailing low line.
        _trueHighIndex := _trailingLowIndex  // And store the bar index of the High.
    if _isLocalLow
        _trailingHigh := na  // When a Low is confirmed, unset the trailing high line.
        _trueLowIndex := _trailingHighIndex  // And store the bar index of the Low.
    
    // Promote Highs, Lows only in strict order
    if _isLocalHigh and _lastPivot != "High"
        _isTrueHigh := true
        _lastPivot := "High"
    else
        _isTrueHigh := false
    if _isLocalLow and _lastPivot != "Low"
        _isTrueLow := true
        _lastPivot := "Low"
    else
        _isTrueLow := false
    
    // Moar cleanup
    if _isTrueHigh
        _pivotHigh := na(_pivotHighTrail) ? math.max(high, high[1]) : math.max(_pivotHighTrail,high)  // Reset the pivot high line
        _pivotHighTrail := na  // Unset the pivot high trail
        _pivotLowTrail := low 
        _trailingHigh := high  
        _trailingHighIndex := bar_index  // Reset the trailing high index, which will reset the True Low Index in due course
    if _isTrueLow
        _pivotLow := na(_pivotLowTrail) ? math.min(low, low[1]) : math.min(_pivotLowTrail, low)  // Reset the pivot low line
        _pivotLowTrail := na  // Unset the pivot high trail
        _pivotHighTrail := high
        _trailingLow := low 
        _trailingLowIndex := bar_index

    // Market Structure bias
    var bool _isBullish = na, var bool _isBearish = na  // Market structure bias
    _isBullish := close > _pivotHigh ? true : _isBearish ? false : _isBullish  // Flip bullish when we make a higher high
    _isBearish := close < _pivotLow ? true : _isBullish ? false : _isBearish
    if na(_isBullish) and na(_isBearish)  // Approximate bias on first pivot
        _isBullish := _isTrueLow ? true : _isBullish
        _isBearish := _isTrueHigh ? true : _isBearish

    [_isTrueHigh, _isTrueLow, _trueHighIndex, _trueLowIndex, _pivotHighTrail, _pivotHigh, _pivotLowTrail, _pivotLow, _isBullish, _isBearish]


// Example usage

[isTrueHigh, isTrueLow, trueHighIndex, trueLowIndex, trueHighTrail, trueHigh, trueLowTrail, trueLow, trueBullish, trueBearish] = f_trueLowHigh()

plotshape(showTrue ? isTrueHigh : na, title="True High Confirmed", style=shape.arrowdown, color=color.red, location=location.abovebar, size=size.small)
plotshape(showTrue ? isTrueLow : na, title="True Low Confirmed", style=shape.arrowup, color=color.green, location=location.belowbar, size=size.small)

int offsetHighTrue = trueHighIndex - bar_index, int offsetLowTrue = trueLowIndex - bar_index  // Offset for the label must be negative to offset to the left.
int historyHighTrue = bar_index - trueHighIndex, int historyLowTrue = bar_index - trueLowIndex   // Offset for the historical operator must be the other way round.

if showTrue and isTrueLow
    SCL_Label.labelLast(_text="True\nLow", _keepLast = false, _offset=offsetLowTrue, _y=low[historyLowTrue], _textAlign=text.align_left, _style=label.style_label_up, _color=labelColour)
if showTrue and isTrueHigh
    SCL_Label.labelLast(_text="True\nHigh", _keepLast = false, _offset=offsetHighTrue, _y=high[historyHighTrue], _textAlign=text.align_left, _style=label.style_label_down, _color=labelColour)

plot(showTrue ? trueHighTrail : na, title="Recent High Level", linewidth=1, color=color.green, style=plot.style_linebr)
plot(showTrue ? trueHigh : na, title="True High Level", linewidth=4, color=color.new(color.green,50), style=plot.style_linebr)

plot(showTrue ? trueLowTrail : na, title="Recent Low Level", linewidth=1, color=color.red, style=plot.style_linebr)
plot(showTrue ? trueLow : na, title="True Low Level", linewidth=4, color=color.new(color.red,50), style=plot.style_linebr)

trueBackGroundColour = not showTrue ? na : trueBullish ? color.new(color.green,80) : trueBearish ? color.new(color.red,80) : na
bgcolor(trueBackGroundColour)


// ================================================= //
//                                                   //
//   (╯°□°）╯︵ ¡sʎɐʍlɐ `ʇsɹᴉɟ ǝɹnʇɔnɹʇs ʇǝʞɹɐW      //
//                                                   //
// ================================================= //