Pine Script alert timing

TradingView alerts: once per bar vs bar close

alert.freq_once_per_bar_close permits an alert only when the realtime bar closes and the script executes the alert() call on that update. It does not queue an earlier call. Once Per Bar permits the first eligible call during the bar, which can occur before close. Waiting for close avoids acting on a temporary chart-bar condition, but does not guarantee that the entire script will never repaint.

Review alert code with AI

What each alert() frequency permits

The frequency parameter filters executed calls. It does not evaluate a condition for you or change when the script runs.

FrequencyEligible callConsequence
alert.freq_once_per_barFirst eligible call in a realtime bar; the defaultAn intrabar notification can outlive a condition that later becomes false.
alert.freq_once_per_bar_closeA call executed on the realtime closing updateA condition that was true earlier but is false at close produces no alert.
alert.freq_allEvery executed call on the realtime barMultiple calls can generate multiple events, subject to platform limits.

A candle that crosses and then reverses

This illustrative sequence assumes an indicator recalculating on realtime updates, with a conditional alert() call. It is an explanation of the execution rules, not a recorded delivery test.

  • If the crossover is true on the closing update instead, the bar-close call can trigger.
  • Historical indicator calculations use completed bars. They do not reconstruct every realtime price update, so an early alert may have no matching marker after reload.
  • The timing rule describes event eligibility, not guaranteed notification delivery latency.
UpdateCross above the EMA?Once Per BarOnce Per Bar Close
Opening updateFalseNo callNo call
Price rises during the barTrueCan trigger hereNo notification yet
Price falls backFalseEarlier alert remains in the logNo call
Closing update, still below EMAFalseNo new eventNo alert for this bar

Compare the two modes with one indicator

Add this Pine v6 indicator to a standard candlestick chart. Set Alert timing before creating an alert on Any alert() function call. The confirmed marker always uses the closing condition, so early alerts can differ from the final chart marker.

  • For the named Cross above EMA alertcondition(), select Once Per Bar Close in the alert dialog if you want closing confirmation. The Alert timing input above controls only alert() calls.
  • To compare modes, create one alert with each input setting and compare their logs during a live session. Historical markers alone cannot verify intrabar notifications.
  • Recreate an alert after editing the script or its inputs. A running alert keeps the script and settings captured when it was created.
Complete example: one selectable alert() frequencypinescript
//@version=6
indicator("Bar-close frequency comparison", overlay = true)

mode = input.string("Bar close", "Alert timing", options = ["Bar close", "Once per bar"])
length = input.int(20, "EMA length", minval = 1)
ema = ta.ema(close, length)
crossUp = ta.crossover(close, ema)
frequency = mode == "Bar close" ? alert.freq_once_per_bar_close : alert.freq_once_per_bar

if crossUp
    alert("Cross above EMA: " + syminfo.tickerid + " close=" + str.tostring(close, format.mintick), frequency)

plot(ema, "EMA", color = color.orange)
plotshape(crossUp and barstate.isconfirmed, title = "Confirmed cross", style = shape.triangleup, location = location.belowbar, color = color.green, size = size.tiny)

// Alternative UI condition: choose this named condition instead of Any alert() function call.
alertcondition(crossUp, "Cross above EMA", "Cross above EMA on {{ticker}} at {{close}}")

alert(), alertcondition(), and strategy fills are different events

Choose the event source before interpreting its frequency. alertcondition() remains a supported indicator feature; it is not a deprecated version of alert().

  • Indicators execute on realtime updates. Strategies normally execute at bar close; calc_on_every_tick enables realtime tick calculations. Additional strategy settings such as calc_on_order_fills can also change the execution schedule.
  • A default strategy using alert.freq_once_per_bar or alert.freq_all still cannot call alert() before its next calculation. Intrabar strategy calculations can differ from historical backtests after reload.
  • With default order processing, a market order created at bar close normally fills at the next available tick, often the next bar open. process_orders_on_close can change this behavior. A fill alert and a closing signal alert therefore need not share a timestamp.
Event sourceFrequency controlScript scope
alert()The freq argument in code; messages may be dynamicIndicators and strategies
alertcondition()The user selects frequency in Create Alert; messages are constant strings with optional placeholdersCreates selectable indicator conditions. Calls can compile in strategies, but cannot create strategy alerts.
Strategy order fillThe broker emulator filling a simulated orderIndependent of alert() frequency; select fills, alert() calls, or both when creating the strategy alert.

Chart-bar confirmation does not confirm a higher timeframe

On a five-minute chart, bar-close frequency follows the five-minute bar. An open hourly candle requested with request.security() can still change. For a confirmed higher-timeframe EMA, offset the requested EMA expression by one bar and use lookahead_on together. This uses the previous completed higher-timeframe value; it deliberately gives up the developing value.

  • Do not remove the [1] offset while keeping lookahead_on: an unoffset higher-timeframe request can leak future values into historical bars.
  • Using [1] with lookahead_off does not provide the same historical and realtime alignment as this documented combination.
  • barstate.isconfirmed can gate an indicator condition or plot at chart close, but it cannot fix future-data leaks, backdated drawings, or later data-feed revisions.
Complete example: confirmed higher-timeframe EMA and chart-bar triggerpinescript
//@version=6
indicator("Confirmed HTF EMA alert", overlay = true)

higherTimeframe = input.timeframe("60", "Higher timeframe")
if timeframe.in_seconds(higherTimeframe) <= timeframe.in_seconds()
    runtime.error("Choose a timeframe higher than the chart timeframe.")

confirmedEma = request.security(syminfo.tickerid, higherTimeframe, ta.ema(close, 50)[1], lookahead = barmerge.lookahead_on)
crossUp = ta.crossover(close, confirmedEma)

if crossUp and barstate.isconfirmed
    alert("Chart close crossed above the confirmed HTF EMA", alert.freq_once_per_bar_close)

plot(confirmedEma, "Confirmed HTF EMA", color = color.orange)
plotshape(crossUp and barstate.isconfirmed, title = "Confirmed cross", style = shape.triangleup, location = location.belowbar, color = color.green, size = size.tiny)

Check a missing or unexpected closing alert

Use the alert log and the exact saved script configuration to locate the mismatch. These checks are a repeatable procedure, not evidence that notification delivery has been measured here.

  • Check that the alert is active and uses the intended event source. A named alertcondition and Any alert() function call are separate choices.
  • Verify that the if branch reaches alert() on the closing update. A branch gated by barstate.isnew will normally miss that update.
  • Compare the saved symbol, timeframe, and inputs with the chart, then recreate the alert if any have changed.
  • For a strategy, compare the calculation settings and fill events separately. For higher-timeframe inputs, check whether the requested data is confirmed.
  • Record one condition that remains true at close and one that reverses before close. If neither occurs during observation, the comparison is incomplete.
Where Pineify fits

Pine Script AI Coding Agent

Bring your script and the expected trigger timing to the coding agent to revise alert conditions. Review the resulting code and test its realtime behavior in TradingView.

Review alert code with AI

Frequently asked questions

Educational programming examples, not trading recommendations. Syntax validation does not verify alert delivery, order execution, or trading performance.

Sources and verification

Published by Pineify. Pineify is an independent product and is not affiliated with TradingView. Sources support the technical explanations; examples do not establish trading performance.