English Русский 中文 Español Deutsch Português
preview
知っておくべきMQL5ウィザードのテクニック(第03回):シャノンのエントロピー

知っておくべきMQL5ウィザードのテクニック(第03回):シャノンのエントロピー

MetaTrader 5テスター | 10 1月 2023, 15:04
131 0
Stephen Njuki
Stephen Njuki

1.0 はじめに

クロード・シャノンは1948年に、情報エントロピーの斬新な理想を持った論文「通信の数学的理論」を発表しました。エントロピーは物理学からの概念で、物質内の粒子がアクティブである範囲の尺度です。たとえば、水の3つの状態、つまり氷、液体、蒸気を考えると、粒子の運動エネルギーは蒸気で最も高く、氷で最も小さいことがわかります。これと同じ概念が、確率を介して数学に適用されます。次の3つのセットを検討してください。

セット1: 

セット1


セット2: 

セット2


セット3: 

セット3


これらのセットのどれが最高のエントロピーを持つかを推測するとしたら、どちらでしょうか。 
最後を選んだ方は正しいですが、その答えをどのように検証するのでしょうか。これに答える最も簡単な方法は、各セットを再編成できる方法の数をエントロピー推定値として取り、同様の色のストレッチを無視することです。したがって、最初のセットを「再配置」する方法は1つしかありませんが、後のセットを見ると、明らかに色に関する順列の数が大幅に増加しているため、最後のセットが最も高いエントロピーを持っていると主張できます。 

情報に基づいてエントロピーを決定するより正確な方法があります。セット1から任意にボールを選ぶとしたら、このボールを選ぶ前に、そのボールについて何がわかるでしょうか。セットには青いボールのみが含まれているため、青いボールであることを確信できます。したがって、セット1から何を選択するかについて完全な情報を持っていると言えます。セット2とセット3を考慮すると、情報はそれぞれますます完全ではなくなります。したがって、数学では、エントロピーは情報に反比例します。エントロピーが高いほど、未知数が多くなります。 

では、エントロピーを計算する式をどのように導き出すのでしょうか。セットについてもう一度考えると、セット内のボールの種類が多様であるほど、エントロピーは高くなります。ボールを選択する前にボールに関する情報を測定する上で最も敏感な要素は、セット内の各ボールを選択する確率です。したがって、各セット全体を検討し、各ボールの選択が独立したイベントであることを前提として、セットに表示される頻度と同じ頻度ですべての色が選択された8つのボールを選択する可能性を見つけるとします。その場合、各セットの確率(したがって「既知の情報」)は、各ボールの個々の確率の積になります。 

セット1: 

(1.0 x 1.0 x 1.0 x 1.0 x 1.0 x 1.0 x 1.0 x 1.0) = 1.0 


セット2: 

(0.625 x 0.625 x 0.625 x 0.625 x 0.625 x 0.375 x 0.375 x 0.375) ~ 0.0050 


セット3: 

(0.375 x 0.375 x 0.375 x 0.25 x 0.25 x 0.25 x 0.25 x 0.125) ~ 0.000025 


セットのサイズと種類が増えるにつれて、確率値が小さくなりすぎて処理できなくなります。そのため、これらの確率の対数、特に負の対数がエントロピーのサイズを測定する際に考慮されます。これは、上記のように既知の情報に反比例します。この恒等式は、正規化の基礎です。 


式_1


1未満の数値の対数は負であるため、対数に-1を掛けます。実際、ウィキペディアによるとエントロピー式は次のとおりです。 


式_2


これは、確率とその対数の積の合計として変換されます。したがって、セットのエントロピーを計算するに次のようになります。、 


セット1: 

-(8 x 0.125 x log2(1.0)) = 0.0 


セット2: 

(-(0.625 x log2(0.625)) - (0.375 x log2(0.375))) ~ 0.9544 


セット3: 

(- (0.375 x log2(0.375)) - (2 x 0.25 x log2(0.25)) - (0.125 x log2(0.125))) ~ 1.906 


セットからランダムに選択されたボールの色を決定するために必要なバイナリ質問の平均数がセットのエントロピーであることが示されています。また、一連のn値の最大エントロピーは次のとおりです。

式_3

