PR

Pine Scriptでマルチタイムフレーム分析を実装する完全ガイド【request.security()徹底解説】

未分類

この記事でわかること

  • request.security()の正しい使い方と、知らないと詰まるリペイント問題の仕組み
  • 上位足のトレンドを現在のチャートに反映させる実装パターン
  • MTF RSIダッシュボード・マルチタイムフレームトレンドバイアスの完成コード

1時間足でエントリーしながら日足のトレンド方向を意識する、4時間足のRSI状態を15分足のチャート上で確認する。こういった「上位足との整合性チェック」を手作業でやっているトレーダーは多い。

Pine Scriptのrequest.security()を使えばこれを自動化できます。ただ、正しく実装しないとリペイントという厄介な問題が発生します。バックテスト結果が現実と大きくかけ離れる原因の一つです。

request.security()の基本構文

request.security(symbol, timeframe, expression, lookahead)
引数 説明
symbol string 対象銘柄(現在のチャートなら syminfo.tickerid)
timeframe string 時間足(”D”=日足、”60″=1時間足、”240″=4時間足)
expression series 取得したい値(close、ta.rsi(close,14) など)
lookahead barmerge バーの参照方法(後述)

リペイントとは何か、なぜ問題なのか

リペイント(repainting)とは、過去に表示していたシグナルや値が、後のバーが確定したタイミングで変わってしまう現象です。バックテストでは機能していたように見えるのに、実際のリアルタイム運用では機能しない原因のひとつです。

設定 動作 リペイントリスク
barmerge.lookahead_off(デフォルト) ヒストリカルでは確定済みバーを参照。リアルタイム最新バーでは未確定値を返す リアルタイムで発生する可能性あり
barmerge.lookahead_on [1]と組み合わせて使う [1]と組み合わせれば回避できる

リペイントしない実装パターン

// ❌ リペイントする
htfClose = request.security(syminfo.tickerid, "D", close)
// ✅ リペイントしない(常に確定済みの前バーの値を使う)
htfClose = request.security(syminfo.tickerid, "D", close[1], barmerge.lookahead_on)

実装例1:上位足トレンドフィルター

//@version=5
indicator("MTF Trend Filter", overlay=true)
htfTF = input.timeframe("D", "上位足の時間足", group="設定")
smaLen = input.int(200, "SMA期間", group="設定", minval=1)
htfSMA = request.security(syminfo.tickerid, htfTF, ta.sma(close, smaLen)[1], barmerge.lookahead_on)
isAbove = close > htfSMA
isBelow = close < htfSMA
plot(htfSMA, "上位足 SMA", color=color.orange, linewidth=2)
bgcolor(isAbove ? color.new(color.green, 90) : isBelow ? color.new(color.red, 90) : na, title="トレンド背景")

実装例2:MTF RSIダッシュボード

//@version=5
indicator("MTF RSI Dashboard", overlay=false)
rsiLen = input.int(14, "RSI期間", minval=1)
f_rsiColor(v) =>
    v >= 70 ? color.red : v <= 30 ? color.lime : color.white
rsi15m = request.security(syminfo.tickerid, "15", ta.rsi(close, rsiLen)[1], barmerge.lookahead_on)
rsi1h = request.security(syminfo.tickerid, "60", ta.rsi(close, rsiLen)[1], barmerge.lookahead_on)
rsi4h = request.security(syminfo.tickerid, "240", ta.rsi(close, rsiLen)[1], barmerge.lookahead_on)
rsi1d = request.security(syminfo.tickerid, "D", ta.rsi(close, rsiLen)[1], barmerge.lookahead_on)
var table t = table.new(position.top_right, 2, 5, border_color=color.gray, border_width=1, bgcolor=color.new(color.black, 70))
if barstate.islast
    table.cell(t, 0, 0, "時間足", text_color=color.silver, text_size=size.small)
    table.cell(t, 1, 0, "RSI", text_color=color.silver, text_size=size.small)
    table.cell(t, 0, 1, "15分", text_color=color.gray, text_size=size.small)
    table.cell(t, 1, 1, str.tostring(math.round(rsi15m, 1)), text_color=f_rsiColor(rsi15m), text_size=size.small)
    table.cell(t, 0, 2, "1時間", text_color=color.gray, text_size=size.small)
    table.cell(t, 1, 2, str.tostring(math.round(rsi1h, 1)), text_color=f_rsiColor(rsi1h), text_size=size.small)
    table.cell(t, 0, 3, "4時間", text_color=color.gray, text_size=size.small)
    table.cell(t, 1, 3, str.tostring(math.round(rsi4h, 1)), text_color=f_rsiColor(rsi4h), text_size=size.small)
    table.cell(t, 0, 4, "日足", text_color=color.gray, text_size=size.small)
    table.cell(t, 1, 4, str.tostring(math.round(rsi1d, 1)), text_color=f_rsiColor(rsi1d), text_size=size.small)

実装例3:マルチタイムフレームトレンドバイアス

//@version=5
indicator("MTF Trend Bias", overlay=true)
smaLen = input.int(50, "SMA期間", minval=1)
f_bias(tf) =>
    smaVal = ta.sma(close, smaLen)
    isBull = close > smaVal
    request.security(syminfo.tickerid, tf, isBull[1], barmerge.lookahead_on)
bull1h = f_bias("60")
bull4h = f_bias("240")
bull1d = f_bias("D")
var table t = table.new(position.top_left, 2, 4, border_color=color.gray, border_width=1, bgcolor=color.new(color.black, 70))
if barstate.islast
    table.cell(t, 0, 0, "時間足", text_color=color.silver, text_size=size.small)
    table.cell(t, 1, 0, "バイアス", text_color=color.silver, text_size=size.small)
    table.cell(t, 0, 1, "1H", text_color=color.gray, text_size=size.small)
    table.cell(t, 1, 1, bull1h ? "▲ 強気" : "▼ 弱気", text_color=bull1h ? color.lime : color.red, text_size=size.small)
    table.cell(t, 0, 2, "4H", text_color=color.gray, text_size=size.small)
    table.cell(t, 1, 2, bull4h ? "▲ 強気" : "▼ 弱気", text_color=bull4h ? color.lime : color.red, text_size=size.small)
    table.cell(t, 0, 3, "1D", text_color=color.gray, text_size=size.small)
    table.cell(t, 1, 3, bull1d ? "▲ 強気" : "▼ 弱気", text_color=bull1d ? color.lime : color.red, text_size=size.small)

よくあるエラーと対処

エラー 原因 Claudeへの指示
Cannot use ‘request.security’ in local scope of ‘if’ if/forブロック内に書いた 「グローバルスコープに移動して」
シグナルが過去に遡って変わる lookahead_on なしで未確定バーを参照 「全request.security()に[1]とbarmerge.lookahead_onを設定して」
チャートが重くなる 呼び出しが多すぎる(上限40回) 「タプルにまとめて1回の呼び出しに統合して」

まとめ

MTF実装で押さえるべき点は2つです。[1] + barmerge.lookahead_onのリペイント防止パターンと、barstate.islastでの描画絞り込みによるパフォーマンス管理。Claudeへのプロンプトにこの2点を明示するだけで品質が上がります。

SMC分析との組み合わせはPine Script v5でSMCを自動化するも参考にしてください。Pine Scriptの基礎はClaude Code × TradingViewでオリジナルインジケーターを作る完全ガイドにまとめています。

タイトルとURLをコピーしました