EA基本テンプレート

MQL4解説

はじめに

単一ポジションによる基本的な自動売買プログラムの例とその解説をします。

以下のプログラムはボリンジャーバンドの+2σで売りエントリー、-2σで買いエントリーし、中心の移動平均線で決済を繰り返す逆張り型の自動売買プログラムの一例です。エントリー条件や決済条件を変更することでオリジナルのプログラムが作成可能です。

まずは、プログラムを各自のメタエディターに貼り付けて、このページを参考にしながら内容を理解し、自分なりにカスタマイズしてみましょう。

本プログラムは解説を目的としたサンプルです。収益を保証するものではありません。

EAの基本

EAは主に以下の3つの関数から成り立っています。
OnInit
OnDeinit
OnTick

OnInit関数はEA起動時、OnDeinit関数はEA終了時、OnTick関数は価格が動くたびに実行されます。

OnInit関数は自作関数の初期化などに主に使われますが、自作関数を使用せず、また、EA起動時に特別な処理を必要としない場合は省略可能です。OnDeinit関数もEA終了時に実行されますが、売買ロジックに直接的な影響はないため必須ではありません。

一方、OnTick関数はリアルタイムでインジケーターの値を取得したり、実際に注文を行ったりするEAの中心となる部分で、基本的にはここに処理を記述していきます。

プログラムの内容説明

①変数定義

OnInit関数の上にプログラム全体で適用される変数(グローバル変数)を定義していきます。
上の例では注文数量を「Lots」という変数で定義しており、現状では「0」となっていますが、実際に注文したい数量に合わせて変化させます。

ここで定義する変数は基本的にはプログラム全体で変わらない変数です。ティックごとに変動するインジケーターの値(移動平均線やRSIなど)は後述するようにOnTick関数内で定義します。

「extern」はプログラムを書き換えなくてもMT4の設定画面から値を変更できるようにするための設定です。→詳しくはこちらをご覧ください。

「double」は変数の「型(データ型)」の1つで小数を扱うことを意味します。
下の表は主なデータ型とその意味です。↓

データ型扱う変数(値)
double小数
int整数
bool真偽(true/false)
string文字列
datetime日時

📌ポイント

<変数定義>

(extern)データ型 変数名 = 値 ;

②決済処理

決済処理は「保有ポジションの確認」「ポジションの選択」という2つの処理を経て、買い/売りそれぞれの条件に分岐して実行されます。

「保有ポジションの確認」は1行目の if(OrdersTotal() != 0) で行われており、

  • OrdersTotal() → 「現在の保有ポジション数
  • !=0 → 0ではない

すなわち、「1つ以上のポジションを保有」している場合、決済処理に進むことになります。
「!=」は演算子の1つであり、よく使われる演算子は以下のようなものがあります。

<条件式(ifやelse if内)でよく使われる演算子>

==等しい(例:A == B → AはBである)
!=等しくない(例:A != B → AはBでない)
>, >=より大きい, 以上(例:A > B → AはBより大きい)
<, <=より小さい, 以下(例:A <= B → AはB以下)
&&かつ(例:a == 0 && b >= 0 → aが0かつbが0以上)
||または(例:a == 5 || a == 10 → aが5または10)

「ポジションの選択」は2行目のif(OrderSelect(0, SELECT_BY_POS, MODE_TRADES))で行われており、

  • 0 → 1番最初のポジション(0番目)
  • SELECT_BY_POS → ポジション番号選択の方式。保有中のポジションに対して、先頭から順番に番号(0,1,2,…)を割り当てるインデックス方式であることを意味する。
  • MODE_TRADES → 現在保有中のポジションから選択。(過去の決済済みポジションではない。)

この1行は、単一ポジションで取引する際の定型処理で、現在保有中のポジションを“選択状態”にします。これにより、決済に必要な情報(注文種別やロットなど)を取得できるようになります

③買いポジションの処理

1つ前のOrderSelect関数でポジションを選択状態にすることで、OrderType関数を使って注文種別を取得することができるようになり、買いポジション場合は「OP_BUY」を選択します。

続いて、決済ロジックを記述していきます。このプログラムでは損切りをエントリー価格(OrderOpenPrice関数で取得)から0.25円下がったタイミング、利食いを現在価格が移動平均線(期間:20)を上回ったタイミングとしています。

Bidは「売りの現在価格」を表し、Askは「買いの現在価格」を表します。この両者の関係は

Ask Bidスプレッド

となり、常にAskがスプレッド分だけBidより高くなります。
買いポジションの場合、決済は「売り」なので、通常はBidを現在価格として用います。

移動平均線を組み込みたい場合はiMA関数を使います。パラメータ設定は以下の通りです。

  • NULL → 挿入したチャートの通過ペア。ドル円を指定する場合は”USDJPY”のように書く。
  • 0 → 挿入したチャートの時間足。1時間足を指定する場合はPERIOD_H1のように書く。
  • 20 → 移動平均線を計算する期間。
  • 0 → 移動平均線の表示をずらす本数。表示用なので、EAでは通常0。
  • MODE_SMA → 移動平均線の種類が単純移動平均線(SMA)。
  • PRICE_CLOSE → 移動平均を計算する価格。通常は終値(CLOSE)。
  • 0 → 取得する移動平均線の位置。0が現在の値。1を指定すると1本前の値を取得できる。

OrderClose関数は実際に決済を実行するための関数です。パラメータの設定は以下の通りです。

  • OrderTicket() → OrderSelectされたポジションのチケット番号を選択。
  • OrderLots() → ロット数の選択。一部決済したい場合は数値を入力(例:0.1)。
  • OrderClosePrice() → 決済価格の選択。売買種別に応じたAsk/Bidを自動で返す。
  • 10 → スリッページが10ポイント。(※ポイント:最小価格変動単位)
  • clrNONE → 決済時にチャートに表示される矢印の無効化。

else ifを増やすことで、決済条件を追加していくことができます。
注意点としては、if/else ifは上から順番に条件判定し、最初に成立した処理だけが実行されるので、優先度の高い条件ほど上に書く必要があります。

④売りポジションの処理

売りポジションの場合、OrderTypeを「OP_SELL」に変更するだけで、買いポジションの場合と同様に記述すればいいのですが、このプログラムでは書き方を少し工夫してあります。

決済ロジックとしては現在価格が移動平均線(期間:20)を下回ったタイミングで利食い、エントリー価格から0.25円上昇したタイミングで損切りとしており、これは買いポジションと条件の向きが逆になっているだけで、ロジックとしては同じです。

一方、買いポジションでは条件ごとにif/else ifで分けて書きましたが、売りポジションの場合は決済処理(OrderClose)が同じであることに目を付け、2つの条件を演算子「||(または)」を使って1つにまとめています。
このように、処理が共通で条件も単純な場合は、コードを簡潔にするために1行にまとめて記述する方法もあります。

⑤エントリー処理

コード自体はelseのみで完結します。これは②決済処理のif(OrdersTotal() != 0)に対応するもので、実質的にはOrdersTotal() == 0と同じ内容を意味します。
このプログラムでは1つのポジションしか保有しないため、ポジションを持っていない場合はエントリー処理、ポジションを持っている場合は決済処理というように区別して書くことができます。
→複数ポジションを扱う場合の処理についてはこちらをご覧下さい。

⑥指標の定義と取得

指標(インジケーター)の値を条件に組み込みたいとき、2つ前の「④売りポジションの処理」の決済条件のようにiMA関数を直接if内に書く方法もありますが、今回のように直前に関数を変数として定義し、その変数を条件に組み込むという方法もあります。

また、「①変数定義」で定義したLots(ロット数)との違いは、ティックごとに値が変わる変数だということです。このように呼び出されるたびに値が変わる変数(内部変数)を定義するときは、プログラムの最上部(関数の外部)ではなく、組み込みたい条件処理の直前で定義します。

band_upper_20で定義されているのはボリンジャーバンド(期間:20)の+2σです。ボリンジャーバンドの値は小数で返されるので、データ型は「double」になります。ボリンジャーバンドはiBands関数で呼び出すことができ、パラメータの設定は以下のようになっています。

  • NULL → 挿入したチャートの通過ペア。ドル円を指定する場合は”USDJPY”のように書く。
  • 0 → 挿入したチャートの時間足。15分足を指定する場合はPERIOD_M15のように書く。
  • 20 → ボリンジャーバンドを計算する期間。
  • 2 → 標準偏差(σ)
  • 0 → ボリンジャーバンドの表示をずらす変数。表示用なので、EAでは通常0。
  • PRICE_CLOSE → ボリンジャーバンドを計算する価格。通常は終値(CLOSE)。
  • MODE_UPPER → アッパーバンドの指定。
  • 0 → 取得するボリンジャーバンドの位置。0が現在の値。1を指定すると1本前の値。

band_lower_20はMODE_UPPER→MODE_LOWERに変更することで、-2σの値を取得しています。

⑦買いエントリーの処理

買いエントリーは
「1本前のローソク足の終値がボリンジャーバンド-2σ以下かつ、現在のローソク足が陽線」
になったタイミングでエントリーされるという逆張り手法です。
また、「&&」で条件を増やすことで、エントリー条件を厳格化し、ダマシを低減させることができます。

OrderSend関数は実際に注文行うための関数です。パラメータの設定は以下の通りです。

  • Symbol() → 挿入したチャートの通過ペア。ドル円を指定したい場合は”USDJPY”と書く。
  • OP_BUY →成行買い注文。成行売り注文の場合は「OP_SELL」を指定。
  • Lots → 注文するロット数。プログラムの最上部で定義した変数から値を取得。
  • Ask → 買い注文の価格。売り注文を出したい場合は「Bid」を指定。
  • 10 → スリッページが10ポイント。(※ポイント:最小価格変動単位)
  • 0 → 損切り価格の設定。0で指定なし。設定したい場合は、実際に値を入れるか、事前に定義した変数を代入する。正しく設定しないと注文されないので注意。
  • 0 → 利食い価格の設定。0で指定なし。損切り価格の設定の仕方と同様。
  • NULL → 注文コメントの設定。NULLで設定なし。設定するとログなどに表示される。
  • 0 → マジックナンバーの設定。単一ポジションを扱う場合は0で問題なし。
  • 0 → 有効期限の設定。主に指値・逆指値注文で使う。成行注文の場合は0。
  • clrNONE → 注文時にチャートに表示される矢印の無効化。

⑧売りエントリーの処理

売りエントリーは
「1本前のローソク足の終値がボリンジャーバンド+2σ以上かつ、現在のローソク足が陰線」
となったタイミングでエントリーされます。買いの場合とは逆のロジックです。

また、OrderSend関数は買い注文の第2、4引数を以下のように変更することで売り注文にすることができます。
OP_BUY → OP_SELL
Ask → Bid

まとめ

いかがだったでしょうか。プログラミング初めての方は少し難しく感じたところもあるかもしれませんが、自分で手直しを加えていったり、関数を調べたりすることで、少しずつ理解が深まっていくと思います。本ページで解説したプログラムはそのまま状態では収益を上げることは難しいですが、決済条件やエントリー条件を変えることで、収益を上げられるプログラムに生まれ変わる可能性があります。日頃からチャートを良く分析し、自分なりのチャートの見方を身に付け、それを売買ロジックに落とし込んでいきましょう。

サイトについて

当サイトではFXの中でも特に自動売買に特化した情報を主に初心者の方を対象に提供しております。自動売買ツールであるMT4のインストールから設定、プログラムの書き方などを説明しておりますので、ご自身のトレードにご活用下さい。

MQL4解説