見出し画像

売買システムレビュー Intraday CMO-FX

今回紹介する売買システムは、Currency Traderの2006年11月号に掲載されていたシステムです。Intradayとあるように日中足チャートで動作させるシステムです。

Chande Momentum Oscillator(CMO)

売買システムの名前にCMOとありますが、このシステムは、Chande Momentum Oscillatorというテクニカル指標を使います。

これは、Tushar S. Chandeさんが「The New Technical Trader (John Wiley & Sons, 1994)」で提案した指標ですが、MT4/MT5には標準では搭載されていないので、まずはCMOを簡単に紹介しておきます。

実はCMO、以下の記事で適応型移動平均を紹介したときにちょっと触れています。

この記事のなかのVariable Index Dynamic Average(可変インデックス動的平均)のところで取り上げています。改めてCMOの部分だけを抜粋します。

CMO[i]=(UpSum[i]-DnSum[i])/(UpSum[i]+DnSum[i])
UpSum[i]:1本前からの変化がプラスとなるものの合計
DnSum[i]:1本前からの変化がマイナスとなるものの合計

算出する期間に対して、価格(終値)の1本前からの変化がプラスの場合とマイナスの場合に分け、プラス分を合計したものをUpSum[i]マイナス分を合計したものをDnSum[i]とします。そして、プラスとマイナスのどちらに偏っているかを-100から100の範囲で表した指標となっています。

CMOをMT4/MT5のカスタム指標としてプログラムすると以下のようになります。

#property indicator_separate_window    //サブウィンドウに表示
#property indicator_buffers 1          //指標バッファの数
#property indicator_plots 1            //表示する指標バッファの数
#property indicator_type1 DRAW_LINE    //指標の種類
#property indicator_color1 clrRed      //ラインの色
#property indicator_minimum -100       //最小値
#property indicator_maximum 100        //最大値
#property indicator_level1 -50         //レベル1
#property indicator_level2 0           //レベル2
#property indicator_level3 50          //レベル3

//指標バッファ用の配列の宣言
double Buf[];

input int CMOPeriod = 14; //CMOの期間

//初期化関数
int OnInit()
{
  //配列を指標バッファに関連付ける
  SetIndexBuffer(0, Buf);
  //時系列配列に設定
  ArraySetAsSeries(Buf, true);

  return(INIT_SUCCEEDED);
}

//指標計算関数
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[])
{
  //時系列配列に設定
  ArraySetAsSeries(close, true);

  int limit = rates_total - prev_calculated; //プロットするバーの数
  limit = MathMin(limit, rates_total-CMOPeriod); //プロットの左端をずらす
  
  for(int i=0; i<limit; i++)
  {
     double UpSum=0, DnSum=0;
     for(int j=0; j<CMOPeriod; j++)
     {
        UpSum += MathMax(close[i+j]-close[i+j+1], 0);
        DnSum -= MathMin(close[i+j]-close[i+j+1], 0);
     }
     if(UpSum+DnSum != 0) Buf[i] = (UpSum-DnSum)/(UpSum+DnSum)*100;
     else Buf[i] = 0;
  }
  return(rates_total-1);
}

これは共通ライブラリなどは使っていないので、MT4/MT5でそのままコンパイルして使えます。

CMOをチャートに挿入すると以下のようになります。この指標はRSIに似ているため、比較のためRSIも載せておきます。

画像1

サブウィンドウの上がCMOで、下がRSIです。どちらも期間は14本です。

RSIでも変化のプラス分とマイナス分に分けます。ただ、それぞれのデータにSMMA(EMAと同じく直近の重みが大きい移動平均)をかけるところが異なります。CMOはプラス分とマイナス分を合計するだけなので、単純移動平均(SMA)をかけたのと同じ処理となります。

また、RSIでは範囲を0から100になるようにスケーリングしていますが、CMOでは-100から100の範囲となっているところが異なります。

指標の変化の違いは、SMMAとSMAの違いとして表れています。RSIでは過去の変化分の影響は小さくなるので、割と平滑化されていますが、CMOでは期間中の変化分は等しく反映されるので、変動が目立ちます。この挙動がモメンタムオシレータと呼ばれるゆえんでしょう。

