Indicator · Pine Script v6 · On the chart

High/Mid/Low of the Previous Month, Week and Day + MA

by IAMATOMIC001

This indicator plots the high, midpoint, and low of the previous day, week, and month as lines on the price chart.

View on GitHub

Repaints

GitHub stars3on the repository
Pine versionv6current
Lines of code1,458
Settings40inputs
LicenceNone statedfile: MPL-2.0
Last update12 months ago31 Oct 2025

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
  4. 4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.

Source Code

1,458 lines of Pine Script v6 from Indicators/INR_5000_INDICATOR.PINE, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

INR_5000_INDICATOR.PINE
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// � soltanifx
// Created: 2024-12-10
// Last modified: 2024-12-12
// version 1.0

//@version=6
indicator('Displays the High, Midpoint, and Low of the Previous Month, Week, and Day + Moving Average', 'High/Mid/Low of the Previous Month, Week and Day + MA', true, max_lines_count = 500)

//--------------------------------------------------------------------
//                             Constants
//--------------------------------------------------------------------

var DAILY_LINE_STYLE = line.style_solid
var DAILY_LINE_WITDH = 1
var WEEKLY_LINE_STYLE = line.style_solid
var WEEKLY_LINE_WIDTH = 1
var MONTHLY_LINE_STYLE = line.style_solid
var MONTHLY_LINE_WIDTH = 1
var MID_LINE_STYLE = line.style_dashed
var MID_LINE_WIDTH = 1
var LABEL_HIGH_STYLE  = label.style_label_lower_left
var LABEL_LOW_STYLE  = label.style_label_upper_left
var LABEL_MID_STYLE  = label.style_label_left
var LABEL_SIZE  = size.small
var LABEL_TEXT_COLOR = color.white
var STR_MONTHLY = "Monthly"
var STR_WEEKLY = "Weekly"
var STR_DAILY = "Daily"
//--------------------------------------------------------------------
//                               Inputs
//--------------------------------------------------------------------

g_indicator = 'Highs & Lows'
g_style = 'Style'
t_heads = 'Extends previous highs and lows in the future.'
t_gradient = 'Show a color gradient that highlights the recency of highs and lows.'

var i_isDailyEnabled = input(true, 'Daily', inline = 'Daily', group = g_indicator)
var i_dailyColor = input(color.blue, '', inline = 'Daily', group = g_indicator)
// var i_dailyLookback = input.int(1, '', 1, inline = 'Daily', group = g_indicator)
var i_isWeeklyEnabled = input(true, 'Weekly', inline = 'Weekly', group = g_indicator)
var i_weeklyColor = input(color.teal, '', inline = 'Weekly', group = g_indicator)
// var i_weeklyLookback = input.int(1, '', 1, inline = 'Weekly', group = g_indicator)
var i_isMonthlyEnabled = input(true, 'Monthly', inline = 'Monthly', group = g_indicator)
var i_monthlyColor = input(color.red, '', inline = 'Monthly', group = g_indicator)
// var i_monthlyLookback = input.int(1, '', 1, inline = 'Monthly', group = g_indicator)
var i_show_labels = input.bool(false, title="Show Labels?", group = g_indicator)
var i_isLogarithmic = input.bool(false, title="Is Chart in Logarithmic Scale?", group = g_indicator)
var i_areHeadsEnabled = input(true, 'Show Projections', t_heads, inline = 'Head', group = g_style)
var i_rightOffset = input.int(25, '', 1, inline = 'Head', group = g_style)

//--------------------------------------------------------------------
//                        Variables declarations
//--------------------------------------------------------------------

var a_lastHighs = array.new_float(3)
var a_lastLows = array.new_float(3)
var a_lastMids = array.new_float(3)
var canShowDaily = i_isDailyEnabled and timeframe.isintraday
var canShowWeekly = i_isWeeklyEnabled and (timeframe.isintraday or timeframe.isdaily)
var canShowMonthly = i_isMonthlyEnabled and not timeframe.ismonthly

[dailyTime, dailyHigh, dailyLow, dailyMid, isLastDaily] = request.security(syminfo.tickerid, 'D', [time, high, low, i_isLogarithmic? math.exp((math.log(high) + math.log(low)) / 2) : (high - low) / 2 + low, barstate.islast], lookahead = barmerge.lookahead_on)
[weeklyTime, weeklyHigh, weeklyLow, weeklyMid, isLastWeekly] = request.security(syminfo.tickerid, 'W', [time, high, low, i_isLogarithmic? math.exp((math.log(high) + math.log(low)) / 2) : (high - low) / 2 + low, barstate.islast], lookahead = barmerge.lookahead_on)
[monthlyTime, monthlyHigh, monthlyLow, monthlyMid, isLastMonthly] = request.security(syminfo.tickerid, 'M', [time, high, low, i_isLogarithmic? math.exp((math.log(high) + math.log(low)) / 2) : (high - low) / 2 + low, barstate.islast], lookahead = barmerge.lookahead_on)

hasDailyTimeChanged = dailyTime != dailyTime[1]
hasWeekklyTimeChanged = weeklyTime != weeklyTime[1]
hasMonthlyTimeChanged = monthlyTime != monthlyTime[1]

//--------------------------------------------------------------------
//                              Functions 
//--------------------------------------------------------------------

f_getRightBarIndex() =>
    bar_index + i_rightOffset

f_draw(bool _isNew, float _h, float _l, float _m, color _color, string _style, string _midStyle, int _width, int _midWidth) =>
    var line _high = na
    var line _low = na
    var line _mid = na
    var _highs = array.new_line()
    var _lows = array.new_line()
    var _mids = array.new_line()

    _end = i_areHeadsEnabled ? f_getRightBarIndex() : bar_index

    if _isNew
        line.set_x2(_high, _end)
        line.set_x2(_mid, _end)
        line.set_x2(_low, _end)

        _high := line.new(bar_index, _h, bar_index, _h, color = _color, style = _style, width = _width)
        _mid := line.new(bar_index, _m, bar_index, _m, color = _color, style = _midStyle, width = _midWidth)
        _low := line.new(bar_index, _l, bar_index, _l, color = _color, style = _style, width = _width)        
        array.push(_highs, _high)
        array.push(_mids, _mid)
        array.push(_lows, _low)        
    
        if array.size(_highs) > 2
            line.delete(array.shift(_highs))
            line.delete(array.shift(_mids))
            line.delete(array.shift(_lows))

    if i_areHeadsEnabled and barstate.islast and array.size(_highs) > 1
        // Avoid updating the last/current high and low 
        for i = 0 to array.size(_highs) - 2 by 1
            line.set_x2(array.get(_highs, i), f_getRightBarIndex())
            line.set_x2(array.get(_mids, i), f_getRightBarIndex())
            line.set_x2(array.get(_lows, i), f_getRightBarIndex())

