列挙型は必須知識ではないけれど、いろんなところで使われているから、この機会に知っておこう!
列挙型とは?
「文字を数値に変換できたら便利なのになぁ」
という方は、列挙型を使ってみましょう!
列挙型は、「文字列と数値」の組み合わせを設定できる型です。
例えば、列挙型に「December」と入力すると「12」が返ってくるというイメージです。
また列挙型は、自分で作らなくても事前に準備されているものが多いです。
なぜなら、関数の引数で使う場合が多いからです。
関数の引数は、ある程度固定されたパラメータになっているので、列挙型と相性が良いのですね。
そのため、列挙型を理解するだけでも、スムーズに関数を使えるようになります。
ちなみに列挙型は、配列ととてもよく似ています。
配列は変数の集合体で、列挙型は定数の集合体です。
定数の集合体のため、列挙型はすでに決まっている数値や文字列を、取り扱うことに優れています。
というわけで、今回は列挙型の使い方についてマスターしていきましょう!
配列が未履修の方はこちらから
列挙型と配列の違い
列挙型の構造は少し特殊なので、初めは理解しづらいかもしれません。
ですが、配列の要素を取り出すときと同じように考えると、理解が早いと思います。
まずは配列と列挙型の違いについてみていきましょう。
以下のサンプルプログラムを見てください。
//配列
string month_array[4] = { "January", "February", "March", "April" };
//列挙型を定義する
enum month_enum { January, February, March, April };
列挙型を見て、「ん?」と思うはずです。
列挙型には、配列と違って文字列という概念が存在しません。
その理由を少しずつ見ていきましょう。
列挙型と配列のデータの取り出し方法の違い
まずは配列のデータの取り出し方法を見ていきましょう。
配列のデータを取り出す場合、配列のデータの番号を入力することで、データを取り出すことができます。
例えば以下のようなプログラムです。
//配列
string month_array[4] ={ "January", "February", "March", "April" };
//配列のデータを取り出す
Print(month_array[0]); //January
Print(month_array[1]); //February
Print(month_array[2]); //March
Print(month_array[3]); //April
このように「0,1,2,3」という番号を入力して、データを取り出します。
次に列挙型のデータの取り出し方法を見ていきましょう。
//列挙型を定義する
enum month_enum{January,February,March,April};
//列挙型のデータを取り出す
Print(January); //0
Print(February); //1
Print(March); //2
Print(April); //3
このように列挙型は、番号の代わりに文字を使用して、データを取り出します。
ここで取り出されるのは「January」という文字列ではなく、「0」であることに注意しましょう。
列挙型は番号を取り出すことができるのです。
列挙型と配列のデータの取り出し方法のまとめ
書き方の違いはありますが、列挙型と配列のデータの取り出し方法は、全く逆と言って良いと思います。
こちらにまとめました。
データ型 | データへのアクセス方法 | 取り出されるデータ |
配列 | 番号(0) | 文字(January) |
列挙型 | 文字(January) | 番号(0) |
このように全く逆になるため、列挙型がイメージしにくい原因にもなっています。
しかしMQLプログラムは、知らず知らずのうちに列挙型を使っています。
もし自動売買やインジケータを作った方は、確実に列挙型を使っています。
なので、マスターすれば「なぜこのプログラムで実行できるのだろうか」が分かってくるようになり、プログラミングが楽しくなると思います。
列挙型の構造と使い方
さて列挙型と配列の違いについて見てきましたが、ここからは列挙型について深く見ていきます。
列挙型の構造
列挙型は「列挙」というだけあって、データに対して番号が順番に設定されます。
上記の例だと、何も設定していないはずなのに、「January → 0」という番号が設定されています。
少しプログラムを見ていきましょう。
先程のプログラム(列挙型の定義)を改行して見ます。
//列挙型を定義する
enum month_enum{
January, //0
February, //1
March, //2
April //3
};
このように何も設定していない場合は、上から「0、1、2、3」と順番に番号が設定されます。
それでは番号を設定するとどうなるのでしょうか。
//列挙型を定義する
enum month_enum{
January = 1,
February = 2,
March = 3,
April = 4
};
このように番号は「=」で設定できます。
これで、「January → 1」という番号が設定できました。
ちなみに番号は順番じゃなくてもOKです。
//列挙型を定義する
enum month_enum{
January = -1,
February = 400,
March = 9,
April = 16
};
マイナスでも昇順でなくても問題ありません。
この例だと「January = -1」になっています。
列挙型の使い方
ここからは列挙型を具体的に使って見ましょう。
まずは先程のプログラムを確認します。
//列挙型を定義する
enum month_enum{
January = 1,
February = 2,
March = 3,
April = 4
};
//列挙型のデータを取り出す
Print(January); //1
Print(February); //2
Print(March); //3
Print(April); //4
それではここに、if文を使って「今1月なら、”正月”と表示する」というプログラムを追加してみます。
if(Month() == January){
Print("正月");
}
このように書くことができます。
一気にプログラムが読みやすくなったかと思います。
列挙型を使うことで、プログラムの可読性を高めることができます。
列挙型はどこで使われているのか
先程、列挙型は知らず知らずのうちに使っていると言いました。
プログラムで定数と呼ばれるものは、ほとんどが列挙型で作られています。
例えば、PERIOD_CURRENTです。
PERIOD_CURRENTという定数は、「ENUM_TIMEFRAMES」という列挙型で作られています。
以下のようにプログラムされています。
enum ENUM_TIMEFRAMES{
PERIOD_CURRENT = 0,
PERIOD_M1 = 1,
PERIOD_M5 = 5,
PERIOD_M15 = 15,
PERIOD_M30 = 30,
PERIOD_H1 = 60,
PERIOD_H4 = 240,
PERIOD_D1 = 1440,
PERIOD_W1 = 10080,
PERIOD_MN1 = 43200
};
このように列挙型は知らず知らずのうちに使っていることが多いので、マスターすることで、プログラムの意味が見えてくるようになります。
列挙型のプログラム例
先程のプログラムの全体を載せておきます。
ファイルとしてもダウンロードできますので、よろしければどうぞ。
//+------------------------------------------------------------------+
//| SampleMQL_Enum.mq4 |
//| Copyright 2021, Risa FX Vtuber |
//| https://mql-programing.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Risa FX Vtuber"
#property link "https://mql-programing.com/"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//配列
string month_array[4]={"January","February","March","April"};
//列挙型
enum month_enum{January=-1,February=200,March=3,April=4};
//配列のデータを取り出す
Print(month_array[0]); //January
Print(month_array[1]); //February
Print(month_array[2]); //March
Print(month_array[3]); //April
//列挙型のデータを取り出す
Print(January); //0
Print(February); //1
Print(March); //2
Print(April); //3
if(Month() == January){
Print("正月");
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//---
}
//+------------------------------------------------------------------+
まとめ
列挙型について、配列と比較しながら確認しました。
列挙型は「文字」→「番号」に変換するツールです。
これをプログラムに取り入れるだけで、プログラムの可読性が格段に上がります。
また、プログラムを作っていると、知らず知らずのうちに列挙型を使っているので、この機会にしっかり理解すると良いでしょう。
MQLプログラムの書き方がだんだん分かってくるはずです。
列挙型をマスターして、可読性の高いプログラムを作成していきましょう!