基本の売買ルール

CMOは、基本的には逆張り指標として使います。CMOが-50で売られすぎ50で買われすぎと判断すれば、仕掛けシグナルは以下のようなルールとなります。

買いシグナル:1本前のCMOが-50を下回ったとき
売りシグナル:1本前のCMOが50を上回ったとき

手仕舞いシグナルについては、元の記事では一定割合の利食いと一定時間経過の手仕舞いが記載されていましたが、最近の相場ではあまり有効ではないようなので、割愛します。

バックテスト

このシステムを以下の条件でバックテストしてみます。使ったツールはAlpari MT5です。

シンボル:EURUSD
タイムフレーム:H1
期間:2011.08.01~2021.08.01
モデル:全ティック
Lots = 0.1; //売買ロット数
CMOPeriod = 14; //CMOの期間

まず、上の基本売買ルールだけで、途転売買させた結果です。

スクリーンショット 2021-08-11 173416

一つの指標だけでうまくいくわけはないので、期待はしていなかったのですが、一方的に負けるというわけでもないので、少しは改良する余地はありそうです。

そこで、1本前のCMOではなく、最新のバーのCMOが-50、50を超えたときにシグナルを出すようにしてみます。結果は以下のようになりました。

スクリーンショット 2021-08-11 180014

最新のバーの形成途中で出るシグナルも使うことができるので、取引回数が1079回から1478回に増えました。プロフィットファクタはほぼ同じですが、純益が増え、最大ドローダウンも減ったことでリカバリファクターは改善が見られました。

次にこのシステムに手仕舞いを追加してみます。手仕舞いのルールは以下のようにしてみました。

買いポジションの決済:最新のバーでCMOがマイナスからプラスに転じたとき
売りポジションの決済:最新のバーでCMOがプラスからマイナスに転じたとき

バックテストの結果です。

スクリーンショット 2021-08-11 183819

手仕舞いを追加することで、ポジション保有時間が短くなり、その結果取引回数が増えました。ただし、純益はマイナスになってしまいました。これだけだといいことはないのですが、最大ドローダウンが小さくなったという改善点は見られました。

フィルタの追加

このままだと誰にも見向きもされないシステムとなってしまうので、フィルタを追加してみます。いまのシステムは1時間足のシステムなので、もう少し長期的なトレンドを見て、その方向だけトレードするようなトレンドフィルタをかけてみます。

トレンドフィルタとしては、拙著CodeBaseのMACDを用いたトレンドフィルタを使ってみます。MACDのパラメータは同じく12、26、1としますが、1時間足ではなく、4時間足に対して計算します。また1本前のMACDではなく、最新のバーでのMACDの値で判別します。

フィルタのルールは以下の通りです。MACDの符号でトレンド判定します。

買いシグナルの採用条件:シグナル発生時のMACDがプラスの場合
売りシグナルの採用条件:シグナル発生時のMACDがマイナスの場合

このフィルタを追加したシステムをバックテストした結果です。

スクリーンショット 2021-08-11 195543

フィルタをかけることで取引回数は半分以下になりましたが、純益もプラスになり、さらに最大ドローダウンも小さくなりました。トレンドフィルタがうまく機能した例です。

今回パラメータの最適化は行っていないので、オーバーフィッティングというわけではないと思います。ただ、EUR/USD以外の通貨ペアではうまくいかないので、ある意味、通貨ペアでフィッティングした結果かもしれません。詳しい分析は省略します。

コード

以下の共通ライブラリを利用すると、今回紹介したシステムのMT4/MT5共用のEAを作成することができます。

仕掛けシグナル、手仕舞いシグナル、仕掛けフィルタといった典型的なシステムです。CodeBaseに色々とサンプルがあるので挑戦してみてください。

うまく作成できなかった方は、以下のコード例を参考にしてください。

ここから先は

1,486字 / 2ファイル

¥ 100

この記事が気に入ったらサポートをしてみませんか?