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