Pine Script strategy alerts

Send PineHook commands from Pine Script with alert() or strategy order-fill messages. Set the TradingView webhook, add unique IDs, and test on demo.

Last updated: 2026-10-08

If you can edit your strategy's Pine Script code, we recommend writing PineHook alerts there. You can tailor each message to the signal, including a position size that your strategy calculates dynamically. Use alert() when a condition runs, or attach alert_message to an order to send it when TradingView's broker emulator fills that order; the setup differs for each method, as shown below.

This guide assumes you already have a connected PineHook license. Test the strategy and its messages on a demo account first.

Send commands with alert()#

On a hedging account, this Pine Script v6 example sends a buy command on a moving-average crossover with magic=12345, a fresh id=, and a generated PineHook ticket=. Remove ticket= on netting or exchange accounts.

//@version=6
strategy("PineHook crossover alerts", overlay = true)
license = input.string("YOUR_LICENSE_KEY", "PineHook license")
fast = ta.sma(close, 10)
slow = ta.sma(close, 20)
var string positionTicket = ""

if ta.crossover(fast, slow) and strategy.position_size == 0
    alertId = str.tostring(timenow) + "-" + str.tostring(math.floor(math.random(0, 999999)))
    positionTicket := "TV-" + alertId
    params = ",size_lots=0.01,sl_pips=50,tp_pips=100,magic=12345"
    message = license + ",buy," + syminfo.ticker + params + ",ticket=" + positionTicket + ",id=" + alertId
    alert(message, alert.freq_once_per_bar_close)
    strategy.entry("Long", strategy.long)

See alert IDs for how id= works and strategy and trade labels for magic= and ticket=. Replace magic=12345 with your strategy number, and keep positionTicket if later commands need to target this position.

The 0.01 lot size is fixed for this example. To vary it with your strategy, calculate a lot value and add it to the message with str.tostring().

Add the strategy to your chart and create an alert with the strategy as its condition. Choose alert() function calls only, then enable Webhook URL under Notifications and enter https://relay.pinehook.io/webhook. TradingView sends the message passed to alert() in your code, so this method does not use {{strategy.order.alert_message}} in the Message field. Avoid Order fills and alert() function calls, which would also send a notification when the simulated order fills.

This command goes out when the crossover code runs, while TradingView may fill the simulated strategy.entry() order later. Test on a demo account and compare TradingView's alert log with PineHook Signal Logs; if you need the webhook to follow simulated fills instead, use the order-fill method below.

Send commands on order fills#

Use this method when the webhook should follow TradingView's simulated order fills. Pass alert_message to each order-producing strategy call. On a hedging account, this Pine Script v6 example gives the entry a PineHook ticket=, then uses the same ticket to close that position. Both messages include magic=12345 and a fresh id=:

//@version=6
strategy("PineHook long alerts", overlay = true, pyramiding = 0)
license = input.string("YOUR_LICENSE_KEY", "PineHook license")
lots = input.float(0.01, "Lots", minval = 0.01, step = 0.01)
fast = ta.sma(close, 10)
slow = ta.sma(close, 20)
var string positionTicket = ""

if ta.crossover(fast, slow) and strategy.position_size == 0
    buyId = str.tostring(timenow) + "-" + str.tostring(math.floor(math.random(0, 999999)))
    positionTicket := "TV-" + buyId
    buyMessage = license + ",buy," + syminfo.ticker + ",size_lots=" + str.tostring(lots) + ",sl_pips=50,tp_pips=100,magic=12345,ticket=" + positionTicket + ",id=" + buyId
    strategy.entry("Long", strategy.long, alert_message = buyMessage)

if ta.crossunder(fast, slow) and strategy.position_size > 0
    closeId = str.tostring(timenow) + "-" + str.tostring(math.floor(math.random(0, 999999)))
    closeMessage = license + ",closelong," + syminfo.ticker + ",magic=12345,ticket=" + positionTicket + ",id=" + closeId
    strategy.close("Long", alert_message = closeMessage)

The buy message sets a broker-side stop loss and take profit. The close message targets the position identified by positionTicket; remove ticket= from both messages on netting or exchange accounts, where PineHook rejects it. Replace magic=12345 with your strategy number, and check the broker's symbol spelling if it differs from syminfo.ticker. See alert IDs and trade identification for how these fields work.

Add the strategy to your chart and create an alert with the strategy as its condition. Choose Order fills only, then enable Webhook URL under Notifications and enter https://relay.pinehook.io/webhook. Put {{strategy.order.alert_message}} in the Message field before creating the alert.

The placeholder is replaced by the alert_message from the order that fills. A strategy's strategy.entry(), strategy.close(), strategy.close_all(), or strategy.exit() can supply that message. strategy.exit() sends its message when TradingView's broker emulator fills an exit order, not when the script declares it. A cancellation through strategy.cancel() does not produce an order-fill message.

Send a final position target#

setposition lets an alert describe the final signed volume instead of another buy or sell quantity. For example, this message requests a final 0.20-lot short when lot conversion is 1:1:

YOUR_LICENSE_KEY,setposition,EURUSD,target=-0.20,magic=12345

Calculate the desired final volume in your alert logic and send it as target, using a positive value for long, a negative value for short, or zero for flat. The quantity of an individual entry, partial exit, or reversal order is not necessarily the final volume. Use the alert() or order-fill message method above to send the target at the intended event.

Confirm lot conversion before using TradingView quantities. Hedging strategies can use one reusable ticket per target group; netting and exchange accounts must omit tickets. Keep normal buy/sell tickets unique. The command does not restore a target after a later stop or manual exit, and its availability and recovery checks still apply.

If you can't edit the strategy's code, mirror its position with setposition from the alert dialog instead.

If the goal is simply to ignore opposite entry alerts while a trade runs, use Allow Hedging off instead of a reversal target.

Test and keep it current#

Test either method on a demo account and follow the demo alert checks to compare TradingView's alert log, PineHook Signal Logs, and your broker account. For the order-fill example, the Strategy Tester shows when TradingView enters and exits, though simulated fills may differ from broker execution. Keep protective stop and take profit values in the PineHook entry message when you need them at the broker.

Recreate alerts after strategy changes

TradingView keeps a snapshot of the strategy and its inputs when you create an alert. If you change the code, inputs, chart symbol, or timeframe, delete the old alert and create a new one; editing the script alone will not update the running alert.

If no message arrives, confirm the alert uses alert() function calls only or Order fills only as intended and that the matching event occurred. For order-fill alerts, also check {{strategy.order.alert_message}} for typos. If PineHook rejects the message, inspect its reason in Signal Logs and check the license key, symbol, and command syntax.