blackFLAG FTS - SwingArm Trend Indicator using ATRTrailing Stop and Fibonacci Retracements

Status
Not open for further replies.
@guyonabuffalo Not sure if it would fit your trading style but if you like the Waddah Attar Explosion and Ray Bull Power indicators then you might also like the Didi Index indicator... It can help stay in trends longer even when they may not look like trends... I run a modified version of the one posted here in the forums at https://usethinkscript.com/threads/...erts-and-mtf-scanner-for-tos.4793/#post-44440... Not sure if will help you or not but I've used it with several setups...
 
I need some help in creating a label for the Swingarm zone that displays the distance from the trailing stop line to the Fib3 line and based on that display the position size to take based on the dollar risk set in the label parameters. I have found a similar label on the forum and think it can be used as reference / modification.

Edit: With my limited copy and paste knowledge I combined the two together. (y)

Code:
input RiskUnit = 100;
input AggregationPeriod = AggregationPeriod.FIFTEEN_MIN;

def highVal = Round(Fib3, 2);
def lowVal = Round(TrailingStop, 2);

AddLabel(
    yes,
    "High: " + highVal + " Low: " + lowVal,
    Color.Gray
    );

def diff = highVal-LowVal;

AddLabel(
    yes,
    AsDollars(RiskUnit) + " risk with " + AsDollars(diff) + " stop = " + Floor(Round(RiskUnit/diff)) + " shares",
    Color.Gray
    );
 
Last edited:
I need some help in creating a label for the Swingarm zone that displays the distance from the trailing stop line to the Fib3 line and based on that display the position size to take based on the dollar risk set in the label parameters. I have found a similar label on the forum and think it can be used as reference / modification.

Edit: With my limited copy and paste knowledge I combined the two together. (y)

Code:
input RiskUnit = 100;
input AggregationPeriod = AggregationPeriod.FIFTEEN_MIN;

def highVal = Round(Fib3, 2);
def lowVal = Round(TrailingStop, 2);

AddLabel(
    yes,
    "High: " + highVal + " Low: " + lowVal,
    Color.Gray
    );

def diff = highVal-LowVal;

AddLabel(
    yes,
    AsDollars(RiskUnit) + " risk with " + AsDollars(diff) + " stop = " + Floor(Round(RiskUnit/diff)) + " shares",
    Color.Gray
    );
Gives 4 errors.
 
@unkownriver

This has shades, no bubbles.

Picture is SPY on 1 min. chart http://tos.mx/p31Urnx

The yellow line is 50% fib.

LR4O0Ml.png
@chewie76 where is Fib .618, a stronger support or resistance level, thanks!
 
@madantv73 I don't recall seeing any backtesting strategy for this indicator. However, it should be fairly simple to set one up. How would you like the buy and sell orders to be triggered? I would keep the conditions within the SwingArm indicator's scope and not get any other scripts involved to simplify the coding process.
Hi Ben, can you create a strategy that opens a position when price crosses the fib3(88.6) level? I've done it with the close of the candle but I'd like it to trigger whenever price touches that 88.6 level.
 
@fjr1300 - thanks for your research and helping heart.

I am still a beginner trying to get success ..

https://tos.mx/lEkVYbC
Added all the studies those discussed in this group with latest code.
this is with white background. So edited a bit to change colors. Also shortened the comments in the bubbles.
I hope this is useful and let me know if you find anything wrong with this.

https://tos.mx/lEkVYbC
I can I remove all of the bubbles and names
 
Could you share the code for close of the candle? I've been trying to create a strategy but no success.
The addorder are at the bottom. As you can see I was playing around with different ways but I couldn't figure it out. Unfortunately I've moved onto a different strategy. Not because this one doesn't work, it really does, but I've found another that fits my style a bit better. If you do figure it out though, please post the results.

Code:
# Original Code From: TD Ameritrade IP Company, Inc. (c) 2009-2020
# Original StudyName: ATRTrailingStop
# Type: Study


# blackFLAG FTS SwingArms
# StudyName: blackFLAG_Futures_SwingArm_ATRTrail
# My preferred setting is 28 / 5 FOR ALL TIMEFRAMES
# Edited by: Jose Azcarate
# blackFLAG Futures Trading - FOR EDUCATIONAL PURPOSES ONLY
# TWITTER: @blackflagfuture
# UPDATED: 5/16/2020


# NOTE:  WHEN IMPORTING STUDY, MAKE SURE YOU UPDATE THE LOOK AND FEEL TO MATCH MY CHARTS WITHIN THE STUDY SETTINGS. 


#-----------------------------------
#-----------------------------------
# BUY & SELL ALERTS ARE CREATED BY THE HULL MOVING AVERAGE TURNING POINTS STUDY AND MUST BE IN AGREEMENT WITH SWINGARM SUPPORT OR RESISTANCE ZONES TO BE VALID. (UseThinkScript.com by mashume - Upper Study).  MY UPDATED CODE INCLUDES THE BUY / SELL BUBBLES. THE SETTINGS ARE:  1 MIN: 255 PERIOD; 5 MIN: 255 PERIOD; 4 HOUR 255 PERIOD.
#-----------------------------------
#-----------------------------------




input trailType = {default modified, unmodified};
input ATRPeriod = 28;
input ATRFactor = 5;
input firstTrade = {default long, short};
input averageType = AverageType.WILDERS;


input fib1Level = 61.8;
input fib2Level = 78.6;
input fib3Level = 88.6;


Assert(ATRFactor > 0, "'atr factor' must be positive: " + ATRFactor);


def HiLo = Min(high - low, 1.5 * Average(high - low, ATRPeriod));
def HRef = if low <= high[1]
    then high - close[1]
    else (high - close[1]) - 0.5 * (low - high[1]);
def LRef = if high >= low[1]
    then close[1] - low
    else (close[1] - low) - 0.5 * (low[1] - high);


def trueRange;
switch (trailType) {
case modified:
    trueRange = Max(HiLo, Max(HRef, LRef));
case unmodified:
    trueRange = TrueRange(high, close, low);
}
def loss = ATRFactor * MovingAverage(averageType, trueRange, ATRPeriod);


def state = {default init, long, short};
def trail;
switch (state[1]) {
case init:
    if (!IsNaN(loss)) {
        switch (firstTrade) {
        case long:
            state = state.long;
            trail = close - loss;
        case short:
            state = state.short;
            trail = close + loss;
    }
    } else {
        state = state.init;
        trail = Double.NaN;
    }
case long:
    if (close > trail[1]) {
        state = state.long;
        trail = Max(trail[1], close - loss);
    } else {
        state = state.short;
        trail = close + loss;
    }
case short:
    if (close < trail[1]) {
        state = state.short;
        trail = Min(trail[1], close + loss);
    } else {
        state = state.long;
        trail = close - loss;
    }
}


def BuySignal = Crosses(state == state.long, 0, CrossingDirection.ABOVE);
def SellSignal = Crosses(state == state.short, 0, CrossingDirection.ABOVE);


def ex = if BuySignal then high else if SellSignal then low else if state == state.long then Max(ex[1], high) else if state == state.short then Min(ex[1], low) else ex[1];


plot TrailingStop = trail;


TrailingStop.SetPaintingStrategy(PaintingStrategy.POINTS);
TrailingStop.DefineColor("Long", Color.GREEN);
TrailingStop.DefineColor("Short", Color.RED);
TrailingStop.AssignValueColor(if state == state.long
    then TrailingStop.Color("Long")
    else TrailingStop.Color("Short"));


plot Extremum = ex;
Extremum.SetPaintingStrategy(PaintingStrategy.POINTS);
Extremum.DefineColor("HH", Color.GREEN);
Extremum.DefineColor("LL", Color.RED);
Extremum.AssignValueColor(if state == state.long
    then Extremum.Color("HH")
    else Extremum.Color("LL"));
Extremum.Hide();


def f1 = ex + (trail - ex) * fib1Level / 100;
def f2 = ex + (trail - ex) * fib2Level / 100;
def f3 = ex + (trail - ex) * fib3Level / 100;
def l100 = trail + 0;


plot Fib1 = f1;
Fib1.SetPaintingStrategy(PaintingStrategy.POINTS);
Fib1.SetDefaultColor(Color.BLACK);
Fib1.Hide();


plot Fib2 = f2;
Fib2.SetPaintingStrategy(PaintingStrategy.POINTS);
Fib2.SetDefaultColor(Color.BLACK);
Fib2.Hide();


plot Fib3 = f3;
Fib3.SetPaintingStrategy(PaintingStrategy.POINTS);
Fib3.SetDefaultColor(Color.BLACK);
Fib3.Hide();


AddCloud(f1, f2, Color.LIGHT_GREEN, Color.LIGHT_RED, no);
AddCloud(f2, f3, Color.GREEN, Color.RED, no);
AddCloud(f3, l100, Color.DARK_GREEN, Color.DARK_RED, no);


def l1 = state[1] == state.long and close crosses below f1[1];
def l2 = state[1] == state.long and close crosses below f2[1];
def l3 = state[1] == state.long and close crosses below f3[1];
def s1 = state[1] == state.short and close crosses above f1[1];
def s2 = state[1] == state.short and close crosses above f2[1];
def s3 = state[1] == state.short and close crosses above f3[1];


def atr = Average(TrueRange(high, close, low), 14);


plot LS1 = if l1 then low - atr else Double.NaN;
plot LS2 = if l2 then low - 1.5 * atr else Double.NaN;
plot LS3 = if l3 then low - 2 * atr else Double.NaN;
plot SS1 = if s1 then high + atr else Double.NaN;
plot SS2 = if s2 then high + 1.5 * atr else Double.NaN;
plot SS3 = if s3 then high + 2 * atr else Double.NaN;


LS1.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
LS1.SetDefaultColor(Color.GREEN);
LS1.SetLineWeight(1);
LS1.Hide();
LS2.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
LS2.SetDefaultColor(Color.GREEN);
LS2.SetLineWeight(1);
LS2.Hide();
LS3.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
LS3.SetDefaultColor(Color.GREEN);
LS3.SetLineWeight(1);
LS3.Hide();


