今回は、MT4のEAサンプルソース(FX用)を公開します。
トレードに使うテクニカル分析はテクニカル分析の王道、移動平均線で順張りエントリーをしています。
はじめに
今回は移動平均線のゴールデンクロス・デッドクロスでエントリーしていく正にトレードの王道というべき手法のサンプルを載せています。
移動平均線といえば、ローソク足の終値が移動平均線を上抜けたらロングエントリーしていくような手法もありますが、そちらのサンプルを確認したい場合はこちらの記事を参照ください。
EAの仕様
それでは、今回のソースコードのエントリー/決済/パラメータ設定についての仕様を説明します。
エントリータイミング
ロングエントリー
ゴールデンクロスでロングエントリーします。
- ①1つ前の移動平均線の値が、中期より短期の方が高くなっている
- ②2つ前の移動平均線の値が、中期より短期の方が低くなっている
- ③1つ前の短期移動平均線の値より、2つ前の移動平均線の値が低くなっている
この3つの条件がそろった場合、ゴールデンクロスしたとみなしてロングエントリーします。
ショートエントリー
デッドクロスでショートエントリーします。
- ①1つ前の移動平均線の値が、中期より短期の方が低くなっている
- ②2つ前の移動平均線の値が、中期より短期の方が高くなっている
- ③1つ前の短期移動平均線の値より、2つ前の移動平均線の値が高くなっている
この3つの条件がそろった場合、デッドクロスしたとみなしてショートエントリーします。
エントリー例
決済タイミング
エントリー時の逆指値、指値でのみ管理。
損切りポイントは中期MAから設定値SL_GOSAの値分離れた場所にしています。
指値は、公平性も兼ねて逆指値と同じ分をプラス側で指値としています。
その他の仕様
設定値は以下の通りです。
- FasterMA = 21 ⇒ 短期移動平均線の期間です
- MediumMA = 84 ⇒ 中期移動平均線の期間です
- A_SPREAD = 20 ⇒ エントリー時に許容するスプレッドの値です(20 = 2pips)
- Lots = 0.01 ⇒ ロット数です(0.01=1000通貨)
既にポジションがある場合は追加でエントリーしません。
新しい足(バー)が出来た際に1度だけ処理を行います。※1時間足の場合だと1時間に1回処理する
EAレポート結果
2005年~2020年の期間の15分足でバックテスト確認してみました。2016年の9月までは右肩上がりですが、2016年の10月以降は微妙な形になっています。最適化して良さそうな設定を選んだのですが、近年の値動きには対応できていないような感じですね・・・。
近年向けの設定を考慮すると、こちらの方が良さそうです。
短期MA、中期MA、ストップロス位置の設定が小さくなっています。こちらは2009年の3月以降右肩上がりのグラフになっています。
短期MA、中期MAの期間を小さくしているのでゴールデンクロス、デッドクロス値動きに対する反応速度が上がったのと、ストップロスを浅めにしたことで近年利益が上がった感じになっています。ここ最近のドル円の値動きを見ていると少し納得の結果となりました。
ダウンロード
上記のEAファイルになります。
“移動平均線EA” をダウンロード 1_MA.ex4 – 5057 回のダウンロード – 9.71 KBソースコード
以下サンプルソースコードになります。
※丸々コピペでコンパイルできます
//+------------------------------------------------------------------+
//| IMA_TEST.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"
input int FasterMA = 21;
input int MediumMA = 84;
input int A_SPREAD = 20;
input double Lots = 0.01;
int MAShift = 0;
int MAMode = 1; // 0 = sma, 1 = ema, 2 = smma, 3 = lwma
input int SL_GOSA = 60;
double maisuu=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;
double ea_order_stop_price=0,ea_order_good_price=0; //ストップロスレート,利確レート,エントリーレート
bool OrderKekka;
//---
//新しい足ができた時だけやる
if(Time[0] != prevtime){
prevtime = Time[0];
}else{
return(0);
}
//***売買判断箇所***//
//----MA短期値取得
double fasterMA_ATAI_1 = iMA(NULL, 0, FasterMA, MAShift, MAMode, PRICE_CLOSE, 1); //短期移動平均線で1つ前の値を取得
double fasterMA_ATAI_2 = iMA(NULL, 0, FasterMA, MAShift, MAMode, PRICE_CLOSE, 2); //短期移動平均線で2つ前の値を取得
//----MA中期値取得
double MediumMA_ATAI_1 = iMA(NULL, 0, MediumMA, MAShift, MAMode, PRICE_CLOSE, 1); //中期移動平均線で1つ前の値を取得
double MediumMA_ATAI_2 = iMA(NULL, 0, MediumMA, MAShift, MAMode, PRICE_CLOSE, 2); //中期移動平均線で2つ前の値を取得
//MAのゴールデンクロスでロング(短期MAが上を向いている事)
if(fasterMA_ATAI_1 > MediumMA_ATAI_1 && fasterMA_ATAI_2 < MediumMA_ATAI_2 && fasterMA_ATAI_1 > fasterMA_ATAI_2)
{
orderPtn=1;
}
//MAのデッドクロスでショート(短期MAが下を向いている事)
else if(fasterMA_ATAI_1 < MediumMA_ATAI_1 && fasterMA_ATAI_2 > MediumMA_ATAI_2 && fasterMA_ATAI_1 < fasterMA_ATAI_2)
{
orderPtn=2;
}
else
{
orderPtn=0;
}
//***売買判断箇所***//
//***決済判断箇所***//
total=OrdersTotal();
if(total ==0 && orderPtn > 0)
{
if(orderPtn == 1)
{
ea_order_stop_price = MediumMA_ATAI_1 - SL_GOSA * Point;
ea_order_good_price = Ask + ((Ask - ea_order_stop_price) * 1000 * Point);
}
else if(orderPtn == 2)
{
ea_order_stop_price = MediumMA_ATAI_1 + SL_GOSA * Point;
ea_order_good_price = Bid - ((ea_order_stop_price - Bid) * 1000 * Point);
}
//新規注文
OrderKekka = funcOrder_Send(orderPtn - 1,ea_order_stop_price,ea_order_good_price,0,0);
}
return(0);
}
//+------------------------------------------------------------------+
//|【関数】新規注文関数 |
//| |
//|【引数】 ea_order_entry_Type:売買(0:買 1:売) |
//|【引数】 ea_order_stop_price:損切値 ea_order_good_price:利確値 |
//|【引数】 orderComment:オーダーコメント ea_order_MagicNo:マジックNo |
//| |
//|【戻値】True:成功 |
//| |
//|
bool funcOrder_Send(int ea_order_entry_Type, double ea_order_stop_price, double ea_order_good_price,int orderComment,int ea_order_MagicNo)
{
int order_resend_num; // エントリー試行回数
int ea_ticket_res; // チケットNo
int errorcode; // エラーコード
double ea_order_entry_price; // エントリーレート
color order_Color;
bool kekka;
for( order_resend_num = 0; order_resend_num < 10; order_resend_num++ ) { // エントリー試行回数上限:10回
if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD ){
if(ea_order_entry_Type == OP_BUY){
ea_order_entry_price = Ask; // 現在の買値でエントリー
order_Color = clrBlue;
Print(Ask+"でロングするよ!");
}else if(ea_order_entry_Type == OP_SELL){
ea_order_entry_price = Bid; // 現在の売値でエントリー
order_Color = clrRed;
Print(Bid+"でショートするよ!");
}
// FXCMでは新規エントリー時にストップ/リミットを設定出来ない。
ea_ticket_res = OrderSend( // 新規エントリー注文
NULL, // 通貨ペア
ea_order_entry_Type, // オーダータイプ[OP_BUY / OP_SELL]
Lots , // ロット[0.01単位](FXTFは1=10Lot)
ea_order_entry_price, // オーダープライスレート
20, // スリップ上限 (int)[分解能 0.1pips]
ea_order_stop_price, // ストップレート
ea_order_good_price, // リミットレート
orderComment, // オーダーコメント
ea_order_MagicNo, // マジックナンバー(識別用)
0, // オーダーリミット時間
order_Color // オーダーアイコンカラー
);
Print("結果:"+ea_ticket_res);
if ( ea_ticket_res == -1) { // オーダーエラー
errorcode = GetLastError(); // エラーコード取得
if( errorcode != ERR_NO_ERROR) { // エラー発生
printf("エラー");
}
Sleep(2000); // 1000msec待ち
RefreshRates(); // レート更新
printf("再エントリー要求回数:%d, 更新エントリーレート:%g",order_resend_num+1 ,ea_order_entry_price);
} else { // 注文約定
Print("新規注文約定。 チケットNo=",ea_ticket_res," レート:",ea_order_entry_price);
Sleep(300); // 300msec待ち(オーダー要求頻度が多過ぎるとエラーになる為)
break;
}
}else{
Print("スプレッドNG 許容スプレッド:"+A_SPREAD+"pips未満 環境スプレッド:"+MarketInfo(NULL,MODE_SPREAD)+"pips");
Sleep(2000); // 2000msec待ち
RefreshRates();
}
}
return kekka;
}
移動平均線の期間や種別を変更したい場合
上記サンプルソースは設定値として移動平均線の短期及び中期の期間を変更できるようにしています。
また、種別は指数移動平均線で作っていますが、先頭部のint MAMode = 1;の部分を変更すると、種別の切り替えが可能です。
※あまり触る事は無いかなと思って設定値にしませんでした
主な構文
iMA()
【使用例】 double dMA_atai = iMA(NULL, 0, 20, 0, MODE_SMA, PRICE_CLOSE, 0);
今回は、移動平均線の値を取得できるiMA()関数を使っています。
引数は以下の通りです。
- 引数1・・・通貨ペアです(NULLでチャートの通貨になります)
- 引数2・・・時間軸です(0でチャートの時間軸になります)
- 引数3・・・期間です(20で20移動平均線、25で25移動平均線になります)
- 引数4・・・表示移動です
- 引数5・・・移動平均の種別です(MODE_SMAで単純移動平均線)
- 引数6・・・適用価格です(PRICE_CLOSEでクローズ値)
- 引数7・・・バーシフトです(0で現在の値、1で1つ前ーのバーの時の値です)
基本的に、3,5,7ぐらいしか触らなさそうな設定ですね。
3:期間、5:移動平均線の種別はMT4の移動平均線設定画面上で見るとイメージしやすいですね。
期間は、何日(20日)移動平均線とかのあの数値です。
移動平均線の種別は、以下4種類です。
- 単純移動平均線:MODE_SMA
- 指数移動平均線:MODE_EMA
- 平滑移動平均線:MODE_SMMA
- 線形加重移動平均線:MODE_LWMA
7:バーシフトは過去の移動平均線値をとりたい場合変更します(0:最新バーの位置、1:1つ前のバーの位置)
さいごに
以上、移動平均線を使ったEAのサンプルソースでした。
移動平均線オンリーでEAを作る事は難しいかもしれませんが、短期、中期以外にも長期、超短期移動平均線等を組み合わせることで良いEAに化けたりする事があります。
※移動平均線の短期、中期、長期等の設定値に困った場合はこちら
※移動平均線の角度の強弱でエントリーしたい・・・と思った場合はこちら
※ MT4・EAが使えるFX会社のおすすめ
※ EAのサンプルソースを一覧表にまとめました
コメント
このままコンパイルしてみたのですが エントリーしないようです
やり方が悪いでしょうか?
パラメータ設定のA_SPREAD=10を20とかにしてもエントリーしないでしょうか?
初期設定が10なので1pips以上スプレッドが開ているとエントリーしないようになっています。