超初心者向けEAプログラミング入門①

EA
スポンサーリンク

はじめに

ここではEAプログラミング未経験者や超初心者といった方向けに、MT4のMetaEditorで新規作成から表示されたソースコードを、1行ずつ読み解いて行きたいと思います。

プログラムできる(ソースコードが書ける)ようになるには、まずはプログラムを読めるようになる必要があります!
※ソースコードとは、プログラミング言語で書かれた文字列です

あと、EAがどういう風に動いているのかも解説していますので、EAの動きについても考えながら読んでみてください。

ここでは、『コメントについて』と『OnTick()について』が何となくわかれば基本的にOKです。
※プログラミングをより詳しく理解したい場合は、記事を隅々まで理解してみてください

もしもの時のツール

もし記事を読んでみてどうしてもプログラミングは厳しいとなった場合は、以下の記事を参考にしてみてください。EAを自作するツールを紹介しています。自分でプログラミングはできないので細かいことはできませんが、簡単操作でしっかりとしたEAが作成できます。

ソースコードの読み方

では早速、ソースコードを確認していきましょう。これから確認するソースコードは、皆さんも新規作成から同じものを準備することが可能です。

もし、どうやって準備するのかわからないという場合は、以下の記事の後半「EAを作る前準備」から読んで行くと同じものが準備できます。

では、最初なので細かく1行ずつ見ていきましょう。

原則、ソースコードは上から下へ読んでいきます。

※一番左側の数字は行数を表しています

解説(1行目~9行目)

まず、1行目を見てみましょう。

1行目://+------------------------------------------------------------------+

プログラムが全く分からない場合、いきなり何のことか分からない記号の羅列になっています。ですがこれはとても簡単で、先頭2文字が「//」になっているものはコメントとなります。EAはこのコメントの部分を読み飛ばします。これを書く意味としては、主にプログラムを書く人間がメモの要素(プログラムを見やすくするため)で書いたりします。ですので「//」となっている部分は全てEAは無視していますので、この行はEAの動きとしては何もしていません。

つまり、EA的には「//」の部分は別に無くてもいいんですね。

こんな感じで、「//」の部分を全部消してもEAの動きは全く同じという事です!ただ、人間が見ると見づらいので「//」を使ってメモ代わりにするわけですね。

次に、2行目~5行目を見てみましょう。

2行目://|                                                         test.mq4 |
3行目://|                                    Copyright 2020, mef Software. |
4行目://|                                             https://fx-prog.com/ |
5行目://+------------------------------------------------------------------+

2行目~5行目も1行目と同じく先頭2文字が「//」になっていますのでコメントです。EAはこの部分の記述を無視します。各行の後方にはこのソースコードを作る際に入力した、「名前+.mq4」と「著作者」と「リンク」の情報が書かれています。人間が視覚的にどのファイルを扱っているのか分かるためのメモが自動で書き出されていたという事ですね。

次に、6行目~9行目を見てみましょう。

6行目:#property copyright "Copyright 2020, mef Software."
7行目:#property link      "https://fx-prog.com/"
8行目:#property version   "1.00"
9行目:#property strict

ここは1行目~5行目までと違い「//」がありませんので、EAはこの部分の記述を見ます。 6行目~9行目全てに「#property」と書かれていますが、これはEAのプロパティを設定しますよというようなニュアンスで書かれています。「#」については深く考える必要は無くて、 プロパティを設定する際は「#」を先頭付ける決まりになっているだけです。このことから、EAの「Copyright」「Link」「Version」「strict」の情報を設定するために書き出されたという事になります。
※自動売買をするうえで取りあえずは変更する必要がないのでこのままにしておきましょう

まとめ(1行目~9行目)

1行目~9行目はどのソースコードでもほぼお決まりで書かれるものという認識でOKです。まず今回は、「//」がコメントになるという事を覚えて頂けたと思います。コメントを覚えるとプログラマーとしての第一歩を歩めたといっても過言ではありません。ソースコードをざっくり見て、この部分はコメントだ、この部分はコメントじゃないというのをサッと見れるようになれればOKです。

