2016年4月15日金曜日

[MT4インジケータ]ATR値幅でポジションを持つ戦略でバックテスト その2

前回の続きです。

前回の記事はこちら
[MT4インジケータ]ATR値幅でポジションを持つ戦略でバックテスト その1

まずは前回の最後に書いた順張りでのUSDJPYの結果から。

通貨ペアUSDJPY (USD/JPY)
期間1時間足(H1) 2010.01.04 00:00 - 2015.12.30 23:59 (2010.01.01 - 2015.12.31)
パラメーターMagicNumber=37858261; SpreadFilter=2; MaxPosition=1; Lot=0.02; Slippage=2; StopLoss=200; TakeProfit=200; MinProfit=2; AtrPeriod=100; ZoomRate=1; StartIndex=1; TargetIsClose=false;
テストバー数38136モデルティック数75265モデリング品質n/a
不整合チャートエラー0
初期証拠金10000.00スプレッド現在値 (4)
純益-1045.49総利益9373.35総損失-10418.84
プロフィットファクタ0.90期待利得-0.26
絶対ドローダウン1046.66最大ドローダウン1112.99 (11.06%)相対ドローダウン11.06% (1112.99)
総取引数4061売りポジション(勝率%)2033 (37.14%)買いポジション(勝率%)2028 (36.14%)
勝率(%)1488 (36.64%)負率 (%)2573 (63.36%)
最大勝トレード51.80敗トレード-51.03
平均勝トレード6.30敗トレード-4.05
最大連勝(金額)12 (42.10)連敗(金額)14 (-48.25)
最大連勝(トレード数)90.56 (9)連敗(トレード数)-96.02 (8)
平均連勝2連敗3


見事にマイナスです。
では、取引ルールは前回と変えず、単純に順張りを逆張りに変えてやってみた結果です。
逆張りなのでATR幅を広げるなどの調整もしています。

通貨ペアUSDJPY (USD/JPY)
期間1時間足(H1) 2010.01.04 00:00 - 2015.12.30 23:59 (2010.01.01 - 2015.12.31)
パラメーターMagicNumber=37858261; SpreadFilter=2; MaxPosition=1; Lot=0.02; Slippage=2; StopLoss=180; TakeProfit=260; MinProfit=2; AtrPeriod=100; ZoomRate=2.6; StartIndex=1; TargetIsClose=false;
テストバー数38136モデルティック数75265モデリング品質n/a
不整合チャートエラー0
初期証拠金10000.00スプレッド現在値 (4)
純益626.90総利益3968.14総損失-3341.24
プロフィットファクタ1.19期待利得1.44
絶対ドローダウン30.25最大ドローダウン478.25 (4.43%)相対ドローダウン4.43% (478.25)
総取引数434売りポジション(勝率%)208 (60.10%)買いポジション(勝率%)226 (61.95%)
勝率(%)265 (61.06%)負率 (%)169 (38.94%)
最大勝トレード68.21敗トレード-45.99
平均勝トレード14.97敗トレード-19.77
最大連勝(金額)12 (203.73)連敗(金額)4 (-101.14)
最大連勝(トレード数)203.73 (12)連敗(トレード数)-101.14 (4)
平均連勝3連敗2


プラスにはなり、それなりにいい感じです。

もっと効率のいい戦略に修正していく必要はありますが、ひとまず注文タイミングの材料のひとつにはなりそうです。


「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。

2016年4月14日木曜日

[MT4インジケータ]ATR値幅でポジションを持つ戦略でバックテスト その1

2016/04/12のインジケータをEAで試してみました。
[MT4インジケータ]値動きが一定を超えたら矢印を出す

ルールとしてはまずはシンプルにこんな感じです。
 ・1ポジションしか持たない
 ・上矢印が出たら買い、下矢印が出たら売る
 ・両方の矢印が出た場合、価格が上がっていれば買い、下がっていれば売る
 ・連続で同じ方向の矢印が出たらポジションは保持したまま何もしない
 ・逆方向の矢印が出たら、保持しているポジションを決済して即注文する

過去5年分のバックテスト結果がこちら。

