Pine Scriptの上位時間足参照で未来参照バイアスを防ぐ方法
15分足ストラテジーへ1時間足の終値を追加すると、情報量が増えたように見えます。しかし、履歴バーへ「その時点ではまだ確定していなかった1時間足終値」を配ると、ストラテジーは未来を知った状態になります。逆に形成中の1時間足をそのまま使えば、リアルタイムで揺れ、再読込後に値が変わることがあります。本稿は複数時間足手法の収益性ではなく、`request.security()`がどの参照先コンテキストの値を、いつチャートバーへ渡すかを時系列で監査します。
この記事が役立つ方: 複数時間足インジケーターをストラテジーへ変換した人、request.securityを使うと成績が良すぎる人、再読込後に上位時間足シグナルが変わる原因をコードレベルで確認したいPine開発者
まず押さえる重要ポイント
- 上位時間足バーの最終値は、その上位時間足バーが閉じるまで下位時間足側で確定情報として利用できない。
- lookahead_onを履歴オフセットなしで上位時間足の取得に使うと、履歴バーへ未来値を漏らす危険がある。
- 確定上位時間足値の代表書き方は式へ履歴参照位置を置き、lookahead_onと組み合わせる。
- lookahead_offでもリアルタイムの未確定上位時間足値と再読込後の確定値が違う可能性を別に監査する。
- 既知の境界時刻で履歴・リアルタイム・再読込を三方向比較し、成績を見る前に上位時間足値の最初の利用可能バーを証拠化する。
1時間足の終値は、四本目の15分足が閉じるまで確定しない
確定前09:00–10:00:前の確定上位時間足値
確定後10:00以降:09:00–10:00の確定値
未来参照の危険未来情報の漏えい:完成値を09:00から見えていたように配る
複数時間足監査の核心は、値ではなく利用可能時刻
上位時間足の終値、高値、安値、インジケーター値は、その上位バーが閉じるまで確定しません。 15分チャート上の09:00時点で、09:00〜10:00の1時間足終値を使うことはできません。履歴表示が09:00から完成値を表示するなら、未来情報が過去へ漏れていないかを確認します。
複数時間足コードの確認では、銘柄、取得先時間足、式、gaps設定、lookahead設定、履歴オフセット、履歴/リアルタイム挙動を一つの取得仕様として保存します。「1時間足を使う」という説明だけでは不十分です。どの1時間足の、確定前か確定後か、下位時間足のどのバーから利用可能かを文章で答えられる必要があります。
本稿で上位時間足と呼ぶのは、参照先時間足がチャート時間足より厳密に大きい場合だけです。60分チャートから60分を取得する同一時間足、60分チャートから15分を取得する下位時間足は、この確定済み上位時間足を参照する書き方の対象外です。両方を秒数へ変換して参照先 > チャートを満たさなければ、値を使わず実行時エラーで停止します。
上位時間足バーの確定境界を下位時間足バーへ写す
15分足4本が1時間足1本に対応する単純例では、09:00〜10:00 上位時間足バーの最終値は10:00の境界で初めて確定します。それ以前のリアルタイム更新で見える高値、安値、終値は流動値です。確定値だけを使う設計なら、09:00〜10:00の間は一つ前の確定上位時間足バーを保持し、10:00以降に新しい確定値へ切り替えます。
| 状態 | 下位時間足側で見えるもの | 再読込後 | 用途 |
|---|---|---|---|
| 前の確定上位時間足 | 固定値 | 同じになりやすい | 再現性重視の基準版 |
| 形成中の上位時間足 | ティックごとに変化 | 途中値が消える | リアルタイム観察・別仕様 |
| 未来漏洩 | 完成値が過去へ早く表示 | 履歴が異常に整う | 使用不可・コード修正 |
データ改訂や取引時間帯差は別途残るため、「同じになりやすい」は完全一致保証ではありません。
上位時間足の終値が利用可能になる時刻 = 上位時間足の確定境界以後確定値の代表的な取得 = 1本前の上位時間足値(式の[1])+ lookahead_onによる整列未来情報の漏えい = 上位時間足の確定値を、確定前の履歴バーへ割り当てることチャートと上位時間足のタイムゾーン、取引時間帯、欠損バーを確認して実際の境界を決めます。| 条件 | 期待する処理 | 残す証拠 |
|---|---|---|
| 参照先=チャート | 上位時間足用関数を拒否 | 両時間足の秒数とエラー |
| 参照先<チャート | 下位時間足問題として分離 | `request.security()`の式と別のテストID |
| 非整数比・取引時間帯分断 | 単純な本数比で断定しない | 実バーの開始/終了時刻 |
| 休日・欠損バー | 想定境界を実データで再計算 | 前後のティッカーIDと時刻 |
| 形成中の上位時間足 | 確定基準版では前回値を保持 | リアルタイム更新と再読込後の値 |
「60÷15=4」だけでは市場時刻上の四本対応を証明できません。実在するバーを使って境界を再現します。
例えば通常営業日の整列した四本、短縮取引日の終端、休日明けの最初のバーを別検証例にします。各検証例で上位時間足開始、上位時間足終了、直前下位時間足、直後下位時間足を時刻付きで記録し、完成値が最初に現れるバーを目視とログの双方で照合します。欠損したはずのバーを架空に補わず、利用不能を監査結果へ残します。
lookahead_onは参照位置の有無で意味が逆転し得る
`barmerge.lookahead_on`は、それだけで安全または危険と決まる設定ではありません。上位時間足式が現在バーの`close`なら、履歴チャートで完成値を期間冒頭へ配り、未来漏洩を起こす危険があります。一方、`close[1]`のように一つ前の確定上位時間足値を取得し、lookahead_onで下位時間足へ揃える書き方は、履歴とリアルタイムで確定値を安定して受け取る代表的な方法です。
| 書き方 | 履歴 | リアルタイム | 判定 |
|---|---|---|---|
| `close` + `lookahead_on` | 未来値を早く配る危険 | 形成中の上位時間足 | 上位時間足では避ける |
| `close` + `lookahead_off` | 上位時間足末で更新 | 未確定値を返し得る | 再読込差を監査 |
| `close[1]` + `lookahead_on` | 前の確定上位時間足を揃える | 前の確定上位時間足 | 確定値基準版 |
同じ時間足や下位時間足参照では意味が異なります。上位時間足前提を検証してから書き方を選びます。
`barstate.isconfirmed`を下位時間足ストラテジーへ足すだけでは、`request.security()`の式へ混入した未来の上位時間足値を取り除けません。チャートバーの確定と、参照先バーの確定は別の状態です。
銘柄・時間足・欠損値の補完・取引時間帯も同時に固定する
取得先の銘柄がチャートと同じでも、取引時間帯、調整、通貨、ティッカー構成が違えば別系列です。`gaps_off`で前値を埋めるか、`gaps_on`で利用不能バーを`na`にするかもシグナルの時点へ影響します。上位時間足の境界だけでなく、休場、時間外取引、週末、夏時間を含む実際のバーの整列を確認します。
- 完全な`syminfo.tickerid`または明示したティッカーIDを保存する。
- チャート時間足より本当に高い時間足か実行時で拒否条件を置く。
- 式内のインジケーターの期間と履歴参照位置を保存する。
- `gaps`と`lookahead`の設定を省略せず、意図をコメントへ書く。
- 取引時間帯・タイムゾーン境界の例日時を手計算で確認する。
| 項目 | 記録値 | 不一致時の扱い |
|---|---|---|
| チャート側 | チャートのティッカーID・取引時間帯・時間足秒 | 別条件の実行を比較から外す |
| 取得先 | 取得先ティッカー・時間足秒・gaps設定 | 暗黙の既定値を明示する |
| 式 | 計算式・期間・履歴参照位置 | 参照位置変更を別版にする |
| 整列 | 先読み設定・最初の利用可能バー | 早すぎる値を未来情報の漏えいへ分類 |
| 実行時 | 履歴・リアルタイム・再読込値 | 三者差を未解決として残す |
同じ表示色や近い最終値は同一仕様の証拠ではありません。入力と時刻を一行単位で比較します。
失敗境界では、取得先の取引時間帯だけを時間外取引へ変えた検証例、gaps_onでnaが出る検証例、銘柄切替で取引所タイムゾーンが変わる検証例を用意します。シグナル数の増減を見る前に、どの系列がどのバーで利用可能になったかを比較し、暗黙の前値埋めを確定情報と取り違えていないか確認します。
前の確定上位時間足値を明示的に取得する
下のPine v6の例は、チャートより高い時間足だけを許可し、`close[1]`と`ta.ema(close, 20)[1]`を上位時間足コンテキストで評価して`lookahead_on`で下位時間足へ揃えます。交差ルールはコードの動作説明用で、エントリー手法や20期間を推奨しません。確定値を使う代償として、現在形成中の上位時間足情報より遅くなります。
//@version=6
strategy("Confirmed HTF audit demo", overlay = true)
string higherTf = input.timeframe("60", "Higher timeframe")
int chartSeconds = timeframe.in_seconds()
int higherSeconds = timeframe.in_seconds(higherTf)
if higherSeconds <= chartSeconds
runtime.error("Choose a timeframe higher than the chart timeframe")
float confirmedHtfClose = request.security(
syminfo.tickerid,
higherTf,
close[1],
lookahead = barmerge.lookahead_on
)
float confirmedHtfEma = request.security(
syminfo.tickerid,
higherTf,
ta.ema(close, 20)[1],
lookahead = barmerge.lookahead_on
)
bool longCondition = ta.crossover(confirmedHtfClose, confirmedHtfEma) and barstate.isconfirmed
bool exitCondition = ta.crossunder(confirmedHtfClose, confirmedHtfEma) and barstate.isconfirmed
if longCondition
strategy.entry("L", strategy.long)
if exitCondition
strategy.close("L")
plot(confirmedHtfClose, "Confirmed HTF close", color.teal)
plot(confirmedHtfEma, "Confirmed HTF EMA", color.orange)この書き方は上位時間足確定値向けです。取引時間帯、gaps設定、銘柄、コンパイラの現行挙動を必ず確認してください。
二つの呼び出しは同じ上位時間足バーの前回の終値と前回のEMAを返します。上位時間足の終値を下位時間足で20回並べてからEMAを計算するのではなく、EMA自体を上位時間足コンテキストで計算し、履歴参照する点を区別します。`request.*()`呼び出しの上限と実行上の制約も現行公式資料で確認します。
履歴・リアルタイム・再読込の三つを同じバーで比較する
- 既知の境界を選ぶ
上位時間足の確定前後の下位時間足バーを一組選び、時刻を保存します。
- 履歴を記録
再読込直後の上位時間足値、シグナル、注文マーカーを保存します。
- リアルタイムを観察
上位時間足の形成中に値が固定か変動かを時刻付きで記録します。
- 上位時間足の確定を確認
どの下位時間足バーから新しい確定値へ切り替わったか確認します。
- 再度再読込
同じバーの値とシグナルが残るか差分を取り、違えば原因を分類します。
さらに安全な書き方と危険書き方を同じ期間へ並べ、シグナル数、最初の利用可能バー、取引時刻を比較します。成績差ではなく、未来値がいつ過去へ現れたかを証拠化します。BT07の過剰最適化とは異なり、ここで直すのはパラメータ選択ではなくデータの利用可能時刻に関する不具合です。
| 観測点 | 確定済み版 | 危険版 | 判定 |
|---|---|---|---|
| 上位時間足の確定直前 | 前回確定値を保持 | 完成値が見えれば失敗 | 利用可能時刻 |
| 上位時間足の確定直後 | 新確定値へ切替 | 切替バーを記録 | 一バーずれを説明 |
| リアルタイム形成中 | 固定 | 流動値なら別仕様 | ティック変化を保存 |
| 再読込後 | 同じバー・同じ値 | 差分を分類 | 再現性 |
比較する二版は式の履歴参照位置と先読み設定以外を同じ設定フィンガープリントへ固定します。
再現は一度の画像で終えません。最初に履歴実行の対象バーと値をCSVへ保存し、次に同じ上位時間足が形成中のリアルタイム観察で更新時刻を記録し、確定後に再読込します。三つの表をティッカーID、版ID、タイムゾーン、取引時間帯で結びます。データ改訂、取引時間帯差、コード差を区別できない行は「同じ」と丸めず未解決のまま公開判定から外します。
公開判定用の利用可能時刻台帳には、各下位時間足バーの開始時刻・終了時刻、対応する上位時間足の開始・終了、予想した最初の利用可能時刻、実際に値が切り替わった時刻を別列で残します。値だけが同じでも、時刻が早ければ合格にしません。休日、短縮取引、時間外取引セッション、`gaps`設定が異なる実行は同じ母集団へ混ぜず、境界ごとの検証例IDを付けます。
検出確認用の対照条件も必須です。参照位置なしのlookahead_on版を意図的に並べ、監査が早すぎる完成値を本当に検出できるか確認します。危険版まで合格する台帳は検出力がないため作り直します。確定済み版は上位時間足の確定前に前回確定値を保持し、確定後の最初の対象バーでのみ更新し、再読込後も同じバーへ残ることを四条件すべて満たして初めてCSV出力へ進めます。
未来参照を除去したストラテジー結果だけを分析ラボへ送る
既知の境界時刻と再読込後の両方で未来参照が消えたことを証明してから、修正版ストラテジーテスターのCSV/XLSXをバックテスト分析ラボへ読み込みます。漏洩あり/なしの版について、成績指標、ドローダウン、ストレステスト、未使用期間、パラメータ安定性の差を追えば、未来情報が作っていた見かけの成績を切り分けられます。比較証拠を保持する段階では有料の版管理が自然です。
無料インジケーターを複数時間足の条件の観察に使う場合も、インジケーター表示はストラテジー出力ではありません。ソースコード公開範囲、参照先時間足、確定値、アラート時点を確認し、ストラテジー変換は注文と約定を含む新しい仕様として扱います。
上位時間足の確定までの待ち時間とバー比率を確認
参照先の上位時間足がチャート時間足より大きい場合だけ使います。両時間足と上位時間足開始後の経過分、式の履歴参照位置を入力し、単純化した確認時計を作ります。参照先がチャート以下なら本稿の上位時間足計算対象外です。
前提はB>Aです。比率=B÷A、待ち時間=C≤0ならB、0
よくある質問
lookahead_onは常に未来参照ですか?
常にではありません。現在の上位時間足値を参照位置なしで使うと危険ですが、前の確定上位時間足式へ履歴参照位置を置く代表書き方ではlookahead_onが整列に使われます。
lookahead_offなら必ずリペイントしませんか?
保証されません。履歴では未来漏洩を避けても、リアルタイムで未確定上位時間足値を返し、再読込後に確定値へ変わる場合があります。
barstate.isconfirmedを足せば上位時間足値も確定しますか?
チャートバーの確定と参照先バーの確定は別です。`request.security()`の式、参照位置、先読み設定を合わせて監査します。
前の確定上位時間足値を使うとシグナルが遅くなりませんか?
形成中の上位時間足値より遅くなりますが、それは確定を待つ因果的な代償です。形成中の値を使うなら、確定値基準版とは別のリアルタイム仕様として再読込差を記録してください。
根拠資料と確認先
- TradingView Pine Script | Other timeframes and datarequest.security、gaps、lookahead、上位/下位時間足の挙動に関する公式資料
- TradingView Pine Script | Repainting上位時間足取得の履歴/リアルタイム差と確定値パターン
- TradingView Pine Script FAQ | Other data and timeframestimeframe requestに関する公式FAQ
- TradingView Pine Script | Timeframestimeframe string、比較、変換の公式説明
- TradingView Pine Script | Limitationsrequest数やdata accessの現行limit
編集・発行: SG Group · 編集方針: TradingView公式ヘルプとPine Script公式文書を優先し、金融市場・商品に関する説明は取引所、監督当局、一次資料で補完しています。機能、データ、料金、接続条件は変わるため、実際の利用前に公式画面とリンク先の最新情報を確認してください。
重要事項: 本記事はTradingViewの画面、チャート、アラート、スクリーナー、ペーパートレード、Pine Script等の一般的な学習情報です。投資助言、売買シグナル、特定商品・データ提供者・ブローカーの推奨、将来価格や利益の保証ではありません。機能、料金、データ、取引所区分、通知、注文連携、Pine Scriptの仕様はプラン・地域・接続先・時点で異なり変更されることがあります。実際の資金を使う前に、TradingView公式資料、データ提供元、接続先事業者の最新条件を確認し、架空データまたはペーパートレードで手順を検証してください。