f_show_labels() =>
    var label _lbl_m_high = na
    var label _lbl_m_mid = na
    var label _lbl_m_low = na
    var label _lbl_w_high = na
    var label _lbl_w_mid = na
    var label _lbl_w_low = na
    var label _lbl_d_high = na
    var label _lbl_d_mid = na
    var label _lbl_d_low = na

    var _lbl_m_highs = array.new_label()
    var _lbl_m_mids = array.new_label()
    var _lbl_m_lows = array.new_label()
    var _lbl_w_highs = array.new_label()
    var _lbl_w_mids = array.new_label()
    var _lbl_w_lows = array.new_label()
    var _lbl_d_highs = array.new_label()
    var _lbl_d_mids = array.new_label()
    var _lbl_d_lows = array.new_label()

    _end = i_areHeadsEnabled ? f_getRightBarIndex() : bar_index

    _lbl_m_high := label.new(_end, array.get(a_lastHighs, 2), text=STR_MONTHLY+" High [ "+str.tostring(array.get(a_lastHighs, 2), "#.#####")+" ]", style=LABEL_HIGH_STYLE, color=i_monthlyColor, textcolor=LABEL_TEXT_COLOR, size = LABEL_SIZE)
    _lbl_m_mid := label.new(_end, array.get(a_lastMids, 2), text="50% "+STR_MONTHLY+" [ "+str.tostring(array.get(a_lastMids, 2), "#.#####")+" ]", style=LABEL_MID_STYLE, color=i_monthlyColor, textcolor=LABEL_TEXT_COLOR, size = LABEL_SIZE)
    _lbl_m_low := label.new(_end, array.get(a_lastLows, 2), text=STR_MONTHLY+" Low [ "+str.tostring(array.get(a_lastLows, 2), "#.#####")+" ]", style=LABEL_LOW_STYLE, color=i_monthlyColor, textcolor=LABEL_TEXT_COLOR, size = LABEL_SIZE)
    _lbl_w_high := label.new(_end, array.get(a_lastHighs, 1), text=STR_WEEKLY+" High [ "+str.tostring(array.get(a_lastHighs, 1), "#.#####")+" ]", style=LABEL_HIGH_STYLE, color=i_weeklyColor, textcolor=LABEL_TEXT_COLOR, size = LABEL_SIZE)
    _lbl_w_mid := label.new(_end, array.get(a_lastMids, 1), text="50% "+STR_WEEKLY+" [ "+str.tostring(array.get(a_lastMids, 1), "#.#####")+" ]", style=LABEL_MID_STYLE, color=i_weeklyColor, textcolor=LABEL_TEXT_COLOR, size = LABEL_SIZE)
    _lbl_w_low := label.new(_end, array.get(a_lastLows, 1), text=STR_WEEKLY+" Low [ "+str.tostring(array.get(a_lastLows, 1), "#.#####")+" ]", style=LABEL_LOW_STYLE, color=i_weeklyColor, textcolor=LABEL_TEXT_COLOR, size = LABEL_SIZE)
    _lbl_d_high := label.new(_end, array.get(a_lastHighs, 0), text=STR_DAILY+" High [ "+str.tostring(array.get(a_lastHighs, 0), "#.#####")+" ]", style=LABEL_HIGH_STYLE, color=i_dailyColor, textcolor=LABEL_TEXT_COLOR, size = LABEL_SIZE)
    _lbl_d_mid := label.new(_end, array.get(a_lastMids, 0), text="50% "+STR_DAILY+" [ "+str.tostring(array.get(a_lastMids, 0), "#.#####")+" ]", style=LABEL_MID_STYLE, color=i_dailyColor, textcolor=LABEL_TEXT_COLOR, size = LABEL_SIZE)
    _lbl_d_low := label.new(_end, array.get(a_lastLows, 0), text=STR_DAILY+" Low [ "+str.tostring(array.get(a_lastLows, 0), "#.#####")+" ]", style=LABEL_LOW_STYLE, color=i_dailyColor, textcolor=LABEL_TEXT_COLOR, size = LABEL_SIZE)

    array.push(_lbl_m_highs, _lbl_m_high)
    array.push(_lbl_m_mids, _lbl_m_mid)
    array.push(_lbl_m_lows, _lbl_m_low)
    array.push(_lbl_w_highs, _lbl_w_high)
    array.push(_lbl_w_mids, _lbl_w_mid)
    array.push(_lbl_w_lows, _lbl_w_low)
    array.push(_lbl_d_highs, _lbl_d_high)
    array.push(_lbl_d_mids, _lbl_d_mid)
    array.push(_lbl_d_lows, _lbl_d_low)

    if array.size(_lbl_m_highs) > 1
        label.delete(array.shift(_lbl_m_highs))
        label.delete(array.shift(_lbl_m_mids))
        label.delete(array.shift(_lbl_m_lows))
        label.delete(array.shift(_lbl_w_highs))
        label.delete(array.shift(_lbl_w_mids))
        label.delete(array.shift(_lbl_w_lows))
        label.delete(array.shift(_lbl_d_highs))
        label.delete(array.shift(_lbl_d_mids))
        label.delete(array.shift(_lbl_d_lows))

//--------------------------------------------------------------------
//                                Logic
//--------------------------------------------------------------------

if canShowDaily and hasDailyTimeChanged and not isLastDaily
    array.set(a_lastHighs, 0, dailyHigh)
    array.set(a_lastLows, 0, dailyLow)
    array.set(a_lastMids, 0, dailyMid)

if canShowWeekly and hasWeekklyTimeChanged and not isLastWeekly
    array.set(a_lastHighs, 1, weeklyHigh)
    array.set(a_lastLows, 1, weeklyLow)
    array.set(a_lastMids, 1, weeklyMid)

if canShowMonthly and hasMonthlyTimeChanged and not isLastMonthly
    array.set(a_lastHighs, 2, monthlyHigh)
    array.set(a_lastLows, 2, monthlyLow)
    array.set(a_lastMids, 2, monthlyMid)

//--------------------------------------------------------------------
//                          Plotting & styling
//--------------------------------------------------------------------

if canShowMonthly
    f_draw(hasMonthlyTimeChanged, monthlyHigh, monthlyLow, monthlyMid, i_monthlyColor, MONTHLY_LINE_STYLE, MID_LINE_STYLE, MONTHLY_LINE_WIDTH, MID_LINE_WIDTH)

if canShowWeekly
    f_draw(hasWeekklyTimeChanged, weeklyHigh, weeklyLow, weeklyMid, i_weeklyColor, WEEKLY_LINE_STYLE, MID_LINE_STYLE, WEEKLY_LINE_WIDTH, MID_LINE_WIDTH)

if canShowDaily
    f_draw(hasDailyTimeChanged, dailyHigh, dailyLow, dailyMid, i_dailyColor, DAILY_LINE_STYLE, MID_LINE_STYLE, DAILY_LINE_WITDH, MID_LINE_WIDTH)

if i_show_labels
    f_show_labels()

