移動平均を勢い良くブレイクアウトした場合に飛び乗るシステム
「ゼロからはじめるEA開発」シリーズの番外編として、「ゼロからはじめるEA開発」で開発したシステムを少し変更して「移動平均を勢い良くブレイクアウトした場合に仕掛ける」というシステムに変更します。
これはマネー報道さん(ブログ:マネー報道 MoneyReport)が記事で書いていた手法です。(どの記事に書いてあったかわからないです;;)
上の画像にあるように移動平均線を大きな陽線(あるいは陰線)が突き抜けた(ブレイクアウトした)場合に仕掛けます。陽線であれば「買い」で陰線であれば「売り」です。(上の画像は「陰線」のため「売り」です)
手仕舞いの手法は書いていなかったため、手仕舞いはこちらで勝手に追加しました。
手法概要
移動平均を2本にして、短期移動平均を手仕舞い用のシグナルとして使うことにしました。
オープン条件(買い)
- 長期移動平均を大きく下から上へブレイクアウト
- 短期移動平均より価格が上
オープン条件(売り)
- 長期移動平均を大きく上から下へブレイクアウト
- 短期移動平均より価格が下
クローズ条件
- ストップロス または テイクプロフィットでクローズ
- 買いの場合、短期移動平均より価格が下
- 売りの場合、短期移動平均より価格が上
プログラミング
「ゼロからはじめるEA開発」で開発したシステムをベースにします。(パラメーターや処理をコピーして作りました)
移動平均が2本あるため、EMAPeriodをFastEMAPeriod、SlowEMAPeriodにします。
input int SlowEMAPeriod = 80; input int FastEMAPeriod = 25;
fastEMAはオープン、クローズ両方で使用するため、iMA関数をfastEMAにしてslowEMAはオープンの時のみ呼び出します。
double fastEMA = iMA(Symbol(),0,FastEMAPeriod,0,MODE_EMA,PRICE_CLOSE,0);
if(OrdersTotal() == 0)
{
double slowEMA = iMA(Symbol(),0,SlowEMAPeriod,0,MODE_EMA,PRICE_CLOSE,0);
オープン条件(買い)を以下のように書き換えます。(コメントで修正前のコードを残しています)
//if(Ask > ema) if(Close[0] > slowEMA && slowEMA > Open[0] && Close[0] > fastEMA)
売りも同様に変更…
//if(ema > Bid) if(Open[0] > slowEMA && slowEMA > Close[0] && fastEMA > Close[0])
クローズ条件は以下のようにします。
if(OrderType() == OP_BUY && fastEMA > Ask)
{
result = OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,clrBlue);
}
else if(OrderType() == OP_SELL && Bid > fastEMA)
{
result = OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,clrRed);
}
これで完成です。
以下、プログラム全文。
//+------------------------------------------------------------------+
//| MABreakout.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property copyright ""
#property link ""
#property version "1.00"
#property strict
#include <ErrorMessage.mqh>
input int Magic = 123465;
input double Lots = 0.1;
input int Slippage = 2;
input string OrdersComment = "MABreakout";
input int StopLoss = 400;
input int TakeProfit = 2400;
input int SlowEMAPeriod = 80;
input int FastEMAPeriod = 25;
input double HeightPercent = 0.45;
datetime OpenBarTime = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
double fastEMA = iMA(Symbol(),0,FastEMAPeriod,0,MODE_EMA,PRICE_CLOSE,0);
if(OrdersTotal() == 0)
{
double slowEMA = iMA(Symbol(),0,SlowEMAPeriod,0,MODE_EMA,PRICE_CLOSE,0);
double barHeight = MathAbs(Close[0] - Open[0]);
double percentage = (barHeight / Ask) * 100;
double stopLoss = 0;
double takeProfit = 0;
int ticket = 0;
if(percentage > HeightPercent && Time[0] != OpenBarTime)
{
if(Close[0] > slowEMA && slowEMA > Open[0] && Close[0] > fastEMA)
{
stopLoss = Ask - StopLoss * Point;
takeProfit = Bid + TakeProfit * Point;
ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,stopLoss,takeProfit,OrdersComment,Magic,0,clrBlue);
}
if(Open[0] > slowEMA && slowEMA > Close[0] && fastEMA > Close[0])
{
stopLoss = Bid + StopLoss * Point;
takeProfit = Ask - TakeProfit * Point;
ticket = OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,stopLoss,takeProfit,OrdersComment,Magic,0,clrRed);
}
if(ticket < 0)
{
Print("OrderSend Error : " + GetErrorMessage(GetLastError()));
}
OpenBarTime = Time[0];
}
}
if(OrdersTotal() > 0)
{
for(int i=0; i<=OrdersTotal()-1; i++)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) == false) break;
bool result = true;
if(OrderType() == OP_BUY && fastEMA > Ask)
{
result = OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,clrBlue);
}
else if(OrderType() == OP_SELL && Bid > fastEMA)
{
result = OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,clrRed);
}
if(!result)
{
Print("OrderClose Error : " + GetErrorMessage(GetLastError()));
}
}
}
}
//+------------------------------------------------------------------+
※パラメーターの初期値は軽く最適化した値を入れました
※ErrorMessage.mqh は、「自動売買システムを作ろう!ゼロから始めるEA開発Part8 エラー時の処理」の「エラーメッセージ関数について」にあります。
バックテスト&最適化
バックテスト結果は以下のとおりです。(ヒストリカルデータはFXDD1分足を使用)
条件
- 期間:2005年1月~2016年8月13日
- 通貨ペア:EURUSD
- 時間軸:H1
- スプレッド:10
- ロット:0.1
- プロフィットファクター:1.69
- 取引数:363回
- 勝率:37.19%
取引回数が少なく、勝率も高くはありませんがPF1.69と悪くない値になっています。
ユーロドルでバックテストしましたが、マネー報道さんはドル円・クロス円(主に売り)がお好きなようですのでユーロ円でバックテストしてみます。
ユーロ円バックテスト結果
通貨ペア以外は同条件です。パラメーターはざっくり最適化しています。
プロフィットファクター 1.11。
右肩上がりですが、安定しているとは言えませんね…。
勝率も23%と低いのでこのまま使用すると、負けが多くてストレスが溜まりそうです(笑)
他の通貨ペア(USDJPYやGBPJPY、GBPUSD)のバックテストをしてみたところプロフィットファクターは1.00を超えるものの、EURUSDのように綺麗な右肩上がりの線にはならず…。優位性はありそうなものの、このまま使用するのは難しそうです。
なんらかのインジケーター等でフィルタをするか…あるいは、「大きく動いた」ことを通知するだけの機能にして「トレードは裁量で実施する」というのも良いかもしれません。
というわけで、次回はこのEAをインジケーター化してみましょう!
以上、ゼロから始めるEAを開発の番外編、「移動平均を大きく(勢い良く)ブレイクアウトした場合に飛び乗る!システム」でした。
次回 → 移動平均のブレイクアウト/大きく動いたことを検知するインジケーター
【参考記事】





コメント
いつも記事の更新を楽しみにしています。
こちらの記事を読んでいますと、プログラミングの知識ゼロの自分でもいつかEAが作れるのではと思ってしまうくらい魅力的です。
(プログラムは全く読めませんが・・・・。)
EAは使っているけど、これから自分で作りたいと考えている初心者にお勧めの書籍などご紹介いただけますと幸いです。
プログラムは誰にでもできるものです。
「ゼロから始めるEA開発」はPart1からじっくり取り組んでいただければ理解できるように書いてきた・・つもりですが、わからないところがありましたでしょうか。
ゼロから始めるEA開発
EA開発の書籍は非常に少ないです。現状、「FXメタトレーダー入門」くらいしかないのではないかと思います。
FXメタトレーダー入門―最先端システムトレードソフト使いこなし術 (現代の錬金術師シリーズ 56)
コメントありがとうございます。
なかなか頭に入ってこないようです(泣)
Part1からもう一度読み直して少しずつですが前に進んでいきたいと思います。
北海道は台風のようですがお気を付けください。
これからも記事を楽しく拝読させて頂きます。
そうですか・・・すみません。
もしわからない所がありましたら、ご連絡ください。
札幌では土砂災害の注意報が出ています…。何もなければよいのですが…