News Alert
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © ivanroyloewen

//@version=5
indicator("News Alert", overlay = true)

//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------( inputs )

// the offest of your personal timezone from Eastern Standard Time ( New York Time )
var time_Zone_Offset = input.int(defval = 0, title = "Timezone offset in hours from EST", maxval = 24, minval = -24)

// the inputs for the first news alert
var news_Time_1 = "News Time 1"
var news_Hour_1 = input.int(defval = 00, title = "Hour", group = news_Time_1, inline = news_Time_1, minval = 0, maxval = 24)
var news_Minute_1 = input.int(defval = 00, title = "Minute", group = news_Time_1, inline = news_Time_1, minval = 0, maxval = 45, step = 15)
var show_News_1 = input.bool(defval = false, title = "Show News 1", group = news_Time_1, inline = news_Time_1)

// the inputs for the second news alert
var news_Time_2 = "News Time 2"
var news_Hour_2 = input.int(defval = 00, title = "Hour", group = news_Time_2, inline = news_Time_2, minval = 0, maxval = 24)
var news_Minute_2 = input.int(defval = 00, title = "Minute", group = news_Time_2, inline = news_Time_2, minval = 0, maxval = 45, step = 15)
var show_News_2 = input.bool(defval = false, title = "Show News 2", group = news_Time_2, inline = news_Time_2)

// the inputs for the third news alert
var news_Time_3 = "News Time 3"
var news_Hour_3 = input.int(defval = 00, title = "Hour", group = news_Time_3, inline = news_Time_3, minval = 0, maxval = 24)
var news_Minute_3 = input.int(defval = 00, title = "Minute", group = news_Time_3, inline = news_Time_3, minval = 0, maxval = 45, step = 15)
var show_News_3 = input.bool(defval = false, title = "Show News 3", group = news_Time_3, inline = news_Time_3)

// the inputs for the warning period before and after the news release
var news_Warning = "News Warning Period"
var minutes_Warning_Before_News = input.int(defval = 10, title = "Minutes Before", group = news_Warning, inline = news_Warning, minval = 0, maxval = 65, step = 5)
var minutes_Warning_After_News = input.int(defval = 10, title = "Minutes After", group = news_Warning, inline = news_Warning, minval = 0, maxval = 65, step = 5)

// the inputs for the news line settings
var line_Settings = "News Line Settings"
var line_Color = input.color(defval = color.rgb(255, 255, 255), title = "Color", inline = line_Settings, group = line_Settings)
var line_Style = input.string(defval = "Dotted", title="Style", options=["Dotted", "Dashed", "Solid"], group = line_Settings, inline = line_Settings)
var line_Width = input.int(defval = 1, title = "Width", minval = 1, maxval = 10, inline = line_Settings, group = line_Settings)

// the inputs for the warning area surrounding the news release
var box_Settings = "News Area Settings"
var box_Background_Color = input.color(defval = color.rgb(0, 0, 255, 75), title = "Background Color", inline = box_Settings, group = box_Settings)
var box_Show = input.bool(defval = true, title = "Show Area", inline = box_Settings, group = box_Settings)

// set the line style using the string input
var line_Style_Selected = line.style_dotted

if line_Style == "Dotted"
    line_Style_Selected := line.style_dotted
else if line_Style == "Dashed"
    line_Style_Selected := line.style_dashed
else if line_Style == "Solid"
    line_Style_Selected := line.style_solid

//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------( time calculations )

// the current time of the current bar
current_Bar_Time = time

// News 1 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// get the time stamps for the first news warning, release, before and after
news_Time_Stamp_Release_1 = timestamp(year, month, dayofmonth, news_Hour_1 + time_Zone_Offset, news_Minute_1, 00)
news_Time_Stamp_Before_1 = timestamp(year, month, dayofmonth, news_Hour_1 + time_Zone_Offset, news_Minute_1 - minutes_Warning_Before_News, 00)
news_Time_Stamp_After_1 = timestamp(year, month, dayofmonth, news_Hour_1 + time_Zone_Offset, news_Minute_1 + minutes_Warning_After_News, 00)

