All time high which is not recent

Viewed 206

I am trying to modify script to get all time high date that is not recent. enter image description here

Eg: Apple made all time high on

  1. 15/10/2021 (last)
  2. 10/05/2017 (second last) ... and so on ...

The problem is that this script is showing the recently ATH, I want ATH that is atleast a year old. Any help/guidance is appreciated. I want to use it for ATH breakout (preferable 5-10 years old)

indicator('All-Time High/Low', shorttitle='ATH/ATL', overlay=true)

////////////
// INPUTS //

show_ath   = input(true,  "Show All Time High?")
show_atl   = input(false, "Show All Time Low?")
show_table = input(true,  "Show table with stats?")

///////////////
// FUNCTIONS //

// all-time high function
get_all_time_high() =>
    h  = 0.0
    t  = 0
    h := bar_index == 0 ? high : high > h[1] ? high : h[1]
    t := bar_index == 0 ? time : high > h[1] ? time : t[1]
    [h, t]

// all-time low function   
get_all_time_low() =>
    l = 0.0
    t = 0
    l := bar_index == 0 ? low  : low < l[1] ? low  : l[1]
    t := bar_index == 0 ? time : low < l[1] ? time : t[1]
    [l, t]

// getting all-time high/low    
[ath, ath_dt] = request.security(syminfo.tickerid, 'D', get_all_time_high())
[atl, atl_dt] = request.security(syminfo.tickerid, 'D', get_all_time_low())

ath_days = math.round((timenow - ath_dt) / 86400000)
atl_days = math.round((timenow - atl_dt) / 86400000)

// plotting
if show_ath
    lATH=line.new(bar_index - 1, ath, bar_index, ath, extend = extend.both, color = color.green)
    line.delete(lATH[1])
    
if show_atl
    lATL=line.new(bar_index - 1, atl, bar_index, atl, extend = extend.both, color = color.red)
    line.delete(lATL[1])

