Pine Scriptのサンプルコードでvarやvaripという、

見慣れないキーワードを見かけて戸惑ったことはありませんか。

既刊のstatic変数についての記事では、

MQLのstatic変数が関数呼び出しをまたいで、

値を保持する仕組みを解説しました。

この記事では、Pine Scriptのvar/varipキーワードを、

MQLのstatic変数と対比しながら解説します。

この記事で分かること
・var/varipの基本とstatic変数との対応
・専用キーワードが必要な理由(再計算モデルの違い)
・varとvaripの違い(ロールバックの有無)
・varipに依存するロジックの実務上の限界

var/varipの基本とMQLのstatic変数との対応

まず、それぞれの基本的な書式を確認します。

Pine Scriptのvarキーワードの書式

var count = 0
count := count + 1

varを付けた変数は、最初のバーで1回だけ初期化され、

以降のバーでも値を保持し続けます。

MQLのstatic変数の書式(既刊記事のおさらい)

static int count = 0;
count++;

MQLのstatic変数も、関数が呼ばれるたびに初期化されず、

前回の値を保持し続ける点はvarと似ています。

専用キーワードが必要な理由(再計算モデルの違い)

書式は似ていても、背景にある実行モデルは大きく異なります。

Pine Scriptはバーごとにスクリプト全体を再計算する

MQLユーザーが驚くポイント
・Pine Scriptはチャートを開くたびに全履歴バーを先頭から再計算する
・何もキーワードを付けない変数は毎バーで初期化され直す
・「前のバーの値を覚えている」ようにしたい変数だけvarが必要

MQLは1本のバーを1回だけ順番に処理する

MQLのEA/インジケーターは、OnTick()が呼ばれるたびに、

その時点の最新バーを1回だけ処理する設計です。

過去のバーをまとめて再計算し直すという動作が、

そもそも存在しないため、static変数に相当するキーワードは、

「値を保持したい」場合にだけ使えば済みます。

varとvaripの違い(ロールバックの有無)

ここが、MQLのstatic変数には無い概念です。

ヒストリカルバーでは両方とも同じ挙動

確定済みの過去バーを計算している間は、

varとvaripに挙動の違いはありません。

リアルタイムバーでvarはロールバックする

var lastTick = 0.0
lastTick := close
補足
・形成中の最新バーは、値が動くたびに再計算される
・varの値は、その都度バー開始時点の値に巻き戻されてから計算し直される
・これを「ロールバック」と呼ぶ

varipはロールバックせず、tickをまたいで持続する

varip tickCount = 0
tickCount := tickCount + 1

varipを付けた変数は、同じバー内の複数回のtick更新を、

まるごと数え続けることができます。

実際に動くサンプルコード

新しいバーが確定した回数をvarで数え、

そのバー内のtick更新回数をvaripで数えるサンプルです。

//@version=6
indicator("Var Varip Sample", overlay = true)

var int barCount = 0
varip int tickCount = 0

if barstate.isconfirmed
    barCount := barCount + 1

tickCount := tickCount + 1

if barstate.islast
    label.new(bar_index, high, "確定バー数: " + str.tostring(barCount) + "\n直近tick数: " + str.tostring(tickCount), style = label.style_label_down)

barstate.isconfirmedは、

既刊のバー確定判定についての記事で解説した組込み変数です。

TradingViewでの貼り付け・実行手順

実際にTradingViewで動かすまでの手順です。

  1. TradingViewのチャート画面下部にある「Pineエディタ」タブを開く
  2. 新規スクリプトを作成し、上のコードを貼り付ける
  3. 「保存」してから「チャートに追加」をクリックする
  4. チャート右端にラベルが表示され、確定バー数とtick数が別々に増えることを確認する
  5. リアルタイムのティックが動くたびにtick数だけが増えることにも注目する

よくあるエラーと注意点

実装でつまずきやすいポイントをまとめます。

varを付けずに書いた変数は毎バー0に戻る

カウンターのつもりで書いた変数にvarを付け忘れると、

毎バーで値が初期化され、カウントが機能しません。

varipに依存したロジックはバックテストで再現できない

注意
・varipの挙動はリアルタイムバーでしか意味を持たない
・過去バーのtick単位の動きは記録が残っておらず再現不可能
・strategy.*と組み合わせたバックテストの結果は意味を持たない

MQLのstatic変数にロールバックという概念は無い

MQLは1本のバーを1回だけ処理するため、

「同じバーをもう一度計算し直す」という場面自体が存在せず、

ロールバックを意識する必要がありません。

Pine ScriptのPineエディタ側から見ると、

この違いは「ヒストリカルバー」と「リアルタイムバー」という、

2つのモードを常に意識させられる設計だといえます。

よくある質問

var/varipについて、よく検索される疑問に回答します。

実践アドバイス
・値を保持したいだけならvarで十分
・varipが必要なのはtick単位の集計等、限られた用途だけ
・varipを使ったロジックは、必ずリアルタイムの
動作確認を別途行う

varを付けなくても動く変数とはどう違いますか?

varを付けない変数は、毎バーの計算が始まるたびに、

宣言した行で再び初期化されます。

値を前のバーから引き継ぎたい場合にだけvarが必要です。

varipはなぜ存在するのですか?

板の動きのように、同じバー内で何度も更新される値を、

リアルタイムで集計したい場合に使います。

通常のvarではバー形成中にロールバックされてしまい、

このような集計ができません。

MQL5のstatic変数はtick単位の集計に使えますか?

使えます。

MQL5のOnTick()はtickが来るたびに呼ばれるため、

static変数はPine Scriptのvaripに近い使われ方もできます。

ただしMQLにはロールバックという概念が無いため、

挙動を気にせず単純にカウントできる点が異なります。

【Pine Script入門】var/varipキーワードをMQLユーザー向けに解説してみた(static変数との比較):まとめ

Pine Scriptのvar/varipは、

MQLのstatic変数と「値を保持する」という役割は同じですが、

背景にPine Script特有の再計算モデルがある点が異なります。

特にvaripに依存したロジックがバックテストで再現できないという限界は、

MQLのストラテジーテスターの感覚のまま移植すると、

誤解しやすいポイントとして覚えておいてください。

関連記事