Pine Scriptのコードで、
matrix.newやmap.newという、
見慣れない関数を見たことはありませんか。
MQLには2次元配列こそありますが、
キーで値を管理する仕組みは標準にありません。
既刊のarray.*解説記事では、
1次元の並びだけを扱いました。
この記事では、その先にあるmatrixとmapを、
MQLの2次元配列・パラレル配列との対比で解説します。
・matrix.new/map.newの基本的な書式
・MQLの2次元配列との対応関係
・mapに言語標準で対応するMQL機能はない点
・パラレル配列をmapで置き換える実装例
設計思想: MQLに無い2つのデータ構造
まず、matrixとmapがそれぞれ何を解決する、
構造なのかを整理します。
既刊array記事との違い
既刊のarray.*解説記事で扱った構造は、
1次元の並びしか持てませんでした。
| 構造 | 次元・管理方法 | MQLの対応 |
|---|---|---|
| array(既刊) | 1次元・インデックス | 1次元配列 |
| matrix(本記事) | 2次元・行と列 | 2次元配列 |
| map(本記事) | 1次元・キー | 標準の対応なし |
matrixは行と列を持つ表形式、mapはキーで、
値を探す仕組みという違いがあります。
MQLでの代替手段
・MQLは2次元配列(例: double arr[10][20])を書ける
・キーで探す仕組みは言語標準にはない
・名前配列+値配列のパラレル配列で代用するのが一般的
・既刊の通貨強弱メーター記事もこの方式
既刊の通貨強弱メーターも、通貨名の配列と、
スコアの配列を同じ添字でセットにして管理していました。
matrix.newの書式と主な関数
公式ドキュメント(Pine Script Docs: Matrices)の内容を整理します。
作成の書式
m = matrix.new<float>(2, 2, 0.0)
行数・列数・初期値の3つを渡すだけで、全要素が同じ値の行列が作られます。
行・列を操作する関数
・matrix.get(row, col)で値を取得
・matrix.set(row, col, value)で値を設定
・matrix.rows()/matrix.columns()で行数・列数を取得
・matrix.add_row()/matrix.add_col()で行・列を追加
MQLの2次元配列はArrayResizeでサイズを変えますが、
matrixは行・列を個別に増減できる点が異なります。
map.newの書式と主な関数
公式ドキュメント(Pine Script Docs: Maps)の内容を整理します。
作成の書式
m = map.new<string, float>()
キーの型とバリューの型を、テンプレートで指定して作ります。
キーで管理するmapとインデックスで管理する配列
| 操作 | map | MQLのパラレル配列 |
|---|---|---|
| 追加・更新 | map.put(key, value) | 名前を探して添字特定後に代入 |
| 取得 | map.get(key) | 名前を探して添字特定後に参照 |
| 存在確認 | map.contains(key) | ループで名前を探す |
mapはキーそのものを渡すだけで、値の取得・更新ができます。
パラレル配列のように、自分で添字を探す手間がありません。
サンプルコード: 通貨強弱スコアをmapとmatrixで管理
既刊currency-strength-meter-indicator-mt4.mdの、
パラレル配列を、map/matrixで書き換える例です。
mapで通貨ごとのスコアを管理する
//@version=6
indicator("Currency Strength Map Sample", overlay = false)
pairs = array.from("EURUSD", "GBPUSD", "USDJPY", "AUDUSD")
var map<string, float> strengthMap = map.new<string, float>()
if barstate.islast
for p in pairs
chgPct = (request.security(p, timeframe.period, close) -
request.security(p, timeframe.period, close[20])) /
request.security(p, timeframe.period, close[20]) * 100
map.put(strengthMap, p, chgPct)
if map.contains(strengthMap, "EURUSD")
eurusdScore = map.get(strengthMap, "EURUSD")
label.new(bar_index, 0, text = "EURUSD: " + str.tostring(eurusdScore))
既刊の実装では、通貨名配列の何番目かを、
ループで探していましたが、map.get(“EURUSD”)の、
ようにキーで直接取り出せます。
matrixで複数ペアのATRも並べて記録する
通貨ごとのスコアだけでなく、
複数ペアのATR(値幅)も1枚の表として、
まとめておきたい場合はmatrixが向いています。
var matrix<float> atrMatrix = matrix.new<float>(1, 4, 0.0)
for i = 0 to array.size(pairs) - 1
atrVal = request.security(array.get(pairs, i), timeframe.period, ta.atr(14))
matrix.set(atrMatrix, 0, i, atrVal)
行をペアの種類、
列を通貨ペアの番号として使えば、
複数の指標をまとめて1つの表で管理できます。
既刊currency-strength-meter-indicator-mt4.mdでは、
複数の指標を扱う場合も配列を増やすしかありませんでしたが、
matrixなら1つの変数で表全体を持てます。
TradingViewでの貼り付け・実行手順
実際にTradingViewで動かすまでの手順です。
- TradingViewのチャート画面下部にある「Pineエディタ」タブを開く
- 新規スクリプトを作成し、上のコードを貼り付ける
- 「保存」してから「チャートに追加」をクリックする
- ラベルにEURUSDのスコアが表示されることを確認する
よくあるエラーと注意点
実装でつまずきやすいポイントをまとめます。
var宣言を忘れると毎バー再生成される
・var無しでmap.new/matrix.newを呼ぶと毎バー空になる
・既刊var/varipの記事と同じ考え方
・保持したいならvarで最初のバーだけ宣言する
MQLには2次元配列はあるがmap相当は無い
本記事の冒頭で触れたとおり、MQLの言語標準には、
mapに相当する機能がありません。
MQL5の標準ライブラリにはCHashMap等のクラスがあり、
近い機能を使えますが、言語組み込みの型ではありません。
既刊array記事との使い分け
似た目的の記事が複数あるため、使い分けを整理します。
| 記事 | データ構造 | 向いている用途 |
|---|---|---|
| array記事(既刊) | 1次元配列 | 単純な値の並び |
| matrix(本記事) | 2次元配列 | 表形式のデータ |
| map(本記事) | キー・バリュー | 名前で管理したい値 |
よくある質問
matrix/mapについて、よくある疑問に回答します。
配列とmap、どちらを使うべきですか?
順番に意味があるならarray、名前(キー)で、
値を探したいならmapが向いています。
mapのキーの順序は保証されますか?
map.keys()/map.values()は、挿入した順序に基づく配列を返しますが、
mapそのものは順序のないコレクションです。
matrixやmapはstrategy()でも使えますか?
使えます。indicator()と同じ書式で、
strategy()で宣言したスクリプトでも使えます。
【Pine Script入門】matrix.new/map.new(v5新機能)をMQLユーザー向けに解説してみた(2次元配列・連想配列との比較):まとめ
Pine Scriptのmatrix.newは、既刊array記事の、
1次元配列を2次元に広げたデータ構造です。
map.newは、MQLの言語標準には無い、
キー・バリューで値を管理する仕組みです。
既刊の通貨強弱メーター記事のような、
パラレル配列は、mapに置き換えると、
添字を探す手間なく名前で値を扱えます。
コメント