あとコメントについてもう少し詳しく説明すると 「//」を書くと、それより後ろの文字(同じ行に限る)は全てコメントになります。従って、先頭ではなくても「//」を書く事ができます。今回のソースコードで先頭ではないパターンとして例を書いてみました。こんな形です。

9行目:#property strict         //MQL4プログラム(新旧)開発の互換性

この場合「//MQL4プログラム(新旧)開発の互換性」の所がコメントとなりますが、前方の「#property strict」の部分はコメントとならず、EAはコメントではないこの部分を見ます。

ここにコメントを書いた理由は、私も「#property strict」というものが何をしているものなのかわからなかったので調べてメモしました。プログラムができるからと言ってソースコードの内容全てを最初から理解できる人は殆どいません。最初はどんどん調べて、徐々に覚えていきます。
※MQL4プログラム(新旧)開発の互換性についてはまだ理解しなくてOKです

解説(10行目~19行目)

次に、10行目~12行目を見てみましょう。

10行目://+------------------------------------------------------------------+
11行目://| Expert initialization function                                   |
12行目://+------------------------------------------------------------------+

この部分は先ほど覚えたコメントですね。11行目に書かれているコメントは、日本語にするとEAを初期化する機能と書かれています。EAを初期化する機能?何それ?と思われると思います。初期化という概念は難しいと思いますので一旦深く考えないようにしてください。話を戻しますが、このコメントはEAを初期化する機能をこの下に書いていきますよという宣言のようなコメントになります。

次に、13行目~19行目を見てみましょう。

13行目:int OnInit()
14行目:  {
15行目://---
16行目:
17行目://---
18行目:   return(INIT_SUCCEEDED);
19行目:  }

13行目の「int OnInit()」の意味は、単純に言うと「EAを初期化する機能」です。先ほどの11行目のコメントの内容がこれというわけですね。次に、14行目の「{」の意味は「始まり」で19行目の「}」の意味は「終わり」です。文章のかぎカッコのようなものですが、プログラムにはこの始まりと終わりを表す事はお決まりとして必須の形式となります。

まずは、13行目と14行目と19行目をみてEAを初期化する機能は14行目から18行目に書かれているんだという事がわかりますね。

14行目から18行目を見ると、あまり大したことは書かれていない事がわかります。15行目、17行目はコメントですね。そして16行目は何も書いていません。これは見た目通りで、EAは何もしません。次に、終わり前の18行目は「return(INIT_SUCCEEDED);」となっており、意味は「EAを初期化する機能は成功したという事を返す(伝える)」です。

この「EAを初期化する機能は成功したという事を返す(伝える)」っていう考えは、Theプログラムというところで難しいので、「int OnInit()」と「EA本体」の関係について少したとえ話を挟んで動きを解説します。

EAを仕事場の人で例える

わかりやすいように例え話で解説します。仕事のリーダーと作業員で例えてみます。「int OnInit()」は作業はするけど作業依頼があるまでは何もしない作業員です。 そして「EA(本体)」は作業依頼はするけど自分は作業を何もしないし、部下の作業状況も全く確認しないちょっと残念なリーダーとでもしておきましょう。

「EA」リーダーが 「int OnInit()」作業員に『作業やってね』と作業依頼をすると、「int OnInit()」作業員 は作業を開始します。その間、「EA」リーダーは「int OnInit()」作業員から作業終了の報告があるまでずーっと待っています。
※注 どんなプログラム(もちろんEAも)も、作業依頼を出した後、リーダーが次の依頼を出す事は基本的に絶対にありません。1つ依頼を出して完了するまで待つの繰り返しです。この考え方はプログラミングでとても重要ですので意識しましょう

ですので、「int OnInit()」作業員は作業が終わると『正常に作業終わったよ』と「EA」リーダーに報告しないといけません。この報告の部分が「return(INIT_SUCCEEDED);」です。作業が正常に終わったという時は「return(INIT_SUCCEEDED);」で、何か問題があった時は「 return(INIT_FAILED);」と()の中身が作業結果になっており、今回は正常としていることがわかります。

簡単なイメージ図だとこんな感じです。

