Pineスクリプト作成代行はこちら

Pineスクリプトアラート実装|alertcondition()の使い方

Pineスクリプトでインジケーターを作ったら、次にやりたいのがアラートの実装だ。チャートに張り付かなくても、条件を満たした瞬間にスマホやメールで通知を受け取れる。

しかし、Pineスクリプトのアラートには2つの関数がある。alertcondition()alert()だ。どちらを使えばいいのか、何が違うのか。初心者がつまずくポイントはここだ。

結論から言うと、インジケーターならalertcondition()が基本。ストラテジーならalert()を使う。そしてどちらも、コードを書いただけではアラートは鳴らない。TradingView上でアラートを手動作成する必要がある。

この記事では、2つのアラート関数の違いから、実用的なアラート付きインジケーターの作成、Webhook連携まで、v6ベースのコード付きで解説する。

Pineスクリプトの実践テクニックを見る

alertcondition()とalert()の違い

Pineスクリプトには2つのアラート関数がある。名前が似ているが、仕組みがまったく異なる。

alertcondition() — アラート条件を「登録」する関数。インジケーター専用。この関数を書くと、TradingViewのアラート作成ダイアログのドロップダウンに選択肢として表示される。1つのスクリプトに複数のalertcondition()を書ける。

alert() — アラートを「直接発火」する関数。インジケーターにもストラテジーにも使える。条件を満たしたときにスクリプト内から直接アラートをトリガーする。メッセージに動的な値(価格、RSI値など)を含められる。

使い分けの基準はこうだ。

alertcondition()を使うケース: インジケーターに複数のアラート条件を登録したいとき。ユーザーがアラート作成時に条件を選べるようにしたいとき。

alert()を使うケース: アラートメッセージに動的な値(現在価格やインジケーターの数値)を含めたいとき。ストラテジーでアラートを使いたいとき。Webhook連携で動的なJSONを送りたいとき。

どちらを使っても、コードを書いただけではアラートは発動しない。TradingViewの「アラート作成」ダイアログで手動でアラートを設定する必要がある。ここを見落とす初心者が非常に多い。

alertcondition()の基本構文

alertcondition()の構文はシンプルだ。3つの引数を取る。

//@version=6
indicator("アラート基本", overlay=true)
sma20 = ta.sma(close, 20)

// alertcondition(条件, タイトル, メッセージ)
alertcondition(ta.crossover(close, sma20), "SMA上抜け", "{{ticker}}: 終値がSMA20を上抜けました")
alertcondition(ta.crossunder(close, sma20), "SMA下抜け", "{{ticker}}: 終値がSMA20を下抜けました")

plot(sma20, "SMA20", color.blue, 2)

第1引数(condition)true/falseを返す条件式。trueになった瞬間にアラートがトリガーされる。

第2引数(title) — アラート作成ダイアログのドロップダウンに表示される名前。わかりやすい日本語で付ける。

第3引数(message) — アラート発動時に表示されるメッセージ。{{ticker}}{{close}}などのプレースホルダが使える。

このコードをチャートに追加した後、TradingViewの「アラート作成」で条件にこのインジケーターを選ぶと、「SMA上抜け」「SMA下抜け」の2つの条件が選択肢として表示される。

alertcondition()のプレースホルダ一覧

メッセージ内で使えるプレースホルダを整理する。これらはアラート発動時にTradingViewが実際の値に置換してくれる。

{{ticker}} — ティッカー名(例: BTCUSDT)。{{exchange}} — 取引所名(例: BINANCE)。{{close}} — 終値。{{open}} — 始値。{{high}} — 高値。{{low}} — 安値。{{volume}} — 出来高。{{time}} — バーの時刻。{{timenow}} — アラート発動時の現在時刻。{{interval}} — 時間足(例: 60)。

alertcondition(
    condition,
    "RSI過熱アラート",
    "{{ticker}}({{interval}}分足) 終値={{close}} RSI過熱ゾーン突入 時刻={{timenow}}"
)

ただし、alertcondition()のプレースホルダではスクリプト内で計算した値(RSIの数値など)は埋め込めない。計算値をメッセージに含めたい場合は、後述のalert()関数を使う。

複数条件のアラートを実装する

実用的なインジケーターでは、複数のアラート条件を1つのスクリプトにまとめることが多い。

//@version=6
indicator("マルチアラート", overlay=true)

// パラメータ
fastLen = input.int(12, "短期EMA")
slowLen = input.int(26, "長期EMA")
rsiLen = input.int(14, "RSI期間")
rsiOB = input.int(70, "RSI買われすぎ")
rsiOS = input.int(30, "RSI売られすぎ")