SS1.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
SS1.SetDefaultColor(Color.RED);
SS1.SetLineWeight(1);
SS1.Hide();
SS2.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
SS2.SetDefaultColor(Color.RED);
SS2.SetLineWeight(1);
SS2.Hide();
SS3.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
SS3.SetDefaultColor(Color.RED);
SS3.SetLineWeight(1);
SS3.Hide();


Alert(l1, "Price crossed below Fib1 level in long trend", Alert.BAR, Sound.Bell);
#Alert(l2, "Price crossed below Fib2 level in long trend", Alert.BAR, Sound.Bell);
#Alert(l3, "Price crossed below Fib3 level in long trend", Alert.BAR, Sound.Bell);
Alert(s1, "Price crossed above Fib1 level in short trend", Alert.BAR, Sound.Bell);
#Alert(s2, "Price crossed above Fib2 level in short trend", Alert.BAR, Sound.Bell);
#Alert(s3, "Price crossed above Fib3 level in short trend", Alert.BAR, Sound.Bell);


#AddOrder(OrderType.BUY_TO_OPEN, condition = l3, price = open, 1, tickColor = GetColor(1), arrowColor = GetColor(1), name #= "BTO");
AddOrder(OrderType.BUY_TO_OPEN, condition = l3, close[0], 1, tickColor = GetColor(1), arrowColor = GetColor(1), name = "BTO");
#AddOrder(OrderType.BUY_TO_OPEN, price crosses below f3, tickcolor = GetColor(1), arrowcolor = GetColor(1), name = "BTO");
#AddOrder(OrderType.SELL_TO_CLOSE, close > EntryPrice() - 40);
#AddOrder(OrderType.SELL_TO_OPEN, condition = s3, price = open, 1, tickColor = GetColor(2), arrowColor = GetColor(2), name #= "STO");
#AddOrder(OrderType.SELL_TO_OPEN, condition = s3, 1, tickColor = GetColor(2), arrowColor = GetColor(2), name = "STO");
 
Can someone who codes take the script from these indicators and make them for TOS? Here are the two indicators I am looking for this code is for average true range trailing stop colored

average true range trailing stop colored
Code:
////////////////////////////////////////////////////////////
//  Copyright by HPotter v2.0 13/10/2014
// Average True Range Trailing Stops Strategy, by Sylvain Vervoort
// The related article is copyrighted material from Stocks & Commodities Jun 2009
////////////////////////////////////////////////////////////
study(title="Average True Range Trailing Stops Strategy, by Sylvain Vervoort", overlay = true)
nATRPeriod = input(5)
nATRMultip = input(3.5)
xATR = atr(nATRPeriod)
nLoss = nATRMultip * xATR
xATRTrailingStop = iff(close > nz(xATRTrailingStop[1], 0) and close[1] > nz(xATRTrailingStop[1], 0), max(nz(xATRTrailingStop[1]), close - nLoss),
                    iff(close < nz(xATRTrailingStop[1], 0) and close[1] < nz(xATRTrailingStop[1], 0), min(nz(xATRTrailingStop[1]), close + nLoss),
                        iff(close > nz(xATRTrailingStop[1], 0), close - nLoss, close + nLoss)))
pos =   iff(close[1] < nz(xATRTrailingStop[1], 0) and close > nz(xATRTrailingStop[1], 0), 1,
        iff(close[1] > nz(xATRTrailingStop[1], 0) and close < nz(xATRTrailingStop[1], 0), -1, nz(pos[1], 0)))
color = pos == -1 ? red: pos == 1 ? green : blue
plot(xATRTrailingStop, color=color, title="ATR Trailing Stop")


smart money Concepts [LUX]

// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
//@version=5
indicator("Smart Money Concepts [LUX]", "Smart Money Concepts [LuxAlgo]"
  , overlay = true
  , max_labels_count = 500
  , max_lines_count = 500
  , max_boxes_count = 500
  , max_bars_back = 500)
//-----------------------------------------------------------------------------{
//Constants
//-----------------------------------------------------------------------------{
color TRANSP_CSS = #ffffff00
//Tooltips
string MODE_TOOLTIP          = 'Allows to display historical Structure or only the recent ones'
string STYLE_TOOLTIP         = 'Indicator color theme'
string COLOR_CANDLES_TOOLTIP = 'Display additional candles with a color reflecting the current trend detected by structure'
string SHOW_INTERNAL         = 'Display internal market structure'
string CONFLUENCE_FILTER     = 'Filter non significant internal structure breakouts'
string SHOW_SWING            = 'Display swing market Structure'
string SHOW_SWING_POINTS     = 'Display swing point as labels on the chart'
string SHOW_SWHL_POINTS      = 'Highlight most recent strong and weak high/low points on the chart'
string INTERNAL_OB           = 'Display internal order blocks on the chart\n\nNumber of internal order blocks to display on the chart'
string SWING_OB              = 'Display swing order blocks on the chart\n\nNumber of internal swing blocks to display on the chart'
string FILTER_OB             = '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'
string SHOW_EQHL             = 'Display equal highs and equal lows on the chart'
string EQHL_BARS             = 'Number of bars used to confirm equal highs and equal lows'
string EQHL_THRESHOLD        = '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'
string SHOW_FVG              = 'Display fair values gaps on the chart'
string AUTO_FVG              = 'Filter out non significant fair value gaps'
string FVG_TF                = 'Fair value gaps timeframe'
string EXTEND_FVG            = 'Determine how many bars to extend the Fair Value Gap boxes on chart'
string PED_ZONES             = 'Display premium, discount, and equilibrium zones on chart'
//-----------------------------------------------------------------------------{
//Settings
//-----------------------------------------------------------------------------{
//General
//----------------------------------------{
mode = input.string('Historical'
  , options = ['Historical', 'Present']
  , group = 'Smart Money Concepts'
  , tooltip = MODE_TOOLTIP)
style = input.string('Colored'
  , options = ['Colored', 'Monochrome']
  , group = 'Smart Money Concepts'
  , tooltip = STYLE_TOOLTIP)
show_trend = input(false, 'Color Candles'
  , group = 'Smart Money Concepts'
  , tooltip = COLOR_CANDLES_TOOLTIP)
//----------------------------------------}
//Internal Structure
//----------------------------------------{
show_internals = input(true, 'Show Internal Structure'
  , group = 'Real Time Internal Structure'
  , tooltip = SHOW_INTERNAL)
show_ibull = input.string('All', 'Bullish Structure'
  , options = ['All', 'BOS', 'CHoCH']
  , inline = 'ibull'
  , group = 'Real Time Internal Structure')
swing_ibull_css = input(#089981, ''
  , inline = 'ibull'
  , group = 'Real Time Internal Structure')
//Bear Structure
show_ibear = input.string('All', 'Bearish Structure'
  , options = ['All', 'BOS', 'CHoCH']
  , inline = 'ibear'
  , group = 'Real Time Internal Structure')
swing_ibear_css = input(#f23645, ''
  , inline = 'ibear'
  , group = 'Real Time Internal Structure')
ifilter_confluence = input(false, 'Confluence Filter'
  , group = 'Real Time Internal Structure'
  , tooltip = CONFLUENCE_FILTER)
//----------------------------------------}
//Swing Structure
//----------------------------------------{
show_Structure = input(true, 'Show Swing Structure'
  , group = 'Real Time Swing Structure'
  , tooltip = SHOW_SWING)
//Bull Structure
show_bull = input.string('All', 'Bullish Structure'
  , options = ['All', 'BOS', 'CHoCH']
  , inline = 'bull'
  , group = 'Real Time Swing Structure')
swing_bull_css = input(#089981, ''
  , inline = 'bull'
  , group = 'Real Time Swing Structure')
//Bear Structure
show_bear = input.string('All', 'Bearish Structure'
  , options = ['All', 'BOS', 'CHoCH']
  , inline = 'bear'
  , group = 'Real Time Swing Structure')
swing_bear_css = input(#f23645, ''
  , inline = 'bear'
  , group = 'Real Time Swing Structure')
//Swings
show_swings = input(false, 'Show Swings Points'
  , inline = 'swings'
  , group = 'Real Time Swing Structure'
  , tooltip = SHOW_SWING_POINTS)
length = input.int(50, ''
  , minval = 10
  , inline = 'swings'
  , group = 'Real Time Swing Structure')
show_hl_swings = input(true, 'Show Strong/Weak High/Low'
  , group = 'Real Time Swing Structure'
  , tooltip = SHOW_SWHL_POINTS)
//----------------------------------------}
//Order Blocks
//----------------------------------------{
show_iob = input(true, 'Internal Order Blocks'
  , inline = 'iob'
  , group = 'Order Blocks'
  , tooltip = INTERNAL_OB)
iob_showlast = input.int(5, ''
  , minval = 1
  , inline = 'iob'
  , group = 'Order Blocks')
show_ob = input(false, 'Swing Order Blocks'
  , inline = 'ob'
  , group = 'Order Blocks'
  , tooltip = SWING_OB)
ob_showlast = input.int(5, ''
  , minval = 1
  , inline = 'ob'
  , group = 'Order Blocks')
ob_filter = input.string('Atr', 'Order Block Filter'
  , options = ['Atr', 'Cumulative Mean Range']
  , group = 'Order Blocks'
  , tooltip = FILTER_OB)