if show_table
    var table ATHtable = table.new(position.bottom_right, 6, 3, frame_color = color.gray, bgcolor = color.gray, border_width = 1, frame_width = 1, border_color = color.white)

    ath_time = str.tostring(year(ath_dt)) + "-" + str.tostring(month(ath_dt)) + "-" + str.tostring(dayofmonth(ath_dt))
    atl_time = str.tostring(year(atl_dt)) + "-" + str.tostring(month(atl_dt)) + "-" + str.tostring(dayofmonth(atl_dt))

    // Header
    table.cell(ATHtable, 0, 0, "",         bgcolor = #cccccc)
    table.cell(ATHtable, 1, 0, "When?",    bgcolor = #cccccc)
    table.cell(ATHtable, 2, 0, "Days ago", bgcolor = #cccccc)
    table.cell(ATHtable, 3, 0, "Price",    bgcolor = #cccccc)
    table.cell(ATHtable, 4, 0, "% away",   bgcolor = #cccccc)
    table.cell(ATHtable, 5, 0, "$ away",   bgcolor = #cccccc)
    
    if (show_ath)
        // ATH
        table.cell(ATHtable, 0, 1, "ATH",                                                  bgcolor = #cccccc)
        table.cell(ATHtable, 1, 1, ath_time,                                               bgcolor = color.new(color.green, transp = 50))
        table.cell(ATHtable, 2, 1, str.tostring(ath_days),                                 bgcolor = color.new(color.green, transp = 50))
        table.cell(ATHtable, 3, 1, str.tostring(ath, format.mintick),                      bgcolor = color.new(color.green, transp = 50))
        table.cell(ATHtable, 4, 1, str.tostring(((ath / close) - 1) * 100 , "#.##") + "%", bgcolor = color.new(color.green, transp = 50))
        table.cell(ATHtable, 5, 1, str.tostring(ath - close , format.mintick),             bgcolor = color.new(color.green, transp = 50))
    
    if (show_atl)
        // ATL
        table.cell(ATHtable, 0, 2, "ATL",                                                  bgcolor = #cccccc)
        table.cell(ATHtable, 1, 2, atl_time,                                               bgcolor = color.new(color.red, transp = 50))
        table.cell(ATHtable, 2, 2, str.tostring(atl_days),                                 bgcolor = color.new(color.red, transp = 50))
        table.cell(ATHtable, 3, 2, str.tostring(atl, format.mintick),                      bgcolor = color.new(color.red, transp = 50))
        table.cell(ATHtable, 4, 2, str.tostring(((atl / close) - 1) * 100 , "#.##") + "%", bgcolor = color.new(color.red, transp = 50))
        table.cell(ATHtable, 5, 2, str.tostring(atl - close, format.mintick),              bgcolor = color.new(color.red, transp = 50))

// alerts
alertcondition(ta.crossover(high, ath), 'All-time High!', 'All-time High!')
alertcondition(ta.crossunder(low, atl), 'All-time Low!',  'All-time Low!')

Example on weekly chart After a few months, recent ATH will be considered by script for breakout, not old one

2 Answers
//@version=5
indicator("Previous Year(s) ATH", overlay = true)

num_years = input.int(1, title = "Number of years back", minval = 1)

var float ATH = high
var int ATH_time = time

var float[] ATH_vals = array.new_float()
var int[] ATH_time_vals = array.new_int()
var int[] ATH_time_change_vals = array.new_int()

ATH := math.max(ATH, high)
if ta.change(ATH) != 0
    ATH_time := time
    
array.unshift(ATH_vals, ATH)
array.unshift(ATH_time_vals, time)
array.unshift(ATH_time_change_vals, ATH_time)

var float ATH1Y = na

if barstate.isconfirmed
    search_time = time - 31536000000 * num_years
    for i = 0 to array.size(ATH_time_vals) - 1
        if array.get(ATH_time_vals, i) < search_time
            ATH1Y := array.get(ATH_vals, i)
            ATH1Y_time = array.get(ATH_time_change_vals, i)
            y = year(ATH1Y_time)
            m = month(ATH1Y_time)
            d = dayofmonth(ATH1Y_time)
            days_ago = (time - ATH1Y_time) / 86400000
            date_text = str.tostring(y) + "/" + str.tostring(m) + "/" + str.tostring(d) + " : " + str.tostring(ATH1Y) + "\nDays Ago : " + str.tostring(math.round(days_ago, 2))

            if ATH > ATH1Y and ATH[1] <= ATH1Y[1]
                label.new(x = bar_index[1], y = ATH[1], text = date_text, style = label.style_label_lower_right)
            break

ATH_val = ATH > ATH1Y ? na : ATH1Y

buy_signal = ATH > ATH1Y and ATH[1] <= ATH1Y[1]

plotshape(buy_signal, color = color.green, location = location.belowbar, size = size.small, style = shape.triangleup)

plot(ATH_val, title = "ATH", style = plot.style_linebr)

You can create a time window where you want to update your calculations. In the below example, it will only calculate the ATH, if the time is between 1970 and 21.11.2020 (exactly one year ago).

It should do what you are looking for. There are some user inputs, so you can be more flexible:

//@version=5
indicator("My Script", overlay=true)

ToMonth   = input.int(defval = 11, title = "To Month", minval = 1, maxval = 12)
ToDay     = input.int(defval = 21, title = "To Day", minval = 1, maxval = 31)
ToYear    = input.int(defval = 2020, title = "To Year")

start     = timestamp(1970, 1, 1, 00, 00, 00)
finish    = timestamp(ToYear, ToMonth, ToDay, 00, 00, 00)
window()  => time >= start and time <= finish ? true : false

var float ath = 0.0

if window() == true
    ath := high > ath ? high : ath

var line athLine = line.new(na, na, na, na, extend=extend.both)

if barstate.islast
    line.set_xy1(athLine, bar_index-1, ath)
    line.set_xy2(athLine, bar_index, ath)

enter image description here

Related