今回は、MT4のEAサンプルソース(FX用)を公開します。
トレードに使うテクニカル分析は一目均衡表と移動平均線(MA)で、順張りエントリーをしています。
はじめに
今回は、ブログへのお問合せで頂いた内容について解決していきたいと思います。
以下のような内容を頂きました。
自分の決めたルール通りにトレードがなかなかできないので、EAを使いたいと思い勉強中です。 一目均衡表の先行スパンと指数移動平均のゴールデンクロス、デットクロスを使用したEAを作りたいのですが、機会があらば説明載せて頂きたいです
裁量トレードだと手法が確立されていても中々思い通りにトレード出来ないですよね。私もそうでした。しかも上記の手法はとてもシンプルなので、EAを使うのがベストだと思います。
ということで!
今回はこの手法のEAを作成し解説させて頂くことにしました。
それでは作っていきましょう!
EAを作る下準備
まずは、今回のEAを作るための下準備をします。
①ベースソース選び
まずは、1からEAを作っても時間がかかるだけなのでベースのソースコードを選びます。
前に、一目均衡表を使ったEAを作っていたのでこれを流用していきます。
②トレード手法に必要な情報の確認
今回は一目均衡表の先行スパンAの値と、指数移動平均線の値を取得する事が必須です。この情報は簡単に取得できるの?という所ですが以下が思い浮かべば簡単だとわかります。
iCustom(NULL,0,"Ichimoku",9,26,52,2,1); //先行スパンA iMA(NULL, 0, FasterMA, 0, MAMode, PRICE_CLOSE, 1); //指数移動平均線
エントリーポイントの確認
次に、EAの肝であるエントリーポイントや決済ポイントを洗い出していきます。上記のお問合せ内容だけでは不明点もあったので詳細を確認させて頂いた所、以下の通りでした。
まず黄色い線の先行スパンAと、赤い線の指数移動平均線を見ます。
この2つの線のゴールデンクロスやデッドクロスでエントリーしていく形です。以下は詳細なエントリータイミングです。
EAの仕様
それでは、今回のソースコードのエントリー/決済/パラメータ設定についての仕様を説明します。
エントリータイミング
ロングエントリー
指数移動平均線が先行スパンAを上抜けるとロングエントリー(ショートポジションがあれば決済)という形です。
ショートエントリー
指数移動平均線が先行スパンAを下抜けるとショートエントリー(ロングポジションがあれば決済)
決済タイミング
今回は、ロングエントリー時にショートポジションがあれば決済、またはショートエントリー時にロングポジションがあれば決済するような形です。
その他の仕様
主な設定値は以下の通りです。
- FasterMA = 21 ⇒ 指数移動平均線の期間設定です。
- A_SPREAD = 50 ⇒ エントリー及び決済時に許容するスプレッドの値です(20 = 2pips)
- Lots = 0.01 ⇒ ロット数です(0.01=1000通貨)
ポジションは最大1ポジションです。
新しい足(バー)が出来た際に1度だけ処理を行います。※1時間足の場合だと1時間に1回処理する
指値、逆指値は設定していません。
ここまで確認できたからあとはガーっと作りこむだけですね!
EAレポート結果
作った後は、バックテストでちゃんと思った通りの動きになっているかや、良い成績になっているかどうかを確認します。
2020年~2023年の期間を1時間足でバックテスト確認してみました。特に指数移動平均線の値や他の微調整等もしていませんがいい感じのプラスになりました。直近でですが有効性の高い手法だと言えます。
ビジュアルモードで確認してみてもわかりますが、思った通りの動きになっていますね!
ビジュアルモードで確認してみてもわかりますが、思った通りの動きになっていますね!
あと、ポジションは基本常時持つような感じです。
ダウンロード
上記のEAファイルになります。
“一目均衡表-MA” をダウンロード 25_Ichimoku-MA.ex4 – 957 回のダウンロード – 14.07 KBソースコード
以下サンプルソースコードになります。
※丸々コピペでコンパイルできます
//+------------------------------------------------------------------+
//| 25_Ichimoku-MA.mq4 |
//| Copyright 2020, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, mef Software."
#property link "https://fx-prog.com/"
#property version "1.00"
input int FasterMA = 21;
int MAMode = 1; // 0 = sma, 1 = ema, 2 = smma, 3 = lwma
input int A_SPREAD = 50;
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;
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);
}
//***一目均衡表とMAの値取得***//
double SenkouSpanA_1 = iCustom(NULL,0,"Ichimoku",9,26,52,2,1);
double fasterMA_1 = iMA(NULL, 0, FasterMA, 0, MAMode, PRICE_CLOSE, 1);
double SenkouSpanA_2 = iCustom(NULL,0,"Ichimoku",9,26,52,2,2);
double fasterMA_2 = iMA(NULL, 0, FasterMA, 0, MAMode, PRICE_CLOSE, 2);
//***売買判断箇所***//
//ゴールデンクロスでロング
if(fasterMA_1 > SenkouSpanA_1 && SenkouSpanA_2 > fasterMA_2){
orderPtn = 1;
}
//デッドクロスでショート
else if(fasterMA_1 < SenkouSpanA_1 && SenkouSpanA_2 < fasterMA_2){
orderPtn = 2;
}else{
orderPtn = 0;
}
//***決済判断箇所***//
total=OrdersTotal();
if(total == 1 ){
bool OrderKekka = OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
if(OrderType() == OP_BUY && orderPtn == 2){
OrderKekka = funcOrder_Close();
orderPtn = 2;
}
if(OrderType() == OP_SELL && orderPtn == 1){
OrderKekka = funcOrder_Close();
orderPtn = 1;
}
}
total=OrdersTotal();
//***エントリー箇所***//
if(total == 0 && orderPtn > 0)
{
ea_order_stop_price = 0;
ea_order_good_price = 0;
//新規注文
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:成功 False:失敗
//|
//|
bool funcOrder_Send(int ea_order_entry_Type, double ea_order_stop_price, double ea_order_good_price,string orderComment,int ea_order_MagicNo)
{
int order_resend_num; // エントリー試行回数
int ea_ticket_res; // チケットNo
double ea_order_entry_price; // エントリーレート
color order_Color;
bool kekka;
kekka=false;
for( order_resend_num = 0; order_resend_num < 10; order_resend_num++ ) { // エントリー試行回数上限:10回
//スプレッドが1銭未満の場合のみ新規注文する(2銭未満にしたい場合は20にする)
if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD){
if(ea_order_entry_Type == OP_BUY){
ea_order_entry_price = Ask; // 現在の買値でエントリー
order_Color = clrBlue;
}else if(ea_order_entry_Type == OP_SELL){
ea_order_entry_price = Bid; // 現在の売値でエントリー
order_Color = clrRed;
}
ea_ticket_res = OrderSend( // 新規エントリー注文
NULL, // 通貨ペア
ea_order_entry_Type, // オーダータイプ[OP_BUY / OP_SELL]
Lots, // ロット数
ea_order_entry_price, // オーダープライスレート
20, // スリッページ
ea_order_stop_price, // ストップレート
ea_order_good_price, // リミットレート
orderComment, // オーダーコメント
ea_order_MagicNo, // マジックナンバー
0, // オーダーリミット時間
order_Color // オーダーアイコンカラー
);
if ( ea_ticket_res == -1) {
Print("エントリー失敗 エラーNo=",GetLastError()," リトライ回数=",order_resend_num+1);
Sleep(5000); // msec待ち
RefreshRates(); // レート更新
} else { // 注文約定
Print("新規注文約定。 レート:",ea_order_entry_price," チケットNo=",ea_ticket_res," オーダーマジックNo=",ea_order_MagicNo);
Sleep(500); // 500msec待ち
kekka=true;
break;
}
}else{
Print("スプレッド拡大中(銭)=",MarketInfo(NULL,MODE_SPREAD) / 10," リトライ回数=",order_resend_num+1);
Sleep(5000); // msec待ち
RefreshRates(); // レート更新
}
}
return kekka;
}
//+------------------------------------------------------------------+
//|【関数】決済関数
//|
//|【引数】 なし
//|
//|【戻値】True:成功 False:失敗
//|
//|
bool funcOrder_Close()
{
bool kekka,OrderKekka;
int total,order_resend_num;
double ea_order_entry_price; // エントリーレート
color order_Color;
kekka=false;
for(order_resend_num = 0; order_resend_num < 100; order_resend_num++ ) {
if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD){
total=OrdersTotal();
if(total >0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true){
if(OrderType() == OP_BUY){
ea_order_entry_price = Bid; // 現在の売値で決済
order_Color = clrLightBlue;
}else if(OrderType() == OP_SELL){
ea_order_entry_price = Ask; // 現在の買値で決済
order_Color = clrLightPink;
}
OrderKekka = OrderClose(OrderTicket(),OrderLots(),ea_order_entry_price,10,order_Color);
if(OrderKekka==false){
Print("決済失敗 エラーNo=",GetLastError()," リトライ回数=",order_resend_num+1);
RefreshRates();
Sleep(1000);
}else{
Print("決済注文約定。 レート=",ea_order_entry_price);
kekka=true;
break;
}
}
}else{
Print("スプレッド拡大中(銭)=",MarketInfo(NULL,MODE_SPREAD) / 10," リトライ回数=",order_resend_num+1);
Sleep(5000); // msec待ち
RefreshRates(); // レート更新
}
}
return kekka;
}
49行目~67行目が最重要ポイントです。ここでエントリーを管理しています。
※2つの値を取得するのがポイント
if(fasterMA_1 > SenkouSpanA_1 && SenkouSpanA_2 > fasterMA_2){
orderPtn = 1;
}
else if(fasterMA_1 < SenkouSpanA_1 && SenkouSpanA_2 < fasterMA_2){
orderPtn = 2;
}
さいごに
以上、一目均衡表と指数移動平均線を使ったEAのサンプルソースでした。
今回は、手法がとてもシンプルな事もあり20分程で完成しました。EA作りは慣れるまでは大変ですが、慣れると簡単な手法であればすぐに作ってバックテストで検証・確認ができるので是非身に着けてほしいです。
また、当ブログのソースコードベースで条件追加等すこし修正して欲しい場合につきまして、簡単な対応であれば無償で対応いたしますのでお気軽にお問合せください。
※ EAのサンプルソースを一覧表にまとめました
※EA作成依頼はこちら
※オンラインレッスンやってます
コメント
問い合わせした者です。
とても参考になりました。ありがとうございます。
利確、損切りルールをしっかり決めることでさらに良いEAになるのかなと思ってます。
これを元に利確損切りルールを設定できるように頑張ります