コンパイル時の典型的エラーと対処法

Pineスクリプトのコンパイル時に発生する典型的なエラーとして下記が挙げられる。この記事では、それぞれのエラーの原因と対処法をサンプルコードを付けてまとめた。

  • Undeclared identifier
  • Value with NA type cannot be assigned to a variable that was defined without type keyword
  • Variable 'x' was declared with 'series[integer]' type. Cannot assign it expression of type 'series[float]'
  • Cannot call 'operator +' with arguments (series[bool], series[bool])

エラー:Undeclared identifier

このエラーが出る典型的な原因として、下記の変数が関係している可能性がある。
  1. self-referenced(自己参照)変数
  2. forward-referenced(前方参照)変数
1. self-referenced(自己参照)変数による Undeclared identifier エラー
下記は self-referenced(自己参照)変数を使ったコードの例。

//@version=4
study("self-referenced variable")

// elapsedは自己参照変数
elapsed = nz(elapsed[1]) + 1

plot(elapsed)

変数 elapsed は、宣言時に自己 elapsed[1] を参照している。このような変数を self-referenced(自己参照)変数という。

自己参照変数はPineスクリプトv2まではサポートされていたが、v3以降では、自己参照変数があるコードは Undeclared identifier というエラーメッセージが出るようになった。v3以降では、下記のように書き直す必要がある。


//@version=4
study("self-referenced variable")

// 変数の初期化を追加
// 整数0で初期化することで、elapsedは整数型であることがPineコンパイラに伝わる
elapsed = 0

// = を := に変更する (elapsedはmutable変数となる)
elapsed := nz(elapsed[1]) + 1

plot(elapsed)

なお、書き直すと、elapsed は自己参照変数ではなくなり、mutable(変更可能な)変数としてPineコンパイラに認識されるようになる。

参考:Self-referenced variables are removed

2. forward-referenced(前方参照)変数による Undeclared identifier エラー

次に、下記は forward-referenced(前方参照)変数を使ったコードの例。変数 s は前方参照変数と呼ばれる。
※変数 s が実際に定義されるのは3行後、その定義前に変数sが参照されるため、「前方参照」変数と呼ばれる


//@version=2
study("forward-referenced variable", overlay=true)

s1 = nz(s[1]) // 変数sは前方参照変数
a = 0.2
s1_w = s1 * (1 - a)
s = close * a + s1_w // 変数sが定義されるのはここ

plot(s)

Pineスクリプトv2でサポートしていた forward-referenced(前方参照)変数は、v3以降サポートされなくなった。そのため、前方参照変数を含むコードをv3以降でコンパイルすると Undeclared identifier エラーが出る。

前方参照変数を含むコードは下記のように修正できる。参照前に変数の宣言を新たに追加し、実際に定義していた箇所の = 演算子を := 演算子に置き換えて mutable 変数に変更する。


//@version=4
study("forward-referenced variable", overlay=true)

s = 0.0 // 参照が行われる前に宣言を新たに追加
s1 = nz(s[1])
a = 0.2
s1_w = s1 * (1 - a)
//s = close * a + s1_w
s := close * a + s1_w // =演算子を:=演算子に変更

plot(s)

参考:Forward-referenced variables are removed


エラー:Value with NA type cannot be assigned to a variable that was defined without type keyword

変数を na で初期化している場合、その変数が原因でこのエラーが出る。

Pineスクリプトv2やv3では、変数を na で初期化しても問題なかったが、v4以降ではコンパイルエラーが出るようになった。


//@version=4
study("init with na", overlay=true)

crossed_line = na // v4以降ではコンパイルエラー

crossed_line := crossed_line[1]

ma = sma(close, 200)

if crossover(close, ma)
    crossed_line := close
if crossunder(close, ma)
    crossed_line := na

plot(crossed_line, style=plot.style_cross, linewidth=2)

上記のコードはv4以降、Value with NA type cannot be assigned to a variable that was defined without type keyword というコンパイルエラーが出る。
※エラーを日本語に訳すと「型キーワードを指定せずに定義された変数にNA型の値を割り当てることはできません」

このエラーへの対処法は、変数を na で初期化したいときは、型キーワードを指定すれば良い。上記コードの例の場合、float 型の close 値を代入する箇所があるので、それに合わせて変数に float 型を指定すれば良い。


//@version=4
study("init with na", overlay=true)

crossed_line = float(na)  // float型を指定してnaを割り当て
//float crossed_line = na // この書き方でも良い

crossed_line := crossed_line[1]

ma = sma(close, 200)

if crossover(close, ma)
    crossed_line := close
if crossunder(close, ma)
    crossed_line := na

plot(crossed_line, style=plot.style_cross, linewidth=2)

参考:na value


エラー:Variable 'x' was declared with 'series[integer]' type. Cannot assign it expression of type 'series[float]'

このエラーが出る典型的な例として、float 型の変数を 0 で初期化している場合が考えられる。

Pineスクリプトv2では、float 型の変数を 0(整数)で初期化しても問題なかったが、v3以降ではコンパイルエラーが発生するようになった。下記はこのようなエラーが発生するコードの例。


//@version=4
study("init with zero")

cost = 0 // v3以降ではエラーになる
cost := nz(cost[1])

if crossover(close[1], sma(close[1], 200))
    cost := open

plot(cost)

上記のコードは、v3では Variable `cost` was declared with series[integer] type. Cannot assign it expression of type series、v4では Variable 'cost' was declared with 'series[integer]' type. Cannot assign it expression of type 'series[float]'. というエラーメッセージが出る。
※エラーメッセージを日本語に訳すと「series[integer] 型(integer 型の一次元データ)で宣言された変数に、series[float] 型(float 型の一次元データ)を割り当てることはできません」

このコンパイルエラーへの対処法は、float 型の値で更新される変数に対して、明示的に 0.0float 型のゼロ)で初期化する必要がある。


//@version=4
study("init with zero")

cost = 0.0 // float型のゼロで初期化
cost := nz(cost[1])

if crossover(close[1], sma(close[1], 200))
    cost := open

plot(cost)

エラー:Cannot call 'operator +' with arguments (series[bool], series[bool])

論理値に対して明示的な型変換をせずに数値演算を行うとこのエラーが出る。

Pineスクリプトv2では、論理値から数値への暗黙的な型変換が行われ、論理値に対して数値演算を行うことができたが、v3以降では、暗黙的な型変換による論理値の数値演算はサポートされなくなり、このようなコードはエラーが出るようになった。
※v2では true1.0false0.0 へ暗黙的に変換される


//@version=2
study("bool to num", overlay=true)

b1 = close > open
b2 = close > close[1]

x = b1 + b2 // 暗黙的な型変換が行われ、v2ではエラーにならない

plotchar(x == 1, char='/', size=size.tiny)
plotchar(x == 2, char='|', size=size.tiny)

v3以降でこのエラーを回避するには、論理値を明示的に数値へ変換する関数を用意すれば良い。下記の修正版コードでは、関数 b_to_n を定義し、この関数を介して、論理値は整数に変換されるように修正している。


//@version=4
study("bool to num", overlay=true)

b_to_n(b) =>
    b ? 1 : 0

b1 = close > open
b2 = close > close[1]

//x = b1 + b2
x = b_to_n(b1) + b_to_n(b2) // 関数 b_to_n() が論理値を整数へ変換

plotchar(x == 1, char='/', size=size.tiny)
plotchar(x == 2, char='|', size=size.tiny)

参考:Math operations with booleans are forbidden