この最大値は、0.0~1.0の範囲のシグナルを生成する際のエントロピー値の正規化に役立ちます。トレーダーにとって、価格履歴のエントロピーは、その履歴から信頼できる取引シグナルを処理できるかどうかの前兆として機能します。しかし、シグナルを生成するためにエントロピー自体を使用したとしたらどうでしょうか。買いシグナルを意味するものとして、最近のバーの固定セット内で上昇バーのエントロピーよりも下降バーのエントロピーが大きい、またはその逆であるという考えを検討したらどうでしょうか。これをMQL5ウィザードのエキスパートアドバイザー(EA)シグナルとしてコーディングする方法を見てみましょう。


2.0 クラスの作成

この記事では、MQL5ライブラリのデシジョンフォレストクラスを使用します。具体的には、シャノンのエントロピーシグナルの有効性を調べる際に、ランダムフォレストのアイデアを抽象化します。この記事はランダムフォレストに関するものではなく、シャノンのエントロピーに関するものです。 

デシジョンフォレストクラスはランダムフォレストモデルの基礎となるため、再度検討してみましょう。これは良いことです。デシジョンフォレストは生得的なものです。私たちは皆、意識しているかどうかにかかわらず、ある時点で決定木を使用しているため、その概念自体は奇妙ではありません。

f_d




どのように機能するかをよりよく説明するために、例を見てみましょう。

データセットが上記の価格バーで構成されているとします。3つの下降ローソク足と5つの上昇ローソク足(弱気市場と強気市場をクラスとして取ります)があり、それらの属性を使用してクラスを分離したいと考えています。属性は、価格の方向性と頭と尻尾の長さの比較です。これらは方向の変化の前兆となる可能性があるためです。どのようにすればいいでしょうか。

白は弱気のローソク足を表し、青は強気を表すため、価格の方向性は単純な属性のように見えます。したがって、「価格は下落していますか?」という質問を使用して、最初のジャンクションを分離します。枝が2つに分かれる点としての木のジャンクションは、「Yes」分岐と「No」分岐を選択する基準を満たします。

No分岐(上昇ローソク足)はすべて頭よりも尾が長いため、そこで終了ですが、Yes分岐ではそうではないため、さらに作業が必要です。2番目の属性を使用して、「頭は尾よりも長いですか?」と尋ねます。2番目の分割をおこないます。

頭が長い2つの下降ローソク足はYesサブブランチの下にあり、尾が長い1つの下降ローソク足は右サブブランチの下に分類されます。この決定木では、2つの属性を使用して、基準に従ってデータを完全に分割することができました。 

実際の取引システムでは、ティックボリューム、時刻、およびその他の多くの取引指標をすべて使用して、より包括的な意思決定木を構築できます。それにもかかわらず、ノードでの各質問の中心的な前提は、上記のデータを2つの異なるセットに分割(または分類)し、各セットの作成されたメンバーが類似している1つの属性を見つけることです。

ランダムフォレストに移行すると、その名前が示すように、グループとして機能する膨大な数の個々の決定木で構成されます。ランダムフォレスト内のすべての木に対してクラス予測がおこなわれ、投票数が最も多いクラスがモデルの予測として選択されます。 ランダムフォレストの背後にある主な概念は見落としがちですが、非常に強力な概念、つまり大衆の知恵です。予測をおこなう際、無相関木は、個々の木がどれほど多くのデータで訓練されていても、個々の木よりも優れています。低相関が核心です。この理由は、Tonによると、木が個々のエラーからお互いを保護するためです(すべてのエラーが常に同じ方向に進まない限り)。ランダムフォレストが機能するには、予測シグナルが平均よりも優れている必要があり、各木のパーディション/エラーが互いに低い相関関係にある必要があります。

例として、2つの取引システムがあり、最初の取引システムでは1年間に最大1000ドルの証拠金注文を出すことができ、もう1つの取引システムでは1000ドルの証拠金注文を1回だけ出すことができるとします。期待が同様だと仮定したらどちらを好まれるでしょうか。ほとんどの人が好むのは、トレーダーに「より多くの制御」を与える最初のシステムです。 

では、ランダムフォレストアルゴリズムはどのようにして、個々の木の特性がフォレスト内の他の木の特性と相関しすぎないようにするのでしょうか。それは、次の2つの特徴に集約されます。

2.0.1 バギング

決定木は訓練データの影響を非常に受けやすく、わずかな変更でもフォレストが大きく異なる可能性があります。 ランダムフォレストは、置換中に各木がデータセットをランダムにサンプリングすることでこれを使用し、異なる木を生成します。このプロセスは、ブートストラップ集約の略語であるバギングとして知られています。

