見出し画像

Block EA 今日のワンポイント:関数の作成

ブロックでEAプログラミング、Block EA今日のワンポイントです。

今回は関数の作成についてです。

EAのプログラミングでは、イベントごとに決まった関数が実行される仕組みになっています。MQL4とMQL5とで違うところはありますが、Block EAでは、MQL4に合わせて以下の3つの関数をブロックとして用意しています。

画像2

これらの関数ブロックは、次のようなコードに変換されます。

void Tick()
{
}

int OnInit()
{
 return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
}

ティック時実行関数がOnTick()ではなくTick()になっているのは、共通ライブラリでMQL4とMQL5の互換性を持たせるためです。

Block EA 今日のワンポイント:変数の宣言」でも書きましたが、MQLでは、変数宣言時にデータ型を指定する必要がありました。

関数の場合も同じで、それぞれの引数のデータ型、戻り値がある場合は戻り値のデータ型が必要となります。

上の3つの関数は、関数名や引数、戻り値のデータ型が決まっているので、ブロックからそのまま変換できるように定義してあります。

ところが、ユーザーが独自に関数を定義する場合、データ型の指定が問題となってきます。

というのも、Blocklyが標準で対応している「関数の作成」の機能には、データ型を設定する部分がないのです。しかも、「関数の作成」ツールボックスは、関数を定義するとその関数がツールボックスに動的に追加されるようになっていて、改修するのがちょっと面倒です。

仕方ないので、「関数の作成」ツールボックスはBlockly標準のまま使い、コードに変換する際に独自のやり方をするようにしました。

なので、ちょっとわかりにくいところがあるかもしれません。

とりあえず、関数の作成には以下の二つのブロックがあります。

画像3

違いは戻り値があるかないかです。上のブロックは戻り値がない場合です。

これをワークスペースにドラッグして関数名を「func」としてみます。

画像4

すると、このコードは

// この関数の説明…
void func()
{
}

となります。「この関数の説明...」の部分は、ブロックの「?」をクリックすると編集することができます。

画像5

また右クリックのメニューでコメントを消すこともできます。

画像6

このブロックのなかに、関数の中身をブロックとして配置すれば、func()関数の定義を行うことができます。

このように戻り値がない場合は、関数の戻り値の型が「void」に決まるので、自動的に変換することができます。

次に戻り値がある関数の生成です。

画像7

同じように「func」という関数名を付けておきます。「返す」のところに何もついていない場合、戻り値がないとみなします。

// この関数の説明…
void func()
{
}

変換すると、先ほどと同じコードになります。

ここで、「返す」のところに「」をつけてみます。

画像8

すると、コードは

// この関数の説明…
int func()
{
 return 0;
}

となり、「return 0;」が追加されます。また関数の戻り値の型は「int」となります。

ただし、この関数の型「int」は、戻り値「0」を分析して付けたわけではありません。どういう戻り値でも「int」になってしまいます。コードに変換するルーチンはそんなに賢くないのです。

そこで、関数の戻り値の型をint以外にしたい場合、次のようにデータ型を明示するブロックをつける方法にしました。

画像9

返す」のところに「何とか型の戻り値」というブロックを挟んで指定します。このブロックは「MQL関数」ツールボックスに配置しています。

すると、コードは次のように変換されます。

// この関数の説明…
double func()
{
 return 0;
}

戻り値の型が「double」になりました。

戻り値の型の指定はこれで何とかなったのですが、問題は引数の型です。

引数の追加はちょっとわかりにくいのですが、ブロックの左上の歯車みたいな記号をクリックします。

画像10

すると、入力を指定するブロックが現れるので、ここで、「入力名:x」というブロックをドラッグして入力のブロックに入れます。

画像11

これで引数「x」が設定できました。引数を増やしたい場合は、同じように入力名ブロックをドラッグします。

例えば、以下のようなブロックで関数を定義したとします。

画像12

このコードは

// この関数の説明…
double func(int x, int y)
{
 return (x + y);
}

となります。引数xとyを足した値を返すだけなのですが、引数のデータ型は指定していないので、「int」になってしまいます。

引数の型を個別に設定するのにさらにブロックを使うとややこしくなってしまうので、Block EAの独自の仕様として、引数のデータ型をint以外にする場合、次のように変数名で指定するようにしました。

データ型をdoubleにしたい場合「double_」から始まる変数名にします。例えば、引数の変数名を「x」「y」の代わりに「double_x」「double_y」にしてみます。

画像13

すると、コードは

// この関数の説明…
double func(double double_x, double double_y)
{
 return (double_x + double_y);
}

となり、引数のデータ型がちゃんとdoubleになりました。ただ、コードはdoubleが何度も出てきてくどいですけどね。

このように定義した関数は、「関数の生成」ツールボックスに作成されているので、それを適当なところにドラッグして使います。例えば、以下のような形です。

画像14

このコードは

void Tick()
{
 double z = (func(0.1, 0.2));
}

となり、ちゃんとfunc()という関数を呼び出していることがわかります。

以上、データ型を指定する必要のないBlocklyからガチガチにデータ型を指定するMQLへの変換のためのBlock EA独自の方法を紹介しました。

あまり初心者向きではないのですが、関数を使いたい場合のご参考にしてください。

ではまた。

いいなと思ったら応援しよう!