ibull_ob_css = input.color(color.new(#3179f5, 80), 'Internal Bullish OB'
  , group = 'Order Blocks')
ibear_ob_css = input.color(color.new(#f77c80, 80), 'Internal Bearish OB'
  , group = 'Order Blocks')
bull_ob_css = input.color(color.new(#1848cc, 80), 'Bullish OB'
  , group = 'Order Blocks')
bear_ob_css = input.color(color.new(#b22833, 80), 'Bearish OB'
  , group = 'Order Blocks')
//----------------------------------------}
//EQH/EQL
//----------------------------------------{
show_eq = input(true, 'Equal High/Low'
  , group = 'EQH/EQL'
  , tooltip = SHOW_EQHL)
eq_len = input.int(3, 'Bars Confirmation'
  , minval = 1
  , group = 'EQH/EQL'
  , tooltip = EQHL_BARS)
eq_threshold = input.float(0.1, 'Threshold'
  , minval = 0
  , maxval = 0.5
  , step = 0.1
  , group = 'EQH/EQL'
  , tooltip = EQHL_THRESHOLD)
//----------------------------------------}
//Fair Value Gaps
//----------------------------------------{
show_fvg = input(false, 'Fair Value Gaps'
  , group = 'Fair Value Gaps'
  , tooltip = SHOW_FVG)
 
fvg_auto = input(true, "Auto Threshold"
  , group = 'Fair Value Gaps'
  , tooltip = AUTO_FVG)
fvg_tf = input.timeframe('', "Timeframe"
  , group = 'Fair Value Gaps'
  , tooltip = FVG_TF)
bull_fvg_css = input.color(color.new(#00ff68, 70), 'Bullish FVG'
  , group = 'Fair Value Gaps')
bear_fvg_css = input.color(color.new(#ff0008, 70), 'Bearish FVG'
  , group = 'Fair Value Gaps')
fvg_extend = input.int(1, "Extend FVG"
  , minval = 0
  , group = 'Fair Value Gaps'
  , tooltip = EXTEND_FVG)
//----------------------------------------}
//Previous day/week high/low
//----------------------------------------{
//Daily
show_pdhl = input(false, 'Daily'
  , inline = 'daily'
  , group = 'Highs & Lows MTF')
pdhl_style = input.string('⎯⎯⎯', ''
  , options = ['⎯⎯⎯', '----', '····']
  , inline = 'daily'
  , group = 'Highs & Lows MTF')
pdhl_css = input(#2157f3, ''
  , inline = 'daily'
  , group = 'Highs & Lows MTF')
//Weekly
show_pwhl = input(false, 'Weekly'
  , inline = 'weekly'
  , group = 'Highs & Lows MTF')
pwhl_style = input.string('⎯⎯⎯', ''
  , options = ['⎯⎯⎯', '----', '····']
  , inline = 'weekly'
  , group = 'Highs & Lows MTF')
pwhl_css = input(#2157f3, ''
  , inline = 'weekly'
  , group = 'Highs & Lows MTF')
//Monthly
show_pmhl = input(false, 'Monthly'
  , inline = 'monthly'
  , group = 'Highs & Lows MTF')
pmhl_style = input.string('⎯⎯⎯', ''
  , options = ['⎯⎯⎯', '----', '····']
  , inline = 'monthly'
  , group = 'Highs & Lows MTF')
pmhl_css = input(#2157f3, ''
  , inline = 'monthly'
  , group = 'Highs & Lows MTF')
//----------------------------------------}
//Premium/Discount zones
//----------------------------------------{
show_sd = input(false, 'Premium/Discount Zones'
  , group = 'Premium & Discount Zones'
  , tooltip = PED_ZONES)
premium_css = input.color(#f23645, 'Premium Zone'
  , group = 'Premium & Discount Zones')
eq_css = input.color(#b2b5be, 'Equilibrium Zone'
  , group = 'Premium & Discount Zones')
discount_css = input.color(#089981, 'Discount Zone'
  , group = 'Premium & Discount Zones')
//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
n = bar_index
atr = ta.atr(200)
cmean_range = ta.cum(high - low) / n
//HL Output function
hl() => [high, low]
//Get ohlc values function
get_ohlc()=> [close[1], open[1], high, low, high[2], low[2]]
//Display Structure function
display_Structure(x, y, txt, css, dashed, down, lbl_size)=>
    structure_line = line.new(x, y, n, y
      , color = css
      , style = dashed ? line.style_dashed : line.style_solid)
    structure_lbl = label.new(int(math.avg(x, n)), y, txt
      , color = TRANSP_CSS
      , textcolor = css
      , style = down ? label.style_label_down : label.style_label_up
      , size = lbl_size)
    if mode == 'Present'
        line.delete(structure_line[1])
        label.delete(structure_lbl[1])
//Swings detection/measurements
swings(len)=>
    var os = 0
  
    upper = ta.highest(len)
    lower = ta.lowest(len)
    os := high[len] > upper ? 0 : low[len] < lower ? 1 : os[1]
    top = os == 0 and os[1] != 0 ? high[len] : 0
    btm = os == 1 and os[1] != 1 ? low[len] : 0
    [top, btm]
//Order block coordinates function
ob_coord(use_max, loc, target_top, target_btm, target_left, target_type)=>
    min = 99999999.
    max = 0.
    idx = 1
    ob_threshold = ob_filter == 'Atr' ? atr : cmean_range
    //Search for highest/lowest high within the structure interval and get range
    if use_max
        for i = 1 to (n - loc)-1
            if (high - low) < ob_threshold * 2
                max := math.max(high, max)
                min := max == high ? low : min
                idx := max == high ? i : idx
    else
        for i = 1 to (n - loc)-1
            if (high - low) < ob_threshold * 2
                min := math.min(low, min)
                max := min == low ? high : max
                idx := min == low ? i : idx
    array.unshift(target_top, max)
    array.unshift(target_btm, min)
    array.unshift(target_left, time[idx])
    array.unshift(target_type, use_max ? -1 : 1)
//Set order blocks
display_ob(boxes, target_top, target_btm, target_left, target_type, show_last, swing, size)=>
    for i = 0 to math.min(show_last-1, size-1)
        get_box = array.get(boxes, i)
        box.set_lefttop(get_box, array.get(target_left, i), array.get(target_top, i))
        box.set_rightbottom(get_box, array.get(target_left, i), array.get(target_btm, i))
        box.set_extend(get_box, extend.right)
        color css = na
        
        if swing 
            if style == 'Monochrome'
                css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) : color.new(#5d606b, 80)
                border_css = array.get(target_type, i) == 1 ? #b2b5be : #5d606b
                box.set_border_color(get_box, border_css)
            else
                css := array.get(target_type, i) == 1 ? bull_ob_css : bear_ob_css
                box.set_border_color(get_box, css)
            box.set_bgcolor(get_box, css)
        else
            if style == 'Monochrome'
                css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) : color.new(#5d606b, 80)
            else
                css := array.get(target_type, i) == 1 ? ibull_ob_css : ibear_ob_css
            
            box.set_border_color(get_box, css)
            box.set_bgcolor(get_box, css)
        
//Line Style function
get_line_style(style) =>
    out = switch style
        '⎯⎯⎯'  => line.style_solid
        '----' => line.style_dashed
        '····' => line.style_dotted
//Set line/labels function for previous high/lows
phl(h, l, tf, css)=>
    var line high_line = line.new(na,na,na,na
      , xloc = xloc.bar_time
      , color = css
      , style = get_line_style(pdhl_style))
    var label high_lbl = label.new(na,na
      , xloc = xloc.bar_time
      , text = str.format('P{0}H', tf)
      , color = TRANSP_CSS
      , textcolor = css
      , size = size.small
      , style = label.style_label_left)
    var line low_line = line.new(na,na,na,na
      , xloc = xloc.bar_time
      , color = css
      , style = get_line_style(pdhl_style))
    var label low_lbl = label.new(na,na
      , xloc = xloc.bar_time
      , text = str.format('P{0}L', tf)
      , color = TRANSP_CSS
      , textcolor = css
      , size = size.small
      , style = label.style_label_left)
    hy = ta.valuewhen(h != h[1], h, 1)
    hx = ta.valuewhen(h == high, time, 1)
    ly = ta.valuewhen(l != l[1], l, 1)
    lx = ta.valuewhen(l == low, time, 1)
    if barstate.islast
        ext = time + (time - time[1])*20
        //High
        line.set_xy1(high_line, hx, hy)
        line.set_xy2(high_line, ext, hy)
        label.set_xy(high_lbl, ext, hy)
        //Low
        line.set_xy1(low_line, lx, ly)
        line.set_xy2(low_line, ext, ly)
        label.set_xy(low_lbl, ext, ly)
//-----------------------------------------------------------------------------}
//Global variables
//-----------------------------------------------------------------------------{
var trend = 0, var itrend = 0
var top_y = 0., var top_x = 0
var btm_y = 0., var btm_x = 0
var itop_y = 0., var itop_x = 0
var ibtm_y = 0., var ibtm_x = 0
var trail_up = high, var trail_dn = low
var trail_up_x = 0,  var trail_dn_x = 0
var top_cross = true,  var btm_cross = true
var itop_cross = true, var ibtm_cross = true
var txt_top = '',  var txt_btm = ''
//Alerts
bull_choch_alert = false 
bull_bos_alert   = false 
bear_choch_alert = false 
bear_bos_alert   = false 
bull_ichoch_alert = false 
bull_ibos_alert   = false 
bear_ichoch_alert = false 
bear_ibos_alert   = false 
bull_iob_break = false 
bear_iob_break = false
bull_ob_break = false 
bear_ob_break = false
eqh_alert = false 
eql_alert = false 
//Structure colors
var bull_css = style == 'Monochrome' ? #b2b5be 
  : swing_bull_css
var bear_css = style == 'Monochrome' ? #b2b5be 
  : swing_bear_css
var ibull_css = style == 'Monochrome' ? #b2b5be 
  : swing_ibull_css
var ibear_css = style == 'Monochrome' ? #b2b5be 
  : swing_ibear_css
//Swings
[top, btm] = swings(length)
[itop, ibtm] = swings(5)
//-----------------------------------------------------------------------------}
//Pivot High
//-----------------------------------------------------------------------------{
var line extend_top = na
var label extend_top_lbl = label.new(na, na
  , color = TRANSP_CSS
  , textcolor = bear_css
  , style = label.style_label_down
  , size = size.tiny)
if top
    top_cross := true
    txt_top := top > top_y ? 'HH' : 'LH'
    if show_swings
        top_lbl = label.new(n-length, top, txt_top
          , color = TRANSP_CSS
          , textcolor = bear_css
          , style = label.style_label_down
          , size = size.small)
        if mode == 'Present'
            label.delete(top_lbl[1])
    //Extend recent top to last bar
    line.delete(extend_top[1])
    extend_top := line.new(n-length, top, n, top
      , color = bear_css)
    top_y := top
    top_x := n - length
    trail_up := top
    trail_up_x := n - length
if itop
    itop_cross := true
    itop_y := itop
    itop_x := n - 5
//Trailing maximum
trail_up := math.max(high, trail_up)
trail_up_x := trail_up == high ? n : trail_up_x
//Set top extension label/line
if barstate.islast and show_hl_swings
    line.set_xy1(extend_top, trail_up_x, trail_up)
    line.set_xy2(extend_top, n + 20, trail_up)
    label.set_x(extend_top_lbl, n + 20)
    label.set_y(extend_top_lbl, trail_up)
    label.set_text(extend_top_lbl, trend < 0 ? 'Strong High' : 'Weak High')
//-----------------------------------------------------------------------------}
//Pivot Low
//-----------------------------------------------------------------------------{
var line extend_btm = na 
var label extend_btm_lbl = label.new(na, na
  , color = TRANSP_CSS
  , textcolor = bull_css
  , style = label.style_label_up
  , size = size.tiny)
if btm
    btm_cross := true
    txt_btm := btm < btm_y ? 'LL' : 'HL'
    
    if show_swings
        btm_lbl = label.new(n - length, btm, txt_btm
          , color = TRANSP_CSS
          , textcolor = bull_css
          , style = label.style_label_up
          , size = size.small)
        if mode == 'Present'
            label.delete(btm_lbl[1])
    
    //Extend recent btm to last bar
    line.delete(extend_btm[1])
    extend_btm := line.new(n - length, btm, n, btm
      , color = bull_css)
    btm_y := btm
    btm_x := n-length
    trail_dn := btm
    trail_dn_x := n-length
if ibtm
    ibtm_cross := true
    ibtm_y := ibtm
    ibtm_x := n - 5
//Trailing minimum
trail_dn := math.min(low, trail_dn)
trail_dn_x := trail_dn == low ? n : trail_dn_x
//Set btm extension label/line
if barstate.islast and show_hl_swings
    line.set_xy1(extend_btm, trail_dn_x, trail_dn)
    line.set_xy2(extend_btm, n + 20, trail_dn)
    label.set_x(extend_btm_lbl, n + 20)
    label.set_y(extend_btm_lbl, trail_dn)
    label.set_text(extend_btm_lbl, trend > 0 ? 'Strong Low' : 'Weak Low')
//-----------------------------------------------------------------------------}
//Order Blocks Arrays
//-----------------------------------------------------------------------------{
var iob_top = array.new_float(0)
var iob_btm = array.new_float(0)
var iob_left = array.new_int(0)
var iob_type = array.new_int(0)
var ob_top = array.new_float(0)
var ob_btm = array.new_float(0)
var ob_left = array.new_int(0)
var ob_type = array.new_int(0)
//-----------------------------------------------------------------------------}
//Pivot High BOS/CHoCH
//-----------------------------------------------------------------------------{
//Filtering
var bull_concordant = true
if ifilter_confluence
    bull_concordant := high - math.max(close, open) > math.min(close, open - low)
//Detect internal bullish Structure
if ta.crossover(close, itop_y) and itop_cross and top_y != itop_y and bull_concordant
    bool choch = na
    
    if itrend < 0
        choch := true
        bull_ichoch_alert := true
    else 
        bull_ibos_alert := true
    
    txt = choch ? 'CHoCH' : 'BOS'
    if show_internals
        if show_ibull == 'All' or (show_ibull == 'BOS' and not choch) or (show_ibull == 'CHoCH' and choch)
            display_Structure(itop_x, itop_y, txt, ibull_css, true, true, size.tiny)
    
    itop_cross := false
    itrend := 1
    
    //Internal Order Block
    if show_iob
        ob_coord(false, itop_x, iob_top, iob_btm, iob_left, iob_type)
//Detect bullish Structure
if ta.crossover(close, top_y) and top_cross
    bool choch = na
    
    if trend < 0
        choch := true
        bull_choch_alert := true
    else 
        bull_bos_alert := true
    txt = choch ? 'CHoCH' : 'BOS'
    
    if show_Structure
        if show_bull == 'All' or (show_bull == 'BOS' and not choch) or (show_bull == 'CHoCH' and choch)
            display_Structure(top_x, top_y, txt, bull_css, false, true, size.small)
    
    //Order Block
    if show_ob
        ob_coord(false, top_x, ob_top, ob_btm, ob_left, ob_type)
    top_cross := false
    trend := 1
//-----------------------------------------------------------------------------}
//Pivot Low BOS/CHoCH
//-----------------------------------------------------------------------------{
var bear_concordant = true
if ifilter_confluence
    bear_concordant := high - math.max(close, open) < math.min(close, open - low)
//Detect internal bearish Structure
if ta.crossunder(close, ibtm_y) and ibtm_cross and btm_y != ibtm_y and bear_concordant
    bool choch = false
    
    if itrend > 0
        choch := true
        bear_ichoch_alert := true
    else 
        bear_ibos_alert := true
    
    txt = choch ? 'CHoCH' : 'BOS'
    if show_internals
        if show_ibear == 'All' or (show_ibear == 'BOS' and not choch) or (show_ibear == 'CHoCH' and choch)
            display_Structure(ibtm_x, ibtm_y, txt, ibear_css, true, false, size.tiny)
    
    ibtm_cross := false
    itrend := -1
    
    //Internal Order Block
    if show_iob
        ob_coord(true, ibtm_x, iob_top, iob_btm, iob_left, iob_type)
//Detect bearish Structure
if ta.crossunder(close, btm_y) and btm_cross
    bool choch = na
    
    if trend > 0
        choch := true
        bear_choch_alert := true
    else 
        bear_bos_alert := true
    txt = choch ? 'CHoCH' : 'BOS'
    
    if show_Structure
        if show_bear == 'All' or (show_bear == 'BOS' and not choch) or (show_bear == 'CHoCH' and choch)
            display_Structure(btm_x, btm_y, txt, bear_css, false, false, size.small)
    
    //Order Block
    if show_ob
        ob_coord(true, btm_x, ob_top, ob_btm, ob_left, ob_type)
    btm_cross := false
    trend := -1
//-----------------------------------------------------------------------------}
//Order Blocks
//-----------------------------------------------------------------------------{
//Set order blocks
var iob_boxes = array.new_box(0)
var ob_boxes = array.new_box(0)
//Delete internal order blocks box coordinates if top/bottom is broken
for element in iob_type
    index = array.indexof(iob_type, element)
    if close < array.get(iob_btm, index) and element == 1
        array.remove(iob_top, index) 
        array.remove(iob_btm, index) 
        array.remove(iob_left, index) 
        array.remove(iob_type, index)
        bull_iob_break := true
    else if close > array.get(iob_top, index) and element == -1
        array.remove(iob_top, index) 
        array.remove(iob_btm, index)
        array.remove(iob_left, index) 
        array.remove(iob_type, index)
        bear_iob_break := true
//Delete internal order blocks box coordinates if top/bottom is broken
for element in ob_type
    index = array.indexof(ob_type, element)
    if close < array.get(ob_btm, index) and element == 1
        array.remove(ob_top, index) 
        array.remove(ob_btm, index) 
        array.remove(ob_left, index) 
        array.remove(ob_type, index)
        bull_ob_break := true
    else if close > array.get(ob_top, index) and element == -1
        array.remove(ob_top, index) 
        array.remove(ob_btm, index)
        array.remove(ob_left, index) 
        array.remove(ob_type, index)
        bear_ob_break := true
iob_size = array.size(iob_type)
ob_size = array.size(ob_type)
if barstate.isfirst
    if show_iob
        for i = 0 to iob_showlast-1
            array.push(iob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time))
    if show_ob
        for i = 0 to ob_showlast-1
            array.push(ob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time))
if iob_size > 0
    if barstate.islast
        display_ob(iob_boxes, iob_top, iob_btm, iob_left, iob_type, iob_showlast, false, iob_size)
if ob_size > 0
    if barstate.islast
        display_ob(ob_boxes, ob_top, ob_btm, ob_left, ob_type, ob_showlast, true, ob_size)
//-----------------------------------------------------------------------------}
//EQH/EQL
//-----------------------------------------------------------------------------{
var eq_prev_top = 0.
var eq_top_x = 0
var eq_prev_btm = 0.
var eq_btm_x = 0
if show_eq
    eq_top = ta.pivothigh(eq_len, eq_len)
    eq_btm = ta.pivotlow(eq_len, eq_len)
    if eq_top 
        max = math.max(eq_top, eq_prev_top)
        min = math.min(eq_top, eq_prev_top)
        
        if max < min + atr * eq_threshold
            eqh_line = line.new(eq_top_x, eq_prev_top, n-eq_len, eq_top
              , color = bear_css
              , style = line.style_dotted)
            eqh_lbl = label.new(int(math.avg(n-eq_len, eq_top_x)), eq_top, 'EQH'
              , color = #00000000
              , textcolor = bear_css
              , style = label.style_label_down
              , size = size.tiny)
            if mode == 'Present'
                line.delete(eqh_line[1])
                label.delete(eqh_lbl[1])
            
            eqh_alert := true
        eq_prev_top := eq_top
        eq_top_x := n-eq_len
    if eq_btm 
        max = math.max(eq_btm, eq_prev_btm)
        min = math.min(eq_btm, eq_prev_btm)
        
        if min > max - atr * eq_threshold
            eql_line = line.new(eq_btm_x, eq_prev_btm, n-eq_len, eq_btm
              , color = bull_css
              , style = line.style_dotted)
            eql_lbl = label.new(int(math.avg(n-eq_len, eq_btm_x)), eq_btm, 'EQL'
              , color = #00000000
              , textcolor = bull_css
              , style = label.style_label_up
              , size = size.tiny)
            eql_alert := true
            if mode == 'Present'
                line.delete(eql_line[1])
                label.delete(eql_lbl[1])
        eq_prev_btm := eq_btm
        eq_btm_x := n-eq_len
//-----------------------------------------------------------------------------}
//Fair Value Gaps
//-----------------------------------------------------------------------------{
var bullish_fvg_max = array.new_box(0)
var bullish_fvg_min = array.new_box(0)
var bearish_fvg_max = array.new_box(0)
var bearish_fvg_min = array.new_box(0)
float bullish_fvg_avg = na
float bearish_fvg_avg = na
bullish_fvg_cnd = false
bearish_fvg_cnd = false
[src_c1, src_o1, src_h, src_l, src_h2, src_l2] =
  request.security(syminfo.tickerid, fvg_tf, get_ohlc())
if show_fvg
    delta_per = (src_c1 - src_o1) / src_o1 * 100
    change_tf = timeframe.change(fvg_tf)
    threshold = fvg_auto ? ta.cum(math.abs(change_tf ? delta_per : 0)) / n * 2 
      : 0
    //FVG conditions
    bullish_fvg_cnd := src_l > src_h2
      and src_c1 > src_h2 
      and delta_per > threshold
      and change_tf
    bearish_fvg_cnd := src_h < src_l2 
      and src_c1 < src_l2 
      and -delta_per > threshold
      and change_tf
    //FVG Areas
    if bullish_fvg_cnd
        array.unshift(bullish_fvg_max, box.new(n-1, src_l, n + fvg_extend, math.avg(src_l, src_h2)
          , border_color = bull_fvg_css
          , bgcolor = bull_fvg_css))
        
        array.unshift(bullish_fvg_min, box.new(n-1, math.avg(src_l, src_h2), n + fvg_extend, src_h2
          , border_color = bull_fvg_css
          , bgcolor = bull_fvg_css))
    
    if bearish_fvg_cnd
        array.unshift(bearish_fvg_max, box.new(n-1, src_h, n + fvg_extend, math.avg(src_h, src_l2)
          , border_color = bear_fvg_css
          , bgcolor = bear_fvg_css))
        
        array.unshift(bearish_fvg_min, box.new(n-1, math.avg(src_h, src_l2), n + fvg_extend, src_l2
          , border_color = bear_fvg_css
          , bgcolor = bear_fvg_css))
    for bx in bullish_fvg_min
        if low < box.get_bottom(bx)
            box.delete(bx)
            box.delete(array.get(bullish_fvg_max, array.indexof(bullish_fvg_min, bx)))
    
    for bx in bearish_fvg_max
        if high > box.get_top(bx)
            box.delete(bx)
            box.delete(array.get(bearish_fvg_min, array.indexof(bearish_fvg_max, bx)))
//-----------------------------------------------------------------------------}
//Previous day/week high/lows
//-----------------------------------------------------------------------------{
//Daily high/low
[pdh, pdl] = request.security(syminfo.tickerid, 'D', hl()
  , lookahead = barmerge.lookahead_on)
//Weekly high/low
[pwh, pwl] = request.security(syminfo.tickerid, 'W', hl()
  , lookahead = barmerge.lookahead_on)
//Monthly high/low
[pmh, pml] = request.security(syminfo.tickerid, 'M', hl()
  , lookahead = barmerge.lookahead_on)
//Display Daily
if show_pdhl
    phl(pdh, pdl, 'D', pdhl_css)
//Display Weekly
if show_pwhl
    phl(pwh, pwl, 'W', pwhl_css)
    
//Display Monthly
if show_pmhl
    phl(pmh, pml, 'M', pmhl_css)
//-----------------------------------------------------------------------------}
//Premium/Discount/Equilibrium zones
//-----------------------------------------------------------------------------{
var premium = box.new(na, na, na, na
  , bgcolor = color.new(premium_css, 80)
  , border_color = na)
var premium_lbl = label.new(na, na
  , text = 'Premium'
  , color = TRANSP_CSS
  , textcolor = premium_css
  , style = label.style_label_down
  , size = size.small)
var eq = box.new(na, na, na, na
  , bgcolor = color.rgb(120, 123, 134, 80)
  , border_color = na)
var eq_lbl = label.new(na, na
  , text = 'Equilibrium'
  , color = TRANSP_CSS
  , textcolor = eq_css
  , style = label.style_label_left
  , size = size.small)
var discount = box.new(na, na, na, na
  , bgcolor = color.new(discount_css, 80)
  , border_color = na)
var discount_lbl = label.new(na, na
  , text = 'Discount'
  , color = TRANSP_CSS
  , textcolor = discount_css
  , style = label.style_label_up
  , size = size.small)
//Show Premium/Discount Areas
if barstate.islast and show_sd
    avg = math.avg(trail_up, trail_dn)
    box.set_lefttop(premium, math.max(top_x, btm_x), trail_up)
    box.set_rightbottom(premium, n, .95 * trail_up + .05 * trail_dn)
    label.set_xy(premium_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_up)
    box.set_lefttop(eq, math.max(top_x, btm_x), .525 * trail_up + .475*trail_dn)
    box.set_rightbottom(eq, n, .525 * trail_dn + .475 * trail_up)
    label.set_xy(eq_lbl, n, avg)
    
    box.set_lefttop(discount, math.max(top_x, btm_x), .95 * trail_dn + .05 * trail_up)
    box.set_rightbottom(discount, n, trail_dn)
    label.set_xy(discount_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_dn)
//-----------------------------------------------------------------------------}
//Trend
//-----------------------------------------------------------------------------{
var color trend_css = na
if show_trend
    if style == 'Colored'
        trend_css := itrend == 1 ? bull_css : bear_css
    else if style == 'Monochrome'
        trend_css := itrend == 1 ? #b2b5be : #5d606b
plotcandle(open, high, low, close
  , color = trend_css
  , wickcolor = trend_css
  , bordercolor = trend_css
  , editable = false)
//-----------------------------------------------------------------------------}
//Alerts
//-----------------------------------------------------------------------------{
//Internal Structure
alertcondition(bull_ibos_alert, 'Internal Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(bull_ichoch_alert, 'Internal Bullish CHoCH', 'Internal Bullish CHoCH formed')
alertcondition(bear_ibos_alert, 'Internal Bearish BOS', 'Internal Bearish BOS formed')
alertcondition(bear_ichoch_alert, 'Internal Bearish CHoCH', 'Internal Bearish CHoCH formed')
//Swing Structure
alertcondition(bull_bos_alert, 'Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(bull_choch_alert, 'Bullish CHoCH', 'Internal Bullish CHoCH formed')
alertcondition(bear_bos_alert, 'Bearish BOS', 'Bearish BOS formed')
alertcondition(bear_choch_alert, 'Bearish CHoCH', 'Bearish CHoCH formed')
//order Blocks
alertcondition(bull_iob_break, 'Bullish Internal OB Breakout', 'Price broke bullish iternal OB')
alertcondition(bear_iob_break, 'Bearish Internal OB Breakout', 'Price broke bearish iternal OB')
alertcondition(bull_ob_break, 'Bullish OB Breakout', 'Price broke bullish iternal OB')
alertcondition(bear_ob_break, 'bearish OB Breakout', 'Price broke bearish iternal OB')
//EQH/EQL
alertcondition(eqh_alert, 'Equal Highs', 'Equal highs detected')
alertcondition(eql_alert, 'Equal Lows', 'Equal lows detected')
//FVG
alertcondition(bullish_fvg_cnd, 'Bullish FVG', 'Bullish FVG formed')
alertcondition(bearish_fvg_cnd, 'Bearish FVG', 'Bearish FVG formed')
//-----------------------------------------------------------------------------}
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
//@version=5
indicator("Smart Money Concepts [LUX]", "Smart Money Concepts [LuxAlgo]"
  , overlay = true
  , max_labels_count = 500
  , max_lines_count = 500
  , max_boxes_count = 500
  , max_bars_back = 500)
//-----------------------------------------------------------------------------{
//Constants
//-----------------------------------------------------------------------------{
color TRANSP_CSS = #ffffff00
//Tooltips
string MODE_TOOLTIP          = 'Allows to display historical Structure or only the recent ones'
string STYLE_TOOLTIP         = 'Indicator color theme'
string COLOR_CANDLES_TOOLTIP = 'Display additional candles with a color reflecting the current trend detected by structure'
string SHOW_INTERNAL         = 'Display internal market structure'
string CONFLUENCE_FILTER     = 'Filter non significant internal structure breakouts'
string SHOW_SWING            = 'Display swing market Structure'
string SHOW_SWING_POINTS     = 'Display swing point as labels on the chart'
string SHOW_SWHL_POINTS      = 'Highlight most recent strong and weak high/low points on the chart'
string INTERNAL_OB           = 'Display internal order blocks on the chart\n\nNumber of internal order blocks to display on the chart'
string SWING_OB              = 'Display swing order blocks on the chart\n\nNumber of internal swing blocks to display on the chart'
string FILTER_OB             = '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'
string SHOW_EQHL             = 'Display equal highs and equal lows on the chart'
string EQHL_BARS             = 'Number of bars used to confirm equal highs and equal lows'
string EQHL_THRESHOLD        = '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'
string SHOW_FVG              = 'Display fair values gaps on the chart'
string AUTO_FVG              = 'Filter out non significant fair value gaps'
string FVG_TF                = 'Fair value gaps timeframe'
string EXTEND_FVG            = 'Determine how many bars to extend the Fair Value Gap boxes on chart'
string PED_ZONES             = 'Display premium, discount, and equilibrium zones on chart'
//-----------------------------------------------------------------------------{
//Settings
//-----------------------------------------------------------------------------{
//General
//----------------------------------------{
mode = input.string('Historical'
  , options = ['Historical', 'Present']
  , group = 'Smart Money Concepts'
  , tooltip = MODE_TOOLTIP)
style = input.string('Colored'
  , options = ['Colored', 'Monochrome']
  , group = 'Smart Money Concepts'
  , tooltip = STYLE_TOOLTIP)
show_trend = input(false, 'Color Candles'
  , group = 'Smart Money Concepts'
  , tooltip = COLOR_CANDLES_TOOLTIP)
//----------------------------------------}
//Internal Structure
//----------------------------------------{
show_internals = input(true, 'Show Internal Structure'
  , group = 'Real Time Internal Structure'
  , tooltip = SHOW_INTERNAL)
show_ibull = input.string('All', 'Bullish Structure'
  , options = ['All', 'BOS', 'CHoCH']
  , inline = 'ibull'
  , group = 'Real Time Internal Structure')
swing_ibull_css = input(#089981, ''
  , inline = 'ibull'
  , group = 'Real Time Internal Structure')
//Bear Structure
show_ibear = input.string('All', 'Bearish Structure'
  , options = ['All', 'BOS', 'CHoCH']
  , inline = 'ibear'
  , group = 'Real Time Internal Structure')
swing_ibear_css = input(#f23645, ''
  , inline = 'ibear'
  , group = 'Real Time Internal Structure')
ifilter_confluence = input(false, 'Confluence Filter'
  , group = 'Real Time Internal Structure'
  , tooltip = CONFLUENCE_FILTER)
//----------------------------------------}
//Swing Structure
//----------------------------------------{
show_Structure = input(true, 'Show Swing Structure'
  , group = 'Real Time Swing Structure'
  , tooltip = SHOW_SWING)
//Bull Structure
show_bull = input.string('All', 'Bullish Structure'
  , options = ['All', 'BOS', 'CHoCH']
  , inline = 'bull'
  , group = 'Real Time Swing Structure')
swing_bull_css = input(#089981, ''
  , inline = 'bull'
  , group = 'Real Time Swing Structure')
//Bear Structure
show_bear = input.string('All', 'Bearish Structure'
  , options = ['All', 'BOS', 'CHoCH']
  , inline = 'bear'
  , group = 'Real Time Swing Structure')
swing_bear_css = input(#f23645, ''
  , inline = 'bear'
  , group = 'Real Time Swing Structure')
//Swings
show_swings = input(false, 'Show Swings Points'
  , inline = 'swings'
  , group = 'Real Time Swing Structure'
  , tooltip = SHOW_SWING_POINTS)
length = input.int(50, ''
  , minval = 10
  , inline = 'swings'
  , group = 'Real Time Swing Structure')
show_hl_swings = input(true, 'Show Strong/Weak High/Low'
  , group = 'Real Time Swing Structure'
  , tooltip = SHOW_SWHL_POINTS)
//----------------------------------------}
//Order Blocks
//----------------------------------------{
show_iob = input(true, 'Internal Order Blocks'
  , inline = 'iob'
  , group = 'Order Blocks'
  , tooltip = INTERNAL_OB)
iob_showlast = input.int(5, ''
  , minval = 1
  , inline = 'iob'
  , group = 'Order Blocks')
show_ob = input(false, 'Swing Order Blocks'
  , inline = 'ob'
  , group = 'Order Blocks'
  , tooltip = SWING_OB)
ob_showlast = input.int(5, ''
  , minval = 1
  , inline = 'ob'
  , group = 'Order Blocks')
ob_filter = input.string('Atr', 'Order Block Filter'
  , options = ['Atr', 'Cumulative Mean Range']
  , group = 'Order Blocks'
  , tooltip = FILTER_OB)
ibull_ob_css = input.color(color.new(#3179f5, 80), 'Internal Bullish OB'
  , group = 'Order Blocks')
ibear_ob_css = input.color(color.new(#f77c80, 80), 'Internal Bearish OB'
  , group = 'Order Blocks')
bull_ob_css = input.color(color.new(#1848cc, 80), 'Bullish OB'
  , group = 'Order Blocks')
bear_ob_css = input.color(color.new(#b22833, 80), 'Bearish OB'
  , group = 'Order Blocks')
//----------------------------------------}
//EQH/EQL
//----------------------------------------{
show_eq = input(true, 'Equal High/Low'
  , group = 'EQH/EQL'
  , tooltip = SHOW_EQHL)
eq_len = input.int(3, 'Bars Confirmation'
  , minval = 1
  , group = 'EQH/EQL'
  , tooltip = EQHL_BARS)
eq_threshold = input.float(0.1, 'Threshold'
  , minval = 0
  , maxval = 0.5
  , step = 0.1
  , group = 'EQH/EQL'
  , tooltip = EQHL_THRESHOLD)
//----------------------------------------}
//Fair Value Gaps
//----------------------------------------{
show_fvg = input(false, 'Fair Value Gaps'
  , group = 'Fair Value Gaps'
  , tooltip = SHOW_FVG)
  
fvg_auto = input(true, "Auto Threshold"
  , group = 'Fair Value Gaps'
  , tooltip = AUTO_FVG)
fvg_tf = input.timeframe('', "Timeframe"
  , group = 'Fair Value Gaps'
  , tooltip = FVG_TF)
bull_fvg_css = input.color(color.new(#00ff68, 70), 'Bullish FVG'
  , group = 'Fair Value Gaps')
bear_fvg_css = input.color(color.new(#ff0008, 70), 'Bearish FVG'
  , group = 'Fair Value Gaps')
fvg_extend = input.int(1, "Extend FVG"
  , minval = 0
  , group = 'Fair Value Gaps'
  , tooltip = EXTEND_FVG)
//----------------------------------------}
//Previous day/week high/low
//----------------------------------------{
//Daily
show_pdhl = input(false, 'Daily'
  , inline = 'daily'
  , group = 'Highs & Lows MTF')
pdhl_style = input.string('⎯⎯⎯', ''
  , options = ['⎯⎯⎯', '----', '····']
  , inline = 'daily'
  , group = 'Highs & Lows MTF')
pdhl_css = input(#2157f3, ''
  , inline = 'daily'
  , group = 'Highs & Lows MTF')
//Weekly
show_pwhl = input(false, 'Weekly'
  , inline = 'weekly'
  , group = 'Highs & Lows MTF')
pwhl_style = input.string('⎯⎯⎯', ''
  , options = ['⎯⎯⎯', '----', '····']
  , inline = 'weekly'
  , group = 'Highs & Lows MTF')
pwhl_css = input(#2157f3, ''
  , inline = 'weekly'
  , group = 'Highs & Lows MTF')
//Monthly
show_pmhl = input(false, 'Monthly'
  , inline = 'monthly'
  , group = 'Highs & Lows MTF')
pmhl_style = input.string('⎯⎯⎯', ''
  , options = ['⎯⎯⎯', '----', '····']
  , inline = 'monthly'
  , group = 'Highs & Lows MTF')
pmhl_css = input(#2157f3, ''
  , inline = 'monthly'
  , group = 'Highs & Lows MTF')
//----------------------------------------}
//Premium/Discount zones
//----------------------------------------{
show_sd = input(false, 'Premium/Discount Zones'
  , group = 'Premium & Discount Zones'
  , tooltip = PED_ZONES)
premium_css = input.color(#f23645, 'Premium Zone'
  , group = 'Premium & Discount Zones')
eq_css = input.color(#b2b5be, 'Equilibrium Zone'
  , group = 'Premium & Discount Zones')
discount_css = input.color(#089981, 'Discount Zone'
  , group = 'Premium & Discount Zones')
//-----------------------------------------------------------------------------}
//Functions
//-----------------------------------------------------------------------------{
n = bar_index
atr = ta.atr(200)
cmean_range = ta.cum(high - low) / n
//HL Output function
hl() => [high, low]
//Get ohlc values function
get_ohlc()=> [close[1], open[1], high, low, high[2], low[2]]
//Display Structure function
display_Structure(x, y, txt, css, dashed, down, lbl_size)=>
    structure_line = line.new(x, y, n, y
      , color = css
      , style = dashed ? line.style_dashed : line.style_solid)
    structure_lbl = label.new(int(math.avg(x, n)), y, txt
      , color = TRANSP_CSS
      , textcolor = css
      , style = down ? label.style_label_down : label.style_label_up
      , size = lbl_size)
    if mode == 'Present'
        line.delete(structure_line[1])
        label.delete(structure_lbl[1])
//Swings detection/measurements
swings(len)=>
    var os = 0
    
    upper = ta.highest(len)
    lower = ta.lowest(len)
    os := high[len] > upper ? 0 : low[len] < lower ? 1 : os[1]
    top = os == 0 and os[1] != 0 ? high[len] : 0
    btm = os == 1 and os[1] != 1 ? low[len] : 0
    [top, btm]
//Order block coordinates function
ob_coord(use_max, loc, target_top, target_btm, target_left, target_type)=>
    min = 99999999.
    max = 0.
    idx = 1
    ob_threshold = ob_filter == 'Atr' ? atr : cmean_range 
    //Search for highest/lowest high within the structure interval and get range
    if use_max
        for i = 1 to (n - loc)-1
            if (high - low) < ob_threshold * 2
                max := math.max(high, max)
                min := max == high ? low : min
                idx := max == high ? i : idx
    else
        for i = 1 to (n - loc)-1
            if (high - low) < ob_threshold * 2
                min := math.min(low, min)
                max := min == low ? high : max
                idx := min == low ? i : idx
    array.unshift(target_top, max)
    array.unshift(target_btm, min)
    array.unshift(target_left, time[idx])
    array.unshift(target_type, use_max ? -1 : 1)
//Set order blocks
display_ob(boxes, target_top, target_btm, target_left, target_type, show_last, swing, size)=>
    for i = 0 to math.min(show_last-1, size-1)
        get_box = array.get(boxes, i)
        box.set_lefttop(get_box, array.get(target_left, i), array.get(target_top, i))
        box.set_rightbottom(get_box, array.get(target_left, i), array.get(target_btm, i))
        box.set_extend(get_box, extend.right)
        color css = na
        
        if swing 
            if style == 'Monochrome'
                css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) : color.new(#5d606b, 80)
                border_css = array.get(target_type, i) == 1 ? #b2b5be : #5d606b
                box.set_border_color(get_box, border_css)
            else
                css := array.get(target_type, i) == 1 ? bull_ob_css : bear_ob_css
                box.set_border_color(get_box, css)
            box.set_bgcolor(get_box, css)
        else
            if style == 'Monochrome'
                css := array.get(target_type, i) == 1 ? color.new(#b2b5be, 80) : color.new(#5d606b, 80)
            else
                css := array.get(target_type, i) == 1 ? ibull_ob_css : ibear_ob_css
            
            box.set_border_color(get_box, css)
            box.set_bgcolor(get_box, css)
        
//Line Style function
get_line_style(style) =>
    out = switch style
        '⎯⎯⎯'  => line.style_solid
        '----' => line.style_dashed
        '····' => line.style_dotted
//Set line/labels function for previous high/lows
phl(h, l, tf, css)=>
    var line high_line = line.new(na,na,na,na
      , xloc = xloc.bar_time
      , color = css
      , style = get_line_style(pdhl_style))
    var label high_lbl = label.new(na,na
      , xloc = xloc.bar_time
      , text = str.format('P{0}H', tf)
      , color = TRANSP_CSS
      , textcolor = css
      , size = size.small
      , style = label.style_label_left)
    var line low_line = line.new(na,na,na,na
      , xloc = xloc.bar_time
      , color = css
      , style = get_line_style(pdhl_style))
    var label low_lbl = label.new(na,na
      , xloc = xloc.bar_time
      , text = str.format('P{0}L', tf)
      , color = TRANSP_CSS
      , textcolor = css
      , size = size.small
      , style = label.style_label_left)
    hy = ta.valuewhen(h != h[1], h, 1)
    hx = ta.valuewhen(h == high, time, 1)
    ly = ta.valuewhen(l != l[1], l, 1)
    lx = ta.valuewhen(l == low, time, 1)
    if barstate.islast
        ext = time + (time - time[1])*20
        //High
        line.set_xy1(high_line, hx, hy)
        line.set_xy2(high_line, ext, hy)
        label.set_xy(high_lbl, ext, hy)
        //Low
        line.set_xy1(low_line, lx, ly)
        line.set_xy2(low_line, ext, ly)
        label.set_xy(low_lbl, ext, ly)
//-----------------------------------------------------------------------------}
//Global variables
//-----------------------------------------------------------------------------{
var trend = 0, var itrend = 0
var top_y = 0., var top_x = 0
var btm_y = 0., var btm_x = 0
var itop_y = 0., var itop_x = 0
var ibtm_y = 0., var ibtm_x = 0
var trail_up = high, var trail_dn = low
var trail_up_x = 0,  var trail_dn_x = 0
var top_cross = true,  var btm_cross = true
var itop_cross = true, var ibtm_cross = true
var txt_top = '',  var txt_btm = ''
//Alerts
bull_choch_alert = false 
bull_bos_alert   = false 
bear_choch_alert = false 
bear_bos_alert   = false 
bull_ichoch_alert = false 
bull_ibos_alert   = false 
bear_ichoch_alert = false 
bear_ibos_alert   = false 
bull_iob_break = false 
bear_iob_break = false
bull_ob_break = false 
bear_ob_break = false
eqh_alert = false 
eql_alert = false 
//Structure colors
var bull_css = style == 'Monochrome' ? #b2b5be 
  : swing_bull_css
var bear_css = style == 'Monochrome' ? #b2b5be 
  : swing_bear_css
var ibull_css = style == 'Monochrome' ? #b2b5be 
  : swing_ibull_css
var ibear_css = style == 'Monochrome' ? #b2b5be 
  : swing_ibear_css
//Swings
[top, btm] = swings(length)
[itop, ibtm] = swings(5)
//-----------------------------------------------------------------------------}
//Pivot High
//-----------------------------------------------------------------------------{
var line extend_top = na
var label extend_top_lbl = label.new(na, na
  , color = TRANSP_CSS
  , textcolor = bear_css
  , style = label.style_label_down
  , size = size.tiny)
if top
    top_cross := true
    txt_top := top > top_y ? 'HH' : 'LH'
    if show_swings
        top_lbl = label.new(n-length, top, txt_top
          , color = TRANSP_CSS
          , textcolor = bear_css
          , style = label.style_label_down
          , size = size.small)
        if mode == 'Present'
            label.delete(top_lbl[1])
    //Extend recent top to last bar
    line.delete(extend_top[1])
    extend_top := line.new(n-length, top, n, top
      , color = bear_css)
    top_y := top
    top_x := n - length
    trail_up := top
    trail_up_x := n - length
if itop
    itop_cross := true
    itop_y := itop
    itop_x := n - 5
//Trailing maximum
trail_up := math.max(high, trail_up)
trail_up_x := trail_up == high ? n : trail_up_x
//Set top extension label/line
if barstate.islast and show_hl_swings
    line.set_xy1(extend_top, trail_up_x, trail_up)
    line.set_xy2(extend_top, n + 20, trail_up)
    label.set_x(extend_top_lbl, n + 20)
    label.set_y(extend_top_lbl, trail_up)
    label.set_text(extend_top_lbl, trend < 0 ? 'Strong High' : 'Weak High')
//-----------------------------------------------------------------------------}
//Pivot Low
//-----------------------------------------------------------------------------{
var line extend_btm = na 
var label extend_btm_lbl = label.new(na, na
  , color = TRANSP_CSS
  , textcolor = bull_css
  , style = label.style_label_up
  , size = size.tiny)
if btm
    btm_cross := true
    txt_btm := btm < btm_y ? 'LL' : 'HL'
    
    if show_swings
        btm_lbl = label.new(n - length, btm, txt_btm
          , color = TRANSP_CSS
          , textcolor = bull_css
          , style = label.style_label_up
          , size = size.small)
        if mode == 'Present'
            label.delete(btm_lbl[1])
    
    //Extend recent btm to last bar
    line.delete(extend_btm[1])
    extend_btm := line.new(n - length, btm, n, btm
      , color = bull_css)
    btm_y := btm
    btm_x := n-length
    trail_dn := btm
    trail_dn_x := n-length
if ibtm
    ibtm_cross := true
    ibtm_y := ibtm
    ibtm_x := n - 5
//Trailing minimum
trail_dn := math.min(low, trail_dn)
trail_dn_x := trail_dn == low ? n : trail_dn_x
//Set btm extension label/line
if barstate.islast and show_hl_swings
    line.set_xy1(extend_btm, trail_dn_x, trail_dn)
    line.set_xy2(extend_btm, n + 20, trail_dn)
    label.set_x(extend_btm_lbl, n + 20)
    label.set_y(extend_btm_lbl, trail_dn)
    label.set_text(extend_btm_lbl, trend > 0 ? 'Strong Low' : 'Weak Low')
//-----------------------------------------------------------------------------}
//Order Blocks Arrays
//-----------------------------------------------------------------------------{
var iob_top = array.new_float(0)
var iob_btm = array.new_float(0)
var iob_left = array.new_int(0)
var iob_type = array.new_int(0)
var ob_top = array.new_float(0)
var ob_btm = array.new_float(0)
var ob_left = array.new_int(0)
var ob_type = array.new_int(0)
//-----------------------------------------------------------------------------}
//Pivot High BOS/CHoCH
//-----------------------------------------------------------------------------{
//Filtering
var bull_concordant = true
if ifilter_confluence
    bull_concordant := high - math.max(close, open) > math.min(close, open - low)
//Detect internal bullish Structure
if ta.crossover(close, itop_y) and itop_cross and top_y != itop_y and bull_concordant
    bool choch = na
    
    if itrend < 0
        choch := true
        bull_ichoch_alert := true
    else 
        bull_ibos_alert := true
    
    txt = choch ? 'CHoCH' : 'BOS'
    if show_internals
        if show_ibull == 'All' or (show_ibull == 'BOS' and not choch) or (show_ibull == 'CHoCH' and choch)
            display_Structure(itop_x, itop_y, txt, ibull_css, true, true, size.tiny)
    
    itop_cross := false
    itrend := 1
    
    //Internal Order Block
    if show_iob
        ob_coord(false, itop_x, iob_top, iob_btm, iob_left, iob_type)
//Detect bullish Structure
if ta.crossover(close, top_y) and top_cross
    bool choch = na
    
    if trend < 0
        choch := true
        bull_choch_alert := true
    else 
        bull_bos_alert := true
    txt = choch ? 'CHoCH' : 'BOS'
    
    if show_Structure
        if show_bull == 'All' or (show_bull == 'BOS' and not choch) or (show_bull == 'CHoCH' and choch)
            display_Structure(top_x, top_y, txt, bull_css, false, true, size.small)
    
    //Order Block
    if show_ob
        ob_coord(false, top_x, ob_top, ob_btm, ob_left, ob_type)
    top_cross := false
    trend := 1
//-----------------------------------------------------------------------------}
//Pivot Low BOS/CHoCH
//-----------------------------------------------------------------------------{
var bear_concordant = true
if ifilter_confluence
    bear_concordant := high - math.max(close, open) < math.min(close, open - low)
//Detect internal bearish Structure
if ta.crossunder(close, ibtm_y) and ibtm_cross and btm_y != ibtm_y and bear_concordant
    bool choch = false
    
    if itrend > 0
        choch := true
        bear_ichoch_alert := true
    else 
        bear_ibos_alert := true
    
    txt = choch ? 'CHoCH' : 'BOS'
    if show_internals
        if show_ibear == 'All' or (show_ibear == 'BOS' and not choch) or (show_ibear == 'CHoCH' and choch)
            display_Structure(ibtm_x, ibtm_y, txt, ibear_css, true, false, size.tiny)
    
    ibtm_cross := false
    itrend := -1
    
    //Internal Order Block
    if show_iob
        ob_coord(true, ibtm_x, iob_top, iob_btm, iob_left, iob_type)
//Detect bearish Structure
if ta.crossunder(close, btm_y) and btm_cross
    bool choch = na
    
    if trend > 0
        choch := true
        bear_choch_alert := true
    else 
        bear_bos_alert := true
    txt = choch ? 'CHoCH' : 'BOS'
    
    if show_Structure
        if show_bear == 'All' or (show_bear == 'BOS' and not choch) or (show_bear == 'CHoCH' and choch)
            display_Structure(btm_x, btm_y, txt, bear_css, false, false, size.small)
    
    //Order Block
    if show_ob
        ob_coord(true, btm_x, ob_top, ob_btm, ob_left, ob_type)
    btm_cross := false
    trend := -1
//-----------------------------------------------------------------------------}
//Order Blocks
//-----------------------------------------------------------------------------{
//Set order blocks
var iob_boxes = array.new_box(0)
var ob_boxes = array.new_box(0)
//Delete internal order blocks box coordinates if top/bottom is broken
for element in iob_type
    index = array.indexof(iob_type, element)
    if close < array.get(iob_btm, index) and element == 1
        array.remove(iob_top, index) 
        array.remove(iob_btm, index) 
        array.remove(iob_left, index) 
        array.remove(iob_type, index)
        bull_iob_break := true
    else if close > array.get(iob_top, index) and element == -1
        array.remove(iob_top, index) 
        array.remove(iob_btm, index)
        array.remove(iob_left, index) 
        array.remove(iob_type, index)
        bear_iob_break := true
//Delete internal order blocks box coordinates if top/bottom is broken
for element in ob_type
    index = array.indexof(ob_type, element)
    if close < array.get(ob_btm, index) and element == 1
        array.remove(ob_top, index) 
        array.remove(ob_btm, index) 
        array.remove(ob_left, index) 
        array.remove(ob_type, index)
        bull_ob_break := true
    else if close > array.get(ob_top, index) and element == -1
        array.remove(ob_top, index) 
        array.remove(ob_btm, index)
        array.remove(ob_left, index) 
        array.remove(ob_type, index)
        bear_ob_break := true
iob_size = array.size(iob_type)
ob_size = array.size(ob_type)
if barstate.isfirst
    if show_iob
        for i = 0 to iob_showlast-1
            array.push(iob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time))
    if show_ob
        for i = 0 to ob_showlast-1
            array.push(ob_boxes, box.new(na,na,na,na, xloc = xloc.bar_time))
if iob_size > 0
    if barstate.islast
        display_ob(iob_boxes, iob_top, iob_btm, iob_left, iob_type, iob_showlast, false, iob_size)
if ob_size > 0
    if barstate.islast
        display_ob(ob_boxes, ob_top, ob_btm, ob_left, ob_type, ob_showlast, true, ob_size)
//-----------------------------------------------------------------------------}
//EQH/EQL
//-----------------------------------------------------------------------------{
var eq_prev_top = 0.
var eq_top_x = 0
var eq_prev_btm = 0.
var eq_btm_x = 0
if show_eq
    eq_top = ta.pivothigh(eq_len, eq_len)
    eq_btm = ta.pivotlow(eq_len, eq_len)
    if eq_top 
        max = math.max(eq_top, eq_prev_top)
        min = math.min(eq_top, eq_prev_top)
        
        if max < min + atr * eq_threshold
            eqh_line = line.new(eq_top_x, eq_prev_top, n-eq_len, eq_top
              , color = bear_css
              , style = line.style_dotted)
            eqh_lbl = label.new(int(math.avg(n-eq_len, eq_top_x)), eq_top, 'EQH'
              , color = #00000000
              , textcolor = bear_css
              , style = label.style_label_down
              , size = size.tiny)
            if mode == 'Present'
                line.delete(eqh_line[1])
                label.delete(eqh_lbl[1])
            
            eqh_alert := true
        eq_prev_top := eq_top
        eq_top_x := n-eq_len
    if eq_btm 
        max = math.max(eq_btm, eq_prev_btm)
        min = math.min(eq_btm, eq_prev_btm)
        
        if min > max - atr * eq_threshold
            eql_line = line.new(eq_btm_x, eq_prev_btm, n-eq_len, eq_btm
              , color = bull_css
              , style = line.style_dotted)
            eql_lbl = label.new(int(math.avg(n-eq_len, eq_btm_x)), eq_btm, 'EQL'
              , color = #00000000
              , textcolor = bull_css
              , style = label.style_label_up
              , size = size.tiny)
            eql_alert := true
            if mode == 'Present'
                line.delete(eql_line[1])
                label.delete(eql_lbl[1])
        eq_prev_btm := eq_btm
        eq_btm_x := n-eq_len
//-----------------------------------------------------------------------------}
//Fair Value Gaps
//-----------------------------------------------------------------------------{
var bullish_fvg_max = array.new_box(0)
var bullish_fvg_min = array.new_box(0)
var bearish_fvg_max = array.new_box(0)
var bearish_fvg_min = array.new_box(0)
float bullish_fvg_avg = na
float bearish_fvg_avg = na
bullish_fvg_cnd = false
bearish_fvg_cnd = false
[src_c1, src_o1, src_h, src_l, src_h2, src_l2] =
  request.security(syminfo.tickerid, fvg_tf, get_ohlc())
if show_fvg
    delta_per = (src_c1 - src_o1) / src_o1 * 100
    change_tf = timeframe.change(fvg_tf)
    threshold = fvg_auto ? ta.cum(math.abs(change_tf ? delta_per : 0)) / n * 2 
      : 0
    //FVG conditions
    bullish_fvg_cnd := src_l > src_h2
      and src_c1 > src_h2 
      and delta_per > threshold
      and change_tf
    bearish_fvg_cnd := src_h < src_l2 
      and src_c1 < src_l2 
      and -delta_per > threshold
      and change_tf
    //FVG Areas
    if bullish_fvg_cnd
        array.unshift(bullish_fvg_max, box.new(n-1, src_l, n + fvg_extend, math.avg(src_l, src_h2)
          , border_color = bull_fvg_css
          , bgcolor = bull_fvg_css))
        
        array.unshift(bullish_fvg_min, box.new(n-1, math.avg(src_l, src_h2), n + fvg_extend, src_h2
          , border_color = bull_fvg_css
          , bgcolor = bull_fvg_css))
    
    if bearish_fvg_cnd
        array.unshift(bearish_fvg_max, box.new(n-1, src_h, n + fvg_extend, math.avg(src_h, src_l2)
          , border_color = bear_fvg_css
          , bgcolor = bear_fvg_css))
        
        array.unshift(bearish_fvg_min, box.new(n-1, math.avg(src_h, src_l2), n + fvg_extend, src_l2
          , border_color = bear_fvg_css
          , bgcolor = bear_fvg_css))
    for bx in bullish_fvg_min
        if low < box.get_bottom(bx)
            box.delete(bx)
            box.delete(array.get(bullish_fvg_max, array.indexof(bullish_fvg_min, bx)))
    
    for bx in bearish_fvg_max
        if high > box.get_top(bx)
            box.delete(bx)
            box.delete(array.get(bearish_fvg_min, array.indexof(bearish_fvg_max, bx)))
//-----------------------------------------------------------------------------}
//Previous day/week high/lows
//-----------------------------------------------------------------------------{
//Daily high/low
[pdh, pdl] = request.security(syminfo.tickerid, 'D', hl()
  , lookahead = barmerge.lookahead_on)
//Weekly high/low
[pwh, pwl] = request.security(syminfo.tickerid, 'W', hl()
  , lookahead = barmerge.lookahead_on)
//Monthly high/low
[pmh, pml] = request.security(syminfo.tickerid, 'M', hl()
  , lookahead = barmerge.lookahead_on)
//Display Daily
if show_pdhl
    phl(pdh, pdl, 'D', pdhl_css)
//Display Weekly
if show_pwhl
    phl(pwh, pwl, 'W', pwhl_css)
    
//Display Monthly
if show_pmhl
    phl(pmh, pml, 'M', pmhl_css)
//-----------------------------------------------------------------------------}
//Premium/Discount/Equilibrium zones
//-----------------------------------------------------------------------------{
var premium = box.new(na, na, na, na
  , bgcolor = color.new(premium_css, 80)
  , border_color = na)
var premium_lbl = label.new(na, na
  , text = 'Premium'
  , color = TRANSP_CSS
  , textcolor = premium_css
  , style = label.style_label_down
  , size = size.small)
var eq = box.new(na, na, na, na
  , bgcolor = color.rgb(120, 123, 134, 80)
  , border_color = na)
var eq_lbl = label.new(na, na
  , text = 'Equilibrium'
  , color = TRANSP_CSS
  , textcolor = eq_css
  , style = label.style_label_left
  , size = size.small)
var discount = box.new(na, na, na, na
  , bgcolor = color.new(discount_css, 80)
  , border_color = na)
var discount_lbl = label.new(na, na
  , text = 'Discount'
  , color = TRANSP_CSS
  , textcolor = discount_css
  , style = label.style_label_up
  , size = size.small)
//Show Premium/Discount Areas
if barstate.islast and show_sd
    avg = math.avg(trail_up, trail_dn)
    box.set_lefttop(premium, math.max(top_x, btm_x), trail_up)
    box.set_rightbottom(premium, n, .95 * trail_up + .05 * trail_dn)
    label.set_xy(premium_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_up)
    box.set_lefttop(eq, math.max(top_x, btm_x), .525 * trail_up + .475*trail_dn)
    box.set_rightbottom(eq, n, .525 * trail_dn + .475 * trail_up)
    label.set_xy(eq_lbl, n, avg)
    
    box.set_lefttop(discount, math.max(top_x, btm_x), .95 * trail_dn + .05 * trail_up)
    box.set_rightbottom(discount, n, trail_dn)
    label.set_xy(discount_lbl, int(math.avg(math.max(top_x, btm_x), n)), trail_dn)
//-----------------------------------------------------------------------------}
//Trend
//-----------------------------------------------------------------------------{
var color trend_css = na
if show_trend
    if style == 'Colored'
        trend_css := itrend == 1 ? bull_css : bear_css
    else if style == 'Monochrome'
        trend_css := itrend == 1 ? #b2b5be : #5d606b
plotcandle(open, high, low, close
  , color = trend_css
  , wickcolor = trend_css
  , bordercolor = trend_css
  , editable = false)
//-----------------------------------------------------------------------------}
//Alerts
//-----------------------------------------------------------------------------{
//Internal Structure
alertcondition(bull_ibos_alert, 'Internal Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(bull_ichoch_alert, 'Internal Bullish CHoCH', 'Internal Bullish CHoCH formed')
alertcondition(bear_ibos_alert, 'Internal Bearish BOS', 'Internal Bearish BOS formed')
alertcondition(bear_ichoch_alert, 'Internal Bearish CHoCH', 'Internal Bearish CHoCH formed')
//Swing Structure
alertcondition(bull_bos_alert, 'Bullish BOS', 'Internal Bullish BOS formed')
alertcondition(bull_choch_alert, 'Bullish CHoCH', 'Internal Bullish CHoCH formed')
alertcondition(bear_bos_alert, 'Bearish BOS', 'Bearish BOS formed')
alertcondition(bear_choch_alert, 'Bearish CHoCH', 'Bearish CHoCH formed')
//order Blocks
alertcondition(bull_iob_break, 'Bullish Internal OB Breakout', 'Price broke bullish iternal OB')
alertcondition(bear_iob_break, 'Bearish Internal OB Breakout', 'Price broke bearish iternal OB')
alertcondition(bull_ob_break, 'Bullish OB Breakout', 'Price broke bullish iternal OB')
alertcondition(bear_ob_break, 'bearish OB Breakout', 'Price broke bearish iternal OB')
//EQH/EQL
alertcondition(eqh_alert, 'Equal Highs', 'Equal highs detected')
alertcondition(eql_alert, 'Equal Lows', 'Equal lows detected')
//FVG
alertcondition(bullish_fvg_cnd, 'Bullish FVG', 'Bullish FVG formed')
alertcondition(bearish_fvg_cnd, 'Bearish FVG', 'Bearish FVG formed')
//-----------------------------------------------------------------------------}
 
Status
Not open for further replies.

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
476 Online
Create Post

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top