// create bools to indicate where price is currently relatated to the first news warning, used for calculations
bool bar_Is_In_News_1 = current_Bar_Time >= news_Time_Stamp_Before_1 and current_Bar_Time <= news_Time_Stamp_After_1 and show_News_1
bool bar_Is_Before_News_1 = current_Bar_Time < news_Time_Stamp_Release_1 and current_Bar_Time >= news_Time_Stamp_Before_1
bool bar_Is_News_Release_1 = current_Bar_Time == news_Time_Stamp_Release_1
bool bar_Is_News_Ongoing_1 = current_Bar_Time > news_Time_Stamp_Release_1 and current_Bar_Time < news_Time_Stamp_After_1
bool bar_Is_Last_News_Candle_1 = current_Bar_Time == news_Time_Stamp_After_1

// draw the news warning objects if showing the first news warning
if show_News_1
    // draw the news warning area
    news_Box_1 = box.new(left = news_Time_Stamp_Before_1, top = (open * 2) + open, right = news_Time_Stamp_After_1, bottom = (open * -2) + open, xloc = xloc.bar_time, border_color = na, bgcolor = box_Background_Color)
    box.delete(news_Box_1[1])
    if box_Show == false
        box.delete(news_Box_1)
    // draw the news release line
    news_Line_1 = line.new(news_Time_Stamp_Release_1, -1, news_Time_Stamp_Release_1, 1, xloc.bar_time, extend.both, line_Color, line_Style_Selected, line_Width)
    line.delete(news_Line_1[1])

// News 2 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// get the time stamps for the second news warning, release, before and after
news_Time_Stamp_Release_2 = timestamp(year, month, dayofmonth, news_Hour_2 + time_Zone_Offset, news_Minute_2, 00)
news_Time_Stamp_Before_2 = timestamp(year, month, dayofmonth, news_Hour_2 + time_Zone_Offset, news_Minute_2 - minutes_Warning_Before_News, 00)
news_Time_Stamp_After_2 = timestamp(year, month, dayofmonth, news_Hour_2 + time_Zone_Offset, news_Minute_2 + minutes_Warning_After_News, 00)

// create bools to indicate where price is currently relatated to the second news warning, used for calculations
bool bar_Is_In_News_2 = current_Bar_Time >= news_Time_Stamp_Before_2 and current_Bar_Time <= news_Time_Stamp_After_2 and show_News_2
bool bar_Is_Before_News_2 = current_Bar_Time < news_Time_Stamp_Release_2 and current_Bar_Time >= news_Time_Stamp_Before_2
bool bar_Is_News_Release_2 = current_Bar_Time == news_Time_Stamp_Release_2
bool bar_Is_News_Ongoing_2 = current_Bar_Time > news_Time_Stamp_Release_2 and current_Bar_Time < news_Time_Stamp_After_2
bool bar_Is_Last_News_Candle_2 = current_Bar_Time == news_Time_Stamp_After_2

// draw the news warning objects if showing the second news warning
if show_News_2
    // draw the news warning area
    news_Box_1 = box.new(left = news_Time_Stamp_Before_2, top = (open * 2) * open, right = news_Time_Stamp_After_2, bottom = (open * -2) + open, xloc = xloc.bar_time, border_color = na, bgcolor = box_Background_Color)
    box.delete(news_Box_1[1])
    // draw the news release line
    news_Line_2 = line.new(news_Time_Stamp_Release_2, -1, news_Time_Stamp_Release_2, 1, xloc.bar_time, extend.both, line_Color, line_Style_Selected, line_Width)
    line.delete(news_Line_2[1])

// News 3 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// get the time stamps for the third news warning, release, before and after
news_Time_Stamp_Release_3 = timestamp(year, month, dayofmonth, news_Hour_3 + time_Zone_Offset, news_Minute_3, 00)
news_Time_Stamp_Before_3 = timestamp(year, month, dayofmonth, news_Hour_3 + time_Zone_Offset, news_Minute_3 - minutes_Warning_Before_News, 00)
news_Time_Stamp_After_3 = timestamp(year, month, dayofmonth, news_Hour_3 + time_Zone_Offset, news_Minute_3 + minutes_Warning_After_News, 00)

