(4) 【MQL5】 サンプルプログラム(EA)を解析

投稿者: | 2017年9月14日

18,248 views

この記事は最終更新から 2578日 が経過しています。

(1) やりたいこと

(2) 過去データの収集 ではMetaTrader4を使用してヒストリカルデータからCSVファイルを作成した。これをPythonプログラムで読んでグラフ表示させようとしていたが、試しに MetaTrader4で表示してみたグラフがとっても美しいので、先にこれを弄ってみることにした。

MetaTraderの提供元サイトを訪れると、最新版は MetaTrader5とのこと。
新しい方がよいのでこちらをダウンロードして使ってみる。
https://www.metaquotes.net/en/metatrader5

(2) プログラムをエディターで開く

(1) [ツール]-[MetaQuotes言語エディタ] メニューを選択する。

 ↓
すると、「MetaEditor」と書かれた別ウィンドウが開く。

(2) 解析対象のプログラム「Moving Average.mq5」(一番入門用っぽいから)を選択する。

コメントを含めて233行の小さなプログラムだ。頑張って理解する。

(3) プログラムの骨格を知る

書かれていた関数は全7個だ。
Onxxxxxx は本プログラム外部から呼ばれるイベントハンドラ、その他は本プログラム内部で呼ぶサブルーチンだ。

骨格は以下の通り。
OnInit : EA開始時の処理を記述する。
OnTick : 価格変動発生時の処理を記述する。
 ・売り or 買いを判断し、その結果に従って売買を実行する。
 ・開いているPositionがあればそのクローズ有無を判断し、その結果に従って Positionを閉じる。
OnDeinit : EA終了時の処理を記述する。このサンプルでは処理なし。

(4) 関数の外に書かれているものは?

12~15行目: EA起動時に与えるパラメーターであり、この値をプログラム内部で使用する。データ型とデフォルト値が書かれている。
17~19行目: プログラム内部で使用するグローバル変数。すなわち関数をまたいで共有できる変数。
21行目: 当該EAを識別するためのユニークな番号。「自分が建てたポジション or not」の判断に使用する。

(5) OnInit()を理解

201行目: 当該口座のヘッジモードON/OFF判定。ヘッジモードONの場合、1つのSymbol(=通貨)について複数のPositionを持てる(=建玉できる)。MetaTrader上のEA設定項目でON/OFFできる。
202行目: トレードクラスのインスタンスに当該EAの magic numberを記憶させる。
203行目: 現在の口座設定に応じて、証拠金計算モードを設定する。???よくわからん
204行目: 指定された銘柄の設定によって注文の履行タイプを設定する。???よくわからん
206行目: 移動平均線指標を作る。

(6) OnTick()を理解

当該ハンドラが起動されるトリガーとなった通貨種別で当該EAがPositionを持っている場合、クローズ判定→可能ならクローズをする。
当該ハンドラが起動されるトリガーとなった通貨種別で当該EAがPositionを持っていない場合、新規ポジションのオープン判定→可能ならオープンをする。

(7) SelectPosition()を理解

前述の OnTick から呼ばれるサブルーチンだ。
171行目: ヘッジモードON(=複数Position許可)の場合…
173行目: 未決済のPosition数を取得する。
174行目: 所有する全Positionについて処理を繰り返し。
176行目: 未決済のPositionのSymbol(=通貨種別)を取得する。
177行目: 今回OnTickが起動するトリガーとなったSymbolと同じ 且つ 当該EAが建てたPositionであるならば…
179行目: Positionが選択できたと呼び出し元に返す。
185行目: ヘッジモードOFF(=複数Position禁止)の場合…
186行目: 今後の作業で使用する保有ポジションを選択する。
ヘッジONの場合にPositionを選択していないがよいのか?
関数リファレンス: PositionsTotal / PositionGetSymbol / PositionSelect

(8) CheckForClose()を理解

こちらも前述の OnTick から呼ばれるサブルーチンだ。
134行目: 最新のバー(=ローソク足)の第1回目の価格通知でなければ無処理とする。
139行目: 最新足のtick_volume(=tick通知回数)が初回でなければ無処理とする。
rt[0] : 前回足
rt[1] : 直近足(初回通知ならばopen,close,high,lowすべてに同じ値が格納されている)
rt[1].tick_volume : 直近足のtick回数(1ならば初回ということ)

143行目: 今回使用している指標(MA)の直近のデータ1個を取得する。
150行目: 現在所持しているPositionの種別(SELL or BUY)を取得する。
152行目: もし BUY 且つ (直近足の始値 > MA) 且つ (直近の終値 < MA) であればクローズと判断する。
154行目: もし SELL 且つ (直近足の始値 < MA) 且つ (直近の終値 > MA) であればクローズと判断する。
157行目: もしクローズと判断されたならば…
159行目: もしEAによる売買実行が許可されている(MetaTrader上で設定)且つ MAの情報量が過去100期間以上あるならば…
160行目: 現在価格から3ポイント以内であれば Positionをクローズする。
むずかしい…
関数リファレンス: CopyRates / CopyBuffer / TerminalInfoInteger / Bars / CTrade::PositionClose

(9) CheckForOpen()を理解

こちらも前述の OnTick から呼ばれるサブルーチンだ。
CheckForCloseと同じ処理については記述を省略する。
110行目: (直近足の始値 > MA) 且つ (直近の終値 < MA) であれば SELLでオープンと判断する。
114行目: (直近足の始値 < MA) 且つ (直近の終値 > MA) であれば BUYでオープンと判断する。
118行目: もしオープンと判断されたならば…
121行目: 最適な量を決めて新規Positionをオープンする。実行価格は SELLならBID, BUYならASKを指定する。

(10) TradeSizeOptimized()を理解

前述の CheckForOpen から呼ばれるサブルーチンだ。
Positionオープン時にそのロット数を決定する重要な関数だ。

だが…
プログラムの構造を理解する目的すなわちレベル1はほぼ達成できた。
レベル2相当の本関数は後日スキルアップ後に熟読しよう。

(11) プログラムを実行

1) [表示]-[ストラテジーテスター] メニューを選択する。→ 画面下部にストラテジーテスターが表示される。

2) Moving Average.ex5を選択する。

3) 通貨ペア、入金額、期間などを選択して [スタート] ボタンを押下する。ビジュアルモードをONにしておくと見ていて面白い。

確かに、
(直前足のOpen > 直近MA)且つ(直前足のClose < 直近MA)でSELL Positionを取り、
(直前足のOpen < 直近MA)且つ(直前足のClose > 直近MA)でPositionをクローズしている様子がビジュアルでわかる。

してその結果は?

だいぶ資産が減りました (^^;

面白いですね MetaTrader5


カテゴリー: MQL

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)