//@version=5
indicator("News Dash", overlay=true, max_labels_count=100, max_lines_count=100)
volMultiplier = input.float(3.0, "Volume Spike Threshold", minval=1.5, step=0.1, tooltip="How many times above average volume to flag as unusual")
rangeMultiplier = input.float(2.5, "Range Spike Threshold", minval=1.5, step=0.1, tooltip="How many times above average range to flag as unusual")
lookback = input.int(20, "Lookback Period", minval=5, maxval=100, tooltip="Number of bars to calculate average from")
showLabels = input.bool(true, "Show News Event Labels")
enableAlerts = input.bool(true, "Enable Alerts")
avgVolume = ta.sma(volume, lookback)
avgRange = ta.atr(lookback)
volumeSpike = volume > avgVolume * volMultiplier
rangeSpike = (high - low) > avgRange * rangeMultiplier
newsEvent = volumeSpike and rangeSpike
if newsEvent and showLabels
label.new(bar_index, high, "News", color=color.new(#ffd54f, 0), textcolor=#000000, style=label.style_label_down, size=size.small)
bgcolor(newsEvent ? color.new(#ffd54f, 85) : na)
var int lastNewsBar = na
if newsEvent
lastNewsBar := bar_index
barsSinceNews = not na(lastNewsBar) ? bar_index - lastNewsBar : 999
riskLevel = barsSinceNews <= 3 ? "HIGH" : barsSinceNews <= 10 ? "MEDIUM" : "LOW"
riskColor = barsSinceNews <= 3 ? #ef5350 : barsSinceNews <= 10 ? #ffd54f : #4caf50
var table infoTable = table.new(position.top_right, 2, 3, bgcolor=color.new(#1a1a2e, 10), border_width=1, border_color=color.new(#333333, 0))
if barstate.islast
table.cell(infoTable, 0, 0, "News Risk", text_color=#e0e0e0, text_size=size.small)
table.cell(infoTable, 1, 0, riskLevel, text_color=riskColor, text_size=size.small)
table.cell(infoTable, 0, 1, "Bars Since", text_color=#e0e0e0, text_size=size.small)
table.cell(infoTable, 1, 1, not na(lastNewsBar) ? str.tostring(barsSinceNews) : "None", text_color=#e0e0e0, text_size=size.small)
table.cell(infoTable, 0, 2, "Vol vs Avg", text_color=#e0e0e0, text_size=size.small)
table.cell(infoTable, 1, 2, str.tostring(volume / avgVolume, "#.#") + "x", text_color=#e0e0e0, text_size=size.small)
alertcondition(newsEvent and enableAlerts, "News Event Detected", "NEWS DASH: Unusual volume and range spike detected. Possible news event.")