MT5エキスパートアドバイザー EA11_FrAMA.mq5

システムの概要

 今回はフラクタルアダプティブ移動平均線(FrAMA)によるトレードです。
この指標はJohn Ehlersによって開発され、指数移動平均のアルゴリズムを
ベースに構成されています。
トレードはFrAMAの値が上あるいは下に大きく変化したときエントリーするようにし、
FrAMAの値の変化が小さくなくなったときポジションをクローズするようにします。
 ここで使われるスムージングファクターは価格配列による実際のフラクタル次元をもとに
計算されており、より進化したFRAMAにより、強いトレンドの動きをフォローし、
さらに値固めのときは十分スローダウンします。

 FrAMAの計算式は次のようになります。
FRAMA(i) = A(i) * Price(i) + (1 - A(i)) * FRAMA(i-1)
ただし
FRAMA(i): FRAMAの今の値
Price(i) : 今の価格
FRAMA(i-1) : FRAMAの一つ前の値
A(i) :今の指数スムージングファクターの値

指数スムージングファクターは下の式から計算
A(i) = EXP(-4.6 * (D(i) - 1))
ただし
D(i): 今のフラクタル次元;
EXP(): 指数関数

直線のフラクタル次元は1に等しく、
D = 1のときは、上の式から  A = EXP(-4.6 *(1-1)) = EXP(0) = 1になります。
価格が直線に変化したとき指数スムージングは使用されません。
なぜならばこの場合、式は次のようになるので 
FRAMA(i) = 1 * Price(i) + (1 - 1) * FRAMA(i-1) = Price(i)
すなわち指標は正確に価格をフォローします。

平面のフラクタル次元は2に等しい 
D = 2ならば、スムージングファクターは式より
A = EXP(-4.6*(2-1)) = EXP(-4.6) = 0.01. 
価格が強いのこぎり歯の動きになるとき、指数スムージングファクターは小さい値が得られます。
おおよそ200期間の単純移動平均に相当した強いスローダウンのようになります。、
 
フラクタル次元の式 
D = (LOG(N1 + N2) - LOG(N3))/LOG(2)
上式は下の式をもとに計算
N(Length,i) = (HighestPrice(i) - LowestPrice(i))/Length
ただし
HighestPrice(i) :今のLength 期間の最大値
LowestPrice(i):今のLength 期間の最小値
N1、 N2、 N3の値はそれぞれ次に等しい
N1(i) = N(Length,i)
N2(i) = N(Length,i + Length)
N3(i) = N(2 * Length,i)

 EM11_FrAMA.mq5 のプログラムは下のダウンロードから行ってください。
ソースファイルですので、ダウンロードした後コンパイルが必要です。

ダウンロード

 ソースファイルはExpertsフォルダーに格納します。
Expertsフォルダーの開き方は、
メタエディタのナビゲータでExpertsを選択し、マウスの右ボタンをクリックします。
そして「フォルダーを開く」を選択します。
Expertsフォルダーを開いた後、ファイルをコピー&ペーストします。

 コンパイルすると問題がなければ次のように表示されます。
0 error(s), 0 warning(s), compile time: 5160 msec  1 1

プログラムの変更箇所

 
 Frsig値がentrylevelを越えたときエントリーします。プラス側ではBUY,
マイナス側ではSELLになります。
Frsig = 100 * (FrAMA(1)- FrAMA(2)/CLOSE(1))の計算で
%表示にします。
上のFrsigの値がcloselevel以下ではクローズするシステムです。
  EM11_FrAMA.mq5 のコードの主だった追加、変更箇所は次のようになります。
----------
input parametersでのコードの追加
input int ma_period=5;
input double entrylevel=0.08; //(%)
input double closelevel=0.0025; //(%)
int FrH;
double maV[5];

----------
int OnInit()でのコードの変更
FrH=iFrAMA(_Symbol,_Period,ma_period,0,PRICE_CLOSE);

//------ 
   if(FrH==INVALID_HANDLE)
     {
      Print("SIGNAL ERROR");
      return(INIT_FAILED);
     }

----------
void OnTick()でのコードの変更と追加
トレンドシグナルのコードの変更
if(CopyBuffer(FrH,0,0,5,maV)<0)  return;
Frsig=100*(maV[3]-maV[2])/sclose;
   bool Buy_S1=(Frsig>=entrylevel);
 
  bool Sell_S1=(Frsig<=-1*entrylevel);

ポジションをオープンするときのストップレベルとテイクプロフィットレベルの設定変更
変更前
double s =NormalizeDouble(l_pr.ask - STP*_Point,_Digits);
double t =NormalizeDouble(l_pr.ask + TKP*_Point,_Digits);
変更後(設定しないときは0にします)
double s =0;
double t =0;
  
