今回は、MT4のEAサンプルソース(FX用)を公開します。
トレードに使うテクニカル分析はMACDと移動平均線(MA)で、順張りエントリーをしています。
はじめに
今回も、お問合せで頂いた内容について解決していきたいと思います。とてもベーシックな手法なので記事にしようと思います。
以下のような内容を頂きました。
価格が移動平均線より上だった場合はMACDのシグナル線とのゴールデンクロスで買いエントリー
┗デットクロスで決済
価格が移動平均線より下だった場合はMACDのシグナル線とのデットクロスで売りエントリー
┗ゴールデンクロスで決済
を実現したいが、どうやってEAを作ったらいいか教えて欲しい。
今回はこの手法のEAを作成し解説させて頂くことにしました。
それでは作っていきましょう!
EAを作る下準備
まずは、今回のEAを作るための下準備をします。
①ベースソース選び
まずは、1からEAを作っても時間がかかるだけなのでベースのソースコードを選びます。
今回は新規注文と決済にMACDを使うため、これを流用していきます。
この記事のサンプルソースを使ってEAを作って行きます。
②移動平均線の情報取得の確認
お問合せ内容にもあった通り、今回は移動平均線の情報が必要なのでそのソースコードのおさらいです。簡単です。
double dMA_atai = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0);
移動平均線の情報を取得するための関数はiMA()関数ですね!これで今回のEAを作成するための材料は出そろいました。
エントリーポイントの確認
次に、EAの肝であるエントリーポイントや決済ポイントを検討していきます。
以下は、ベースEAのMACDのゴールデンクロスで買い、デッドクロスで決済というEAになります。
青矢印が買い、赤矢印が売りエントリーです。ベースのEAなので当たり前ですが赤色表示されている移動平均線は考慮できていません。
今回は移動平均線の上に価格がある場合にロングエントリー、ショートは移動平均線の下にあった場合にショートエントリーしないといけないので、黄色丸の部分はエントリーしてはいけない事になります。
この部分を修正していくことになります。
ソースコード
では実際に修正したサンプルソースコードになります。濃い色になっている箇所が主な修正ポイントです。
※丸々コピペでコンパイルできます
//+------------------------------------------------------------------+
//| MACD_MA_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 MA_KIKAN = 21;
input int MACD_FAST = 12;
input int MACD_SLOW = 26;
input int MACD_SIGNAL = 9;
input int A_SPREAD = 150;
input double Lots = 0.01;
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_entry_price=0; //ストップロスレート,利確レート,エントリーレート
color order_Color = clrRed;
//---
//新しい足ができた時だけやる
if(Time[0] != prevtime){
prevtime = Time[0];
}else{
return(0);
}
//***売買判断箇所***//
double MA_ATAI = iMA(NULL, 0, MA_KIKAN, 0, 1, PRICE_CLOSE, 1);
//MACD状態取得関数から状態を取得
if(getMACDSign(3,1,0)==true && MA_ATAI < Ask)
{
orderPtn=1;
}
else if(getMACDSign(4,1,0)==true && MA_ATAI > Bid)
{
orderPtn=2;
}
else
{
orderPtn=0;
}
//***売買判断箇所***//
//***決済判断箇所***//
total=OrdersTotal();
if(total == 1){
bool OrderKekka = OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
//買いエントリー中に、上から下にMACDがクロスしたら決済する
if(OrderKekka == true && OrderType() == OP_BUY && getMACDSign(2,1,0)==true){
OrderKekka = OrderClose(OrderTicket(),OrderLots(),Bid,10,Violet);
}
//売りエントリー中に、下から上にMACDがクロスしたら決済する
else if(OrderKekka == true && OrderType() == OP_SELL &&getMACDSign(1,1,0)==true){
OrderKekka = OrderClose(OrderTicket(),OrderLots(),Ask,10,Violet);
}
}
else if(total == 0 && orderPtn > 0)
{
if(orderPtn == 1)
{
ea_order_entry_price = Ask; // 現在の買値でエントリー
ea_order_entry_Type = OP_BUY; //OP_BUY
order_Color = clrBlue;
int index = iLowest(NULL,0,MODE_LOW,24,1); //直近24本前の最安値のバーを探す
}
else if(orderPtn == 2)
{
ea_order_entry_price = Bid; // 現在の売値でエントリー
ea_order_entry_Type = OP_SELL; //OP_SELL
order_Color = clrRed;
int index = iHighest(NULL,0,MODE_HIGH,24,1); //直近24本前の最高値のバーを探す
}
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, // スリップ上限
0, // ストップレート
0, // リミットレート
"テストオーダー", // オーダーコメント
ea_order_MagicNo, // マジックナンバー(識別用)
0, // オーダーリミット時間
order_Color // オーダーアイコンカラー
);
if ( ea_ticket_No == -1) // オーダーエラー
{
errorcode = GetLastError(); // エラーコード取得
if( errorcode != ERR_NO_ERROR) // エラー発生
{
printf("エラー:"+ IntegerToString(errorcode));
}
}
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",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n);
MACD_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n+1);
Signal_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n);
Signal_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,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",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n);
Signal_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n);
MACD_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n+1);
Signal_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,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",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n);
MACD_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n+1);
Signal_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n);
Signal_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,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",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n);
Signal_1 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n);
MACD_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,0,n+1);
Signal_2 = iCustom(NULL,0,"MACD",MACD_FAST,MACD_SLOW,MACD_SIGNAL,1,n+1);
if(MACD_2 >= Signal_2 && MACD_1 < Signal_1 && MACD_1 >= 0 )
{
sign=true;
break;
}
}
}
return(sign);
}
53行目、56行目、60行目で対応しているので確認してみてください。
どうですか?MACDに移動平均線の条件も組み込む・・・。意外に簡単ですよね!パラメータ等の細かいEAの仕様は以下に記載します。
EAの仕様
上記ソースコードのエントリー/決済/パラメータ設定についての仕様です。
エントリータイミング
ロングエントリー
価格が移動平均線より上だった場合はMACDのシグナル線とのゴールデンクロスした場合にロングエントリー。
ショートエントリー
価格が移動平均線より下だった場合はMACDのシグナル線とのデットクロスした場合にショートエントリー。
決済タイミング
ロング決済
ロングポジション保持中に、デッドクロスした場合に決済。
ショート決済
ショートポジション保持中に、ゴールデンクロスした場合に決済。
その他の仕様
主な設定値は以下の通りです。
- MA_KIKAN = 21 ⇒ 移動平均線側の期間設定です。
- MACD_FAST = 12 ⇒ MACD側の短期EMAの期間設定です。
- MACD_SLOW = 26 ⇒ MACD側の長期EAMの期間設定です。
- MACD_SIGNAL = 9 ⇒ MACD側のシグナル設定です。
- A_SPREAD = 150 ⇒ エントリー及び決済時に許容するスプレッドの値です(150 = 15pips)
- Lots = 0.01 ⇒ ロット数です(0.01=1000通貨)
ポジションは最大1ポジションです。
新しい足(バー)が出来た際に1度だけ処理を行います。※1時間足の場合だと1時間に1回処理する
今回は決済条件があるため指値、逆指値は設定していません。
EAレポート結果
作った後は、バックテストでちゃんと思った通りの動きになっている事を確認しましょう。
移動平均線の条件を加えた事で、ベースのEAよりも取引数が減少しました。
※ベースのEAは2005~2020の期間で4796件の取引だったため
ビジュアルモードで確認してみてもわかりますが、思った通りの動きになっていますね!先ほどの黄色丸の部分でエントリーされなくなりました。
ダウンロード
上記のEAファイルになります。
“MACDとMAのEA” をダウンロード 7_MACD3.ex4 – 164 回のダウンロード – 10.05 KBさいごに
以上、MACDと移動平均線を使ったEAのサンプルソースでした。
今回は、ベースプロググラムからあまり変更を加えずに対応できたので記事を書くのも含めて2時間程で対応できました。手法がベーシックな事もあり記事にさせて頂きました。
また、当ブログのソースコードベースで条件追加等すこし修正して欲しい場合につきまして、簡単な対応であれば無償で対応いたしますのでお気軽にお問合せください。
※条件が複雑なものに関してはご相談→対応するにあたり料金が発生する場合もございます
※ EAのサンプルソースを一覧表にまとめました
※オンラインレッスンやってます
コメント