そして、「EA」リーダーは「int OnInit()」作業員から報告があがってきた作業結果を見て、次の作業を進めていいか勝手に判断してくれます。 「int OnInit()」作業員は作業報告が終わると、また次の作業依頼がくるまで待ち状態になります。
※int OnInit()は、初期化処理なので次の作業依頼は基本来ません

ちなみに、 「int OnInit()」作業員が作業報告「return(INIT_SUCCEEDED);」を返さなかった場合でも一応動きます。どんな動きになるかというと、「}」の後に「EA」リーダーは勝手に正常に作業が終わったと判断して次の作業員に作業を出すという形です。

return(INIT_SUCCEEDED); の具体的な意味は?

プログラムの話に戻し 「return(INIT_SUCCEEDED);」を分解してみます。

retrun ・・・返す
(INIT_SUCCEEDED) ・・・成功 ※失敗の場合(INIT_FAILED)
; ・・・これは文章の最後に必ずつける句読点の「。」のような扱いですので必須

あと、 プログラムは基本的に()の中に返事を書きます。

()の中にINIT_SUCCEEDEDと書いているので 、EAに初期化処理が成功した事を返事していることになります。

プログラムは、原則上から下へ1行づつ文字を読んで行きますの。 成功した事を返した後「}」で終わりとなっていますので、この「int OnInit()」の所は終わりとなります。

まとめ(10行目~19行目)

13行目~19行目はEAを初期化する機能が書かれていました。 EAの仕様(決まり事)ですが、「int OnInit()」はEAを起動した際、最初に、しかも1度だけ『作業依頼(以降の文章は『実行』で統一)』がきます。

だから、EAを起動した際にスタート(始まりの)状態にしておこう(EAを初期化する機能をしておこう)という場を作っているわけなんですね。 ただ、今回の 「int OnInit()」 はretrunしか書かれていないので、初期化処理は特に何もしておらず「初期化成功したよ(何もしてないから)」ということだけ書かれているんですね。

ちなみに、ごく初歩的なEAを作る場合だと、別にこのint OnInit()はこのままの(成功だけ返している)状態でも全然問題ありません。

まずは、この10~19行目が1つのグループ(初期化班)です

解説(20行目~27行目)

次に、20行目~27行目を見てみましょう。

20行目://+------------------------------------------------------------------+
21行目://| Expert deinitialization function                                 |
22行目://+------------------------------------------------------------------+
23行目: void OnDeinit(const int reason)
24行目:   {
25行目: //---
26行目:
27行目:   }

何となくですが、先ほどの 「int OnInit()」 に似ていますよね。実はこれは、簡単に言うと「int OnInit()」と対になるもので EAを終了する際に1度実行する機能になります。

まとめ(20行目~27行目)

さらっと流してしまいました「OnDeinit(const int reason)」ですが、「int OnInit()」 を開会式に例えると、「OnDeinit(const int reason)」は閉会式です。「int OnInit()」と違ってretrun(INIT_SUCCEEDED);が無いのは、最後の処理で後は終わるだけなので報告しなくてよいからです。

あとこの、 「OnDeinit(const int reason)」の部分ですが「int OnInit()」と同様に特に触らなくて良いです。私のEAもここでは(EAを終了させるタイミングで)特に何もしていません。

この20~27行目が1つのグループ(終了班)です

解説(28行目~36行目)

次に、28行目~36行目を見てみましょう。

28行目://+------------------------------------------------------------------+
29行目://| Expert tick function                                             |
30行目://+------------------------------------------------------------------+
31行目:void OnTick()
32行目:  {
33行目://---
34行目:
35行目:}
36行目://+------------------------------------------------------------------+

ここまで記事を読み進めると、もうお分かりかもしれません。

「OnTick()」はどんなときに実行されると思いますか?先ほど「始まり int OnInit()」と「終わり OnDeinit()」の機能があったので・・・、残りのこの 「OnTick()」 こそがEAの肝ともいえる場所になります。

実行されるのは、最初に1回とか終わりに1回とかではないですよ!チャートに値動きが発生したタイミングです。忙しいですね!

