In Pine Script v6, the alert() function takes a freq argument with three options: alert.freq_once_per_bar (fires on the first triggering call of each realtime bar — the default), alert.freq_once_per_bar_close (fires only when the realtime bar closes) and alert.freq_all (fires on every triggering call within the bar). If you want alerts that never repaint and never fire mid-candle, use alert.freq_once_per_bar_close. If you want the fastest possible intrabar signal and can tolerate a value that may change before the candle closes, use alert.freq_all. This is the single most important choice when wiring TradingView alerts to a live broker. As of July 2026, this behaviour is unchanged in Pine v6.
In my 8 years coding Pine Script — over 7,700 strategies shipped for clients in 14+ countries — the alert that fires at the wrong moment is the bug I get paid to fix most after multi-timeframe repainting. A client in Singapore once sent me a scalping bot that placed three orders per candle instead of one. The script was perfect; the alert frequency was set to alert.freq_all on a condition that stayed true for several intrabar ticks. Change one enum, problem solved. Let me walk you through exactly how each frequency behaves.
The three alert frequencies, precisely
The official TradingView alerts documentation gives the alert() signature as alert(message, freq). The message is a series string, so it can be built dynamically and differ bar to bar. The freq is an input string — it must be one of three built-in constants:
| Frequency constant | When it fires | Repaints? | Best for |
|---|---|---|---|
alert.freq_once_per_bar (default) |
Only the first call per realtime bar | Can repaint (fires mid-bar) | One signal per candle, reasonably fast |
alert.freq_once_per_bar_close |
Only when the realtime bar closes and the call executes | No — confirmed value | Reliable live execution, webhooks to brokers |
alert.freq_all |
Every call during the realtime bar | Can repaint heavily | Tick-level monitoring, scalping alerts |
Two conditions must both be true for an alert to fire: your script’s logic must allow the alert() call to execute, and the frequency must permit it to trigger. Note also that alerts only ever trigger on the realtime bar — alert code has no effect on historical bars.
once_per_bar vs once_per_bar_close: the intrabar distinction
This is the exact query traders search for, so let me be concrete. Suppose your condition is close > open (a green candle so far). During a live 15-minute bar, price moves up and down many times before the candle closes.
- With
alert.freq_once_per_bar, the alert fires the first time the candle turns green intrabar. If price later reverses and the bar closes red, the alert already fired — that is repainting at the alert level. - With
alert.freq_once_per_bar_close, the alert only fires when the bar closes, and only if the condition is still true at that moment. No premature signal, no reversal surprises.
Here is a v6 indicator that lets you feel the difference. Load it, create two alerts from it — one on each frequency — and watch when they fire:
//@version=6
indicator("Alert frequency demo", overlay = true)
// Simple condition: fast EMA crosses above slow EMA
fast = ta.ema(close, 9)
slow = ta.ema(close, 21)
crossUp = ta.crossover(fast, slow)
plot(fast, "Fast EMA", color.aqua)
plot(slow, "Slow EMA", color.orange)
plotshape(crossUp, "Cross Up", shape.triangleup, location.belowbar, color.lime, size = size.small)
// Change the freq value to compare behaviour live
if crossUp
alert("EMA cross up on " + syminfo.ticker + " at " + str.tostring(close),
alert.freq_once_per_bar_close)
Swap alert.freq_once_per_bar_close for alert.freq_once_per_bar or alert.freq_all and re-create the alert to compare. Because ta.crossover() can flip on and off intrabar, the difference is easy to observe on a volatile symbol.
How strategies change the rules
Strategies behave differently, and this trips up almost everyone. By default a strategy recalculates only on the close of the realtime bar. So unless you set calc_on_every_tick = true in the strategy() declaration, every alert() call in a strategy uses alert.freq_once_per_bar_close behaviour — regardless of the freq argument you pass. Passing alert.freq_all to a default strategy does nothing.
//@version=6
// calc_on_every_tick = true is required for intrabar alerts in a strategy
strategy("Intrabar strategy alerts", calc_on_every_tick = true)
longCond = ta.crossover(ta.rsi(close, 14), 30)
if longCond
strategy.entry("Long", strategy.long)
alert("RSI reversal long", alert.freq_all) // now respected
Be careful: enabling calc_on_every_tick makes a strategy behave differently in the backtest (which uses historical bars) versus live (which uses ticks), and it is a classic source of repainting. For most of my broker-connected clients I keep alerts on once_per_bar_close so the live signal matches the backtested logic.
alert() vs alertcondition(): which to use
The older alertcondition() function still exists for backward compatibility, but alert() more or less supersedes it. Key differences straight from the docs:
- Dynamic messages:
alert()accepts a series string, so you can embed live prices withstr.tostring().alertcondition()requires a const string known at compile time — dynamic values only via placeholders like{{close}}or{{plot_0}}. - Placement:
alert()can sit inside anifblock so it only runs on your condition.alertcondition()must start at column zero in the global scope. - Scope:
alert()works in both indicators and strategies.alertcondition()works in indicators only (it compiles in a strategy but you cannot create an alert from it). - Frequency control:
alert()lets the programmer setfreq. Withalertcondition(), the frequency is chosen by the user in the Create Alert dialog, not in code.
My rule of thumb: use alert() for anything new, especially if you need the price or other live data inside the message, or if you are routing to a webhook.
For strategy order routing there is a third mechanism — the alert_message parameter on strategy.entry(), strategy.exit(), strategy.close() and strategy.order(). It fires on the actual order fill event (when the broker emulator executes the order), which alert() cannot detect. Pair it with the {{strategy.order.alert_message}} placeholder in the Create Alert dialog to send custom JSON to your execution bridge.
Need this wired correctly for live trading? Message me on WhatsApp at +91 77352 68199 and I’ll audit your alert setup.
Frequency, repainting and intrabar ticks
The reason alert frequency matters so much is repainting. An alert repaints when it fires at some point during the realtime bar but would not have fired at the bar’s close. Per the TradingView docs, this happens when two things line up: the triggering calculation can change during the bar (anything using high, low, close, or a higher-timeframe request.security() whose bar has not closed), and the alert can fire before the bar closes — i.e. any frequency other than once-per-bar-close.
The simplest fix is to trigger only on bar close. There is no free lunch here: avoiding this class of repainting always means waiting for confirmed data, so you trade immediacy for reliability. Multi-timeframe repainting has its own subtleties — I cover the lookahead mechanics in depth in my guide to request.security() and lookahead, which pairs directly with this alert discussion when your signal comes from a higher timeframe.
Webhook alert reliability for live trading
TradingView alerts run 24×7 on TradingView’s servers — you do not need to be logged in for them to fire. When an alert is created, TradingView saves a snapshot of the script, its inputs, and the chart’s symbol and timeframe; later edits to your script or chart do not affect an already-running alert. If you change your logic, you must delete and recreate the alert.
For webhook-driven execution to a broker, frequency choice is a reliability decision, not a preference:
- Use
once_per_bar_closefor order-placing webhooks so the payload reflects a confirmed candle. A mid-bar webhook that later reverses can send an order your backtest never took. - Keep the message deterministic — build clean JSON in the
alert()message so your bridge parses it reliably every time. - Remember alerts fire only on realtime bars, so test on a live or replay session, not on history.
Once your frequency is right, the last mile is getting the webhook to your broker. I walk through that end-to-end in the easiest way to connect TradingView alerts to Zerodha guide, and I build custom alert automation as a service — see my Pine Script development page or my dedicated alert automation service.
FAQ
What does alert.freq_once_per_bar_close mean?
It means the alert() call only triggers when the realtime bar closes and the call executes during that closing iteration. It is the non-repainting choice: the signal is based on a confirmed candle, so it will not fire early and then vanish if price reverses.
What is the difference between once_per_bar and once_per_bar_close intrabar?
once_per_bar fires the first time your condition becomes true during the live bar — potentially many minutes before the candle closes, and it may not reflect the final candle. once_per_bar_close waits for the candle to actually close. Intrabar, once_per_bar is faster but can repaint; once_per_bar_close is slower but confirmed.
Why does my Pine Script alert ignore freq_all in a strategy?
Because strategies recalculate only on bar close by default. Unless you add calc_on_every_tick = true to the strategy() declaration, all alert() calls behave as once_per_bar_close no matter what freq you pass.
Should I use alert() or alertcondition()?
Use alert() for almost everything. It allows dynamic messages, works in both indicators and strategies, can sit inside conditional blocks, and lets you set the frequency in code. Keep alertcondition() only when you specifically want separately selectable conditions in the Create Alert dialog.
Which alert frequency is safest for connecting TradingView to a broker?
alert.freq_once_per_bar_close. It ensures the webhook payload is based on a closed, confirmed candle, so your live orders match your backtested logic and you avoid mid-bar signals that reverse.
Want alerts, webhooks and your broker wired together and tested? WhatsApp me at +91 77352 68199 and I’ll set it up right the first time.
Risk disclaimer: Trading and algorithmic trading involve substantial risk of loss and are not suitable for every investor. Code examples in this article are for educational purposes only and are not financial advice. Alert frequency and repainting behaviour can materially affect live results — always test thoroughly on a demo or replay session before trading real capital.

Leave a Reply