記事"MQL5ウィザード:トレーディングシグナル用モジュール作成方法"についてのディスカッション - ページ 6

 
Karputov Vladimir:
あるいは資金管理モジュール。どちらを選ぶかは、もっと詳しく見る必要がある。

コンセプトはあまり明確ではありません。ポジションを建てるシグナルもあるが、決済するシグナルもある。投票などを使うことも可能だろうし、トレーリングに加えてこれらすべてを使うこともできる。

また、基本クラスはどれくらいの頻度で変更されるのだろうか?もし私が前のバージョンのウィザードでシグナル・モジュールを書いたとしたら、今それを設計し直さなければならないだろう。

このウィザードとExpert Advisorsの基本クラスを本気で使っている人はいるのでしょうか?それとも自分で何もしたくない怠け者のためだけなのでしょうか?

 
Karputov Vladimir:
あるいは資金管理モジュール。具体的に何を選べばいいのか、もっと詳しく見てください。

すみません、私はOOPが苦手なのですが、わかるように教えていただけますか?

ここで、私はСMySignal.mqhという売買シグナルのモジュールを作りました。今、私は自分自身の終値シグナルを実装したいと考えています。CExpertにはそのような呼び出しがあるので、そのために自分の資金管理モジュール CMyMoney.mqhを作成します:

protected:
  CExpertMoney     *m_money;

bool CExpert::CheckClose(void)

  {
   double lot;
//--- position must be selected before call
   if((lot=m_money.CheckClose(GetPointer(m_position)))!=0.0)
      return(CloseAll(lot));

しかし、私はCMySignalクラスのメソッドをクロージングロジックに使いたい。そこで、CMyMoneyの中で次のように書きます:

class CMyMoney : public CExpertMoney

protected:

   //--- input parameters
   virtual bool      CheckCloseLong(void);
   virtual bool      CheckCloseShort(void);

   CMySignal         *filter0;

...

double CMyMoney::CheckClose(CPositionInfo *position)
  {
   double lot;
   lot=position.Volume();
   if(position.PositionType()==POSITION_TYPE_BUY)
     {
      //--- check the possibility of closing the long position
      if(filter0.CheckCloseLong(lot))
         Print(__FUNCTION__+": close long position signal detected. Lot to be closed ",lot); 
     }
   else
     {
      //--- check the possibility of closing the short position
      if(filter0.CheckCloseShort(lot))
         Print(__FUNCTION__+": close short position signal detected. Lot to be closed ",lot);
     }
   return(lot);
  }


そして、すべてのクロージング・ロジックをCMySignalクラスに移す:

class CMySignal : public CExpertSignal

public:

   virtual bool      CheckCloseLong(double &lot);
   virtual bool      CheckCloseShort(double &lot);

bool CMySignal::CheckCloseLong(double &lot)

  {

   //логика закрытия Long

  }

bool CMySignal::CheckCloseShort(double &lot)

  {

   //логика закрытия Short

  }

しかし、すでに作成されたfilter0オブジェクトではなく、新しいfilter0オブジェクトを扱っていることがわかりました。そのためのデータ(インジケータなど)を再初期化しなければなりません。CMySignalクラスの既に存在するオブジェクトにアクセスするにはどうすればよいでしょうか?私は自分自身を明確にしたことを願っています =)

このすべては標準的な方法でウィザードを通して動作するはずです。すべての変更は、私の取引シグナルと資金管理モジュールでのみ可能です。

 
t101:

申し訳ありませんが、私はOOPが得意ではありません。

私はСMySignal.mqhという売買シグナルのモジュールを作りました。今、私は自分の終値シグナルを実装したいと思っています。CExpertにはそのような呼び出しがあるので、そのために自分の資金管理モジュール CMyMoney.mqhを作成します:

protected:
  CExpertMoney     *m_money;

bool CExpert::CheckClose(void)

  {
   double lot;
//--- position must be selected before call
   if((lot=m_money.CheckClose(GetPointer(m_position)))!=0.0)
      return(CloseAll(lot));

しかし、私はCMySignalクラスのメソッドをクロージングロジックに使いたい。そこで、CMyMoneyの中で次のように書きます:

class CMyMoney : public CExpertMoney

protected:

   //--- input parameters
   virtual bool      CheckCloseLong(void);
   virtual bool      CheckCloseShort(void);

   CMySignal         *filter0;

...

double CMyMoney::CheckClose(CPositionInfo *position)
  {
   double lot;
   lot=position.Volume();
   if(position.PositionType()==POSITION_TYPE_BUY)
     {
      //--- check the possibility of closing the long position
      if(filter0.CheckCloseLong(lot))
         Print(__FUNCTION__+": close long position signal detected. Lot to be closed ",lot); 
     }
   else
     {
      //--- check the possibility of closing the short position
      if(filter0.CheckCloseShort(lot))
         Print(__FUNCTION__+": close short position signal detected. Lot to be closed ",lot);
     }
   return(lot);
  }


そして、すべてのクロージング・ロジックをCMySignalクラスに移す:

class CMySignal : public CExpertSignal

public:

   virtual bool      CheckCloseLong(double &lot);
   virtual bool      CheckCloseShort(double &lot);

bool CMySignal::CheckCloseLong(double &lot)

  {

   //логика закрытия Long

  }

bool CMySignal::CheckCloseShort(double &lot)

  {

   //логика закрытия Short

  }

しかし、すでに作成されたfilter0オブジェクトではなく、新しいfilter0オブジェクトを扱っていることがわかりました。そのためのデータ(インジケータなど)を再初期化しなければなりません。CMySignalクラスの既に存在するオブジェクトにアクセスするにはどうすればよいでしょうか?私は自分自身を明確にしたことを願っています =)

