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で動かすまでの手順です。

  1. TradingViewのチャート画面下部にある「Pineエディタ」タブを開く
  2. 新規スクリプトを作成し、上のコードを貼り付ける
  3. 「保存」してから「チャートに追加」をクリックする
  4. ラベルに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に置き換えると、

添字を探す手間なく名前で値を扱えます。

関連記事