バギングでは、訓練データを小さなセットに置き換えるのではなく、元の訓練データの代わりに、サイズNのランダムサンプルをいくつかの置換で取得することに注意してください。初期設定サイズNが維持されます。たとえば、訓練データが[U、V、W、X、Y、Z]の場合、木の1つに次のリスト[U、U、V、X、X、Z]を与えることができます。両方のリストで、サイズN(6)が保持され、「U」と「X」の両方がランダムに選択されたデータで繰り返されます。


2.0.2 特徴のランダム性

通常、決定木では、ノードの分割には、考えられるすべての特徴を考慮し、最終的な左ノードの観測値と最終的な右ノードの観測値の違いが最も大きくなるものを選択する必要があります。一方、ランダムフォレストでは、各木は特徴のランダムなサブセットからのみ選択できます。これにより、フォレスト内でより多くのバリエーションが強制される傾向があり、最終的には木間の相関関係が低くなり、多様化が進みます。

視覚的な例を見てみましょう。上の図では、ノードを分割する方法を決定する際に、従来の決定木(青色)が4つの特徴すべてから選択できます。データを可能な限り分離されたグループに分割するため、特徴1(黒と下線付き)を使用することにしました。

では、ランダムフォレストを見てみましょう。この例では、森の2本の木だけを調べます。ランダムフォレストの木1をチェックアウトすると、ノード分割の決定には(ランダムに選択された)特徴2と3しか考慮できないことがわかります。従来の決定木(青)から、特徴1が分割に最適な特徴であることがわかっていますが、木1には特徴1が表示されないため、特徴2(黒と下線)を使用する必要があります。一方、木2は特徴1と3しか表示できないため、特徴1を選択できます。

そのため、ランダムフォレストでは、木はデータセットで訓練されるだけでなく(バギングのおかげで)、決定を下す際にさまざまな特徴も使用します。



s_d



ランダムフォレストを使用することで、EAは過去の取引結果と市場シグナルを処理して、売買の決定に到達します。エントロピーからスクリーナーだけでなくシグナルを取得する際に、最近のセット内の正の価格バーのエントロピーと負の価格バーのエントロピーを別々に検討します。 

ランダムフォレストの構築と訓練は、単一のスレッドによる最適化でのみおこなわれます。

2.1 EAシグナルクラス 

// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signals of'Shannon Entropy'                                |
//| Type=SignalAdvanced                                              |
//| Name=Shannon Entropy                                             |
//| ShortName=SE                                                     |
//| Class=CSignalSE                                                  |
//| Page=signal_se                                                   |
//| Parameter=Reset,bool,false,Reset Training                        |
//| Parameter=Trees,int,50,Trees number                              |
//| Parameter=Regularization,double,0.15,Regularization Threshold    |
//| Parameter=Trainings,int,21,Trainings number                      |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CSignalSE.                                                 |
//| Purpose: Class of generator of trade signals based on            |
//|          the 'Shannon Entropy' signals.                          |
//| Is derived from the CExpertSignal class.                         |
//+------------------------------------------------------------------+
class CSignalSE : public CExpertSignal
   {
      public:
         
         //Decision Forest objects.
         CDecisionForest               DF;                                                   //Decision Forest
         CMatrixDouble                 DF_SIGNAL;                                            //Decision Forest Matrix for inputs and output
         CDFReport                     DF_REPORT;                                            //Decision Forest Report for results
         int                           DF_INFO;                                              //Decision Forest feedback

         double                        m_out_calculations[2], m_in_calculations[__INPUTS];   //Decision Forest calculation arrays

         //--- adjusted parameters
         bool                          m_reset;
         int                           m_trees;
         double                        m_regularization;
         int                           m_trainings;
         //--- methods of setting adjustable parameters
         void                          Reset(bool value){ m_reset=value; }
         void                          Trees(int value){ m_trees=value; }
         void                          Regularization(double value){ m_regularization=value; }
         void                          Trainings(int value){ m_trainings=value; }
         
         //Decision Forest FUZZY system objects
         CMamdaniFuzzySystem           *m_fuzzy;
         
         CFuzzyVariable                *m_in_variables[__INPUTS];
         CFuzzyVariable                *m_out_variable;

         CDictionary_Obj_Double        *m_in_text[__INPUTS];
         CDictionary_Obj_Double        *m_out_text;

         CMamdaniFuzzyRule             *m_rule[__RULES];
         CList                         *m_in_list;

         double                        m_signals[][__INPUTS];
         
         CNormalMembershipFunction     *m_update;
         
         datetime                      m_last_time;
         double                        m_last_signal;
         double                        m_last_condition;

                                       CSignalSE(void);
                                       ~CSignalSE(void);
         //--- method of verification of settings
         virtual bool                  ValidationSettings(void);
         //--- method of creating the indicator and timeseries
         virtual bool                  InitIndicators(CIndicators *indicators);
         //--- methods of checking if the market models are formed
         virtual int                   LongCondition(void);
         virtual int                   ShortCondition(void);

         bool                          m_random;
         bool                          m_read_forest;
         int                           m_samples;

         //--- method of initialization of the oscillator
         bool                          InitSE(CIndicators *indicators);
         
         double                        Data(int Index){ return(Close(StartIndex()+Index)-Close(StartIndex()+Index+1)); }
         
         void                          ReadForest();
         void                          WriteForest();
         
         void                          SignalUpdate(double Signal);
         void                          ResultUpdate(double Result);
         
         double                        Signal(void);
         double                        Result(void);
         
         bool                          IsNewBar(void);
  };

 

2.1.1 シグナル

このエントロピーは、最新性のためにインデックスによって重み付けされます。 

            if(_data>0.0)
            {
               _long_entropy-=((1.0/__SIGNALS[i])*((__SIGNALS[i]-s)/__SIGNALS[i])*(fabs(_data)/_range)*(log10(1.0/__SIGNALS[i])/log10(2.0)));
            }
            else if(_data<0.0)
            {
               _short_entropy-=((1.0/__SIGNALS[i])*((__SIGNALS[i]-s)/__SIGNALS[i])*(fabs(_data)/_range)*(log10(1.0/__SIGNALS[i])/log10(2.0)));
            }

また、価格バーの大きさによって重み付けされます。

            if(_data>0.0)
            {
               _long_entropy-=((1.0/__SIGNALS[i])*((__SIGNALS[i]-s)/__SIGNALS[i])*(fabs(_data)/_range)*(log10(1.0/__SIGNALS[i])/log10(2.0)));
            }
            else if(_data<0.0)
            {
               _short_entropy-=((1.0/__SIGNALS[i])*((__SIGNALS[i]-s)/__SIGNALS[i])*(fabs(_data)/_range)*(log10(1.0/__SIGNALS[i])/log10(2.0)));
            }

生成されるシグナルは、負のバーのエントロピーから正のバーのエントロピーを引いたものになります。ここでの理由は、負のバーのエントロピーが正のバーのエントロピーを超える場合、負のバーに関する情報が少ないため、同様にロングポジションを意味する正のバーの場合よりもショートポジションになるからです。表面的には、これは「危険な」トレンドフォローシステムになるように見えます。ただし、エントロピーを計算する際に上記の重み付けが適用されるため、そうではない場合があります。

ポジションが開かれることを意味するため、ロングまたはショートの状態がオープンしきい値を超えると、シグナルが更新されます。これはタイマーで発生するため、これに対応するようにウィザードアセンブルEAを変更します。

//+------------------------------------------------------------------+
//| "Timer" event handler function                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(PositionSelect(Symbol()) && Signal_ThresholdClose<=fabs(filter0.m_last_condition))
     {
      filter0.ResultUpdate(filter0.Result());
     }
   //
   if(!PositionSelect(Symbol()) && Signal_ThresholdOpen<=fabs(filter0.m_last_condition))
     {
      filter0.SignalUpdate(filter0.m_last_signal);
     }
   ExtExpert.OnTimer();
  }

クラスのソース関数は、既に述べたように最適化でのみ実行されます。

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+  
void CSignalSE::SignalUpdate(double Signal)
   {
      if(MQLInfoInteger(MQL_OPTIMIZATION))
      {
         m_samples++;
         DF_SIGNAL.Resize(m_samples,__INPUTS+2);
         
         for(int i=0;i<__INPUTS;i++)
         {
            DF_SIGNAL[m_samples-1].Set(i,m_signals[0][i]);
         }
         //
         DF_SIGNAL[m_samples-1].Set(__INPUTS,Signal);
         DF_SIGNAL[m_samples-1].Set(__INPUTS+1,1-Signal);    
      }
   }

 

2.1.2 結果

