ブログタイトルを「FX自動売買システム開発部」から「autoFX」に変更しました!

トリプルデイ・プルバック戦略のEAを作成してみる(2)

「コナーズの短期売買実践」のトレード戦略のEA化【第3弾】

トレンドフォローの押し目、戻りを狙った王道の戦略。バックテストは以下の条件で実施しました。

  • 対象EA:TripleDayPullBack
  • 通貨ペア:EURUSD
  • ローソク足の種類:始値のみ
  • モデル:全ティック
  • スプレッド:3pips固定
  • バックテスト期間:2008/1/1~2016/7/5
  • ヒストリカルデータ:Dukascopy社のJForexからダウンロードした1分足
  • 初期口座残高:10,000ドル
  • ロット数:0.01固定

結果はこちらです。

TripleDayPullBackのトレード結果(グラフ)

TripleDayPullBackのトレード結果(チャート)

実はひっそりとパラメータをいじっています。具体的には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;
}

MQL4プログラミングの最新記事8件

>完全放ったらかしEA 「AutoEndlessCatchRange」

完全放ったらかしEA 「AutoEndlessCatchRange」

「本業が忙しい!」「でも資産運用したい!」そんなあなたに最適なEAです。兼業トレーダーの方はチャートを毎日みて分析してトレードする時間はなかなか確保できないものです。トレードは本EAに任せて、本業やプライベートの時間をもっと増やしませんか?元々は自分自身のために開発したEAですので、手抜き無しのガチものです。

CTR IMG