通貨ペアEURUSD (EUR/USD)
期間1時間足(H1) 2010.01.04 00:00 - 2015.12.30 23:59 (2010.01.01 - 2015.12.31)
パラメーターMagicNumber=37858261; SpreadFilter=2; MaxPosition=1; Lot=0.02; Slippage=2; StopLoss=200; TakeProfit=200; MinProfit=2; AtrPeriod=100; ZoomRate=1; StartIndex=1; TargetIsClose=false;
テストバー数38135モデルティック数75263モデリング品質n/a
不整合チャートエラー0
初期証拠金10000.00スプレッド現在値 (5)
純益404.62総利益13883.26総損失-13478.64
プロフィットファクタ1.03期待利得0.10
絶対ドローダウン172.50最大ドローダウン850.02 (7.96%)相対ドローダウン7.96% (850.02)
総取引数4093売りポジション(勝率%)2056 (36.72%)買いポジション(勝率%)2037 (37.56%)
勝率(%)1520 (37.14%)負率 (%)2573 (62.86%)
最大勝トレード40.00敗トレード-32.70
平均勝トレード9.13敗トレード-5.24
最大連勝(金額)9 (76.54)連敗(金額)14 (-67.04)
最大連勝(トレード数)92.42 (5)連敗(トレード数)-95.52 (10)
平均連勝2連敗3


順張りでシンプルに組んでみただけにしては、プラスになっていて意外といい感じです。
また、ATR幅とストップロス/利益確定を最適化してみるとこんな感じ。

通貨ペアEURUSD (EUR/USD)
期間1時間足(H1) 2010.01.04 00:00 - 2015.12.30 23:59 (2010.01.01 - 2015.12.31)
パラメーターMagicNumber=37858261; SpreadFilter=2; MaxPosition=1; Lot=0.02; Slippage=2; StopLoss=50; TakeProfit=220; MinProfit=2; AtrPeriod=100; ZoomRate=1.6; StartIndex=1; TargetIsClose=false;
テストバー数38135モデルティック数75263モデリング品質n/a
不整合チャートエラー0
初期証拠金10000.00スプレッド現在値 (5)
純益1540.82総利益9426.20総損失-7885.38
プロフィットファクタ1.20期待利得0.92
絶対ドローダウン25.50最大ドローダウン422.24 (3.66%)相対ドローダウン3.66% (422.24)
総取引数1678売りポジション(勝率%)840 (37.26%)買いポジション(勝率%)838 (34.01%)
勝率(%)598 (35.64%)負率 (%)1080 (64.36%)
最大勝トレード44.00敗トレード-10.00
平均勝トレード15.76敗トレード-7.30
最大連勝(金額)11 (187.44)連敗(金額)16 (-122.40)
最大連勝(トレード数)187.44 (11)連敗(トレード数)-122.40 (16)
平均連勝2連敗3


ドローダウンを上手く抑えられ、いい感じです。
EURUSDだと方向性が出やすく順張り向きですね。

ただ、USDJPYでやってみるとマイナスになりました。
USDJPYだとレンジ相場になりやすいので、順張りには向いてなさそうですね。
次回は逆張り向けも作って試してみようかと思います。


「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。

2016年4月13日水曜日

[雑記]トレンドとレンジをインジケータで判定したい。~HVRateとRSIを使用して~

トレンドとレンジ相場をなんとかインジケータで判定できないかなぁと、まだ検討中です。

一つのアイデアとして、ヒストリカルボラティリティレートと、RSIを使って判定する方法を検討しています。
ヒストリカルボラティリティは変化率、RSIは変化量をもとにしています。

変化率が高まった際、RSIにおいてある一定量を超えていない場合は、レンジ相場、超えている場合はトレンドといった感じで、相場が動いている際、どちらの方向に動いているか?ということを判定してトレンド状態かレンジ状態かを区別できないかなーと眺めています。

■ヒストリカルボラティリティ レートとRSIを表示する。


EURUSD1Hにおいては、なとなくHVレートが90を超えている期間が、RSIで65を超えている値があれば上げ、RSIが35を下回っていれば下げ、35~65の間であればレンジといった形で判定できないかをチャレンジ中です。

ヒストリカルボラティリティ レートはFX-ONで無料公開しています。
ダウンロード

「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。

2016年4月12日火曜日

[MT4インジケータ]値動きが一定を超えたら矢印を出す

staplaさん、いつもブログにコメントありがとうございます。

[MT4プログラミング]MT4のチャート上に矢印を表示する。
にてコメントをいただきました。
http://mt4program.blogspot.jp/2015/10/mt4mt4_8.html?showComment=1460093397701#c5006228500137749190

ちょっと、開発中のインジケータをEAで試すのに手一杯で時間が取れなかったのですが、煮詰まったので一息がてらに作ってみました。

