investment

[第4回]ボリンジャーバンドとCCIを用いた検証

今回はボリンジャーバンドとCCIを用いた手法を紹介したいと思います。
前回、ボリンジャーバンドを用いた逆張りの検証を行いましたのでよかったら見てください。

[第3回]ボリンジャーバンドの逆張りを用いた手法今回はボリンジャーバンドの逆張りを用いた手法を紹介したいと思います。 ついに、omurinはMT5デビューしましたので今後は皆さんにより正確な情報が届けられると思っています。 しかし、残念なことにプログラミング言語もMQL4からMQL5に替わってしまったため、MT4を使用している人々には大変申し訳ないです。 ボリンジャーバンドも一般的に逆張りで用います。使い方はエンベロープとほとんど変わらないです。...

みなさんはCCIというオシレーター系インジケータを聞いたことがあるでしょうか?
あまりなじみのないインジケータですが使い方は非常に単純なのではじめに紹介したいと思います。

オシレーター系インジケータのCCIとは

CCIとは(コモディティ・チャネル・インデックス)の略で、値動きの幅に対して今どのくらい乖離しているかを示すインジケーターです。どちらかというと逆張り指標として用いられます。一般的な使い方は以下の通りです。

  1. -100以下から-100以上になったとき買いエントリー
  2. 100以上から100以下になったとき売りエントリー

今回はボリンジャーバンドとCCIを併用して使うのでエントリーとエグジットの条件は以下のようになります。

エントリーとエグジットの条件

買いエントリーの条件

  • CCIが-200を超えたとき
  • 終値が下のエンベロープを超えたとき

売りエントリーの条件

  • CCIが200を下回ったとき
  • 終値が上のエンベロープを下回ったとき

買いエントリーのエグジット

  1. 始値<上のエンベロープ<終値のとき
  2. CCIが0を超えたとき
  3. 利益が50pipsを超えたとき
  4. 損失が110pipsを超えたとき

売りエントリーのエグジット

  1. 始値>下のエンベロープ>終値のとき
  2. CCIが0を下回ったとき
  3. 利益が50pipsを超えたとき
  4. 損失が110pipsを超えたとき

赤丸箇条書きが両方を満たすとき、数字箇条書きがひとつでも満たせばいいことを表しています

最適なパラメータ分析

2Dグラフ

横軸が損切りpips、縦軸が利食いpipsを表しています。濃い色ほど利益がでています。

3Dグラフ

損切りpipsと利食いpipsの関係を表しています。緑色が高い利益を出しています。

使用したソースコード

//本書ライブラリ
#include "LibEA.mqh"

sinput double Lots = 0.1; //売買ロット数
input ENUM_TIMEFRAMES TF = 0; //移動平均線のタイムフレーム
input int FastMAPeriod = 10; //移動平均線の期間
input ENUM_TIMEFRAMES TFbands =0;//ボリンジャーバンドのタイムフレーム
input int BandsPeriod = 20; //ボリンジャーバンドの期間
input double BandsDeviation= 2;//ボリンジャーバンドの偏差%
input ENUM_TIMEFRAMES TFCCI =0;//CCIのタイムフレーム
input int CCIPeriod = 14; //CCIの期間

input int SLpips = 110; //損切り値幅(pips)
input int TPpips = 50; //利食い値幅(pips)

//ティック時実行関数
void Tick()
{
   
   //損切り・利食い決済
   if(isNewBar(_Symbol, PERIOD_M1) //1分足の始値で判別
      && (MyOrderProfitPips() >= TPpips || MyOrderProfitPips() <= -SLpips)
   ) MyOrderClose();
   
   int sig_entry = EntrySignal(); //仕掛けシグナル
   int sig_exit = ExitSignal();// 手仕舞いシグナル
   //成行売買
   MyOrderSendMarket(sig_entry, sig_exit, Lots);
   
}

//仕掛けシグナル関数
int EntrySignal()
{
   //移動平均線
   double Fast_SMA_1=iMA(_Symbol,0,FastMAPeriod,0,MODE_SMA,PRICE_CLOSE,1);
   double Fast_SMA_2=iMA(_Symbol,0,FastMAPeriod,0,MODE_SMA,PRICE_CLOSE,2);
   //ボリンジャーバンド
   double High_Band_1=iBands(_Symbol,TFbands,BandsPeriod,BandsDeviation,0,PRICE_CLOSE,MODE_HIGH,1);
   double Low_Band_1=iBands(_Symbol,TFbands,BandsPeriod,BandsDeviation,0,PRICE_CLOSE,MODE_LOW,1);
   double High_Band_2=iBands(_Symbol,TFbands,BandsPeriod,3,0,PRICE_CLOSE,MODE_HIGH,1);
   double Low_Band_2=iBands(_Symbol,TFbands,BandsPeriod,3,0,PRICE_CLOSE,MODE_LOW,1);
   
   //CCI
   double CCI_1=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,1);
   double CCI_2=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,2);
   double CCI_3=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,3); 
   double CCI_4=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,4);
   double CCI_5=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,5);
   double CCI_6=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,6);
   double CCI_7=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,7); 
   double CCI_8=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,8);
   //ローソク足
   double Close1 = iClose(_Symbol, TF, 1);
   double Close2 = iClose(_Symbol, TF, 2);
   double Open1 = iOpen(_Symbol, TF, 1);
   double Open2 = iOpen(_Symbol, TF, 2);
   
   int ret = 0; //シグナルの初期化
   
   //買いエントリー
   if(
      (CCI_4>200&&CCI_3<200&&Close1<Open1&&Close1<High_Band_1&&Open1>High_Band_1)
      ||(CCI_3<-200&&CCI_2>-200&&Close1>Open1&&Close1>Low_Band_1&&Open1<Low_Band_1)
      ||(CCI_2<-200&&CCI_1>-200&&Close1>Open1&&Close1>Low_Band_1&&Open1<Low_Band_1))
      
      ret = 1;
   //売りエントリー
   if(
      (CCI_4>200&&CCI_3<200&&Close1<Open1&&Close1<High_Band_1&&Open1>High_Band_1)
      ||(CCI_3>200&&CCI_2<200&&Close1<Open1&&Close1<High_Band_1&&Open1>High_Band_1)
      ||(CCI_2>200&&CCI_1<200&&Close1<Open1&&Close1<High_Band_1&&Open1>High_Band_1))
     
      ret = -1;

   return ret; //シグナルの出力
}

//手仕舞いシグナル関数
int ExitSignal()
{
  //ボリンジャーバンド
   double High_Band_1=iBands(_Symbol,TFbands,BandsPeriod,BandsDeviation,0,PRICE_CLOSE,MODE_HIGH,1);
   double Low_Band_1=iBands(_Symbol,TFbands,BandsPeriod,BandsDeviation,0,PRICE_CLOSE,MODE_LOW,1);
   double High_Band_2=iBands(_Symbol,TFbands,BandsPeriod,BandsDeviation,0,PRICE_CLOSE,MODE_HIGH,2);
   double Low_Band_2=iBands(_Symbol,TFbands,BandsPeriod,BandsDeviation,0,PRICE_CLOSE,MODE_LOW,2);
   //CCI
   double CCI_1=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,1);
   double CCI_2=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,2);
   double CCI_3=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,3);
   double CCI_4=iCCI(_Symbol,TFCCI,CCIPeriod,PRICE_CLOSE,4);
   //ローソク足
   double Close1 = iClose(_Symbol, PERIOD_M1, 1);
   double Open1 = iOpen(_Symbol, PERIOD_M1, 1);
   int ret = 0; //シグナルの初期化
   //買いエントリーのエグジット
   if((Close1>High_Band_1&&Open1<High_Band_1)
      ||(CCI_2<0&&CCI_1>0))
      ret = -1;
   //売りエントリーのエグジット
   if((Close1<Low_Band_1&&Open1>Low_Band_1)
      ||(CCI_2>0&&CCI_1<0))
      ret = 1;

   return ret; //シグナルの出力
}


CCIが0を超えたときというのはピンポイントすぎるのでCCIが0を超えた1,2,3本後のローソク足も含めています

結果

通貨ペア USD/JPY 1時間足
期間 2012.01.01~2019.12.31
ロット数 1(1万通貨)
初期証拠金 10000.00
純益 3029.31
プロフィットファクタ 1.78
総取引数 24
残高最大ドローダウン 1267.88(12.15%)
期待利得 126.22
勝率 54.17%
勝ちトレード(平均) 531.20
負けトレード(平均) -352.39

結果としてはちゃんと利益が出ました!このプログラムの良いところがドローダウンが低いことでしょう。12.15%と言われると普通だと思いますが今回は1ロットで取引しているためすごいと思います。(いつもは0.1ロットで検証)だめなところは8年間のバックテストを通してたった24回しかトレードをしない点ですかね。フィルタを厳しくしたせいでこのような結果になってしまいましたね。期待利得も立派すぎる数字です。今回はUSD/JPYでしか検証していませんがいろんな通貨で取引したら取引回数も増えるのでいいのかもしれません。

まとめ
  • ボリンジャーバンドとCCIは相性が良かった
  • ボリンジャーバンドは他のオシレーターと組み合わせてもよさそう
  • 利益は出せたがフィルタを厳しくしすぎたため取引回数が少なくなった