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

 
t101:
需要在 OnInit() 中手动添加吗?这样我就不能通过向导做我想做的事情了吗?
有什么问题?您正在引入额外的功能,因此需要做一些手工工作。
 
Karputov Vladimir:
有什么问题?您正在引入额外的功能,因此需要做一些手工工作。

完全没问题,但这不符合 "主控器在信号、资本等自定义模块的基础上完成所有工作 "的概念。而且这篇文章已经过时,与事实不符:

CheckCloseLong() 方法在确定退出水平后生成多头平仓信号。Expert Advisor 调用该方法来确定是否有必要关闭多头头寸。如果要生成关闭多头头寸的信号,则需要覆盖该方法。

virtual bool CheckCloseLong(double& price);
无论如何,感谢您的帮助。
 
快 6 年过去了,这篇文章还不过时吗? 我只是不确定,因为我几乎每周都会看到终端更新。
 
yerlan Imangeldinov:
快 6 年过去了,这篇文章还不过时吗? 我不确定,因为我看到终端几乎每周都在更新。
最近有一篇关于编写交易信号模块的文章:"六小时内创建一个交易机器人!"。
 

大家好、

我想知道如何使用此处提出的方法以及 Harvester在《 标准库中的交易策略类探索--定制策略》中提出的方法,创建具有 "突破 "和 "进入 "观察到的交易区间这两种模式的 CExpertSignal 的子类 。我认为每个信号类都可以(应该)通过重载

//+------------------------------------------------------------------+
//| "投票 "认为价格会增长。|
//| INPUT: no.|
//| 输出:价格将增长的 "票数"。
//| 备注:没有。|
//+------------------------------------------------------------------+
int CSignalBreakOutOrIn::LongCondition()
  {
   int result=0;
   int idx   =StartIndex();
//---
   //--- 以防我们需要某种默认模式
   if(IS_PATTERN_USAGE(0)) result=m_pattern_0;                                   //"确认 "信号编号 0
   //--- 如果使用了模式 1,则检查模式 1 的条件
   if(IS_PATTERN_USAGE(1) && ConditionForPattern1(idx)) result=m_pattern_1;      // 信号 1
   //--- 如果使用了模式 2,则检查模式 2 的条件
   if(IS_PATTERN_USAGE(2) && ConditionForPattern2(idx)) result=m_pattern_2;      // 信号 2
//--- 返回结果
   return(result);
  }

//+------------------------------------------------------------------+
//| "投票 "认为价格会下跌。|
//| INPUT: no.|
// | 输出:认为价格会下跌的 "票数"。
//| 备注:没有。|
//+------------------------------------------------------------------+
int CSignalBreakOutOrIn::ShortCondition()
  {
   int result=0;
   int idx   =StartIndex();
//---
   //--- 以防我们需要某种默认模式
   if(IS_PATTERN_USAGE(0)) result=m_pattern_0;                                   //"确认 "信号编号 0
   //--- 如果使用了模式 1,则检查模式 1 的条件
   if(IS_PATTERN_USAGE(1) && ConditionForPattern1(idx)) result=m_pattern_1;      // 信号 1
   //--- 如果使用了模式 2,则检查模式 2 的条件
   if(IS_PATTERN_USAGE(2) && ConditionForPattern2(idx)) result=m_pattern_2;      // 信号 2
//--- 返回结果
   return(result);
  }

然后我们会发现

int CExpertSignal::Direction()
  {
   ...
   int result=LongCondition()-ShortCondition();
   ...
  }

中的signal.m_threshold_opensignal.m_threshold_close进行测试

  1. bool CExpertSignal::CheckOpenLong(...)
  2. bool CExpertSignal::CheckOpenShort(...)
  3. bool CExpertSignal::CheckCloseLong(...)
  4. bool CExpertSignal::CheckCloseShort(...)
  5. bool CExpertSignal::CheckReverseLong(...), 和
  6. bool CExpertSignal::CheckReverseShort(...)

然后,指定入市水平以及设置止损和止盈价格的参数将由

//+------------------------------------------------------------------+
//| 检测购买水平|
//+------------------------------------------------------------------+
bool CExpertSignal::OpenLongParams(double &price,double &sl,double &tp,datetime &expiration)
  {
  }
