Simple Watchlist with % Change Screener  & Alerts
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ralagh

//@version=4
// Change the Percentage input box to 1,2,3,4 etc for the desired % Alerts
// line 45 has the range for color gradient for heatmap
// alerts() are set for 2%

study("Simple Watchlist", format=format.price, precision=2, overlay=true)

res = input("D", "Timeframe")
pct = input(2, "Percentage for Alerts", minval=1, step=1)
colm = input(5, "Column multiplier", minval=4, step=1, maxval=7)


alert_strings = array.new_string(2)
array.set(alert_strings, 0, "")
array.set(alert_strings, 1, "")

table_row_count = array.new_int(1) //keeps track of number of total entries
array.set(table_row_count, 0, 0)

var UpTabl = table.new(position = position.bottom_center, columns = 7, rows = 9, bgcolor = color.rgb(255,255,255), border_width = 4, frame_color= color.black, frame_width = 2)

f_chgpct(_ticker)=>
    
    [cl_dp, val_c0, hi_p, lo_p, rs_14] = security(_ticker, res, [close[1], close, high, low, rsi(close, 14)], lookahead = barmerge.lookahead_on)
    p_chg = (val_c0 - cl_dp)/cl_dp * 100
    _msg = _ticker + "~Cls-" + tostring(round(val_c0 * 100) / 100) + "/" + tostring(round(p_chg * 100) / 100) + "% ,"
    
    if p_chg >= pct   
        _msg := _msg + "High~" + tostring(round(hi_p * 100) / 100) + ", Low~" + tostring(round(lo_p * 100) / 100) + "UP More Than-->" + tostring(pct) + "%▲▲"
        array.set(alert_strings, 0, array.get(alert_strings, 0) + "\n" + _msg)
    
    if p_chg < -pct
        _msg := _msg + "High~" + tostring(round(hi_p * 100) / 100) + ", Low~" + tostring(round(lo_p * 100) / 100) + "Down More Than-->" + tostring(pct) + "%▼▼"
        array.set(alert_strings, 1, array.get(alert_strings, 1) + "\n" + _msg)
    
    if val_c0 >= 100   
        array.set(table_row_count, 0, array.get(table_row_count, 0) + 1)
        
        if barstate.islast
            table.cell(table_id = UpTabl, column = int((array.get(table_row_count, 0)  - 1) / colm), height = 12, row = ((array.get(table_row_count, 0) - 1) % colm) +1, text = _ticker + "\n cls -: " + tostring(round(val_c0 * 1000) / 1000) +  "\n chg ~: " + tostring(round(p_chg * 1000) / 1000) + "%"+ "\n RSI -: " + tostring(round(rs_14 * 100) / 100), text_size = size.large, text_halign=text.align_center, bgcolor=color.from_gradient(p_chg, -3, 3, color.rgb(255, 70, 70), color.rgb(0, 200, 100))) 
                        
f_chgpct(syminfo.tickerid)
f_chgpct(input('DJI', title=input.symbol)) 
f_chgpct(input('IXIC', title=input.symbol)) 
f_chgpct(input('SPX', title=input.symbol)) 
f_chgpct(input('RUT', title=input.symbol)) 
f_chgpct(input('AAPL', title=input.symbol))
f_chgpct(input('AMZN', title=input.symbol)) 
f_chgpct(input('FB', title=input.symbol)) 
f_chgpct(input('GOOG', title=input.symbol)) 
f_chgpct(input('NFLX', title=input.symbol))
f_chgpct(input('MSFT', title=input.symbol)) 
f_chgpct(input('NVDA', title=input.symbol)) 
f_chgpct(input('FDX', title=input.symbol)) 
f_chgpct(input('GLD', title=input.symbol))
f_chgpct(input('DIS', title=input.symbol))
f_chgpct(input('GOOG', title=input.symbol)) 
f_chgpct(input('NKE', title=input.symbol))
f_chgpct(input('MSFT', title=input.symbol)) 
f_chgpct(input('BABA', title=input.symbol)) 
f_chgpct(input('JNJ', title=input.symbol)) 
f_chgpct(input('TMO', title=input.symbol))
f_chgpct(input('SLV', title=input.symbol))
f_chgpct(input('IBM', title=input.symbol))
f_chgpct(input('TSLA', title=input.symbol))
f_chgpct(input('V', title=input.symbol))
f_chgpct(input('TMO', title=input.symbol))
f_chgpct(input('QQQ', title=input.symbol))
f_chgpct(input('IBM', title=input.symbol))
f_chgpct(input('SPY', title=input.symbol))
f_chgpct(input('ADBE', title=input.symbol))
f_chgpct(input('DOCU', title=input.symbol))
f_chgpct(input('CRM', title=input.symbol))
f_chgpct(input('BTCUSD', title=input.symbol))
f_chgpct(input('ETHUSD', title=input.symbol))
f_chgpct(input('LTCUSD', title=input.symbol))
f_chgpct(input('USDJPY', title=input.symbol))

if array.get(alert_strings, 0) != ""
    alert(array.get(alert_strings, 0),  alert.freq_once_per_bar_close)

if array.get(alert_strings, 1) != ""
    alert(array.get(alert_strings, 1),  alert.freq_once_per_bar_close)