結果は、最後に閉じたポジションの利益に基づきます。  

      if(HistorySelect(0,m_symbol.Time()))
      {
         int _deals=HistoryDealsTotal();
         
         for(int d=_deals-1;d>=0;d--)
         {
            ulong _deal_ticket=HistoryDealGetTicket(d);
            if(HistoryDealSelect(_deal_ticket))
            {
               if(HistoryDealGetInteger(_deal_ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT)
               {
                  _result=HistoryDealGetDouble(_deal_ticket,DEAL_PROFIT);
                  break;
               }
            }
         }
      }
   
      return(_result);

また、ポジションが決済されることを意味するため、ロングまたはショートの条件が決済しきい値を超えると更新されます。これも上記のように、クラス関数が最適化時にデシジョンフォレストファイルのみを更新するタイマーで発生します。

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+  
void CSignalSE::ResultUpdate(double Result)
   {
      if(MQLInfoInteger(MQL_OPTIMIZATION))
      {
         int _err;
         if(Result<0.0) 
         {
            double _odds = MathRandomUniform(0,1,_err);
            //
            DF_SIGNAL[m_samples-1].Set(__INPUTS,_odds);
            DF_SIGNAL[m_samples-1].Set(__INPUTS+1,1-_odds);
         }
      }
   }


2.1.3 フォレストの書き込み

フォレストは読み取り前にティックで書き込まれるため、これに対応するようにウィザードアセンブルEAを変更します。 

//+------------------------------------------------------------------+
//| "Tick" event handler function                                    |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(!signal_se.m_read_forest) signal_se.WriteForest();
   
   ExtExpert.OnTick();
  }


2.1.4 フォレストの読み取り

フォレストはテスターパスの最後にテスターで読み取られるため、これに対応するようにウィザードアセンブルEAを変更します。 

//+------------------------------------------------------------------+
//| "Tester" event handler function                                  |
//+------------------------------------------------------------------+  
double OnTester()
   {
    signal_se.ReadForest();
    return(0.0);
   }


2.2 EAマネークラス

この記事では、ウィザードで使用するカスタマイズされた位置サイジングクラスの作成についても検討しています。「MoneySizeOptimized」クラスを使用して、シャノンエントロピーに基づいてポジションサイズを正規化するように修正します。新しいインターフェイスは次のようになります。 

// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Trading with 'Shannon Entropy' optimized trade volume      |
//| Type=Money                                                       |
//| Name=SE                                                          |
//| Class=CMoneySE                                                   |
//| Page=money_se                                                    |
//| Parameter=ScaleFactor,int,3,Scale factor                         |
//| Parameter=Percent,double,10.0,Percent                            |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CMoneySE.                                                  |
//| Purpose: Class of money management with 'Shannon Entropy' optimized volume.          |
//|              Derives from class CExpertMoney.                    |
//+------------------------------------------------------------------+
class CMoneySE : public CExpertMoney
  {
protected:
   int               m_scale_factor;

public:
   double            m_absolute_condition;
   
                     CMoneySE(void);
                    ~CMoneySE(void);
   //---
   void              ScaleFactor(int scale_factor) { m_scale_factor=scale_factor; }
   void              AbsoluteCondition(double absolute_condition) { m_absolute_condition=absolute_condition; }
   virtual bool      ValidationSettings(void);
   //---
   virtual double    CheckOpenLong(double price,double sl);
   virtual double    CheckOpenShort(double price,double sl);

protected:
   double            Optimize(double lots);
  };

 変数「m_absolute_condition」は、「LongCondition」および「ShortCondition」関数によって返される整数の絶対値になります。これは正規化された値であるため、そのサイズを使用してポジションサイズを比例させることができます。この変数は、ウィザードアセンブルEAへの変更を介して、シグナルクラスからマネークラスに渡されます。

//+------------------------------------------------------------------+
//| Global expert object                                             |
//+------------------------------------------------------------------+
CExpert ExtExpert;
CSignalSE *signal_se;
CMoneySE *money_se;

そしてティック関数について

//+------------------------------------------------------------------+
//| "Tick" event handler function                                    |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(!signal_se.m_read_forest) signal_se.WriteForest();
   
   money_se.AbsoluteCondition(fabs(signal_se.m_last_condition));
   
   ExtExpert.OnTick();
  }

主な変更点は、以下のOptimize関数にあります。 

