記事「知っておくべきMQL5ウィザードのテクニック(第02回):コホネンマップ」についてのディスカッション

 

新しい記事「知っておくべきMQL5ウィザードのテクニック(第02回):コホネンマップ」はパブリッシュされました:

この連載では、MQL5ウィザードがトレーダーの主力であるべきことを示します。なぜでしょうか。MQL5ウィザードを使用すれば、新しいアイデアを組み立てることで時間を節約できるだけでなく、コーディングの重複によるミスを大幅に減らすことができるため、最終的に、取引の哲学のいくつかの重要な分野にエネルギーを注ぐことができるからです。

これらの地図でよくある誤解は、ファンクタのデータは画像か2次元であるべきだということです。以下のような画像は、どれも「コホネンマップ」を代表するものとしてよく共有されています。

典型的なイメージ

間違ってはいませんが、ファンクタは一次元でもいいし、おそらく(トレーダーにとっては)一次元であるべきだということを強調したいと思います。そこで、高次元のデータを2次元の地図に落とし込むのではなく、1本の線にマッピングすることにしました。 コホネンマップには次元を減らすという定義があるので、今回はこれを次の段階に進めたいと思います。 コホネンマップと通常のニューラルネットワークは、層数、アルゴリズムともに異なります。

コホネンマップは、多層ではなく、単層(前述したように通常は線形2Dグリッドニューロンのセットです。ファンクタと呼んでいるこの層のすべてのニューロンはフィードに接続しますが、自分自身には接続しません。つまり、ニューロンは互いの重みの影響を直接受けず、フィードデータに対してのみ更新されます。 ファンクタデータ層は、多くの場合、フィードデータに応じて学習反復ごとに自己組織化するマップです。 そのため、訓練後、各ニューロンはファンクタ層で重み調整された次元を持ち、これにより、そのような任意の2つのニューロン間のユークリッド距離を計算することができます。

作者: Stephen Njuki

 

一つ疑問が残るのは、なぜIN_RADIUSの値がデータを正規化するためにmoduloで取られるのかを理解するにはどうすればよいかということである:

double _dimension=fabs(IN_RADIUS)*((Low(StartIndex()+w+Index)-Low(StartIndex()+w+Index+1))-(High(StartIndex()+w+Index)-High(StartIndex()+w+Index+1)))/fmax(m_symbol.Point(),fmax(High(StartIndex()+w+Index),High(StartIndex()+w+Index+1))-fmin(Low(StartIndex()+w+Index),Low(StartIndex()+w+Index+1)));

なぜなら、クラスタ半径は定数であり、正の値だからです。

おそらくこれはエラーで、分子全体をモジュロすべきなのでしょうか?

 

Expert Advisorを組み立てたのですが、Stop LossとTake Profitの2つのパラメータが記事のスクリーンショットと同じではありません:

記事の中で

私は

その結果、トレードが1件もありません。

何か間違っているのでしょうか?

また、ATRの代わりに他のインジケータ、例えばMACDを使用するにはどうすればよいでしょうか?

 
Oleg Pavlenko #:

Expert Advisorを構築したのですが、Stop LossとTake Profitの2つのパラメータが記事のスクリーンショットと同じではありません:

その結果、1つのトレードも...

何か間違っているのでしょうか?

また、ATRの代わりに他のインジケータ、例えばMACDを使うにはどうすればいいでしょうか?

この方法でできます:

bool CSignalMACD::InitMACD(CIndicators *indicators)
  {
//--- オブジェクトをコレクションに追加する
   if(!indicators.Add(GetPointer(m_MACD)))
     {
      printf(__FUNCTION__+": error adding object");
      return(false);
     }
//--- オブジェクトの初期化
   if(!m_MACD.Create(m_symbol.Name(),m_period,m_period_fast,m_period_slow,m_period_signal,m_applied))
     {
      printf(__FUNCTION__+": error initializing object");
      return(false);
     }
//--- OK
   return(true);
  }

また、保護されています:

protected:
   CiMACD            m_MACD;           // オブジェクト・オシレーター
   //--- パラメータを調整
   int               m_period_fast;    // オシレーターの「高速EMAの周期」パラメーター
   int               m_period_slow;    // オシレーターの「低速EMAの周期」パラメーター
   int               m_period_signal;  // 発振器の "差の平均化周期 "パラメーター
   ENUM_APPLIED_PRICE m_applied;       // オシレーターの「価格系列」パラメーター

そして公開で

 void              PeriodFast(int value)             { m_period_fast=value;           }
 void              PeriodSlow(int value)             { m_period_slow=value;           }
 void              PeriodSignal(int value)           { m_period_signal=value;         }
 void              Applied(ENUM_APPLIED_PRICE value) { m_applied=value;  

そしてまた保護 された状態で

protected:
   //--- 発振器の初期化方法
   bool              InitMACD(CIndicators *indicators);
   //--- データの取得方法
   double            Main(int ind)                     { return(m_MACD.Main(ind));      }
   double            Signal(int ind)                   { return(m_MACD.Signal(ind));    }

そして最後に

bool CSignalKM::OpenLongParams(double &price,double &sl,double &tp,datetime &expiration)
  {
   CExpertSignal *general=(m_general!=-1) ? m_filters.At(m_general) : NULL;
//---
   if(general==NULL)
     {
      m_MACD.Refresh(-1);
      //--- ベース価格が明示的に指定されていない場合は、現在の市場価格を採用する。
      double base_price=(m_base_price==0.0) ? m_symbol.Ask() : m_base_price;

      //--- エントリー価格をMACDに基づいて設定する価格オーバーロード
      price      =base_price;
      double _range=m_MACD.Main(StartIndex())+((m_symbol.StopsLevel()+m_symbol.FreezeLevel())*m_symbol.Point());
      //

しかし、何のために?