// 計算
emaFast = ta.ema(close, fastLen)
emaSlow = ta.ema(close, slowLen)
rsi = ta.rsi(close, rsiLen)

// 条件
goldenCross = ta.crossover(emaFast, emaSlow)
deadCross = ta.crossunder(emaFast, emaSlow)
rsiOverbought = ta.crossover(rsi, rsiOB)
rsiOversold = ta.crossunder(rsi, rsiOS)

// アラート条件(4つ登録)
alertcondition(goldenCross, "ゴールデンクロス", "{{ticker}}: EMAゴールデンクロス発生")
alertcondition(deadCross, "デッドクロス", "{{ticker}}: EMAデッドクロス発生")
alertcondition(rsiOverbought, "RSI買われすぎ突入", "{{ticker}}: RSIが" + str.tostring(rsiOB) + "を超えました")
alertcondition(rsiOversold, "RSI売られすぎ突入", "{{ticker}}: RSIが" + str.tostring(rsiOS) + "を下回りました")

// 描画
plot(emaFast, "EMA Fast", color.blue, 2)
plot(emaSlow, "EMA Slow", color.red, 2)
plotshape(goldenCross, "GC", shape.triangleup, location.belowbar, color.green, size=size.small)
plotshape(deadCross, "DC", shape.triangledown, location.abovebar, color.red, size=size.small)

1つのインジケーターにalertcondition()を何個でも書ける。アラート作成ダイアログで、どの条件を使うか選択する形になる。

注意点として、alertcondition()の第3引数(メッセージ)にstr.tostring(rsiOB)のようなinput変数の文字列化は使えるが、str.tostring(rsi)のようなシリーズ変数の文字列化は使えない。バーごとに変わる動的な値をメッセージに入れたい場合はalert()関数を使う。

alert()関数の基本構文

alert()は、条件を満たしたときにスクリプト内から直接アラートを発火する関数だ。

//@version=6
indicator("alert()の例", overlay=true)
sma20 = ta.sma(close, 20)
rsi = ta.rsi(close, 14)

if ta.crossover(close, sma20)
    alert("SMA上抜け " + syminfo.ticker + " 価格=" + str.tostring(close) + " RSI=" + str.tostring(rsi, "#.#"), alert.freq_once_per_bar_close)

plot(sma20, "SMA20", color.blue, 2)

alert()の第1引数はメッセージ文字列。alertcondition()と違い、str.tostring(close)str.tostring(rsi)で動的な値をメッセージに直接埋め込める。これがalert()最大のメリットだ。

第2引数はトリガー頻度で、3つの選択肢がある。

alert.freq_once_per_bar — 1本のバーにつき最初の1回だけ発火。リアルタイムバーの途中でも条件を満たした瞬間に発火する。

alert.freq_once_per_bar_close — バーの確定時に1回だけ発火。リアルタイムバーの途中では発火しない。確定した値でのシグナルに使う。

alert.freq_all — 条件を満たすたびに毎回発火。リアルタイムバーのティックごとに発火する可能性がある。使いすぎるとアラートが大量に飛ぶので注意。

基本的にはalert.freq_once_per_bar_closeを使うのが安全だ。バーが確定する前の中途半端なシグナルでアラートが飛ぶのを防げる。

alert()を使った実用アラートインジケーター

EMAクロスとRSIフィルターを組み合わせた、実用レベルのアラートインジケーター。

//@version=6
indicator("EMA+RSI アラート", overlay=true)

// パラメータ
fastLen = input.int(12, "短期EMA", group="EMA")
slowLen = input.int(26, "長期EMA", group="EMA")
rsiLen = input.int(14, "RSI期間", group="RSI")
rsiFilter = input.bool(true, "RSIフィルター有効", group="RSI")
rsiOB = input.int(70, "買われすぎ", group="RSI")
rsiOS = input.int(30, "売られすぎ", group="RSI")

// 計算
emaFast = ta.ema(close, fastLen)
emaSlow = ta.ema(close, slowLen)
rsi = ta.rsi(close, rsiLen)

// エントリー条件(RSIフィルター付き)
longSignal = ta.crossover(emaFast, emaSlow) and (not rsiFilter or rsi < rsiOB)
shortSignal = ta.crossunder(emaFast, emaSlow) and (not rsiFilter or rsi > rsiOS)

// alert()で動的メッセージ送信
if longSignal
    alert("🟢 買いシグナル\n" + syminfo.ticker + " (" + timeframe.period + ")\n" + "価格: " + str.tostring(close, format.mintick) + "\n" + "RSI: " + str.tostring(rsi, "#.#"), alert.freq_once_per_bar_close)