ポジションクローズのコードの追加
ouble FrsigAbs=0.0;
   FrsigAbs=MathAbs(Frsig);
   bool Close_sig=(FrsigAbs<=closelevel);

   if(Buy_sig || Sell_sig)
     {
      if(Close_sig)
        {
         CTrade m_trade;
         m_trade.PositionClose(Symbol());

        }
     }

Commentのコードの変更
Comment("Buy_S1 = ",Buy_S1,"  Sell_S1 = ",Sell_S1,"  Close_sig = ",Close_sig);

-------------------
iFrAMAの使用法 
 
フラクタルアダプイブ移動平均線 
int  iFrAMA( 
   string              symbol,            // symbol name 
   ENUM_TIMEFRAMES     period,            // period 
   int                 ma_period,         // averaging period 
   int                 ma_shift,          // horizontal shift on the chart 
   ENUM_APPLIED_PRICE  applied_price      // type of price or handle 
   );
 
Parameters
Symbol:通貨ペア設定(_Symbol)
period:通貨ペアの時間足設定(_Period)
ma_period:プライスチャートの計算期間
ma_shift:プライスチャート指標のシフト
applied_price:プライスチャートの終値

プログラムコード

 

 EA11_FrAMA..mq5  のプログラムコードは以下のようになります。
赤字の部分は変更箇所です。
#property copyright "T.S"
#property link      "http://mt5myprogrammingts.blogspot.com"
#property version   "1.00"

#include <Trade/Trade.mqh>
//--- input parameters
input int      Magic=1001;
input double    Lots=0.01;
input int    Slipage=10;

input int ma_period=5;
input double entrylevel=0.08; //(%)
input double closelevel=0.0025; //(%)
//---------------------------
int FrH;
double maV[5];

double sclose;
int STP,TKP,SL;
//+---------------------------+
// Expert initialization function   
//+---------------------------+
int OnInit()
  {
//---
   FrH=iFrAMA(_Symbol,_Period,ma_period,0,PRICE_CLOSE);

//------ 
   if(FrH==INVALID_HANDLE)
     {
      Print("SIGNAL ERROR");
      return(INIT_FAILED);
     }
//---
   SL=Slipage;
   if(_Digits==5 || _Digits==3) //EURUSD=5
     {
      SL=Slipage*10;
     }
//---
   return(INIT_SUCCEEDED);
  }
//+----------------------------+
// Expert deinitialization function     
//+----------------------------+
void OnDeinit(const int reason)
  {
//---
   IndicatorRelease(FrH);
   Comment("");
  }
//+-----------------------------+
// Expert tick function        
//+-----------------------------+
void OnTick()
  {
//------------------------------
   MqlTick l_pr;
   MqlRates mrate[2];
//------------------------------

   if(!SymbolInfoTick(_Symbol,l_pr))
     {
      Print("the latest price  error");
      return;
     }

   if(CopyRates(_Symbol,_Period,0,2,mrate)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }

//-----

   if(CopyBuffer(FrH,0,0,5,maV)<0)  return;
//-----   

   bool Buy_sig =false;
   bool Sell_sig=false;

   if(PositionSelect(_Symbol)==true)
     {
      if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
        {
         Buy_sig=true;
        }
      else if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
        {
         Sell_sig=true;
        }
     }

   sclose=mrate[0].close;
   double Frsig=0.0;
   Frsig=100*(maV[3]-maV[2])/sclose;

   bool Buy_S1=(Frsig >=entrylevel);

   if(Buy_S1)
     {
      if(Buy_sig)  return;
      if(Sell_sig) return;

      double l= Lots;
      double p=NormalizeDouble(l_pr.ask,_Digits);
      double s =0;
      double t =0;

      CTrade m_trade;
      m_trade.SetExpertMagicNumber(Magic);
      m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,l,p,s,t,"");

     }

   bool Sell_S1=(Frsig<=-1*entrylevel);;

   if(Sell_S1)
     {
      if(Sell_sig) return;
      if(Buy_sig)  return;

      double l = Lots;
      double p = NormalizeDouble(l_pr.bid,_Digits);
      double s =0;
      double t =0;

      CTrade m_trade;
      m_trade.SetExpertMagicNumber(Magic);
      m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,l,p,s,t,"");

     }
   double FrsigAbs=0.0;
   FrsigAbs=MathAbs(Frsig);
   bool Close_sig=(FrsigAbs<=closelevel);

   if(Buy_sig || Sell_sig)
     {
      if(Close_sig)
        {
         CTrade m_trade;
         m_trade.PositionClose(Symbol());

        }
     }

   Comment("Buy_S1 = ",Buy_S1,"  Sell_S1 = ",Sell_S1,"  Close_sig = ",Close_sig);
  }
//END



注意事項:プログラムはあくまでFX個人投資家の学習のための、
デモ口座によるMQL5売買プログラミングの情報提供を目的としております。
プログラムによる運用結果につきましては、自己責任であることをご了承ください。
パラメータの設定、最適化は読者自ら行ってください。
リアルトレードではテストしておりません。