// Plot invisible highs and lows for displaying their last values in `status line`, `scale`, `data window` as well for providing defaults alert conditions
plot(array.get(a_lastHighs, 0), 'DH', color.new(i_dailyColor, 100), editable = false, display = i_show_labels? display.none : display.price_scale)
plot(array.get(a_lastLows, 0), 'DL', color.new(i_dailyColor, 100), editable = false, display = i_show_labels? display.none : display.price_scale)
plot(array.get(a_lastMids, 0), 'DM', color.new(i_dailyColor, 100), editable = false, display = i_show_labels? display.none : display.price_scale)
plot(array.get(a_lastHighs, 1), 'WH', color.new(i_weeklyColor, 100), editable = false, display = i_show_labels? display.none : display.price_scale)
plot(array.get(a_lastLows, 1), 'WL', color.new(i_weeklyColor, 100), editable = false, display = i_show_labels? display.none : display.price_scale)
plot(array.get(a_lastMids, 1), 'WM', color.new(i_weeklyColor, 100), editable = false, display = i_show_labels? display.none : display.price_scale)
plot(array.get(a_lastHighs, 2), 'MH', color.new(i_monthlyColor, 100), editable = false, display = i_show_labels? display.none : display.price_scale)
plot(array.get(a_lastLows, 2), 'ML', color.new(i_monthlyColor, 100), editable = false, display = i_show_labels? display.none : display.price_scale)
plot(array.get(a_lastMids, 2), 'MM', color.new(i_monthlyColor, 100), editable = false, display = i_show_labels? display.none : display.price_scale)

//--------------------------------------------------------------------
//                          Moving Average Exponential
//--------------------------------------------------------------------
g_period = 'Period'
g_ma_style = 'Moving Average Style'
var i_show_ma = input.bool(false, title="Show Moving Average?", group = g_period)
len = input.int(14, minval=1, title="Length", group = g_period)
src = input(hlc3, title="Source", group = g_period)
var i_ma_color = input(color.new(color.black,75), '', tooltip = "simple ma color", group = g_ma_style)
var i_sma_color = input(color.new(color.blue,50), '', tooltip = "ema color", group = g_ma_style)
var i_bb_color = input(color.new(color.green,90), '', tooltip = "bollinger band color", group = g_ma_style)
offset = input.int(title="Offset", defval=0, minval=-500, maxval=500, display = display.data_window, group = g_period)
out = ta.ema(src, len)
plot(i_show_ma ? out : na, title="EMA", color=i_ma_color, offset=offset)

