文章 "MQL5 向导:如何创建交易信号模块" - 页 6

 
Karputov Vladimir:
或者是资金管理模块。至于选择哪一个,您需要详细了解。

这个概念不是很清楚。有开仓信号,也有平仓信号。还可以使用投票等等,所有这些都是在追踪的基础上进行的。

基类的变化频率如何?如果我用以前版本的向导编写信号模块,现在就必须重新设计。

我只是想知道,有人会认真使用这个向导和 Expert Advisors 基类吗?

 
Karputov Vladimir:
或者是资金管理模块。具体选择什么,你需要详细了解一下。

对不起,我不擅长 OOP,您能帮我理解一下吗?

在这里,我做了一个交易信号模块,名为 СMySignal.mqh。现在我想实现自己的平仓信号。为此,我创建了自己的资金管理模块 CMyMoney.mqh,因为 CExpert 有这样的调用:

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 中进行所有计算。因此,我在 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 对象,而不是一个已经创建的对象。我必须为它重新初始化数据(指标等)。我怎样才能访问 CMySignal 类中已经存在的对象呢?希望我已经说得很清楚了 =)

所有这些都应通过向导以标准方式运行,因此我不会更改任何基类。所有更改只能在我的交易信号和资金管理模块中进行。

 
t101:

对不起,我不擅长 OOP,您能帮我理解一下吗?

我制作了一个交易信号模块,名为 СMySignal.mqh。现在我想实现自己的平仓信号。为此,我创建了自己的资本管理模块 CMyMoney.mqh,因为 CExpert 有这样的调用:

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 中进行所有计算。因此,我在 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 对象,而不是一个已经创建的对象。我必须为它重新初始化数据(指标等)。我怎样才能访问 CMySignal 类中已经存在的对象呢?希望我已经说得很清楚了 =)

所有这些都应通过向导以标准方式运行,因此我不会更改任何基类。所有更改只能在我的交易信号和资金管理模块中进行。

我对第二个 "工作表 "有一个疑问--为什么要在资金管理模块中插入"CMySignal *filter0;"?
 
Karputov Vladimir:
关于第二个 "工作表",我有一个问题--为什么要在资金管理模块中插入"CMySignal *filter0;"?

filter0 是我的交易信号模块 CMySignal 的类对象。它是在 Expert Advisor 的主文件中创建的:

CMySignal *filter0=new CMySignal;

我试图从资金管理模块 访问它,将所有收盘计算转移到我的信号模块。我找不到其他方法来实现我自己的平仓逻辑。
 
t101:

filter0 是我的交易信号模块 CMySignal 的类对象。它是在主 EA 文件中创建的:

CMySignal *filter0=new CMySignal;

我试图从资金管理模块 访问它,将所有平仓计算转移到我的信号模块。我找不到其他方法来实现我自己的平仓逻辑。

请看将主信号指针转移到信号模块的实现(MQL5 向导:如何教智能交易系统在任何价格打开挂单):

根据我们的想法实现方案,有必要声明一个内部变量,用于存储主信号指针。

由于该变量必须是内部变量(作用域仅限于交易信号发生器类内部),我们将把它添加到下一个代码块中:

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 向导:如何教智能交易系统以任何价格开立挂单):

也许这正是您所需要的。只有主信号的指针才会传递给资金管理模块。

如果我需要指向我的信号(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:

好吧 我们去另一边 All right.我们再来看另一边。在你的资金管理模块 中,你需要这样声明一个变量:

和这个方法

及其实现

现在我可以尝试从资金管理模块访问我的信号,通过

在调用我的信号模块的方法时,指针访问无效
m_signal.метод вашего модуля сигналов
InitSignal 必须事先在某个地方调用?
 
t101:
调用信号模块方法时指针访问无效 InitSignal 必须事先调用吗?
当然,"InitSignal "应该事先调用:从 EA 的 OnInit(),在资金管理模块 初始化块的末尾。
 
Karputov Vladimir:
当然,我们需要提前调用 "InitSignal":从 EA 的 OnInit(),在资金管理模块 初始化块的末尾。
我应该手动将其添加到 OnInit() 中吗?这样我就不能通过向导实现我的愿望了吗?