配列を使いこなす|MQL入門(6回目)

2018年11月10日

大量の箱

今回は「配列」について学んでいきます。

配列はプログラムをやっていないと聞きなれない言葉だと思いますので、用語の説明から使い方までを説明していきます。

第5回目までを確認いただいている前提で進めますので、まだ見ていない方は先にご確認いただければと思います。

初心者でも分かる!MT4/MT5のプログラミング入門|MQL入門(1回目)

MT4/MT5のコメントと変数について|MQL入門(2回目)

MT4/MT5で数値の計算をしてみる|MQL入門(3回目)

条件分岐をマスターする|MQL入門(4回目)

ループ処理をマスターする|MQL入門(5回目)

配列とは何か?

同じデータ型をメモリ上に連続で確保したものです。

もう少し簡単に言うと、いくつかの箱を1つとして管理するようなイメージです。

例えばint型の配列array[5]というものがあった場合、以下のように5つの箱がひとまとまりに用意されています。

一次元配列のイメージ

そして、この箱に値を入れたり出したりする場合に、[0]~[4]という添え字でアクセスすることができます。

array[0] = 94;
array[1] = 42;
array[2] = 5;
array[3] = 125;
array[4] = 999;

このように「1行:複数列」のデータの塊を一次元配列といいます。

オセロやチェスを表現する時のように、「複数行:複数列」の塊は二次元配列といいます。

チェスの盤面

 

この時点で意味がよく分からなくても、プログラムを実際に書いて動かせば理解できますので、焦らずに1つ1つ学んでいきましょう。

(3次元以上の配列を作ることもできますが、使用頻度が低いのでここでは説明しません。)

 

どういう時に使われるのか?

例えば、FXの日ごとの価格、ユーザー一覧、オセロゲーム等々、配列はいたるところで利用されています。

 

プログラムを書く

プログラムの準備

MetaEditorを開いて新しいプログラムを作成しましょう。

私は「Practice006.mq4/mq5」としていますが、好きな名称を付けていただいて大丈夫です。

 

一次元配列

基本的な使い方

最初の図を再現したものをプログラムにしましたので、プログラムを書き換えて実行しましょう。

配列の添え字は[0]から始まりますので、ご注意ください。

0番目というのは最初は違和感があるかもしれませんが、プログラムを学んでいくとあまり気にならなくなるので、そういうものだと思っておきましょう。

int arr[] = { };で、arrという名前の配列に5つの数値を入れています。

0番目、2番目、4番目をprintfで出力したので、以下の結果になりました。

配列の表示確認

 

配列の範囲外を指定する

試しに「printf(“%d”, arr[5]);」を追加して実行してください。

配列の5番目は存在しないので、存在しないものを指定した場合の動作を確認します。

配列の範囲外を指定した場合の確認

out of range(範囲外)を示すエラーが出力されました。

さらに一番上の行を見ていただくと、removedの文字があります。

「致命的なエラーが発生したのでMT4のチャート上に適用されたプログラムを削除した。」という意味です。

チャート上から削除されただけなので、プログラム自体は消えていません。

先ほどの1行を消した状態でコンパイルして、もう一度チャートに適用しておきましょう。

 

※MT5では厳密なチェックにより、コンパイル自体が通らないのでプログラムを実行することができません。

MT5の方が安全な設計になっているということです。

 

サイズだけ宣言して後から中身を追加

最初にサイズが[3]の配列を作って、後から中身を追加したパターンです。

せっかくなのでstring型の配列にしました。

結果を確認すると、追加した配列の中身が表示されました。

配列の中身を後から追加する

 

配列のサイズを確認する

ArraySize()を使用することで配列のサイズを確認することができます。

サイズを5として配列を作成して、サイズを確認してみましょう。

想定通りのサイズであることが確認できました。

サイズの確認

 

ループで配列の中身を取り出す

実戦では、配列の中身が3個というようなケースは稀で、1000個以上であることが多いです。

1000を超えるサイズの配列に対して、1個1個中身を取り出して条件を判定していくようなことがよくあります。

