既刊のcci-signal-arrow-indicator.md等では、

矢印を出さないバーの値を、SetIndexEmptyValue()で指定した、

EMPTY_VALUEという数値で表してきました。

この記事では、Pine Scriptが同じ「値が無い状態」をどう表すか、

MQL4との違いを対比しながら解説します。

この記事で分かること
・既刊EMPTY_VALUE/SetIndexEmptyValue()のおさらい
・naという言語レベルの特別な値
・nz()で欠損値を置き換える方法
・v6でbool型がnaを持てなくなった変更点

既刊EMPTY_VALUEとPine Scriptのnaのおさらい

まず、MQL4側とPine Script側、それぞれの前提を振り返ります。

MQL4のEMPTY_VALUEの書式(おさらい)

SetIndexEmptyValue(0, EMPTY_VALUE);
UpArrow[i] = EMPTY_VALUE; //この位置には矢印を描かない

バッファの該当する値をEMPTY_VALUEにしておくと、そのバーには何も描画されません。

Pine Scriptのna

float lastSignal = na

naは「値が決まっていない・無い」ことを表す、

Pine Script自体が持つ特別な値です。

EMPTY_VALUEとnaの一番の違い

EMPTY_VALUEは「とても大きい、普通あり得ない数値」

という、実はただのdouble型の値です。

naは、数値そのものではなく、言語レベルで「値が無い」ことを表す専用の状態です。

なぜMQLは特定の数値、Pine Scriptは専用の値を使うのか

同じ「値が無い」という状態でも、表現方法の前提が異なります。

MQL4: 「あり得ない数値」を目印にする設計

補足
・EMPTY_VALUEの実体は非常に大きい数値(おおむね2147483647)
・チャート描画ソフト側が「この値は描画しない」と約束として扱う
・あくまで数値の一種であり、型としては普通のdoubleと同じ

Pine Script: 値そのものに「無い」状態を持たせる設計

naは数値でもbooleanでもなく、どの型の変数にも代入できる、

特別な「状態」として言語に組み込まれています。

比較演算の挙動の違い

MQL4ユーザーが驚くポイント
・EMPTY_VALUEは普通の数値なので==で比較できる
・naは==で比較しても安定した結果にならないことがある
・naかどうかの判定には専用のna()関数を使う

naを判定・置き換えるna()とnz()

naを扱うための、2つの基本的な関数です。

関数 役割 MQL4での相当処理
na(value) valueがnaかどうかをtrue/falseで返す value == EMPTY_VALUEの比較
nz(value) naならゼロに、値があればそのまま返す 自分でif文を書いて0に置き換える処理
nz(value, repl) naならreplに、値があればそのまま返す 自分でif文を書いて任意の値に置き換える処理

na()でnaかどうかを判定する

if na(ma)
    label.new(bar_index, close, "計算中")

計算対象の本数が足りずまだ値が出ていないバーを、na()で検出してラベルを出す例です。

nz()で欠損値を置き換える

safeMa = nz(ma, close)

maがnaの間はcloseの値で代用し、計算処理が途中で止まらないようにします。

MQL4で同じことをする場合

MQL4には専用の判定関数が無いため、

if(value == EMPTY_VALUE)のような比較を、

自分でコードに書く必要があります。

v6でbool型がnaを持てなくなった変更点

Pine Script v6で、na絡みの仕様に変更が入りました。

v5まではbool型の変数もnaになれた

これまでのバージョンでは、boolean型の変数にもnaを代入できていました。

v6ではbool型はtrue/falseのどちらかに固定

注意
・v6ではbool型の変数はnaを持てない
・na()/nz()/fixnan()もbool型の引数を受け付けない
・v5時代のコードをv6へ移行する際は、bool変数へのna代入を削除する必要がある

MQL4のbool型は元からnaの概念を持たない

MQL4のbool型は常にtrueかfalseのどちらかで、

「値が無い」状態自体が存在しないため、

この変更はMQL4ユーザーにとってむしろ馴染みのある挙動です。

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

計算対象の本数が足りない序盤のバーをna()で検出し、

nz()で安全に処理を続けるサンプルです。

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

length = input.int(20, title = "期間", minval = 1)

ma = ta.sma(close, length)

if na(ma)
    label.new(bar_index, close, "計算中", style = label.style_label_up, color = color.gray)

safeMa = nz(ma, close)

plot(safeMa, title = "安全化したMA", color = color.blue)

maがまだ計算できていない間はラベルで知らせ、

plot()にはnzで置き換えた安全な値を渡す設計です。

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

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

  1. TradingViewのチャート画面下部にある「Pineエディタ」タブを開く
  2. 新規スクリプトを作成し、上のコードを貼り付ける
  3. 「保存」してから「チャートに追加」をクリックする
  4. チャートの左端(表示本数が期間に満たない部分)に「計算中」ラベルが出ることを確認する
  5. それ以降のバーでは、安全化したMAの線が途切れずに表示されることを確認する

よくあるエラーと注意点

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

naのまま四則演算すると結果もnaになる

na + 1のような計算は、エラーにはならず、結果がそのままnaになります。

plot()にnaをそのまま渡すと、その点だけ描画されない

これはEMPTY_VALUEと同じ目的で使える挙動のため、

既刊の「矢印を出さないバーだけEMPTY_VALUEにする」パターンは、

naにそのまま置き換えて移植できます。

v5のコードでbool変数にnaを使っている箇所を見落とす

補足
・古いサンプルコードをv6で動かす際によく出るエラーの1つ
・bool型のna代入を、tureまたはfalseの初期値に書き換える
・数値型
・文字列型のnaはv6でも変わらず使える

よくある質問

na値とnz()について、よく検索される疑問に回答します。

実践アドバイス
・plot()で点を出したくない位置には、EMPTY_VALUEの代わりにnaを渡す
・計算結果をそのまま使う前に、na()で欠損の可能性を確認する
・boolean型のna対応コードは、v6移行時に必ず見直す

nz()はゼロ以外の値に置き換えることもできますか?

できます。

nz(value, repl)のように第2引数を指定すると、

naだった場合にreplの値で置き換えられます。

fixnan()とnz()は何が違いますか?

nz()はその場でnaを置き換えますが、

fixnan()は直近の有効な値(naでなかった最後の値)を、

naの位置まで引き継いで埋める関数です。

MQL5にもEMPTY_VALUEと同じ仕組みはありますか?

あります。

MQL5のインジケーターバッファもMQL4と同じEMPTY_VALUEの考え方を使い、

PlotIndexSetDouble()のPLOT_EMPTY_VALUEで指定します。

【Pine Script入門】na値とnz()の扱いをMQLユーザー向けに解説してみた(EMPTY_VALUEとの比較):まとめ

Pine Scriptのnaは、MQL4のEMPTY_VALUEが「あり得ない数値」

という約束で表していた、「値が無い」状態を、言語レベルの専用の値として持たせたものです。

na()での判定・nz()での置き換え、

そしてv6でbool型がnaを持てなくなった変更点は、

MQL4のEMPTY_VALUEには無い、

Pine Script側で意識すべきポイントです。

関連記事