//+------------------------------------------------------------------+
//| 检测销售水平|
//+------------------------------------------------------------------+
bool CExpertSignal::OpenShortParams(double &price,double &sl,double &tp,datetime &expiration)
  {
  }

将调用 基类中定义bool CExpertSignal::CheckOpenLong(...)bool CExpertSignal::CheckOpenShort(...)的标准实现 因此,只需重载

  1. int CExpertSignal::LongCondition(...)
  2. int CExpertSignal::ShortCondition(...)
  3. bool CExpertSignal::OpenLongParams(...)
  4. bool CExpertSignal::OpenShortParams(...)
  5. bool CExpertSignal::CloseLongParams(...), 和
  6. bool CExpertSignal::CloseShortParams(...)

用于定义任意新信号。请注意, CExpertTrade 包含用于检测所需的入市价格是否与当前价格相差太远而无法下达市场订单的代码,并使用入市价格选择自动决定是下达止损订单还是限价订单。

但是,如果交易范围被定义为最后n 个 条形图的最高价 (HH) 和最低价 (LL) 之间的区域,那么条件 LL < 价格 < HH 始终为真。因此, int CExpertSignal::LongCondition(...) int CExpertSignal::ShortCondition(...) 应始终检测 0 "突破 "模式,无论我们将什么值与此模式关联,函数 int CExpertSignal::Direction() 都将始终返回 0!

重载

  1. bool CExpertSignal::CheckOpenLong(...)
  2. bool CExpertSignal::CheckOpenShort(...)

以便前者检查

  1. LongCondition()>m_threshold_open 而后者检查
  2. ShortCondition()>m_threshold_open

而不是

  1. m_direction>=m_threshold_open
  2. - m_direction>=m_threshold_open

的版本还不能成功。正如所指出的,让 bool CExpertSignal::OpenLongParams(...) 返回入市价格 HH 和让 bool CExpertSignal::OpenShortParams(...)返回入市价格 LL非常简单,这样就可以 完成连续生成 2 个止损订单的信号。

在我看来,最好能有一个示例,说明如何在标准库中实现这一标准突破策略,并通过提供 "闯入 "替代模式使其足够灵活,从而在 LL 和 HH 处生成限价订单。显然,这种信号将结合以下策略

  1. 高买高卖或低买低卖,以及另一种策略
  2. 低买高卖或高卖低买。

将它们作为模式提供。如果能帮助我完成这一方法,我将不胜感激。

 
AnonymousTrades:

大家好、

我想知道如何使用此处提出的方法以及 Harvester 在《标准库中的交易策略类探索--定制策略》中提出的方法,创建具有 "突破 "和 "进入 "观察到的交易区间这两种模式的 CExpertSignal 的子类 。我认为每个信号类都可以(应该)通过重载 以下两个函数 来实现

int CSignalBreakOutOrIn::LongCondition()  { if(IS_PATTERN_USAGE(X) && LongConditionForPatternX(idx)) return(m_pattern_X); }
int CSignalBreakOutOrIn::ShortCondition() { if(IS_PATTERN_USAGE(X) && ShortConditionForPatternX(idx)) return(m_pattern_X); }

请注意CExpertTrade 包含用于检测所需的入市价格是否与当前价格相差太远而无法下达市场订单的代码,并使用入市价格选择自动决定是下达止损订单还是限价订单。

[...]

在我看来,最好能有一个示例,说明如何在标准库中实施这种标准的突破策略,并通过提供在 LL 和 HH 位置下限价订单的替代模式 "突破进入",使其足够灵活


我决定重新表述我所关注的问题,以使其尽可能易于理解。在我看来,这两篇文章

  1. MQL5 向导:如何创建交易信号模块(这一篇)和
  2. 探索标准库的交易策略类 - Harvester Trading的定制策略

两篇 文章总体上 展示了如何以最简单的方式编写我们自己的信号类。我将在下文中总结我的这一感悟。

