今回は、MT4のEAサンプルソース(FX用)を公開します。
トレードに使うテクニカル分析はMACDで、順張り目線でエントリーしています。
はじめに
MACDのEAはMT4に既存で付属していますが、少しわかりにくいため自作しました。今回は利益を追求したものではないため簡単なソースコードになっております。EAの勉強用・MACDの検証用に使って頂ければと思います。
利益追求型は以下の記事を参照ください↓
EAの仕様
それでは、今回のソースコードのエントリー/決済/パラメータ設定についての仕様を説明します。
エントリータイミング
ロングエントリー
MACDの値が0より下で、MACD値が下から上へゴールデンクロスした場合にロングエントリーします。
ショートエントリー
MACDの値が0より上で、MACD値が上から下へデッドクロスした場合にショートエントリーします。
決済タイミング
プログラム中に決済のコードは入っていません。
エントリー時の損切、利確の設定で決済を行っています。(共に20pips固定)
その他の仕様
設定値は以下の通りです。
- FAST_EMA_PERIOD = 12 ⇒ 短期EMA期間です
- SLOW_EMA_PERIOD = 26 ⇒ 長期EMA期間です
- SIGNAL_SMA_PERIOD = 9 ⇒ シグナル値です
- Lots = 1 ⇒ ロット数です(0.01=1000通貨)
既に建玉がある場合は追加でエントリーはしません。
新しい足(バー)が出来た際に1度だけ処理を行います。※1時間足の場合だと1時間に1回処理する
EAレポート結果
2005年~2020年の期間の1時間足(USDJPY)でバックテスト確認してみました。 やはり、トレード根拠としてMACDだけで戦うのは難しいかもしれませんね。
ダウンロード
上記のEAファイルになります。
“MACD-EA” をダウンロード 7_MACD.ex4 – 3202 回のダウンロード – 9.12 KBソースコード
以下サンプルソースコードと簡単な解説になります。
※丸々コピペでコンパイルできます
//+------------------------------------------------------------------+
//| MACD_Sample.mq4 |
//| Copyright 2020, mef Software. |
//| https://fx-prog.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, mef Software."
#property link "https://fx-prog.com/"
#property version "1.00"
#property strict
input int FAST_EMA_PERIOD = 12;
input int SLOW_EMA_PERIOD = 26;
input int SIGNAL_SMA_PERIOD = 9;
input double Lots = 1;
datetime prevtime;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
int start()
{
int orderPtn=0; //0:何もしない 1:買い 2:売り
int total=0;
int errorcode; // エラーコード
int ea_ticket_No,ea_order_entry_Type=0,ea_order_MagicNo; // チケットNo,エントリタイプ,マジックNo.
double ea_order_stop_price=0,ea_order_good_price=0,ea_order_entry_price=0; //ストップロスレート,利確レート,エントリーレート
//---
//新しい足ができた時だけやる
if(Time[0] != prevtime){
prevtime = Time[0];
}else{
return(0);
}
//***売買判断箇所***//
//MACD状態取得関数から状態を取得
if(getMACDSign(3,1,0)==true)
{
orderPtn=1;
}
else if(getMACDSign(4,1,0)==true)
{
orderPtn=2;
}
else
{
orderPtn=0;
}
//***売買判断箇所***//
//***エントリー箇所***//
//エントリーカウント(既に建玉を保有していたらエントリーしない)
total=OrdersTotal();
if(total == 0 && orderPtn > 0)
{
if(orderPtn == 1)
{
ea_order_entry_price = Ask; // 現在の買値でエントリー
ea_order_entry_Type = OP_BUY; //OP_BUY
ea_order_stop_price = Ask - 200 * Point; //損切りポイント(-20銭)
ea_order_good_price = Ask + 200 * Point; //利喰いポイント(+20銭)
}
else if(orderPtn == 2)
{
ea_order_entry_price = Bid; // 現在の売値でエントリー
ea_order_entry_Type = OP_SELL; //OP_SELL
ea_order_stop_price = Bid + 200 * Point; //損切りポイント(-20銭)
ea_order_good_price = Bid - 200 * Point; //利喰いポイント(+20銭)
}
ea_order_MagicNo=0000; //マジックナンバーは0000固定とする
ea_ticket_No = OrderSend( // 新規エントリー注文
NULL, // 通貨ペア
ea_order_entry_Type, // オーダータイプ[OP_BUY / OP_SELL]
Lots, // ロット(0.01単位,FXTFは1=10Lot)
ea_order_entry_price, // オーダープライスレート
20, // スリップ上限
ea_order_stop_price, // ストップレート
ea_order_good_price, // リミットレート
"テストオーダー", // オーダーコメント
ea_order_MagicNo, // マジックナンバー(識別用)
0, // オーダーリミット時間
clrRed // オーダーアイコンカラー
);
if ( ea_ticket_No == -1) // オーダーエラー
{
errorcode = GetLastError(); // エラーコード取得
if( errorcode != ERR_NO_ERROR) // エラー発生
{
printf("エラー");
}
}
else { // 注文約定
Print("新規注文約定。 チケットNo=",ea_ticket_No);
}
}
return(0);
}
//***エントリー箇所***//
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|【関数】MACDのクロスを探す
//|
//|【引数】 IN OUT 引数名 説明
//| ---------------------------------------------------------
//| ○ aType 上下
//| 1:下から上へ
//| 2:上から下へ
//| 3:下から上へ(マイナス域の場合のみ)
//| 4:上から下へ(プラス域の場合のみ)
//|
//| ○ limit どこまで遡るか
//| ○ i 現在のBar位置
//|【戻値】True(クロス有り) or False(クロス無し)
//|
//|【備考】なし
//+------------------------------------------------------------------+
bool getMACDSign(int type,int limit,int i)
{
int n;
bool sign = false;
double MACD_1,Signal_1,MACD_2,Signal_2;
limit = i + limit;
i = i + 1;
//下から上へのクロス
if(type==1){
for(n=i;n<=limit;n++){
MACD_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n);
MACD_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n+1);
Signal_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n);
Signal_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n+1);
if(MACD_2 <= Signal_2 && MACD_1 > Signal_1)
{
sign=true;
break;
}
}
}
//上から下へのクロス
else if(type==2){
for(n=i;n<=limit;n++){
MACD_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n);
Signal_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n);
MACD_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n+1);
Signal_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n+1);
if(MACD_2 >= Signal_2 && MACD_1 < Signal_1)
{
sign=true;
break;
}
}
}
//下から上へのクロス
if(type==3){
for(n=i;n<=limit;n++){
MACD_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n);
MACD_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n+1);
Signal_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n);
Signal_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n+1);
if(MACD_2 <= Signal_2 && MACD_1 > Signal_1 && MACD_1 <= 0 )
{
sign=true;
break;
}
}
}
//上から下へのクロス
else if(type==4){
for(n=i;n<=limit;n++){
MACD_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n);
Signal_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n);
MACD_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n+1);
Signal_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n+1);
if(MACD_2 >= Signal_2 && MACD_1 < Signal_1 && MACD_1 >= 0 )
{
sign=true;
break;
}
}
}
return(sign);
}
getMACDSign() ※自作関数
getMACDSign()関数を作ってそこで判断するようにしています。この関数だけコピペしてもらえばMACDのクロス判断はできるようになります。
やっていることは簡単で、iCustom()関数でMACDの値及びSignalの値を取得し、大小を比較しています。
デッドクロス後の例ですが、クロス後は必ずSignal値(赤の線)よりMACD値(水色の線)の方が小さくなるので、Signal値よりもMACD値の方が小さい場合はクロスしたと判定しています。
引数についてはサンプルソースに記載の通り3つです。戻り値は、クロスしていたらTrue、クロスしていなければFalseです。
MACDの0ラインに関わらずエントリーしたい場合(引数1)
サンプルソースでは、MACDの0ラインより上でゴールデンクロスした場合、ロングエントリーしません。逆(ショート時)もしかりです。
もし0ラインに関わらずエントリーしたい場合、サンプルソースのgetMACDSign(3,1,0)をgetMACDSign(1,1,0)にすると、MACDの値が0より下かどうかに関係なく下から上へクロスした場合にロングエントリーするようになり、getMACDSign(4,1,0)をgetMACDSign(2,1,0)にすると、MACDの値が0より上かどうかに関係なく上から下へクロスした場合にショートエントリーするようになります。
クロス状態を維持したい場合(引数2)
ゴールデン(デッド)クロス後、しばらくクロスしたという状態を返したい場合は、getMACDSign(3,1,0)をgetMACDSign(3,5,0)のようにすれば、クロスした後も5つバーまではクロスしたという(trueが返ってくる)状態になります。
これは、主にMACD以外のエントリータイミングも併用する場合に使えます。例えば、ゴールデンクロス後、RSIの値が落ち着いたらエントリーする等です。
バーシフトの役割(引数3)
クロスしたと判断するタイミングを1つ後ろにずらしたい場合、getMACDSign(3,1,0)をgetMACDSign(3,2,1)にすることでずらすことが可能です。
※基本的な関数にも常備されているバーシフトと同じ役割です
主な構文
iCustom()
【使用例】 iCustom(NULL,0,"MACD",12,26,9,0,1);
引数は以下の通りです。
- 通貨ペア(NULLで当該通貨)
- 時間軸(0で当該時間軸)
- インジケータ名称(MACDを使う場合”MACD”でOKです)
- 短期EMA期間
- 長期EMA期間
- シグナルライン期間
- 取得する値(0:MACD値 1:Signal値)
- バーシフト
iMACD()関数は使わずに、iCustom()関数でMACDの値を取得しています。
※iMACD()関数と基本的に全く同じ値が返ってきますので、以下のようにiMACD()関数に書き換えてもらっても結果は同じです
【使用例】 iCustom(NULL,0,"MACD",12,26,9,0,n); //MACD値 ↓ iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,n); //MACD値 iCustom(NULL,0,"MACD",12,26,9,1,n); //Signal値 ↓ iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,n); //Signal値
さいごに
以上、MACDを使ったEAのサンプルソースでした。
今回はシンプルに作ったため利益をあげるEAにはなっていませんが、EAを作ったりMACDを検証したりする助けになれば幸いです。
※ EAのサンプルソースを一覧表にまとめました
※オンラインレッスンやってます
コメント