// create bools to indicate where price is currently relatated to the third news warning, used for calculations
bool bar_Is_In_News_3 = current_Bar_Time >= news_Time_Stamp_Before_3 and current_Bar_Time <= news_Time_Stamp_After_3 and show_News_3
bool bar_Is_Before_News_3 = current_Bar_Time < news_Time_Stamp_Release_3 and current_Bar_Time >= news_Time_Stamp_Before_3
bool bar_Is_News_Release_3 = current_Bar_Time == news_Time_Stamp_Release_3
bool bar_Is_News_Ongoing_3 = current_Bar_Time > news_Time_Stamp_Release_3 and current_Bar_Time < news_Time_Stamp_After_3
bool bar_Is_Last_News_Candle_3 = current_Bar_Time == news_Time_Stamp_After_3

// draw the news warning objects if showing the third news warning
if show_News_3
    // draw the news warning area
    news_Box_1 = box.new(left = news_Time_Stamp_Before_3, top = (open * 2) * open, right = news_Time_Stamp_After_3, bottom = (open * -2) + open, xloc = xloc.bar_time, border_color = na, bgcolor = box_Background_Color)
    // delete old boxes
    box.delete(news_Box_1[1])
    // draw the news release line
    news_Line_3 = line.new(news_Time_Stamp_Release_3, -1, news_Time_Stamp_Release_3, 1, xloc.bar_time, extend.both, line_Color, line_Style_Selected, line_Width)
    // delete old lines
    line.delete(news_Line_3[1])

// All News ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

// create bools to indicate where price is currently relatated to all the news warning, used for calculations
bool bar_Is_In_News = bar_Is_In_News_1 or bar_Is_In_News_2 or bar_Is_In_News_3
bool bar_Is_Before_News = bar_Is_Before_News_1 or bar_Is_Before_News_2 or bar_Is_Before_News_3
bool bar_Is_News_Release = bar_Is_News_Release_1 or bar_Is_News_Release_2 or bar_Is_News_Release_3
bool bar_Is_News_Ongoing = bar_Is_News_Ongoing_1 or bar_Is_News_Ongoing_2 or bar_Is_News_Ongoing_3
bool bar_Is_Last_News_Candle = bar_Is_Last_News_Candle_1 or bar_Is_Last_News_Candle_2 or bar_Is_Last_News_Candle_3

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------( News Table )

// create a table that will be used to display the news warning before, after and during the news release
news_Table = table.new(position = position.bottom_right, columns = 1, rows = 2, bgcolor = color.red, frame_color = color.white, frame_width = 2)

// if price is currently in a news warning area
if bar_Is_In_News == true
    // indacate that there is currently active news
    table.cell(table_id = news_Table, column = 0, row = 0, text = "Active News")
    table.cell_set_text_size(news_Table, 0, 0, size.large)
    table.cell_set_text_color(news_Table, 0, 0, color.white)
    if bar_Is_News_Release
        // indicate that it is the news release
        table.cell(table_id = news_Table, column = 0, row = 1, text = "Release")
        table.cell_set_text_size(news_Table, 0, 1, size.large)
        table.cell_set_text_color(news_Table, 0, 1, color.white)
    else if bar_Is_News_Ongoing
        // indicate if news is ongoing ( after the news release )
        table.cell(table_id = news_Table, column = 0, row = 1, text = "Ongoing")
        table.cell_set_text_size(news_Table, 0, 1, size.large)
        table.cell_set_text_color(news_Table, 0, 1, color.white)
    else if bar_Is_Last_News_Candle
        // indate if news is on the last candle before the warning ends
        table.cell(table_id = news_Table, column = 0, row = 1, text = "Last Candle")
        table.cell_set_text_size(news_Table, 0, 1, size.large)
        table.cell_set_text_color(news_Table, 0, 1, color.white)
    else if bar_Is_Before_News
        // indicate if the news release is coming soon
        table.cell(table_id = news_Table, column = 0, row = 1, text = "Incoming")
        table.cell_set_text_size(news_Table, 0, 1, size.large)
        table.cell_set_text_color(news_Table, 0, 1, color.white)

else
    // indicate that price is currently not in a news warning
    table.set_bgcolor(news_Table, bgcolor = color.green)
    table.cell(table_id = news_Table, column = 0, row = 0, text = " Clear ")
    table.cell_set_text_size(news_Table, 0, 0, size.normal)
    table.cell_set_text_color(news_Table, 0, 0, color.white)

// delete old tables
table.delete(news_Table[1])