if shortSignal
    alert("🔴 売りシグナル\n" + syminfo.ticker + " (" + timeframe.period + ")\n" + "価格: " + str.tostring(close, format.mintick) + "\n" + "RSI: " + str.tostring(rsi, "#.#"), alert.freq_once_per_bar_close)

// alertcondition()も併設(ユーザー選択用)
alertcondition(longSignal, "買いシグナル", "{{ticker}}: 買いシグナル発生")
alertcondition(shortSignal, "売りシグナル", "{{ticker}}: 売りシグナル発生")

// 描画
plot(emaFast, "EMA Fast", color.blue, 2)
plot(emaSlow, "EMA Slow", color.red, 2)
plotshape(longSignal, "Long", shape.triangleup, location.belowbar, color.green, size=size.small)
plotshape(shortSignal, "Short", shape.triangledown, location.abovebar, color.red, size=size.small)

alert()alertcondition()を同じスクリプトに併設しているのがポイントだ。alert()は動的なメッセージ(価格やRSI値入り)を送るため、alertcondition()はシンプルな通知が欲しいユーザーのため。TradingViewのアラート作成時にどちらを使うか選べる。

Pineスクリプトの基本構文を復習したい方はこちら。

Pineスクリプトの書き方|基本構文をコード付きで完全解説

Pineスクリプトの応用テクニックを探す

ストラテジーでのアラート

strategy()で作成したストラテジーでは、alertcondition()は使えない。代わりに2つの方法がある。

方法①: strategy関数の約定イベントでアラート。コードの変更は不要。TradingViewのアラート作成ダイアログで、ストラテジーを選択すると「注文が約定」「注文が発注」などのイベントを選択できる。

方法②: alert()関数でカスタムアラート