また先ほどの例え話になりますが、「EA」リーダーは「int OnInit()」作業員から作業報告を受けたあと、待ち状態になります。そして、次に作業依頼をするのはほぼ100%この「OnTick()」作業員です。MT4のチャートに値動きがあった場合「EA」リーダーは「OnTick()」作業員に作業依頼を出します。

簡単なイメージ図だとこんな感じです。

「OnTick()」作業員は値動きがあるたびに作業依頼がくるので常に大忙しです。しかも「OnTick()」作業員がチャートの状態を確認してロングやショートをエントリーする役割をにないます。

流れはこんな感じ。

「MT4」(値動きあったで)→「EA」(作業しよか)→「OnTick()」(作業終わったで)→「EA」(終わった)

補足情報ですが、頻繁に値動きが起きる場合ももちろんあります。「OnTick()」作業員がまだ作業が終わってない内に次の作業依頼が来たら・・・一気作業依頼が来ててんやわんやにならないの?という疑問を持たれた方もいるかもしれません。

頻繁に値動きが起きると(指標発表時等)、MT4は値動きあったで!と頻繁にEAリーダーに伝えてきますが、ここはEAリーダーの腕の見せ所。ちゃんと作業管理をしてくれます。EAリーダーは「OnTick()」作業員が作業中(作業完了が確認できるまで)は次の作業依頼は出しません!(過労で倒れちゃうので)

「OnTick()」作業員も現在行っている作業は確実に最後までやり終えてから次の作業依頼に手を付けます。
※厳密には違うかもしれませんが大体のイメージはこんな感じ

なので頻繁に値動きが起きたとしても、MT4とEAと「OnTick()」作業員がそこは勝手に連携してくれているので、私たち作り手側は特に気にしなくてOKです。
※そもそも簡単なEAの場合「OnTick()」作業員の作業時間は0.0・・・1秒?コンピュータなので驚く程はやいです。なので、為替の値動き速度よりも「OnTick()」作業員の作業速度が勝ちます

まとめ(28行目~36行目)

漠然とイメージしてもらったらわかると思います。

チャートに値動きが発生したタイミングで「OnTick()」が実行される = 値動きが発生する度にロングやショートやチャートを確認する事ができる

という事です。この「OnTick()」を駆使すれば人間と同じタイミングでエントリーしたりチャート確認したりがコンピュータの速度で正確にできるという事ですよね!

したがって、EAは基本的に「OnTick()」にやりたい事を全て書いていきます。例えば、米ドル/円が109.940→ 109.941と値動きがあった場合に「OnTick()」が実行されます。ですので、行数で言えば34行目以降に米ドル/円がどんな状態かチャート確認し、(例えば移動平均線より上)になったらロングする・ショートするといった指示を書いていくわけですね。

そして、ロング・ショートの判断が終了し1回の値動きで全部見たい事を書いたら、「}」で作業終了という具合にします(return(INIT_SUCCEEDED);というった物は特に不要)。「EA」リーダーは 「OnTick()」 作業員が作業を終了したと確認できます。そして、またチャートに値動きが発生したタイミングで「 OnTick()」作業員に作業依頼を出します。EAはこの動作を無限にループ(EAを終了させるまで)しているという形になります。

この28~36行目が1つのグループ(実行班)です。

EAを作る際はこのグループがメイン中のメインとなります。

最後に

お疲れ様でした。ベースとなるEAのソースコード及び簡単な動きについて一通り説明させて頂きましたが如何でしたでしょうか。少し難しいところはあったかもしれませんが、ソースコードを読めるようになってきたのではないでしょうか。

一部ソースコードの話ではなく、プログラムの動作(リーダーと作業員)の話もありましたが、ここは完全に理解しなくても大丈夫です。※理解していた方が、後々応用が利きますしプログラムも作りやすいです

ソースコードは慣れてくると、だんだん日本語を読むかのようにスラスラと読めるようになってきますので、まずは慣れるところから始めましょう。

次回は、「OnTick()」の34行目以降に実際にソースコードを書いていく記事です。

※プログラミング知識が無くてもEAが作れる!


※オンラインレッスン

コメント