その時に先ほどの取り出し方では、arr[0]、arr[1]…..arr[1000]となってしまい、とんでもなく長いプログラムになってしまいます。

ループ処理を利用すれば、以下のようなプログラムを書くことができます。

最初の塊はサイズが1000の配列の中身を自分で準備しているもので、後ろの塊が出力している部分です。

また、forのループ条件を「i < ArraySize(arr)」とすることで、配列のサイズを変更することになっても即対応できるようになっています。

配列をforで出力

 

二次元配列

基本的な使い方

基本的な使い方は一次元配列と同じです。

異なる部分は「一次元配列が1行限定で扱う」のに対して、「二次元配列は複数行扱う」点です。

2行4列の二次元配列を見てみましょう。

 

#define ROW 2とは新しく#defineが出てきましたので説明します。

#defineとは定数という意味で、固定したい値を使うときに用います。

行方向のサイズを定数ROWという名前にして2を設定しました。

列方向のサイズを定数COLUMNという名前にして4を設定しました。
配列の初期サイズを定義する場合などに使われることがあります。

 

結果を確認してみましょう。

define設定での確認

 

配列のサイズを確認する

一次元配列の時と同様にサイズを確認してみましょう。

結果は8となりました。

配列サイズ確認

実は、この8は全く使い物にならない数字です。

ArraySize(2次元配列)では行と列の合計サイズが取れてしまうので注意が必要です。

「合計サイズでは何が困るのか?」と考えられると思いますが、ループ処理で値を取り出すことができなくなってしまうのです。

値を取り出すときは「2行4列」という情報が必要であって、合計値の8は意味を成しません。

次で詳しく見ていきます。

 

ループで取り出す場合

試しに一次元配列と同じ方法で値を取り出してみます。

結果、コンパイルエラーになります。

‘arr’ – invalid array access Practice006.mq4 23 39

このエラーは、二次元配列を一次元配列のように扱おうとしたため、発生しています。

 

そこで、少し面倒なのですがforを2重にして値を取り出します。

以下のプログラムで二次元配列内のすべての値を取り出すことができました。

 

2重ループ時の配列の処理順は以下のようになっています。

2重ループのイメージ

 

慣れるまでは混乱することもあると思いますが、プログラムを変更して何度も試すうちに理解できます。

例えば九九の結果を格納して、段ごとに表示するようなプログラムを書いてみます。

九九の表示結果

本筋からずれるようなことでも、少しの遊び心を持って試してみるのが大事です。

 

実戦ではどのように使われるか

MT4では重要な値を最初から一次元配列に格納してくれています。(MT5で同じ書き方をするには共通ライブラリが必要)

取り出す処理のみ書けばいいのでとても簡単です。

例えばローソク足の4本値(始値、終値、高値、安値)ですが、以下のように取り出すことが可能です。

結果を確認すると、MT4/MT5上の1本前のローソク足の値と一致していることが分かります。

ローソク足の4本値確認

チャート上の4本値

 

2本前の終値が知りたければ、Close[2]とすれば取得できます。

小話Close[0]を使わない理由は、現在作成中のローソク足だからです。

アクセスするたびに値が変わってしまうので、売買の判断には[1]を利用することが多いです。

スキャルピングなどのように瞬時に判断が必要な場合は[0]を利用します。

 

まとめ

今回は一次元配列と二次元配列の構造と、取り出し方について学びました。

次回は組み込み関数と自作関数を理解する|MQL入門(7回目)です。

関数まで理解できれば、立派に初級プログラマーの仲間入りです。

今回の記事のまとめ

  • 「1行:複数列」のデータの塊を一次元配列と呼ぶ
  • 「複数行:複数列」のデータの塊を二次元配列と呼ぶ
  • 配列の添え字は[0]かは始まる
  • removedの文字が出た場合は、再度チャートにプログラムを適用する必要がある
  • 配列はループ処理で簡単に取り出せる
  • 本筋からずれるようなことでも、少しの遊び心を持って試してみる

 

自動売買入門のまとめは以下をご参照ください