// Smoothing MA inputs
GRP = "Moving Average"
TT_BB = "Only applies when 'SMA + Bollinger Bands' is selected. Determines the distance between the SMA and the bands."
maTypeInput = input.string("None", "Type", options = ["None", "SMA", "SMA + Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group = GRP, display = display.data_window)
maLengthInput = input.int(26, "Length", group = GRP, display = display.data_window)
bbMultInput = input.float(2.0, "BB StdDev", minval = 0.001, maxval = 50, step = 0.5, tooltip = TT_BB, group = GRP, display = display.data_window)
var enableMA = maTypeInput != "None"
var isBB = maTypeInput == "SMA + Bollinger Bands"

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

// Smoothing MA plots
smoothingMA = i_show_ma and enableMA ? ma(out, maLengthInput, maTypeInput) : na
smoothingStDev = isBB ? ta.stdev(out, maLengthInput) * bbMultInput : na
plot(smoothingMA, "EMA-based MA", color=i_sma_color, display = enableMA ? display.all : display.none)
bbUpperBand = plot(smoothingMA + smoothingStDev, title = "Upper Bollinger Band", color=i_bb_color, display = isBB ? display.all : display.none)
bbLowerBand = plot(smoothingMA - smoothingStDev, title = "Lower Bollinger Band", color=i_bb_color, display = isBB ? display.all : display.none)
fill(bbUpperBand, bbLowerBand, color= isBB ? i_bb_color : na, title="Bollinger Bands Background Fill", display = isBB ? display.all : display.none)

// Parametri di personalizzazione
linea29_colore = input.color(color.blue, title = 'Colore Linea 29')
linea29_spessore = input.int(1, title = 'Spessore Linea 29')
linea71_colore = input.color(color.black, title = 'Colore Linea 71')
linea71_spessore = input.int(1, title = 'Spessore Linea 71')

// Input per selezionare/deselezionare le linee
mostra_linea29 = input.bool(true, title = 'Mostra Linea 29')
mostra_linea71 = input.bool(true, title = 'Mostra Linea 71')

// Funzione per tracciare le linee orizzontali e le etichette
f_traccia_linee(prezzo_iniziale, diviso_per, spessore, colore, livello) =>
    valore_diviso = int(prezzo_iniziale / diviso_per) * diviso_per
    for i = -2 to 2 by 1
        livello_corrente = valore_diviso + i * diviso_per
        // Traccia la linea orizzontale estendendola infinitamente a sinistra e a destra
        line.new(x1 = bar_index, y1 = livello_corrente, x2 = bar_index + 1, y2 = livello_corrente, color = colore, width = spessore, extend = extend.both)
        // Determina il nome per l'etichetta
        label_text = (livello == 29 ? 'Linea 29: ' : 'Linea 71: ') + str.tostring(livello_corrente)
        // Aggiungi etichetta con il valore
        label.new(x = bar_index + 1, y = livello_corrente, text = label_text, style = label.style_label_left, color = colore, textcolor = color.white, size = size.small)

// Usa il prezzo di chiusura del momento per tracciare le linee
prezzo_corrente = close

// Traccia le linee per il livello 29 se selezionato
if mostra_linea29
    f_traccia_linee(prezzo_corrente, 29, linea29_spessore, linea29_colore, 29)

// Traccia le linee per il livello 71 se selezionato
if mostra_linea71
    f_traccia_linee(prezzo_corrente, 71, linea71_spessore, linea71_colore, 71)

// User Inputs

fastMA = input(10, title="Fast MA")

slowMA = input(30, title="Slow MA")

atrLength = input(14, title="ATR Length")

atrMultiplierSL = input.float(1.5, title="ATR Stop Multiplier")

tp1Multiplier = input.float(0.5, title="TP1 Multiplier")

tp2Multiplier = input.float(1.0, title="TP2 Multiplier")

tp3Multiplier = input.float(1.5, title="TP3 Multiplier")



// Indicators

fastMA_val = ta.ema(close, fastMA)

slowMA_val = ta.ema(close, slowMA)

atr_val = ta.atr(atrLength)



// Entry Conditions

longCondition = ta.crossover(fastMA_val, slowMA_val)

shortCondition = ta.crossunder(fastMA_val, slowMA_val)



// Stop Loss and Take Profit Levels

longStopLoss = close - (atr_val * atrMultiplierSL)

shortStopLoss = close + (atr_val * atrMultiplierSL)



longTP1 = close + (atr_val * tp1Multiplier)

longTP2 = close + (atr_val * tp2Multiplier)

longTP3 = close + (atr_val * tp3Multiplier)



shortTP1 = close - (atr_val * tp1Multiplier)

shortTP2 = close - (atr_val * tp2Multiplier)

shortTP3 = close - (atr_val * tp3Multiplier)



// Define explicit colors for each column with green and black

signalColor = #32CD32 // Lime Green (for Signal)

tpColor = #008000 // Green (for TP columns)

strengthColor = #000000 // Black (for Strength columns)

slColor = #008000 // Green (for Stop Loss)

transparentColor = color.rgb(0, 0, 0, 0)  // Fully transparent color



// Create Table for displaying TP, SL, and Strength levels (Vertical Table)

var table myTable = table.new(position.top_right, 2, 7, border_width=1, frame_color=color.black, bgcolor=transparentColor)



// Buyers and Sellers Strength Calculation

buyerStrength = (close > open) ? volume : 0

sellerStrength = (close < open) ? volume : 0



// Update table when a new trade is triggered

if (longCondition)

    table.cell(myTable, 0, 0, "Signal", bgcolor=signalColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 0, "Long", bgcolor=signalColor, text_color=color.white, text_size=size.tiny)

    

    table.cell(myTable, 0, 1, "TP1", bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 1, str.tostring(longTP1), bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    

    table.cell(myTable, 0, 2, "TP2", bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 2, str.tostring(longTP2), bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    

    table.cell(myTable, 0, 3, "TP3", bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 3, str.tostring(longTP3), bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    

    table.cell(myTable, 0, 4, "Buyers Strength", bgcolor=strengthColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 4, str.tostring(buyerStrength), bgcolor=strengthColor, text_color=color.white, text_size=size.tiny)

    

    table.cell(myTable, 0, 5, "Sellers Strength", bgcolor=strengthColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 5, str.tostring(sellerStrength), bgcolor=strengthColor, text_color=color.white, text_size=size.tiny)



    table.cell(myTable, 0, 6, "Stop Loss", bgcolor=slColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 6, str.tostring(longStopLoss), bgcolor=slColor, text_color=color.white, text_size=size.tiny)



if (shortCondition)

    table.cell(myTable, 0, 0, "Signal", bgcolor=signalColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 0, "Short", bgcolor=signalColor, text_color=color.white, text_size=size.tiny)

    

    table.cell(myTable, 0, 1, "TP1", bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 1, str.tostring(shortTP1), bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    

    table.cell(myTable, 0, 2, "TP2", bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 2, str.tostring(shortTP2), bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    

    table.cell(myTable, 0, 3, "TP3", bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 3, str.tostring(shortTP3), bgcolor=tpColor, text_color=color.white, text_size=size.tiny)

    

    table.cell(myTable, 0, 4, "Buyers Strength", bgcolor=strengthColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 4, str.tostring(buyerStrength), bgcolor=strengthColor, text_color=color.white, text_size=size.tiny)

    

    table.cell(myTable, 0, 5, "Sellers Strength", bgcolor=strengthColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 5, str.tostring(sellerStrength), bgcolor=strengthColor, text_color=color.white, text_size=size.tiny)



    table.cell(myTable, 0, 6, "Stop Loss", bgcolor=slColor, text_color=color.white, text_size=size.tiny)

    table.cell(myTable, 1, 6, str.tostring(shortStopLoss), bgcolor=slColor, text_color=color.white, text_size=size.tiny)



// Visual Signals

//plotshape(series=longCondition, title="Buy Signal", location=location.belowbar, color=color.green, style=shape.labelup, text="BUY")

//plotshape(series=shortCondition, title="Sell Signal", location=location.abovebar, color=color.red, style=shape.labeldown, text="SELL")



// Plot MAs

//plot(fastMA_val, color=color.green, title="Fast MA")

//plot(slowMA_val, color=color.red, title="Slow MA")



// This Pine Script� code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/

// � fluxchart



//@version=5

const bool DEBUG = false

const int maxBoxesCount = 500

const float overlapThresholdPercentage = 0

const int maxDistanceToLastBar = 1750 // Affects Running Time

const int maxOrderBlocks = 30





showInvalidated = input.bool(true, "Show Historic Zones", group = "General Configuration", display = display.none)

OBsEnabled = true

orderBlockVolumetricInfo = input.bool(true, "Volumetric Info", group = "General Configuration", inline="EV", display = display.none)

obEndMethod = input.string("Wick", "Zone Invalidation", options = ["Wick", "Close"],  group = "General Configuration", display = display.none)

combineOBs = DEBUG ? input.bool(true, "Combine Zones", group = "General Configuration", display = display.none) : true

maxATRMult = DEBUG ? input.float(3.5,"Max Atr Multiplier", group = "General Configuration") : 3.5

swingLength = input.int(10, 'Swing Length', minval = 3, tooltip="Swing length is used when finding order block formations. Smaller values will result in finding smaller order blocks.",group = "General Configuration", display = display.none)

zoneCount = input.string("Low", 'Zone Count', options = ["High", "Medium", "Low", "One"], tooltip = "Number of Order Block Zones to be rendered. Higher options will result in older Order Blocks shown.",  group = "General Configuration", display = display.none)

bullOrderBlockColor = input(#08998180, 'Bullish', inline = 'obColor', group = 'General Configuration', display = display.none)

bearOrderBlockColor = input(#f2364680, 'Bearish', inline = 'obColor', group = 'General Configuration', display = display.none)



bullishOrderBlocks = zoneCount == "One" ? 1 : zoneCount == "Low" ? 3 : zoneCount == "Medium" ? 5 : 10

bearishOrderBlocks = zoneCount == "One" ? 1 : zoneCount == "Low" ? 3 : zoneCount == "Medium" ? 5 : 10



timeframe1Enabled = true

timeframe1 = ""



textColor = input.color(#ffffff80, "Text Color", group = "Style")

extendZonesBy = DEBUG ? input.int(15, "Extend Zones", group = "Style", minval = 1, maxval = 30, inline = "ExtendZones") : 15

extendZonesDynamic = DEBUG ? input.bool(true, "Dynamic", group = "Style", inline = "ExtendZones") : true

combinedText = DEBUG ? input.bool(false, "Combined Text", group = "Style", inline = "CombinedColor") : false

volumeBarsPlace = DEBUG ? input.string("Left", "Show Volume Bars At", options = ["Left", "Right"], group = "Style", inline = "volumebars") : "Left"

mirrorVolumeBars = DEBUG ? input.bool(true, "Mirror Volume Bars", group = "Style", inline = "volumebars") : true



volumeBarsLeftSide = (volumeBarsPlace == "Left")

extendZonesByTime = extendZonesBy * timeframe.in_seconds(timeframe.period) * 1000



atr = ta.atr(10)



type orderBlockInfo

    float top

    float bottom

    float obVolume

    string obType

    int startTime

    float bbVolume

    float obLowVolume

    float obHighVolume

    bool breaker

    int breakTime

    string timeframeStr

    bool disabled = false

    string combinedTimeframesStr = na

    bool combined = false



type orderBlock

    orderBlockInfo info

    bool isRendered = false



    box orderBox = na

    box breakerBox = na



    line orderBoxLineTop = na

    line orderBoxLineBottom = na

    line breakerBoxLineTop = na

    line breakerBoxLineBottom = na

    //

    box orderBoxText = na

    box orderBoxPositive = na

    box orderBoxNegative = na



    line orderSeperator = na

    line orderTextSeperator = na



createOrderBlock (orderBlockInfo orderBlockInfoF) =>

    orderBlock newOrderBlock = orderBlock.new(orderBlockInfoF)

    newOrderBlock



safeDeleteOrderBlock (orderBlock orderBlockF) =>

    orderBlockF.isRendered := false



    box.delete(orderBlockF.orderBox)

    box.delete(orderBlockF.breakerBox)

    box.delete(orderBlockF.orderBoxText)

    box.delete(orderBlockF.orderBoxPositive)

    box.delete(orderBlockF.orderBoxNegative)



    line.delete(orderBlockF.orderBoxLineTop)

    line.delete(orderBlockF.orderBoxLineBottom)

    line.delete(orderBlockF.breakerBoxLineTop)

    line.delete(orderBlockF.breakerBoxLineBottom)

    line.delete(orderBlockF.orderSeperator)

    line.delete(orderBlockF.orderTextSeperator)



type timeframeInfo

    int index = na

    string timeframeStr = na

    bool isEnabled = false



    orderBlockInfo[] bullishOrderBlocksList = na

    orderBlockInfo[] bearishOrderBlocksList = na



newTimeframeInfo (index, timeframeStr, isEnabled) =>

    newTFInfo = timeframeInfo.new()

    newTFInfo.index := index

    newTFInfo.isEnabled := isEnabled

    newTFInfo.timeframeStr := timeframeStr



    newTFInfo



type obSwing

    int x = na    

    float y = na

    float swingVolume = na

    bool crossed = false



// ____ TYPES END ____



var timeframeInfo[] timeframeInfos = array.from(newTimeframeInfo(1, timeframe1, timeframe1Enabled))

var bullishOrderBlocksList = array.new<orderBlockInfo>(0)

var bearishOrderBlocksList = array.new<orderBlockInfo>(0)



var allOrderBlocksList = array.new<orderBlock>(0)



moveLine(_line, _x, _y, _x2) =>

    line.set_xy1(_line, _x,  _y)

    line.set_xy2(_line, _x2, _y)



moveBox (_box, _topLeftX, _topLeftY, _bottomRightX, _bottomRightY) =>

    box.set_lefttop(_box, _topLeftX, _topLeftY)

    box.set_rightbottom(_box, _bottomRightX, _bottomRightY)



isTimeframeLower (timeframe1F, timeframe2F) =>

    timeframe.in_seconds(timeframe1F) < timeframe.in_seconds(timeframe2F)



getMinTimeframe (timeframe1F, timeframe2F) =>

    if isTimeframeLower(timeframe1F, timeframe2F)

        timeframe1F

    else

        timeframe2F



getMaxTimeframe (timeframe1F, timeframe2F) =>

    if isTimeframeLower(timeframe1F, timeframe2F)

        timeframe2F

    else

        timeframe1F



formatTimeframeString (formatTimeframe) =>

    timeframeF = formatTimeframe == "" ? timeframe.period : formatTimeframe

    

    if str.contains(timeframeF, "D") or str.contains(timeframeF, "W") or str.contains(timeframeF, "S") or str.contains(timeframeF, "M")

        timeframeF

    else

        seconds = timeframe.in_seconds(timeframeF)

        if seconds >= 3600

            hourCount = int(seconds / 3600)

            str.tostring(hourCount) + " Hour" + (hourCount > 1 ? "s" : "")

        else

            timeframeF + " Min"



betterCross(s1, s2) =>

    string ret = na

    if s1 >= s2 and s1[1] < s2

        ret := "Bull"

    if s1 < s2 and s1[1] >= s2

        ret := "Bear"

    ret



colorWithTransparency (colorF, transparencyX) =>

    color.new(colorF, color.t(colorF) * transparencyX)



createOBBox (boxColor, transparencyX = 1.0, xlocType = xloc.bar_time) =>

    box.new(na, na, na, na, text_size = size.normal, xloc = xlocType, extend = extend.none, bgcolor = colorWithTransparency(boxColor, transparencyX), text_color = textColor, text_halign = text.align_center, border_color = #00000000)



renderOrderBlock (orderBlock ob) =>

    orderBlockInfo info = ob.info

    ob.isRendered := true

    orderColor = ob.info.obType == "Bull" ? bullOrderBlockColor : bearOrderBlockColor



    if OBsEnabled and (not false or not (false and info.breaker)) and not (not showInvalidated and info.breaker)

        ob.orderBox := createOBBox(orderColor, 1.5)

        if ob.info.combined

            ob.orderBox.set_bgcolor(colorWithTransparency(orderColor, 1.1))

        ob.orderBoxText := createOBBox(color.new(color.white, 100))

        if orderBlockVolumetricInfo

            ob.orderBoxPositive := createOBBox(bullOrderBlockColor)

            ob.orderBoxNegative := createOBBox(bearOrderBlockColor)

            ob.orderSeperator := line.new(na,na,na,na,xloc.bar_time,extend.none,textColor,line.style_dashed,1)

            ob.orderTextSeperator := line.new(na,na,na,na,xloc.bar_time,extend.none,textColor,line.style_solid,1)



        zoneSize = extendZonesDynamic ? na(info.breakTime) ? extendZonesByTime : (info.breakTime - info.startTime) : extendZonesByTime

        if na(info.breakTime)

            zoneSize := (time + 1) - info.startTime



        startX = volumeBarsLeftSide ? info.startTime : info.startTime + zoneSize - zoneSize / 3

        maxEndX = volumeBarsLeftSide ? info.startTime + zoneSize / 3 : info.startTime + zoneSize



        moveBox(ob.orderBox, info.startTime, info.top, info.startTime + zoneSize, info.bottom)

        moveBox(ob.orderBoxText, volumeBarsLeftSide ? maxEndX : info.startTime, info.top, volumeBarsLeftSide ? info.startTime + zoneSize : startX, info.bottom)



        percentage = int((math.min(info.obHighVolume, info.obLowVolume) / math.max(info.obHighVolume, info.obLowVolume)) * 100.0)

        OBText = (na(ob.info.combinedTimeframesStr) ? formatTimeframeString(ob.info.timeframeStr) : ob.info.combinedTimeframesStr) + " OB"

        box.set_text(ob.orderBoxText, (orderBlockVolumetricInfo ? str.tostring(ob.info.obVolume, format.volume) + " (" + str.tostring(percentage) + "%)\n" : "") + (combinedText and ob.info.combined ? "[Combined]\n" : "") + OBText)



        if orderBlockVolumetricInfo

            showHighLowBoxText = false



            curEndXHigh = int(math.ceil((info.obHighVolume / info.obVolume) * (maxEndX - startX) + startX))

            curEndXLow = int(math.ceil((info.obLowVolume / info.obVolume) * (maxEndX - startX) + startX))



            moveBox(ob.orderBoxPositive, mirrorVolumeBars ? startX : curEndXLow, info.top, mirrorVolumeBars ? curEndXHigh : maxEndX, (info.bottom + info.top) / 2)

            box.set_text(ob.orderBoxPositive, showHighLowBoxText ? str.tostring(info.obHighVolume, format.volume) : "")



            moveBox(ob.orderBoxNegative, mirrorVolumeBars ? startX : curEndXHigh, info.bottom, mirrorVolumeBars ? curEndXLow : maxEndX, (info.bottom + info.top) / 2)

            box.set_text(ob.orderBoxNegative, showHighLowBoxText ? str.tostring(info.obLowVolume, format.volume) : "")



            moveLine(ob.orderSeperator, volumeBarsLeftSide ? startX : maxEndX, (info.bottom + info.top) / 2, volumeBarsLeftSide ? maxEndX : startX)



            line.set_xy1(ob.orderTextSeperator, volumeBarsLeftSide ? maxEndX : startX, info.top)

            line.set_xy2(ob.orderTextSeperator, volumeBarsLeftSide ? maxEndX : startX, info.bottom)



findOBSwings(len) =>

    var swingType = 0

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

    var obSwing bottom = obSwing.new(na, na)

    

    upper = ta.highest(len)

    lower = ta.lowest(len)



    swingType := high[len] > upper ? 0 : low[len] < lower ? 1 : swingType



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

        top := obSwing.new(bar_index[len], high[len], volume[len])

    

    if swingType == 1 and swingType[1] != 1

        bottom := obSwing.new(bar_index[len], low[len], volume[len])



    [top, bottom]



findOrderBlocks () =>

    if bar_index > last_bar_index - maxDistanceToLastBar

        [top, btm] = findOBSwings(swingLength)

        useBody = false

        max = useBody ? math.max(close, open) : high

        min = useBody ? math.min(close, open) : low



        // Bullish Order Block

        bullishBreaked = 0



        if bullishOrderBlocksList.size() > 0

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

                currentOB = bullishOrderBlocksList.get(i)

            

                if not currentOB.breaker 

                    if (obEndMethod == "Wick" ? low : math.min(open, close)) < currentOB.bottom

                        currentOB.breaker := true

                        currentOB.breakTime := time

                        currentOB.bbVolume := volume

                else

                    if high > currentOB.top

                        bullishOrderBlocksList.remove(i)

                    else if i < bullishOrderBlocks and top.y < currentOB.top and top.y > currentOB.bottom 

                        bullishBreaked := 1



        if close > top.y and not top.crossed

            top.crossed := true



            boxBtm = max[1]

            boxTop = min[1]

            boxLoc = time[1]



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

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

                boxTop := boxBtm == min[i] ? max[i] : boxTop

                boxLoc := boxBtm == min[i] ? time[i] : boxLoc



            newOrderBlockInfo = orderBlockInfo.new(boxTop, boxBtm, volume + volume[1] + volume[2], "Bull", boxLoc)

            newOrderBlockInfo.obLowVolume := volume[2]

            newOrderBlockInfo.obHighVolume := volume + volume[1]

            

            obSize = math.abs(newOrderBlockInfo.top - newOrderBlockInfo.bottom)

            if obSize <= atr * maxATRMult

                bullishOrderBlocksList.unshift(newOrderBlockInfo)

                if bullishOrderBlocksList.size() > maxOrderBlocks

                    bullishOrderBlocksList.pop()



        // Bearish Order Block

        

        bearishBreaked = 0



        if bearishOrderBlocksList.size() > 0

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

                currentOB = bearishOrderBlocksList.get(i)



                if not currentOB.breaker 

                    if (obEndMethod == "Wick" ? high : math.max(open, close)) > currentOB.top

                        currentOB.breaker := true

                        currentOB.breakTime := time

                        currentOB.bbVolume := volume

                else

                    if low < currentOB.bottom

                        bearishOrderBlocksList.remove(i)

                    else if i < bearishOrderBlocks and btm.y > currentOB.bottom and btm.y < currentOB.top 

                        bearishBreaked := 1



        if close < btm.y and not btm.crossed

            btm.crossed := true



            boxBtm = min[1]

            boxTop = max[1]

            boxLoc = time[1]



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

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

                boxBtm := boxTop == max[i] ? min[i] : boxBtm

                boxLoc := boxTop == max[i] ? time[i] : boxLoc



            newOrderBlockInfo = orderBlockInfo.new(boxTop, boxBtm, volume + volume[1] + volume[2], "Bear", boxLoc)

            newOrderBlockInfo.obLowVolume := volume + volume[1]

            newOrderBlockInfo.obHighVolume := volume[2]



            obSize = math.abs(newOrderBlockInfo.top - newOrderBlockInfo.bottom)

            if obSize <= atr * maxATRMult

                bearishOrderBlocksList.unshift(newOrderBlockInfo)

                if bearishOrderBlocksList.size() > maxOrderBlocks

                    bearishOrderBlocksList.pop()

    true



areaOfOB (orderBlockInfo OBInfoF) =>

    float XA1 = OBInfoF.startTime

    float XA2 = na(OBInfoF.breakTime) ? time + 1 : OBInfoF.breakTime

    float YA1 = OBInfoF.top

    float YA2 = OBInfoF.bottom

    float edge1 = math.sqrt((XA2 - XA1) * (XA2 - XA1) + (YA2 - YA2) * (YA2 - YA2))

    float edge2 = math.sqrt((XA2 - XA2) * (XA2 - XA2) + (YA2 - YA1) * (YA2 - YA1))

    float totalArea = edge1 * edge2

    totalArea



doOBsTouch (orderBlockInfo OBInfo1, orderBlockInfo OBInfo2) =>

    float XA1 = OBInfo1.startTime

    float XA2 = na(OBInfo1.breakTime) ? time + 1 : OBInfo1.breakTime

    float YA1 = OBInfo1.top

    float YA2 = OBInfo1.bottom



    float XB1 = OBInfo2.startTime

    float XB2 = na(OBInfo2.breakTime) ? time + 1 : OBInfo2.breakTime

    float YB1 = OBInfo2.top

    float YB2 = OBInfo2.bottom

    float intersectionArea = math.max(0, math.min(XA2, XB2) - math.max(XA1, XB1)) * math.max(0, math.min(YA1, YB1) - math.max(YA2, YB2))

    float unionArea = areaOfOB(OBInfo1) + areaOfOB(OBInfo2) - intersectionArea

    

    float overlapPercentage = (intersectionArea / unionArea) * 100.0



    if overlapPercentage > overlapThresholdPercentage

        true

    else

        false



isOBValid (orderBlockInfo OBInfo) =>

    valid = true

    if OBInfo.disabled

        valid := false

    valid



combineOBsFunc () =>

    if allOrderBlocksList.size() > 0

        lastCombinations = 999

        while lastCombinations > 0

            lastCombinations := 0

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

                curOB1 = allOrderBlocksList.get(i)

                for j = 0 to allOrderBlocksList.size() - 1

                    curOB2 = allOrderBlocksList.get(j)

                    if i == j

                        continue

                    if not isOBValid(curOB1.info) or not isOBValid(curOB2.info)

                        continue

                    if curOB1.info.obType != curOB2.info.obType

                        continue

                    if doOBsTouch(curOB1.info, curOB2.info)

                        curOB1.info.disabled := true

                        curOB2.info.disabled := true

                        orderBlock newOB = createOrderBlock(orderBlockInfo.new(math.max(curOB1.info.top, curOB2.info.top), math.min(curOB1.info.bottom, curOB2.info.bottom), curOB1.info.obVolume + curOB2.info.obVolume, curOB1.info.obType))

                        newOB.info.startTime := math.min(curOB1.info.startTime, curOB2.info.startTime)

                        newOB.info.breakTime := math.max(nz(curOB1.info.breakTime), nz(curOB2.info.breakTime))

                        newOB.info.breakTime := newOB.info.breakTime == 0 ? na : newOB.info.breakTime

                        newOB.info.timeframeStr := curOB1.info.timeframeStr



                        newOB.info.obVolume := curOB1.info.obVolume + curOB2.info.obVolume

                        newOB.info.obLowVolume := curOB1.info.obLowVolume + curOB2.info.obLowVolume

                        newOB.info.obHighVolume := curOB1.info.obHighVolume + curOB2.info.obHighVolume

                        newOB.info.bbVolume := nz(curOB1.info.bbVolume, 0) + nz(curOB2.info.bbVolume, 0)

                        newOB.info.breaker := curOB1.info.breaker or curOB2.info.breaker

                        

                        newOB.info.combined := true

                        if timeframe.in_seconds(curOB1.info.timeframeStr) != timeframe.in_seconds(curOB2.info.timeframeStr)

                            newOB.info.combinedTimeframesStr := (na(curOB1.info.combinedTimeframesStr) ? formatTimeframeString(curOB1.info.timeframeStr) : curOB1.info.combinedTimeframesStr) + " & " + (na(curOB2.info.combinedTimeframesStr) ? formatTimeframeString(curOB2.info.timeframeStr) : curOB2.info.combinedTimeframesStr)

                        allOrderBlocksList.unshift(newOB)

                        lastCombinations += 1





reqSeq (timeframeStr) =>

    [bullishOrderBlocksListF, bearishOrderBlocksListF] = request.security(syminfo.tickerid, timeframeStr, [bullishOrderBlocksList, bearishOrderBlocksList])

    [bullishOrderBlocksListF, bearishOrderBlocksListF]



getTFData (timeframeInfo timeframeInfoF, timeframeStr) =>

    if not isTimeframeLower(timeframeInfoF.timeframeStr, timeframe.period) and timeframeInfoF.isEnabled

        [bullishOrderBlocksListF, bearishOrderBlocksListF] = reqSeq(timeframeStr)

        [bullishOrderBlocksListF, bearishOrderBlocksListF]

    else

        [na, na]



handleTimeframeInfo (timeframeInfo timeframeInfoF, bullishOrderBlocksListF, bearishOrderBlocksListF) =>

    if not isTimeframeLower(timeframeInfoF.timeframeStr, timeframe.period) and timeframeInfoF.isEnabled

        timeframeInfoF.bullishOrderBlocksList := bullishOrderBlocksListF

        timeframeInfoF.bearishOrderBlocksList := bearishOrderBlocksListF





handleOrderBlocksFinal () =>

    if DEBUG

        log.info("Bullish OB Count " + str.tostring(bullishOrderBlocksList.size()))

        log.info("Bearish OB Count " + str.tostring(bearishOrderBlocksList.size()))



    if allOrderBlocksList.size () > 0

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

            safeDeleteOrderBlock(allOrderBlocksList.get(i))

    allOrderBlocksList.clear()    



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

        curTimeframe = timeframeInfos.get(i)

        if not curTimeframe.isEnabled

            continue

        if curTimeframe.bullishOrderBlocksList.size() > 0

            for j = 0 to math.min(curTimeframe.bullishOrderBlocksList.size() - 1, bullishOrderBlocks - 1)

                orderBlockInfoF = curTimeframe.bullishOrderBlocksList.get(j)

                orderBlockInfoF.timeframeStr := curTimeframe.timeframeStr

                allOrderBlocksList.unshift(createOrderBlock(orderBlockInfo.copy(orderBlockInfoF)))



        if curTimeframe.bearishOrderBlocksList.size() > 0

            for j = 0 to math.min(curTimeframe.bearishOrderBlocksList.size() - 1, bearishOrderBlocks - 1)

                orderBlockInfoF = curTimeframe.bearishOrderBlocksList.get(j)

                orderBlockInfoF.timeframeStr := curTimeframe.timeframeStr

                allOrderBlocksList.unshift(createOrderBlock(orderBlockInfo.copy(orderBlockInfoF)))



    if combineOBs

        combineOBsFunc()    



    if allOrderBlocksList.size() > 0

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

            curOB = allOrderBlocksList.get(i)

            if isOBValid(curOB.info)

                renderOrderBlock(curOB)



findOrderBlocks()



[bullishOrderBlocksListTimeframe1, bearishOrderBlocksListTimeframe1] = getTFData(timeframeInfos.get(0), timeframe1)



if barstate.isconfirmed

    handleTimeframeInfo(timeframeInfos.get(0), bullishOrderBlocksListTimeframe1, bearishOrderBlocksListTimeframe1)

    handleOrderBlocksFinal()    










coeff = input.float(1, 'Multiplier', step=0.1)
AP = input(14, 'Common Period')
ATR = ta.sma(ta.tr, AP)
asrc = input(close)
showsignalsk = input(title='Show Signals?', defval=true)
novolumedata = input(title='Change calculation (no volume data)?', defval=false)
upT = low - ATR * coeff
downT = high + ATR * coeff
AlphaTrend = 0.0
AlphaTrend := (novolumedata ? ta.rsi(asrc, AP) >= 50 : ta.mfi(hlc3, AP) >= 50) ? upT < nz(AlphaTrend[1]) ? nz(AlphaTrend[1]) : upT : downT > nz(AlphaTrend[1]) ? nz(AlphaTrend[1]) : downT

color1 = AlphaTrend > AlphaTrend[2] ? #00E60F : AlphaTrend < AlphaTrend[2] ? #80000B : AlphaTrend[1] > AlphaTrend[3] ? #00E60F : #80000B
k1 = plot(AlphaTrend, color=color.new(#0022FC, 0), linewidth=3)
k2 = plot(AlphaTrend[2], color=color.new(#FC0400, 0), linewidth=3)

fill(k1, k2, color=color1)

buySignalk = ta.crossover(AlphaTrend, AlphaTrend[2])
sellSignalk = ta.crossunder(AlphaTrend, AlphaTrend[2])


K1 = ta.barssince(buySignalk)
K2 = ta.barssince(sellSignalk)
O1 = ta.barssince(buySignalk[1])
O2 = ta.barssince(sellSignalk[1])

plotshape(buySignalk and showsignalsk and O1 > K2 ? AlphaTrend[2] * 0.9999 : na, title='BUY', text='BUY', location=location.absolute, style=shape.labelup, size=size.tiny, color=color.new(#0022FC, 0), textcolor=color.new(color.white, 0))

plotshape(sellSignalk and showsignalsk and O2 > K1 ? AlphaTrend[2] * 1.0001 : na, title='SELL', text='SELL', location=location.absolute, style=shape.labeldown, size=size.tiny, color=color.new(color.maroon, 0), textcolor=color.new(color.white, 0))


alertcondition(buySignalk and O1 > K2, title='Potential BUY Alarm', message='BUY SIGNAL!')
alertcondition(sellSignalk and O2 > K1, title='Potential SELL Alarm', message='SELL SIGNAL!')

alertcondition(buySignalk[1] and O1[1] > K2, title='Confirmed BUY Alarm', message='BUY SIGNAL APPROVED!')
alertcondition(sellSignalk[1] and O2[1] > K1, title='Confirmed SELL Alarm', message='SELL SIGNAL APPROVED!')



alertcondition(ta.cross(close, AlphaTrend), title='Price Cross Alert', message='Price - AlphaTrend Crossing!')
alertcondition(ta.crossover(low, AlphaTrend), title='Candle CrossOver Alarm', message='LAST BAR is ABOVE ALPHATREND')
alertcondition(ta.crossunder(high, AlphaTrend), title='Candle CrossUnder Alarm', message='LAST BAR is BELOW ALPHATREND!')

alertcondition(ta.cross(close[1], AlphaTrend[1]), title='Price Cross Alert After Bar Close', message='Price - AlphaTrend Crossing!')
alertcondition(ta.crossover(low[1], AlphaTrend[1]), title='Candle CrossOver Alarm After Bar Close', message='LAST BAR is ABOVE ALPHATREND!')
alertcondition(ta.crossunder(high[1], AlphaTrend[1]), title='Candle CrossUnder Alarm After Bar Close', message='LAST BAR is BELOW ALPHATREND!')

Overview

Daily levels appear on intraday charts, weekly levels on intraday or daily charts, and monthly levels on charts that are not monthly. Users can toggle each period, colors, labels, and a logarithmic midpoint. Optional projections extend the levels to the right. A moving average with type, length, source, and offset can be overlaid. Higher-timeframe values are requested with lookahead enabled, so plotted levels can use unfinished higher-timeframe data.

Details

Published by

IAMATOMIC001 on GitHub

Type

Indicator, Pine Script v6

Draws

On the price chart

Category

Support & resistance, Moving averages

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

  • Signals can change on the live bar or after it closes (repainting)
  • Reads higher-timeframe data with lookahead on, so the history can show signals that were not there in real time

Settings

The inputs you can change from the gear icon on the chart. Defaults are the author's.

SettingTypeDefaultVariable
Dailybooltruei_isDailyEnabled
i_dailyColorcolorcolor.bluei_dailyColor
Weeklybooltruei_isWeeklyEnabled
i_weeklyColorcolorcolor.teali_weeklyColor
Monthlybooltruei_isMonthlyEnabled
i_monthlyColorcolorcolor.redi_monthlyColor
Show Labels?boolfalsei_show_labels
Is Chart in Logarithmic Scale?boolfalsei_isLogarithmic
Show Projectionsbooltruei_areHeadsEnabled
i_rightOffsetint25i_rightOffset
Show Moving Average?boolfalsei_show_ma
Lengthint14len
Show all 40 settings
SettingTypeDefaultVariable
Sourcesourcehlc3src
i_ma_colorcolorcolor.new(color.black,75)i_ma_color
i_sma_colorcolorcolor.new(color.blue,50)i_sma_color
i_bb_colorcolorcolor.new(color.green,90)i_bb_color
Offsetint0offset
TypestringNonemaTypeInput
Lengthint26maLengthInput
BB StdDevfloat2.0bbMultInput
Colore Linea 29colorcolor.bluelinea29_colore
Spessore Linea 29int1linea29_spessore
Colore Linea 71colorcolor.blacklinea71_colore
Spessore Linea 71int1linea71_spessore
Mostra Linea 29booltruemostra_linea29
Mostra Linea 71booltruemostra_linea71
Fast MAint10fastMA
Slow MAint30slowMA
ATR Lengthint14atrLength
ATR Stop Multiplierfloat1.5atrMultiplierSL
TP1 Multiplierfloat0.5tp1Multiplier
TP2 Multiplierfloat1.0tp2Multiplier
TP3 Multiplierfloat1.5tp3Multiplier
Show Historic ZonesbooltrueshowInvalidated
Volumetric InfobooltrueorderBlockVolumetricInfo
Zone InvalidationstringWickobEndMethod
Combine ZonesbooltrueCombine Zones
Max Atr Multiplierfloat3.5Max Atr Multiplier
Swing Lengthint10swingLength
Zone CountstringLowzoneCount
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

948 stars

Moving Average Channel plots separate simple moving averages for upper and lower bands on the price chart. It fills the space between bands with semi-transparent color and colors bars green above the upper band, red below the lower band, or gray in between. Us

Indicator v4 Moving averagesSupport & resistance
Updated 10 days ago · GPL-3.0 GitHub repository of Moving Average Channel

PivotHighLow

by Alorse
330 stars

This indicator calculates pivot high and pivot low points on the price chart based on configurable left and right bar counts. Confirmed pivot highs and lows are plotted with negative bar offsets directly on the price chart using line and cross styles. Addition

Indicator v4 Support & resistanceOscillators & momentum Repaints
Updated 2 months ago · None stated GitHub repository of PivotHighLow

Deduct

by TaichiS
219 stars

This indicator displays moving average deduction reference points directly on the price chart. It plots dynamic labels on historical bars corresponding to short, medium, and long lookback periods, defaulted to 20, 60, and 120 bars. Each text label displays the

Indicator v4 Moving averagesSupport & resistance
Updated 5 years ago · None stated GitHub repository of Deduct

Ichimoku Cloud

by harryguiacorn
219 stars

This indicator plots Ichimoku Cloud elements on the price chart, including Tenkan-sen, Kijun-sen, Senkou Span A and B lines with optional Chikou Span. It signals trend changes via Tenkan-sen and Kijun-sen crosses and places arrows at Kijun-sen direction shifts

Indicator v5 TrendMoving averages
Updated 1 year ago · None stated GitHub repository of Ichimoku Cloud

Midnight VWAP

by TradersPost
218 stars

The Midnight VWAP indicator calculates and overlays two distinct Volume Weighted Average Price (VWAP) lines on the price chart based on customizable session timeframes. It tracks an overnight or pre-market session alongside regular trading hours, resetting cal

Indicator v6 Moving averagesSessions & time
Updated 3 months ago · None stated GitHub repository of Midnight VWAP

More indicators

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers