エンベロープを用いたトレンドフィルタは、終値がエンベロープの上位ラインより上であれば、上昇トレンドとして買いシグナルのみを採用し、終値がエンベロープの下位ラインより下であれば、下落トレンドとして売りシグナルのみを採用するものでした。

ここでは、このフィルタを利用して売買ロット数を変えるシステムを作成します。

終値がエンベロープの上位ラインより上の位置で買いシグナルが出た場合、あるいは、終値がエンベロープの下位ラインより下の位置で売りシグナルが出た場合、売買ロット数を通常のロット数より増やすというものです。

コード

//共通ライブラリ
#include "LibEA.mqh"

//ティック時実行関数
void Tick()
{
   int sig_entry = EntrySignal(); //仕掛けシグナル
   double lots = CalculateLots(sig_entry); //トレンドフィルタによるロット数
   //成行売買
   MyOrderSendMarket(sig_entry, sig_entry, lots);
}

input int RSIPeriod = 5; //RSIの期間

//仕掛けシグナル関数
int EntrySignal()
{
   //1本前のRSI
   double RSI1 = iRSI(_Symbol, 0, RSIPeriod, PRICE_CLOSE, 1);

   int ret = 0; //シグナルの初期化

   //買いシグナル
   if(RSI1 < 30) ret = 1;
   //売りシグナル
   if(RSI1 > 70) ret = -1;

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

input int EnvPeriod = 200; //エンベロープの期間
input double EnvDev = 0.1; //偏差%
input double InitialLots = 0.1; //初期ロット数

//ロット数算出関数
double CalculateLots(int signal)
{
   //1本前ののエンベロープ
   double EnvUpper1= iEnvelopes(_Symbol, 0, EnvPeriod, MODE_SMA, 0, PRICE_CLOSE, EnvDev, MODE_UPPER, 1);
   double EnvLower1 = iEnvelopes(_Symbol, 0, EnvPeriod, MODE_SMA, 0, PRICE_CLOSE, EnvDev, MODE_LOWER, 1);

   double lots = InitialLots; //初期ロット数

   //買いシグナルの場合
   if(signal > 0 && Close[1] > EnvUpper1) lots *= 2;

   //売りシグナルの場合
   if(signal < 0 && Close[1] < EnvLower1) lots *= 2;

   return lots; //ロット数の出力
}

説明

FilterSignal()の代わりにロット数を算出する関数CalculateLots()を作成します。これは、仕掛けシグナルsig_entryを引数として、ロット数lotsを返す関数とします。

CalculateLots()の内容はFilterSignal()と似ています。終値がエンベロープの上位ラインを上回ったとき、買いシグナルが入力されれば、ロット数lotsを2倍にします。また終値がエンベロープの下位ラインを下回ったときに売りシグナルが入力された場合もロット数lotsを2倍にします。

ここで、ロット数lotsは、InitialLotsとして宣言した初期ロット数を代入して使います。