■ATR幅を超えた値動きをした場合、矢印を出すインジケータ


画像は、EURUSD1Hにおいて、前の足の(高値+安値+始値+終値)/ 4を基準位置として100本ATR幅を超えた場合に矢印を出しています。パパッと見る限り、この設定ですと連続して矢印が出る事が多いように思われます。この設定では順張り向けですね。

インジケータとしては、自分の足の始値や前の足の終値など少し幅を持たせた設定ができるようにしてあります。このインジケータは基準位置をどこにするかがカギに思われます。

逆張り向けとしては、もう少し大きくATR幅を取ったほうが良いように思われますが、EURUSDにおいては上がると上がりっぱなしといった動きをすることが多々あるため、別の通貨のほうが良いように思われます。

あ、プログラム的には、「MT4のチャート上に矢印を出す」では、オブジェクトを使って矢印を出していますが、こちらは、バッファを使用しています。
ちゃちゃっとだすにはこちらの方が簡単です。

ポイントは、次の二つです。
#property indicator_type4   DRAW_ARROW
SetIndexArrow(3, TopArrowType);

indicator_typeをDRAW_ARROWにすることと、SetIndexArrowにて矢印の種別を指定することです。

「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。

プログラムはこちらから

2016年4月11日月曜日

[MT4プログラミング]クラスを使うとEAもインジケータも同じコードを利用できる。


先週金曜日の記事で、EAとインジケータで移植しやすい形にするための注意点を書きました。

・[MT4プログラミング]EAに組み込みやすいようにインジケータを作成する
http://mt4program.blogspot.com/2016/04/mt4ea.html

さらに、EA化する際、インジケータ値に不具合があって修正するという作業が発生します。そのとき、インジケータ側、EA側と二つ修正しているのでは手間がかかります。そこでこれを共通的に扱うためにあとひと手間かけてみます。

前回記事のインジケータをクラスとして移植します。
基本はコピペです。クラスの形に従って初期化位置などを書いています。OnCalculateの戻り値として古い未計算値を返すようにしています。これは、インジケータで表示する場合、更新必要な本数を取得するためです。

//------------------------------------------------------------------
// テストインジケータ クラス
#property copyright "Copyright 2016,  Daisuke"
#property link      "http://mt4program.blogspot.jp/"
#property version   "1.00"
#property strict

//------------------------------------------------------------------
// テストインジケータ クラス
class CHarfIndicator
{
private:
   //対象シンボル
   string m_symbol;
   
   //タイムフレーム
   ENUM_TIMEFRAMES m_timeframe;

   // バッファ
   double m_harfCalc[];   

   // 前回計算値
   int m_prevCalculated;  
public:
   //------------------------------------------------------------------
   // コンストラクタ
   CHarfIndicator(
      string symbol              //シンボル
   ,  ENUM_TIMEFRAMES timeframe  //タイムフレーム
      );
   
   //------------------------------------------------------------------
   // デストラクタ
   ~CHarfIndicator();
  
   //------------------------------------------------------------------
   // バッファの値を取得する。
   // return バッファの値
   double GetHarf(int i)
   {
//       安全性を高めるなら範囲チェックがあったほうがいいが、速度を考える。呼び出し側で考慮する   
//      if( i < 0 || i >= ArraySize(i) ) return 0;
      return m_harfCalc[i];
   }
   
   //------------------------------------------------------------------
   // Tick更新時の計算
   // return 未計算数
   int OnCalculate();
};

//------------------------------------------------------------------
// コンストラクタ
CHarfIndicator::CHarfIndicator(
   string symbol              //シンボル
,  ENUM_TIMEFRAMES timeframe  //タイムフレーム
   ):
   m_symbol(symbol)
,  m_timeframe(timeframe)
,  m_prevCalculated(0)
{
}

//------------------------------------------------------------------
// デストラクタ
CHarfIndicator::~CHarfIndicator()
{
   ArrayFree(m_harfCalc);
}