//@version=6
strategy("アラート付きストラテジー", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

fast = ta.ema(close, 12)
slow = ta.ema(close, 26)

if ta.crossover(fast, slow)
    strategy.entry("Long", strategy.long)
    alert("ENTRY LONG " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)

if ta.crossunder(fast, slow)
    strategy.close("Long")
    alert("EXIT LONG " + syminfo.ticker + " at " + str.tostring(close), alert.freq_once_per_bar_close)

plot(fast, "Fast", color.blue)
plot(slow, "Slow", color.red)

ストラテジーではstrategy.entry()strategy.close()の直後にalert()を置くパターンが一般的だ。アラート作成ダイアログでは「alert()関数の呼び出し」を選択する。

Webhook連携でJSON送信

alert()のメッセージにJSON文字列を入れれば、Webhook経由で外部サービスに構造化データを送信できる。自動売買botとの連携に使われるパターンだ。

//@version=6
indicator("Webhookアラート", overlay=true)
fast = ta.ema(close, 12)
slow = ta.ema(close, 26)

longSignal = ta.crossover(fast, slow)
shortSignal = ta.crossunder(fast, slow)

if longSignal
    alert('{"action":"buy","ticker":"' + syminfo.ticker + '","price":' + str.tostring(close) + ',"time":"' + str.tostring(timenow) + '"}', alert.freq_once_per_bar_close)

if shortSignal
    alert('{"action":"sell","ticker":"' + syminfo.ticker + '","price":' + str.tostring(close) + ',"time":"' + str.tostring(timenow) + '"}', alert.freq_once_per_bar_close)

plot(fast, "Fast", color.blue)
plot(slow, "Slow", color.red)

TradingViewのアラート作成ダイアログで「通知」タブを開き、「Webhook URL」に受信先のURLを入力する。「メッセージ」欄は空にしておけば、alert()で指定した文字列がそのまま送信される。

Webhook連携はTradingViewの有料プラン(Pro以上)が必要だ。

時間帯限定アラート

特定の市場セッション内でのみアラートを鳴らすインジケーター。セッション外のノイズシグナルを除外できる。

//@version=6
indicator("セッション限定アラート", overlay=true)

// セッション設定
sessionStr = input.string("0800-1630", "セッション", tooltip="HHMM-HHMM")
sessionTZ = input.string("Europe/London", "タイムゾーン", options=["Asia/Tokyo", "Europe/London", "America/New_York"])

// EMA
fast = ta.ema(close, 12)
slow = ta.ema(close, 26)

// セッション内判定
inSession = not na(time(timeframe.period, sessionStr, sessionTZ))

// セッション内のみシグナル
longSig = ta.crossover(fast, slow) and inSession
shortSig = ta.crossunder(fast, slow) and inSession

// アラート
alertcondition(longSig, "セッション内買い", "{{ticker}}: セッション内でGC発生")
alertcondition(shortSig, "セッション内売り", "{{ticker}}: セッション内でDC発生")

if longSig
    alert("BUY " + syminfo.ticker + " in " + sessionTZ + " session, price=" + str.tostring(close, format.mintick), alert.freq_once_per_bar_close)

// 描画
plot(fast, "Fast", color.blue)
plot(slow, "Slow", color.red)
bgcolor(inSession ? color.new(color.gray, 95) : na)
plotshape(longSig, "Long", shape.triangleup, location.belowbar, color.green, size=size.small)
plotshape(shortSig, "Short", shape.triangledown, location.abovebar, color.red, size=size.small)

and inSessionの一句を条件に追加するだけで、セッション外のシグナルを完全に除外できる。時間帯の指定方法を詳しく知りたい方はこちら。

Pineスクリプトで時間指定する方法|東京・ロンドン・NY時間の実装コード

TradingViewでのアラート作成手順

コードを書いた後、TradingView上でアラートを有効化する手順を確認しておく。

ステップ1: インジケーターをチャートに追加する。Pineエディタで「保存」→「チャートへ追加」。

ステップ2: チャート上部のツールバーにある「アラート」アイコン(時計マーク)をクリック、またはAlt + A(Mac: Option + A)を押す。

ステップ3: 「条件」のドロップダウンで、追加したインジケーター名を選択する。

ステップ4: alertcondition()を使っている場合は、その下のドロップダウンでアラート条件(タイトル)を選ぶ。alert()を使っている場合は「alert()関数の呼び出し」を選ぶ。

ステップ5: トリガー頻度を設定する。「バーにつき1回」が一般的だ。

ステップ6: 「通知」タブで通知方法を選ぶ。アプリ通知、メール、Webhookなど。

ステップ7: 有効期限を設定し、「作成」をクリック。

重要なのは、スクリプトを変更した場合、既存のアラートには反映されないということだ。スクリプトを修正したら、古いアラートを削除して新しいアラートを作り直す必要がある。

アラートの制限事項

TradingViewのアラートにはプランによる制限がある。

無料プラン(Basic)はアクティブアラート1件。Essentialは20件。Plusは100件。Premiumは400件。Expertは800件。Ultimateは無制限だ。

スクリプトアラートが3分間に15回以上トリガーされると、自動的に停止される。alert.freq_allを使うときは特に注意が必要だ。

アラートはリアルタイムバーでのみトリガーされる。ヒストリカルバー(過去のバー)ではalertcondition()alert()も発火しない。つまり、バックテストではアラートの動作を確認できない。

Webhook連携はPro以上の有料プランが必要だ。

よくあるミスと対処法

ミス①: コードを書いたのにアラートが鳴らないalertcondition()はアラート条件を「登録」するだけ。TradingViewのアラート作成ダイアログで手動でアラートを作成する必要がある。

ミス②: alertcondition()をストラテジーで使おうとするalertcondition()はインジケーター(indicator())専用。ストラテジー(strategy())では使えない。ストラテジーではalert()を使うか、約定イベントでアラートを設定する。

ミス③: スクリプト変更後もアラートが古い条件で発動する。アラート作成時のスクリプト状態がサーバーに保存される。スクリプトを変更したら、アラートを削除して作り直す。

ミス④: alertcondition()のメッセージに動的な値を入れようとするstr.tostring(rsi)のようなシリーズ変数はalertcondition()のメッセージには使えない。動的な値を含めたい場合はalert()関数を使う。

ミス⑤: alert.freq_allで大量アラートが飛ぶ。リアルタイムバーのティックごとに条件を評価するため、数秒間に何十回もアラートが発火する可能性がある。通常はalert.freq_once_per_bar_closeで十分だ。

まとめ

Pineスクリプトのアラートはalertcondition()alert()の2つ。インジケーターで複数の条件を登録したいならalertcondition()、動的なメッセージやWebhook連携ならalert()を使う。どちらもコードを書いた後にTradingView上でアラートを手動作成する手順が必要だ。

アラートのトリガー頻度はalert.freq_once_per_bar_closeが安全。スクリプトを変更したらアラートは作り直す。この2点を押さえておけば、意図しない動作を防げる。

Pineスクリプトの実践ノウハウをもっと見る

※当サイトの内容は投資助言を目的としたものではありません。FX取引にはリスクが伴い、投資元本を失う可能性があります。投資判断はご自身の責任でお願いいたします。