Price Change Alerts
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © domsito

// To enable alerts do this:
// - Click on alerts clock icon in top right corner of the screen
// - Click on "Create alert button"
// - In Condition dropdown select "alerts"
// - In the next dropdown select "Any alert function() call" and click on "Create" button

// Script uses repainting on purpose to display daily percentage changes since the previous day's closing 

//@version=5
indicator("Price Change Alerts", "alerts", overlay = true)
max_bars_back(time, 5000)

var bool showDailyChange = input.bool(true, "Show change since previous day close", group = "General")

var bool showPrevDayLine = input.bool(true, "Prevous day's closing line", group = "line", inline = "0")
var lineColor = input(color.blue, "", inline = "0", group = "line")

var bool showPrevWeekCloseLine = input.bool(true, "Prevous week's closing line", group = "line", inline = "1")
var lineColor2 = input(color.lime, "", inline = "1", group = "line")

var float alertDelta = input.float(5.0, "Alert delta", 0.01, 10000, tooltip = "Alerts will be triggered only after price changes by 'delta' amount from the last alert price")
var int minSeconds = input.int(60, "Minimum number of seconds between alerts", 10, 10000)

varip float lastAlertValue = 0.0
varip int lastAlertTime = 0

var lbl = label.new(na, na, na, style = label.style_label_left)
var lineDay = line.new(na, na, na, na, color = lineColor, style = line.style_solid, width = 2)
var lineWeek = line.new(na, na, na, na, color = lineColor2, style = line.style_solid, width = 2)

varip float change = 0.0
varip float changeSign = na

delta(float v1, float v2) => 
    (((v2 / v1)-1) * 100.0)


var float prevDayClose = na
var int bar_time_prev_day_close = 0
var int bar_time_prev_week_close = 0
var float prevWeekClose = 0

if (ta.change(dayofmonth))   
    prevDayClose := close[2] //previous bar close is previous day's closing price, since we just entered after hours        
    bar_time_prev_day_close := bar_index[2]

if (ta.change(weekofyear))
    bar_time_prev_week_close := bar_index[2]
    prevWeekClose := close[2]

if barstate.islast 
    change := delta(prevDayClose, close)
    backColor = change < 0.0 ? color.red : color.green 
    if showPrevDayLine
        line.set_x1(lineDay, bar_time_prev_day_close )
        line.set_x2(lineDay, bar_index)
        line.set_y1(lineDay, prevDayClose) 
        line.set_y2(lineDay, prevDayClose)
    if showPrevWeekCloseLine
        line.set_x1(lineWeek, bar_time_prev_week_close)
        line.set_x2(lineWeek, bar_index)
        line.set_y1(lineWeek, prevWeekClose)
        line.set_y2(lineWeek, prevWeekClose)
    if showDailyChange
        label.set_text(lbl, str.tostring(change, "0.00") + "% ")
        label.set_color(lbl, backColor)
        label.set_x(lbl, bar_index+1)
        label.set_y(lbl, close)

if (barstate.islastconfirmedhistory)
    change := delta(prevDayClose, close)
    changeSign := math.sign(change)
    lastAlertValue := math.round(close / alertDelta) * alertDelta

if (math.abs(close-lastAlertValue) >= alertDelta) and ((time - lastAlertTime)/1000.0 >= minSeconds)
    alert(syminfo.ticker + ((close-lastAlertValue) > 0 ? " UP" : " DOWN") + " to " + str.tostring(close, "0.00"), alert.freq_all)
    //lastAlertValue:= close
    lastAlertValue := math.round(close / alertDelta) * alertDelta
    lastAlertTime := time


plot(lastAlertValue, "last alert value", display = display.data_window)
plot((time - lastAlertTime)/1000.0, "Seconds since last alert", display = display.data_window)