//------------------------------------------------------------------
// Tick更新時の計算
// return 未計算数
int CHarfIndicator::OnCalculate()
{
   //インジケータの計算
   int ratesTotal = iBars(m_symbol, m_timeframe);
   int currentArraySize = ArraySize(m_harfCalc);
   if( currentArraySize < ratesTotal )
   {
      ArraySetAsSeries(m_harfCalc, false);

      ArrayResize(m_harfCalc, ratesTotal);
      
      ArraySetAsSeries(m_harfCalc, true);
      
      for( int i = 0; i < ratesTotal - currentArraySize; i++ )
      {
         m_harfCalc[i] = EMPTY_VALUE;
      }
   }

   for( int i = ratesTotal - m_prevCalculated - 1; i >= 0 && !IsStopped(); i-- )
   {
      if( i >= ratesTotal - 1 )
      {
         m_harfCalc[i] = (iOpen(m_symbol, m_timeframe, i) + iClose(m_symbol, m_timeframe, i) + iHigh(m_symbol, m_timeframe, i) + iLow(m_symbol, m_timeframe, i)) / 4 ;
      }
      else
      {
         m_harfCalc[i] = ((iOpen(m_symbol, m_timeframe, i) + iClose(m_symbol, m_timeframe, i) + iHigh(m_symbol, m_timeframe, i) + iLow(m_symbol, m_timeframe, i)) / 4 + m_harfCalc[i + 1]) / 2;
      }
   }
   int oldPrevCalculated = m_prevCalculated;
   m_prevCalculated = ratesTotal - 1;
   return oldPrevCalculated;
}

これをインジケータで表示するには次のような形になります。

//------------------------------------------------------------------
// テストインジケータ
#property copyright "Copyright 2016,  Daisuke"
#property link      "http://mt4program.blogspot.jp/"
#property version   "1.00"
#property strict
#property indicator_chart_window

#include <harfindicator.mqh>

//バッファーを指定する。
#property indicator_buffers 1

//プロット数を指定する。
#property indicator_plots   1

#property indicator_label1  "HARF"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrIndianRed
#property indicator_width1  2

// バッファー
double harf[];

CHarfIndicator *harfIndicator;

//------------------------------------------------------------------
//初期化
int OnInit()
{
   string short_name = "Test";
   
   int count = 0;
   SetIndexBuffer(count++, harf);
   
   harfIndicator = new CHarfIndicator(Symbol(), (ENUM_TIMEFRAMES)Period());

   return INIT_SUCCEEDED;
}

//------------------------------------------------------------------
//終了処理
void OnDeinit(const int reason)
{
   delete harfIndicator;
}

//------------------------------------------------------------------
//計算イベント
int OnCalculate(const int rates_total,          //各レート要素数
                const int prev_calculated,      //計算済み要素数
                const datetime &time[],         //要素ごとの時間配列
                const double &open[],           //オープン価格配列
                const double &high[],           //高値配列
                const double &low[],            //安値配列
                const double &close[],          //クローズ価格配列
                const long &tick_volume[],      //ティック数(要素の更新回数)
                const long &volume[],           //実ボリューム(?)
                const int &spread[])            //スプレット
{
   int prevCalculated = harfIndicator.OnCalculate();

   for( int i = rates_total - prevCalculated - 1; i >= 0 && !IsStopped(); i-- )
   {
      harf[i] = harfIndicator.GetHarf(i);
   }
   
   return rates_total - 1;
}

もうほとんど何もないインジケータのコードとなりました
EAで使う場合は次のような形です。
//+------------------------------------------------------------------+
//|                                                       TestEA.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <harfindicator.mqh>
CHarfIndicator *harfIndicator;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   harfIndicator = new CHarfIndicator(Symbol(), (ENUM_TIMEFRAMES)Period());
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   delete harfIndicator;
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   harfIndicator.OnCalculate();
   
   if( harfIndicator.GetHarf(1) < harfIndicator.GetHarf(0) )
   {
      //売ったり買ったり
   }
}

こちらも前回と見比べてください。かなりすっきりしましたね!
インジケータもEAも同じCHarfIndicatorクラスを利用しています。そのため、indicator値に計算違いなどの不具合があった場合はCHarfIndicatorクラスのコードを直すだけで、EAとインジケータが同時に修正されます。
EAを開発する際、最終的にはバックテストのポジションが想定通りの箇所で売買されているかを確認していく作業となります。その際チャート上にインジケータ値が表示されている必要がありますので、同時にインジケータも開発することになります。

このようにEA化しやすいインジケータコードと、クラスを利用した共用化によってEAに向けての実装コストを大幅に削減可能です。

ちなみに、今回作成したインジケータを表示するとこんな感じになります。バーの中央値を0.5本遅れて表示するといった形ですね。中央値に対して何か仕掛ける場合の基準値になるかも?
■今回のテストインジケータ


「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。