Pine Scriptのarray.new_float()や、
array.push()を見て、
「MQLのArrayResize()と同じようなものだろう」と、
思ったことはありませんか。
実は、配列そのものの仕組みが大きく違います。
既刊array-print-insert-remove-mql5.md・
mql4-array-functions.mdでは、
MQLのArrayResize/ArrayInsert/ArrayRemoveを、
解説しました。
この記事では、Pine Scriptの配列関数を、
MQLの配列操作と対比しながら解説します。
・array.new_float/push/get/setの基本
・varを付けないと毎バー配列が空に戻る理由
・自動で伸びるか、自分でArrayResizeするか
・MQLの配列操作との対応関係
array.new_float/push/get/setの基本とMQLの対応
まず、それぞれの基本的な書式を確認します。
Pine Scriptの配列関数の書式
myArray = array.new_float(0) array.push(myArray, close) firstValue = array.get(myArray, 0) array.set(myArray, 0, 1.2345)
array.new_float(0)で空の配列を作り、
push/get/setで要素を追加・取得・書き換えます。
MQLではArrayResizeとインデックス操作で代用する処理
double myArray[]; ArrayResize(myArray, 1); myArray[0] = Close[0]; double firstValue = myArray[0]; myArray[0] = 1.2345;
MQLでは、先に配列の大きさを決めてから、
添字を指定して値を代入・取得します。
最大の違い: varを付けないと毎バー配列が空に戻る
ここが、MQLユーザーが最初に戸惑うポイントです。
Pine Scriptの配列はvarを付けないと再生成される
・array.new_float()を毎バー呼ぶと、配列が空に戻る
・var宣言すれば、同じ配列を指し続けてくれる
・既刊var/varipの記事と同じ『再計算モデル』が原因
MQLの配列はグローバル変数と同じように値を保持する
MQLのグローバル配列は、
OnInit()で宣言すれば、
EA・インジケーターが動いている間、値を保持し続けます。
Pine Scriptのような「再生成」の心配はありません。
自動で伸びるか、自分でArrayResizeするか
ここが、この記事で最も伝えたいポイントです。
array.push()は自動でサイズが増える
array.push()を呼ぶたびに、
配列のサイズが自動で1つ増えます。
事前に容量を確保する必要はありません。
MQLはArrayResize()で先に容量を確保する設計
既刊mql4-array-functions.mdのArrayResize()は、
要素を増やす前に、
必ず自分でサイズを指定して呼び出す必要があります。
既刊のArrayInsert()の記事も、
内部的には同じ考え方です。
実際に動くサンプルコード: 直近N件の値を配列で保持
直近N件の終値を配列に保持し、平均を計算する設計です。
//@version=6
indicator("Array Sample", overlay = true)
lookback = input.int(20, title = "保持件数", minval = 1)
var float[] closeHistory = array.new_float(0)
array.push(closeHistory, close)
if array.size(closeHistory) > lookback
array.shift(closeHistory)
avgClose = array.avg(closeHistory)
plot(avgClose, title = "直近N件の平均(配列ベース)", color = color.blue)
array.shift()は先頭の要素を削除して返すため、
古いデータを捨てながら、常に直近N件だけを保持できます。
TradingViewでの貼り付け・実行手順
実際にTradingViewで動かすまでの手順です。
- TradingViewのチャート画面下部にある「Pineエディタ」タブを開く
- 新規スクリプトを作成し、上のコードを貼り付ける
- 「保存」してから「チャートに追加」をクリックする
- 入力欄の「保持件数」を変えて、平均線の滑らかさが変わることを確認する
- varを外して再度試し、平均線がcloseとほぼ同じ値になることも確認する
よくあるエラーと注意点
実装でつまずきやすいポイントをまとめます。
varを付け忘れて意図通り動かない
・var float[] を var なしで書くと毎バー初期化される
・array.size()が常に1のままで増えない原因になる
・既刊var/varipの記事のvarキーワードと同じ仕組み
MQL4にはArrayRemove()が存在しない
既刊のArrayRemove()の記事で解説したとおり、
これはMQL5限定の関数です。
MQL4で先頭要素を削除するには、
既刊mql4-array-functions.mdのArrayCopy()等を使い、
自分でループして詰め直す処理が必要になります。
よくある質問
array.new_float等について、よく検索される疑問に回答します。
・バーをまたいで保持したい配列には必ずvarを付ける
・容量を事前に確保する処理は基本的に不要
・先頭を捨てるだけならarray.shift()で十分
array.new_float以外の型の配列も作れますか?
作れます。
array.new_int()・array.new_bool()等、
型ごとに専用の生成関数が用意されています。
MQL5のArrayResize()には上限がありますか?
あります。
MQL5のArrayResize()はreserve_size引数で、
メモリ再確保の頻度を抑える工夫ができますが、
array.push()側にはそのような引数はなく、
内部で自動的に管理されます。
array.push()を使いすぎると重くなりませんか?
可能性はあります。
既刊mql4-array-functions.mdのArrayResize()と同様、
配列が無制限に大きくなり続ける設計は避け、
array.shift()等で古い要素を定期的に捨てる工夫が必要です。
【Pine Script入門】array.new_float/array.push/array.getをMQLユーザー向けに解説してみた(ArrayResize・ArrayInsertとの比較):まとめ
Pine Scriptのarray.new_float/push/get/setは、
MQLのArrayResize等と役割は近いものの、
varを付けないと毎バー配列が空に戻るという、
MQLには無い制約があります。
array.push()が自動でサイズを増やしてくれる点も、
MQLのArrayResize()で先に容量を確保する設計とは対照的です。
直近N件のデータを保持する処理を書くときは、
この2点を押さえておくと移植がスムーズになります。
コメント