自動売買システムではシグナルに対し、複数のフィルターを使い、利益とするのが難しいであろう取引を回避させます。
ここでは基本的なフィルターをMT4プログラムを含めて紹介します。
項目は以下の記事のフィルターの最適化の手順の内容になります。
Table of Contents
指定期間の標準偏差を算出し、その標準偏差が価格の指定パーセントを超えたときのシグナルをフィルターします。
ボラティリティが高すぎるときのシグナルを避けることで安定化を図ります。
外部変数は3つ使用しています。
- ZscoreOverFilter:標準偏差上限フィルターを有効または無効にします。
- BandsOverFilterPeriod:標準偏差期間を指定します。
- BandsOverFilterDev:標準偏差/価格パーセントの境界を決めます。
retを戻り値とし、0とするときはフィルター無しを意味しています。後に紹介するフィルターも同様です。
if( ZscoreOverFilter == true ){ dIndiVal[2] = iStdDev(NULL,0,BandsOverFilterPeriod,0,MODE_SMA,PRICE_CLOSE,1); // 偏差1 dIndiVal[3] = dIndiVal[2] / iClose(NULL,0,1) * 100; // 価格:倍率 if( dIndiVal[3] > BandsOverFilterDev ) ret = 0; }
上限フィルターとは逆に指定期間の標準偏差を算出し、標準偏差が価格の指定パーセント未満のとき、シグナルをフィルターします。
ボラティリティが低すぎるときのシグナルを無効とすることで、確実性を高めます。
外部変数は3つ使用しています。
- ZscoreUnderFilter:標準偏差下限フィルターを有効または無効にします。
- BandsUnderFilterPeriod:標準偏差期間を指定します。
- BandsUnderFilterDev:標準偏差/価格パーセントの境界を指定します。
if( ZscoreUnderFilter == true ){ dIndiVal[2] = iStdDev(NULL,0,BandsUnderFilterPeriod,0,MODE_SMA,PRICE_CLOSE,1); // 偏差1 dIndiVal[3] = dIndiVal[2] / iClose(NULL,0,1) * 100; // 価格:倍率 if( dIndiVal[3] < BandsUnderFilterDev ) ret = 0; }
指定期間のATRを算出し、ATR値が価格の指定パーセントを超えたときのシグナルをフィルターします。
値幅が大きすぎるときは上下動が激しくなりますので、シグナルをフィルターするとリスクを避けることになります。
外部変数は3つ使用しています。
- AtrOverFilter:ATR上限フィルターの有効または無効にします。
- AtrOverFilterPeriod:ATR期間を指定します。
- AtrOverFilterDev:ATR/価格パーセントの境界を指定します。
if( AtrOverFilter == true ){ dIndiVal[0] = iATR(NULL,0,AtrOverFilterPeriod,1) / iClose(NULL,0,1) * 100; if( dIndiVal[0] > AtrOverFilterDev ) ret = 0; }
上限とは逆のフィルターになります。指定期間のATRが価格の指定パーセント未満のときのシグナルをフィルターします。
値幅が小さすぎると利益幅も小さくなりがちで、取引してもリスクしかないようなシグナルを避けます。
外部変数は3つ使用しています。
- AtrUnderFilter:ATR下限フィルターの有効または無効を指定します。
- AtrUnderFilterPeriod:ATR期間を指定します。
- AtrUnderFilterDev:ATR/価格パーセントの境界を指定します。
if( AtrUnderFilter == true ){ dIndiVal[0] = iATR(NULL,0,AtrUnderFilterPeriod,1) / iClose(NULL,0,1) * 100; if( dIndiVal[0] < AtrUnderFilterDev ) ret = 0; }
シグナル発生から注文するまで、指定した経過足数が作成されるまで待ちます。日足であれば、1:1日となります。
シグナル発生から一定時間経過すると利益が出やすい傾向があるのが分かっている場合に使用するフィルターです。
外部変数はcountdownFilterを1つ使用しています。0はフィルター無しを示します。
オーダー関係の処理に以下の内容を加えた実装をしています。買いの場合のサンプルになります。
足が更新された最初のティックで1回実行され、次の足が更新されるまで実行されないことが前提になっています。
またカウントダウン中にEAを再起動した場合等の処理は考慮されていません。
if((signalchk(0) == 1 && filterchk(0) == 1 )||( countdownb > 0 )) /* セットアップの確認 */ { if( countdownb == 0 ){ countdownb = countdownFilter; } if( countdownb > 0 ){ countdownb--; } if( countdownb == 0 ){ /* オーダー処理を行う */ } }
指定期間前の終値と現在の直近の終値を比較し、買いであれば直近の終値が指定期間前以上であればシグナルを有効とします。売りはその逆を行います。
外部変数は2つ使用します。
- LookBackFilter:ルックバックフィルターの有効または無効を指定します。
- LookBackFilterPeriod:ルックバック期間を指定します。
selは0:買い、1:売りを示します。
if( LookBackFilter == true ){ dIndiVal[0] = iClose(NULL,0,LookBackFilterPeriod+1); dIndiVal[1] = iClose(NULL,0,1); if( sel == 0 ){ if( dIndiVal[0] >= dIndiVal[1] ) ret = 0; }else{ if( dIndiVal[0] <= dIndiVal[1] ) ret = 0; } }
名前のままのフィルターです。曜日ごとに取引の許可、不許可を指定します。
週初めの方向性が見えないときは取引を避けるといったような使い方をします。
外部変数は6つ使用します。
- WeekdayFilter:曜日フィルターの有効または無効を指定します。
- monday:月曜日フィルターの有効または無効。
- tuesday:火曜日フィルターの有効または無効。
- wednesday:水曜日フィルターの有効または無効。
- thursday:木曜日フィルターの有効または無効。
- friday:金曜日フィルターの有効または無効。
if( WeekdayFilter == true ){ switch( DayOfWeek() ){ case 0: //sun break; case 1: //mon if( monday == true ) ret = 0; break; case 2: //tue if( tuesday == true ) ret = 0; break; case 3: //wed if( wednesday == true ) ret = 0; break; case 4: //thu if( thursday == true ) ret = 0; break; case 5: //fri if( friday == true ) ret = 0; break; case 6: //sat break; } }
複数のフィルターを紹介しましたが、標準偏差とATRは狙いが似たフィルターになりますので、どちらかを選択して使用したほうが良いと思います。
あまり多くフィルターを使うことも過剰最適化の原因となってきますので注意しながら使用したいところです。