これはすべて標準的な方法でウィザードを通して動作するはずなので、私は基本クラスを変更しません。すべての変更は、私の取引シグナルと資金管理モジュールでのみ可能です。

枚目の「シート」について質問があります。なぜ「CMySignal *filter0;」を資金管理モジュールに挿入するのですか?
 
Karputov Vladimir:
枚目の「シート」について質問があります。なぜ「CMySignal *filter0;」を資金管理モジュールに挿入するのですか?

filter0は私の取引シグナルモジュールCMySignalのクラスオブジェクトです。Expert Advisorのメインファイルに作成されています:

CMySignal *filter0=new CMySignal;

私は資金管理モジュールから このオブジェクトにアクセスし、すべての終値計算をシグナルモジュールに転送しようとしています。独自のクロージングロジックを実装する他の方法は見当たりません。
 
t101:

filter0は私の取引シグナルモジュールCMySignalのクラスオブジェクトです。これはメインEAファイルに作成されています:

CMySignal *filter0=new CMySignal;

私は資金管理モジュールから このオブジェクトにアクセスし、すべてのクロージング計算をシグナルモジュールに転送しようとしています。独自のクロージングロジックを実装する他の方法は見当たりません。

メインシグナルへのポインタをシグナルモジュールに転送する実装を見てください(MQL5 Wizard: How to teach an Expert Advisor to open pending orders at any price):

アイデアの実装スキームに よると、メインシグナルへのポインタを格納する内部変数を宣言する必要があります。

この変数は内部変数でなければならないので(取引シグナル・ジェネレーターのクラス内でのみスコープを持つ)、次のコード・ブロックに追加します:

protected:
   CiEnvelopes       m_env;          // オブジェクト・インジケーター
   //--- パラメータを調整
   int               m_ma_period;    // インジケーターの「平均化期間」パラメーター
   int               m_ma_shift;     // インジケーターの「タイムシフト」パラメーター
   ENUM_MA_METHOD    m_ma_method;     // インジケーターの「平均化方法」パラメーター
   ENUM_APPLIED_PRICE m_ma_applied;    // インジケータの「平均化対象」パラメータ
   double            m_deviation;    // インジケーターの「偏差」パラメーター
   //--- 市場モデルの「重み」(0~100)
   int               m_pattern_0;      // モデル0
   CExpertSignal    *m_signal;         // メイン・シグナルへの参照を保存する

また、コードで使用しない変数を削除したことにも注意してください。

メイン・シグナルへのポインタを格納するメソッドは、別のコード・ブロック「メイン・シグナルへのポインタを設定するメソッド」で宣言します。不要なメソッドもいくつか削除しました。

おそらく、これが必要なのだろう。メイン・シグナルへのポインタだけが、資本管理モジュールに渡される。

 
Karputov Vladimir:

メインシグナルへのポインタをシグナルモジュールに渡す実装を見てください(MQL5 Wizard: Expert Advisorに任意の価格で未決注文をオープンするように教える方法):

おそらくこれが必要なものでしょう。メインシグナルへのポインタのみが資金管理モジュールに渡されます。

CExpertSignalクラスを継承したシグナルへのポインタが必要なのに、なぜメインシグナルへのポインタが必要なのでしょうか?CExpertMoneyの子孫であるマネー・マネージメント・モジュールに欲しいのです。
 
t101:
CExpertSignalクラスの子孫である自分のシグナルへのポインタが欲しいのに、なぜヘッドシグナルへのポインタが必要なのですか?CExpertMoneyの継承者である私のマネー・マネジメント・モジュールに欲しいのだ。

なるほど。反対側を見てみよう。資金管理モジュールでは、このように変数を宣言する必要がある:

CMySignal    *m_signal;         // シグナルへの参照を格納する

そして、このようにメソッドを宣言します:

   //--- メイン・シグナルへのポインタを設定する方法
   virtual bool      InitSignal(СMySignal *filter=NULL);

そしてその実装

//+------------------------------------------------------------------+
//| 初期化シグナルオブジェクト|
//+------------------------------------------------------------------+
bool CMyMoney::InitSignal(СMySignal *filter)
  {
   m_signal=filter;
   return(true);
  }

これで、資金管理モジュールからシグナルにアクセスできるようになります。

m_signal.метод вашего модуля сигналов
 
Karputov Vladimir:

よし。反対側に行こう。資金管理モジュールでは、このように変数を宣言する必要があります:

そしてこのメソッド:

そしてその実装

これで、資金管理モジュールから以下の方法でシグナルにアクセスできるようになりました。

私のシグナル・モジュールのメソッドを呼び出すときに無効なポインタ・アクセス
m_signal.метод вашего модуля сигналов
InitSignalは、あらかじめどこかで呼び出されなければなりませんか?
 
t101:
シグナルモジュールのメソッドを呼び出す際に無効なポインタアクセスが発生する InitSignal は事前にどこかで呼び出されなければならないのでしょうか?
もちろん、"InitSignal" は事前に呼び出す必要があります。EA の OnInit() から、資金管理モジュールの 初期化ブロックの最後に呼び出します。
 
Karputov Vladimir:
EAのOnInit()から、資金管理モジュールの 初期化ブロックの最後にです。
手動でOnInit()に追加すべきでしょうか?それでは、ウィザードを通して望むことはできないのでしょうか?