この記事でわかること
- 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でオリジナルインジケーターを作る完全ガイドにまとめています。