//+------------------------------------------------------------------+
//| Optimizing lot size for open.                                    |
//+------------------------------------------------------------------+
double CMoneySE::Optimize(double lots)
  {
   double lot=lots;
   
      //--- normalize lot size based on magnitude of condition
      lot*=(20*m_scale_factor/fmax(20.0,((100.0-m_absolute_condition)/100.0)*20.0*m_scale_factor*m_scale_factor));
      
      //--- reduce lot based on number of losses orders without a break
      if(m_scale_factor>0)
      {
         //--- select history for access
         HistorySelect(0,TimeCurrent());
         //---
         int       orders=HistoryDealsTotal();  // total history deals
         int       losses=0;                    // number of consequent losing orders
         CDealInfo deal;
         //---
         for(int i=orders-1;i>=0;i--)
         {
            deal.Ticket(HistoryDealGetTicket(i));
            if(deal.Ticket()==0)
            {
               Print("CMoneySE::Optimize: HistoryDealGetTicket failed, no trade history");
               break;
            }
            //--- check symbol
            if(deal.Symbol()!=m_symbol.Name())
               continue;
            //--- check profit
            double profit=deal.Profit();
            if(profit>0.0)
               break;
            if(profit<0.0)
               losses++;
         }
         //---
         if(losses>1){
         lot*=m_scale_factor;
         lot/=(losses+m_scale_factor);
         lot=NormalizeDouble(lot,2);}
      }
      //--- normalize and check limits
      double stepvol=m_symbol.LotsStep();
      lot=stepvol*NormalizeDouble(lot/stepvol,0);
      //---
      double minvol=m_symbol.LotsMin();
      if(lot<minvol){ lot=minvol; }
      //---
      double maxvol=m_symbol.LotsMax();
      if(lot>maxvol){ lot=maxvol; }
//---
   return(lot);
  }

 

3.0 MQL5ウィザード

2つのEAを組み立てます。1つは、作成したシグナルクラスとマネー管理用の最小取引高取引のみを備え、もう1つは、作成したシグナルとマネー管理クラスの両方を備えています。


4.0 ストラレジーテスター

最初のEAの最適化を実行すると、2.89のプロフィットファクターと4.87のシャープレシオが得られますが、2番目のEAの最適化では3.65のプロフィットファクターと5.79のシャープレシオが得られます。

 

最初のレポート

 

s_r

 

最初のエクイティカーブ


s_c

 

二次報告

 

m_r

 

2番目のエクイティカーブ

 

m_c


5.0 結論

付属のEAは、理想的なテイクプロフィットとストップロスレベルの4時間枠の始値で最適化されています。つまり、これらの結果をライブ口座やすべてのティックモードのストラテジーテスターで再現することはできません。それは記事のポイントではありませんでした。再現すべき聖杯を見つけようとするのではなく、この連載ではすべてのトレーダーが自分の優位性を思いつくことができるように、さらにカスタマイズできる明確なアイデアを明らかにしようとします。市場は依然として全体的に相関が強すぎるため、ボラティリティが高い場合にエッジを探すことがうまく機能します。ご精読ありがとうございました。

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/11487

添付されたファイル |
expert_se.mq5 (7.48 KB)
se.mq5 (7.75 KB)
SignalSE.mqh (24.84 KB)
MoneySE.mqh (6.55 KB)
EAを用いたリスクとキャピタルの管理 EAを用いたリスクとキャピタルの管理
この記事では、バックテストレポートでは見えないこと、自動売買ソフトを使用する際の注意点、エキスパートアドバイザー(EA)を使用している場合の資金管理、自動売買をおこなっている場合に取引活動を続けるために大きな損失をカバーする方法について説明します。
DoEasy-コントロール(第19部):TabControl、WinFormsオブジェクトイベントでのタブのスクロール DoEasy-コントロール(第19部):TabControl、WinFormsオブジェクトイベントでのタブのスクロール
この記事では、スクロールボタンを使用してTabControlでタブヘッダーをスクロールする機能を作成します。この機能は、コントロールの両方側からタブヘッダーを1行に配置するためのものです。
DoEasy-コントロール(第20部):SplitContainer WinFormsオブジェクト DoEasy-コントロール(第20部):SplitContainer WinFormsオブジェクト
今回の記事では、MS Visual StudioツールキットからSplitContainerコントロールの開発を開始します。このコントロールは、垂直または水平の可動セパレータで区切られた2つのパネルで構成されています。
ニューラルネットワークが簡単に(第30部):遺伝的アルゴリズム ニューラルネットワークが簡単に(第30部):遺伝的アルゴリズム
今日はちょっと変わった学習法を紹介したいと思います。ダーウィンの進化論からの借用と言えます。先に述べた手法よりも制御性は劣るでしょうが、非差別的なモデルの訓練が可能です。