「コナーズの短期売買実践」のトレード戦略のEA化【第3弾】
トレンドフォローの押し目、戻りを狙った王道の戦略。バックテストは以下の条件で実施しました。
- 対象EA:TripleDayPullBack
- 通貨ペア:EURUSD
- ローソク足の種類:始値のみ
- モデル:全ティック
- スプレッド:3pips固定
- バックテスト期間:2008/1/1~2016/7/5
- ヒストリカルデータ:Dukascopy社のJForexからダウンロードした1分足
- 初期口座残高:10,000ドル
- ロット数:0.01固定
結果はこちらです。

実はひっそりとパラメータをいじっています。具体的にはADXは25でも30でもなく35に、手仕舞いは6本目ではなく7本目(仕掛けてから3本後)にしています。
これぞカーブフィッティング!(笑)
日足ではパラメータに手を加えることで、ようやくプラスになるEAになりましたが、1時間足や4時間足では何をやってもマイナスのままでした。
2011年6月に出版された書籍ですが、本書内で使われているデータは古く、1990年代だったりします。相場は変わってしまったと見るべきなのでしょうか…。
とは言え、まだ3つの手法しか試していません。現在の相場では使えないと断定するには早すぎますね。作ったコードは再利用できますので、めげずにこれからもどんどん作っていこうと思います!
TripleDayPullBack.mq4のコードを公開しますので、良かったら参考になさってください。
//+------------------------------------------------------------------+
//| Sample.mq4 |
//| Copyright (c) 2016, りゅーき |
//| https://autofx100.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright (c) 2016, りゅーき"
#property link "https://autofx100.com/"
#property version "1.00"
//+------------------------------------------------------------------+
//| ライブラリ |
//+------------------------------------------------------------------+
#include <stderror.mqh>
#include <stdlib.mqh>
#include <WinUser32.mqh>
#include <Original/Application.mqh>
#include <Original/Basic.mqh>
#include <Original/DateAndTime.mqh>
#include <Original/LotSizing.mqh>
#include <Original/OrderHandle.mqh>
#include <Original/OrderReliable.mqh>
//+------------------------------------------------------------------+
//| 定数 |
//+------------------------------------------------------------------+
// #define
//+------------------------------------------------------------------+
//| EAパラメータ設定情報 |
//+------------------------------------------------------------------+
extern string Note01 = "=== General ==================================================";
extern int MagicNumber = 7777777;
extern int SlippagePips = 5;
extern string Comments = "";
extern double FixLotSize = 0.01;
extern string Note02 = "=== Entry ====================================================";
extern int ADX_Period = 14;
extern double ADX_Value = 25.0;
extern string Note03 = "=== Exit =====================================================";
extern double SL_Pips = 0.0;
extern double TP_Pips = 0.0;
extern int ExitInterval = 2;
/*
extern string Note03_1 = "--- Trailing Stop --------------------------------------------";
extern bool UseTS = false;
extern double TS_StartPips = 15.0;
extern double TS_StopPips = 10.0;
*/
//+------------------------------------------------------------------+
//| グローバル変数 |
//+------------------------------------------------------------------+
// 共通
double gPipsPoint = 0.0;
int gSlippage = 0;
color gArrowColor[6] = {Blue, Red, Blue, Red, Blue, Red}; //BUY: Blue, SELL: Red
int gPrvBars = 0;
// バックテストでひとまず動作確認しているだけなので、仕掛け時のローソク足本数はグローバル変数でOK。
// 但し、実運用を考えた場合、ポジション保有中にMT4を閉じるケースを考慮する必要がある。
// そうしないと、そのポジションは永遠に手仕舞いされ無くなってしまう。
// ※グローバル変数の格納先はメモリで、メモリ上のデータはMT4のプロセスが終了してしまうと消えてしまう
int gEntryBars = 0;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
gPipsPoint = currencyUnitPerPips(Symbol());
gSlippage = getSlippage(Symbol(), SlippagePips);
gPrvBars = Bars;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
int currentBars = Bars;
// -----------------------------------------------------------------
// 手仕舞い
// -----------------------------------------------------------------
if(gEntryBars != 0 && Bars - gEntryBars >= ExitInterval){
allOrderClose(MagicNumber, gSlippage);
gEntryBars = 0;
}
/*
if(UseTS){
trailingStopGeneral(MagicNumber, TS_StartPips, TS_StopPips);
}
*/
// -----------------------------------------------------------------
// 仕掛けフィルター
// -----------------------------------------------------------------
// 新しい足を生成した時ではない場合は、仕掛けない
if(currentBars == gPrvBars){
gPrvBars = currentBars;
return;
}
// オーダーが1つ以上ある場合は、仕掛けない
double orderNum = sumOrderNumberOrLotSize(OP_OPEN, MagicNumber, SUM_ORDER_NUMBER);
if(orderNum > 0.0){
gPrvBars = currentBars;
return;
}
// -----------------------------------------------------------------
// 仕掛け
// -----------------------------------------------------------------
double ADX = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_MAIN, 1);
double P_DI = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_PLUSDI, 1);
double M_DI = iADX(NULL, 0, ADX_Period, PRICE_CLOSE, MODE_MINUSDI, 1);
double open1 = NormalizeDouble(Open[1], Digits);
double open2 = NormalizeDouble(Open[2], Digits);
double open3 = NormalizeDouble(Open[3], Digits);
double close1 = NormalizeDouble(Close[1], Digits);
double close2 = NormalizeDouble(Close[2], Digits);
double close3 = NormalizeDouble(Close[3], Digits);
if(ADX > ADX_Value){
if(P_DI > M_DI){
if((close3 < open3 && close2 < open2 && close1 < open1) && (close3 > close2 && close2 > close1)){
int ticket = orderSendReliableRange(Symbol(), OP_BUY, FixLotSize, Ask, gSlippage, SL_Pips, TP_Pips, Comments, MagicNumber, 0, gArrowColor[OP_BUY]);
gEntryBars = Bars;
}
}else if(M_DI > P_DI){
if((close3 > open3 && close2 > open2 && close1 > open1) && (close3 < close2 && close2 < close1)){
ticket = orderSendReliableRange(Symbol(), OP_SELL, FixLotSize, Bid, gSlippage, SL_Pips, TP_Pips, Comments, MagicNumber, 0, gArrowColor[OP_SELL]);
gEntryBars = Bars;
}
}
}
// 本来はticketの値によって後続の処理を制御する必要があるが、簡単のため、ここでは無視
gPrvBars = currentBars;
}