不过,我仍然需要一个想法,来完成一个信号的实现,使用这种方法,当价格高于/低于过去n 个 期间观察到的最高/最低价格时,建议买入/卖出。这样做的结果应该是在当前价格上下设置一对止损订单。我已经尝试通过替换以下条件来实现这一点

  • Direction()>=m_threshold_open 替换为
  • LongCondition()>=m_threshold_open 来实现、

但似乎仍然不起作用。这对我来说毫无意义,因为我还重载了函数OpenLongParams(...)OpenShortParams (...)。它们决定在哪个价位下达所需的止损订单。请对 MetaQuotes 开发人员的想法有更多了解的人解释一下,他们是如何实现这一最基本的突破策略的?

由于源代码通常被视为任何软件的最佳文档,因此我花了一些时间来分析 MQL5\Include\Expert\ExpertSignal.mqh 中的 CExpertSignal 类。

我的结果是,检查交易条件的函数基本上简化为测试函数Direction() { return(LongCondition()-ShortCondition()); } 的值,如下所示:

bool CExpertSignal::CheckOpenLong(...)     { if(Direction()>=m_threshold_open && OpenLongParams(price,sl,tp,expiration)) return(true); return(false); }
bool CExpertSignal::CheckOpenShort(...)    { if(-Direction()>=m_threshold_open && OpenShortParams(price,sl,tp,expiration)) return(true); return(false); }
bool CExpertSignal::CheckCloseLong(...)    { if(-Direction()>=m_threshold_close && CloseLongParams(price,sl,tp,expiration)) return(true); return(false); }
bool CExpertSignal::CheckCloseShort(...)   { if(Direction()>=m_threshold_close && CloseShortParams(price,sl,tp,expiration)) return(true); return(false); }
bool CExpertSignal::CheckReverseLong(...)  { if(!CheckCloseLong(c_price) || !CheckOpenShort(price,sl,tp,expiration)) return(false); return(true); }
bool CExpertSignal::CheckReverseShort(...) { if(!CheckCloseShort(c_price) || !CheckOpenLong(price,sl,tp,expiration)) return(false); return(true); }

(我删除了一些代码,这些代码似乎只是稳定执行所必需的,对功能没有任何帮助)。

以上总结表明,对于任何定制的策略类,重载以下函数就足够了

  1. int CExpertSignal::LongCondition(...)
  2. int CExpertSignal::ShortCondition(...)
  3. bool CExpertSignal::OpenLongParams(...)
  4. bool CExpertSignal::OpenShortParams(...)
  5. bool CExpertSignal::CloseLongParams(...), 和
  6. bool CExpertSignal::CloseShortParams(...)

和 bool CExpertSignal::CloseLongParams (...),以及Harvester 在上面链接的文章 2.中解释了如何在前两个中使用宏IS_PATTERN_USAGE(x),从而使生成的信号检测到多个预定义模式。

我发现了一个问题: 价格是否介于最后n 个 条形图的最高价和最低价之间这一条件必须始终为真。因此,LongCondition(...)ShortCondition(...) 都返回与突破交易模式相关的相同值,而Direction() 的值必然为零,除非CheckOpenLong(...)CheckOpenShort(...) 中的条件发生变化。

但为什么使用 LongCondition()>=m_threshold_open 和 ShortCondition()>=m_threshold_open 还不够?

 
yankai0219:

当我使用您附在文章后面的文件时,出现了一些问题。

我发现关于 "类型 "的注释应该如下:

//| Type=SignalAdvanced                                          |

感谢您的留言。您的留言解决了我的问题。干杯

乔治

 

你好、

当我编译代码时,出现了三个警告

m_open' 声明隐藏了成员 samplesignal.mqh 42 23

m_close' 声明隐藏了成员 samplesignal.mqh 43 23

声明 "m_expiration "会隐藏成员 samplesignal.mqh 52 23


m_open 和 m_close 在 ExpertBase.mqh 中定义,但类型不同。

m_expiratin 在 ExpertSignal.mqh 中定义。

注释掉以上三行。警告已消失。

乔治

 
如果可以重写该程序的准确、完整和可执行的代码,并纠正其错误,并将其放在这里
 
touhid Qolizadeh #:
如果有可能重写这个程序的准确、完整和可执行的代码,并修正其错误,然后把它放在这里

给你!

干杯,扎里克

附加的文件: