既刊mtf-ma.mdの記事では、MQL4のiMA()に、
PERIOD_H4のような時間軸を渡すだけで、
上位足の移動平均線を取得できることを解説しました。
この記事では、Pine Scriptで同じことをするとどう違うのかを、
対比しながら解説します。
・既刊iMA()のtimeframe引数のおさらい
・request.security()のシグネチャと役割
・gaps/lookaheadというMQL4には無い2つの引数
・close[1]でリペイントを避ける実務上の定石
既刊iMA等のタイムフレーム引数とrequest.securityのおさらい
まず、MQL4側とPine Script側、それぞれの前提を振り返ります。
MQL4のiMA()はtimeframe引数で直接MTFを取得できる
double h4Ma = iMA(NULL, PERIOD_H4, 20, 0, MODE_SMA, PRICE_CLOSE, 0);
第2引数にPERIOD_H4を渡すだけで、今見ているチャートの時間軸とは関係なく、
H4の移動平均線を取得できます。
Pine Scriptのta.*関数はチャート自身の時間軸しか見ない
ma = ta.sma(close, 20)
このコードは、今チャートに表示している時間軸のcloseだけを使って計算します。
時間軸を切り替える引数は、ta.sma()自体には存在しません。
request.security()のシグネチャ
request.security(symbol, timeframe, expression, gaps, lookahead, ignore_invalid_symbol, currency, calc_bars_count) → series
計算したい式そのもの(expression)を、
別の銘柄・別の時間軸のコンテキストで評価し直すための関数です。
なぜMQLは関数の引数で済み、Pine Scriptは別関数で包む必要があるのか
同じ「別の時間軸のデータを見る」という目的でも、仕組みが異なります。
MQL4: 1回の呼び出しで完結する設計
iMA()・iRSI()・iCustom()など、
MQL4のテクニカル指標関数はほぼ全てtimeframe引数を持っているため、
関数を呼ぶたびに時間軸を指定するだけで済みます。
Pine Script: スクリプト全体のコンテキストを切り替える設計
・PineScriptのta.*関数には時間軸を指定する引数が無い
・「別の時間軸で計算したい式」をexpressionとしてまるごと渡す
・request.security()がその式を別のコンテキストで実行し直す
「式を包む」という発想がMQL4ユーザーには無い
MQL4では「関数を呼ぶ」だけで済んでいたことが、
Pine Scriptでは「式を包んで呼び直す」という、
一段階多い手順になります。
gaps/lookaheadという、MQL4にはない2つの引数
request.security()には、
MQL4のiMA()には存在しない引数があります。
gaps: 前の値で埋めるか、naにするか
barmerge.gaps_offは、上位足のバーがまだ確定していない間、
直前に確定した値で埋め続けます。
barmerge.gaps_onは、新しい上位足バーが確定するまでnaを返します。
lookahead: 未来のデータを使うかどうか
・barmerge.lookahead_onは、形成中の上位足バーの最終値まで使ってしまう
・ヒストリカルなバックテストでは実際には知り得ない未来の情報が混ざる
・通常はbarmerge.lookahead_off(未来のデータを使わない)を指定する
初期値のまま使うとどうなるか
gaps/lookaheadを省略しても動作はしますが、
意図しない設定のまま動いてしまう警告が出ることがあるため、
v6では明示的に指定することが推奨されています。
close[1]を使う理由(リペイント対策)
実務上よく使われる、確定済みの値だけを参照する書き方です。
リアルタイムバーのcloseはまだ確定していない
上位足のリアルタイムバーの中では、closeの値はティックが来るたびに変わり続けます。
MQL4のiMAも未確定の0番目バーには同じ注意がある
MQL4でもshift=0(現在のバー)の値は確定しておらず、
EAの発注条件にそのまま使うと同じ問題が起きます。
close[1]で確定済みの値を参照する
htfClose = request.security(syminfo.tickerid, "240", close[1], barmerge.gaps_off, barmerge.lookahead_off)
closeではなくclose[1]を渡すことで、
既に確定した1本前のバーの終値だけを参照するようにします。
実際に動くPine Scriptのサンプルコード
H4の確定済み終値から求めたMA(移動平均)を、
現在のチャートに重ねて表示するサンプルです。
//@version=6
indicator("MTF MA Sample", overlay = true)
length = input.int(20, title = "期間", minval = 1)
htfClose = request.security(syminfo.tickerid, "240", close[1],
barmerge.gaps_off, barmerge.lookahead_off)
htfMa = ta.sma(htfClose, length)
plot(htfMa, title = "H4 MA", color = color.orange, linewidth = 2)
確定済みのH4終値だけを取り出し、現在のチャート上に上位足のMAとして描画する設計です。
TradingViewでの貼り付け・実行手順
実際にTradingViewで動かすまでの手順です。
- TradingViewのチャート画面下部にある「Pineエディタ」タブを開く
- 新規スクリプトを作成し、上のコードを貼り付ける
- 「保存」してから「チャートに追加」をクリックする
- 15分足などの下位足チャートに切り替え、H4のMAラインが重ねて表示されることを確認する
- チャートをH4自体に切り替えても、ラインの形が崩れないことを確認する
よくあるエラーと注意点
実装でつまずきやすいポイントをまとめます。
第3引数(expression)に複雑な式をそのまま書けない場合がある
一部の関数は、expressionの中に直接書くとエラーになることがあるため、
先に変数へ計算結果を入れてから渡す書き方が安全です。
ループの中でrequest.security()を呼ぶ(v6で可能になった)
・v5以前はfor文の中でrequest.security()を直接呼べなかった
・v6からはループ内での呼び出しに対応している
・複数の時間軸をまとめて取得するコードが書きやすくなった
無料プランのリクエスト数制限
同じスクリプト内でrequest.security()を呼べる回数には、
プランごとに上限があるため、多用しすぎると制限に達することがあります。
よくある質問
request.securityについて、よく検索される疑問に回答します。
・リアルタイムの値が必要な場合を除き、closeではなくclose[1]を渡す
・gaps/lookaheadは省略せず、意図を込めて明示的に指定する
・既刊iMA()のtimeframe引数と同じ考え方で使える
timeframeには”240″のような文字列を渡すのですか?
はい。
分を表す数値の文字列(“240″でH4相当)のほか、
“D”(日足)・”W”(週足)のような文字列も使えます。
MQL5にもiMA()のtimeframe引数と同じ仕組みはありますか?
あります。
MQL5のiMA()もENUM_TIMEFRAMES型の引数を渡せますが、
値を取得するにはCopyBuffer()と組み合わせる手順が追加で必要です。
request.security()を使うとバックテストの結果が実運用とズレることはありますか?
lookaheadをlookahead_onにしたまま、
または未確定のcloseをそのまま使った場合、
バックテストの結果が実運用より良く見えることがあります。
close[1]とlookahead_offを使うことで、このズレを避けられます。
【Pine Script入門】request.securityの使い方をMQLユーザー向けに解説してみた(iMA等のタイムフレーム引数との比較):まとめ
Pine Scriptのrequest.security()は、
MQL4のiMA()等が引数1つで済ませていた「別の時間軸を見る」
という処理を、式を包んで別のコンテキストで評価し直す、という発想で実現しています。
gaps/lookaheadという2つの引数、
そしてclose[1]でリペイントを避ける定石は、
MQL4のタイムフレーム引数には無い、Pine Script側で意識すべき設計です。
コメント