你好,恩里科。我刚刚看了您的作品,希望能找到解决问题的办法。在编译 StopBase 类时,我发现了一系列错误,请参见下文
implicit conversion from 'number' to 'string' OrderStopBase.mqh 395 25 implicit conversion from 'number' to 'string' OrderStopBase.mqh 467 26 implicit enum conversion OrderStopBase.mqh 468 33 implicit enum conversion OrderStop.mqh 37 33 implicit conversion from 'number' to 'string' OrderStop.mqh 44 43 'COrderBase' - import not defined OrderStop.mqh 54 7 'else' - semicolon expected OrderStop.mqh 81 4 ')' - unexpected token OrderStop.mqh 81 46 implicit conversion from 'number' to 'string' StopBase.mqh 767 22 implicit conversion from 'number' to 'string' StopBase.mqh 774 28 implicit conversion from 'number' to 'string' StopBase.mqh 796 22 implicit conversion from 'number' to 'string' StopBase.mqh 803 28 implicit conversion from 'number' to 'string' StopBase.mqh 698 36 'OrderType' - cannot convert enum Stop.mqh 227 52 'StopLossCustom' - no one of the overloads can be applied to the function call Stop.mqh 228 61 could be one of 2 function(s) Stop.mqh 228 61 double CStopBase::StopLossCustom(const string,const ENUM_ORDER_TYPE,const double) StopBase.mqh 136 22 bool CStopBase::StopLossCustom() StopBase.mqh 99 22 'OrderType' - cannot convert enum Stop.mqh 215 71 'TakeProfitCustom' - no one of the overloads can be applied to the function call Stop.mqh 215 98 could be one of 2 function(s) Stop.mqh 215 98 double CStopBase::TakeProfitCustom(const string,const ENUM_ORDER_TYPE,const double) StopBase.mqh 140 22 bool CStopBase::TakeProfitCustom() StopBase.mqh 111 22 implicit conversion from 'number' to 'string' Stop.mqh 250 39 implicit enum conversion Stop.mqh 291 31 implicit conversion from 'number' to 'string' Stop.mqh 292 36
忽略警告,这些错误似乎是由顺序类型问题引起的。此外,在编译您的示例 signal_ma 时还出现了以下错误
'GetPointer' - parameter conversion not allowed OrderStopVirtualBase.mqh 51 39 'GetPointer' - parameter conversion not allowed OrderStopVirtualBase.mqh 58 41 '=' - type mismatch OrderStopsBase.mqh 106 23 '=' - type mismatch OrderStopsBase.mqh 108 23 '=' - type mismatch OrderStopsBase.mqh 110 23 '=' - type mismatch OrderStopsBase.mqh 180 20 '=' - type mismatch OrderStopsBase.mqh 182 20 '=' - type mismatch OrderStopsBase.mqh 184 20
请问这些错误来自何处,我该如何解决? 关于相关问题,据我所知,利斯科夫替代法规定,我们应该按照接口编程,因为超类可以用基类替代。你为什么选择将对象传入函数(函数本身就是接口),而不是使用它们的基类?我的理解可能有误,但我认为这是最佳做法,不是吗?
提前感谢您的帮助和您所做的出色工作。你好,Shephard,感谢您的评论。关于您的问题:
- 不幸的是,目前还无法单独编译 StopBase.mqh。虽然 MQL4 和 MQL5 编译器接受前向声明,但如果您尝试访问类中被前向声明的方法或成员,它们就会出错。您需要将 StopBase.mqh 与更大的类一起编译,如 COrderManager 或CExpertAdvisor(CStop 和 CStops 是这两个类的组件)。
- 关于类型不匹配错误,我在原始文件中没有发现(您是否修改了源文件?)
- 我认为在大多数情况下,基类可以顺利传递给类方法。当专家使用库编码时,假定基类根本不存在会更容易。但有些对象有新的虚拟方法和非虚拟方法。基类无法单独访问这两组方法。如果使用派生类而不是基类,编译器就能选择派生类的正确版本,因此使用派生类比单独使用基类更全面。
你好,Shephard,感谢您的评论。关于您的问题:
- 不幸的是,目前还无法单独编译 StopBase.mqh。虽然 MQL4 和 MQL5 编译器接受前向声明,但如果您尝试访问类中被前向声明的方法或成员,它们就会出错。您需要将 StopBase.mqh 与更大的类一起编译,如 COrderManager 或 CExpertAdvisor(CStop 和 CStops 是这两个类的组件)。
- 关于类型不匹配错误,我在原始文件中没有发现(您是否修改了源文件?)
- 我认为在大多数情况下,基类可以顺利传递给类方法。当专家使用库编码时,假定基类根本不存在会更容易。但有些对象有新的虚拟方法和非虚拟方法。基类无法单独访问这两组方法。如果使用派生类而不是基类,编译器就能选择派生类的正确版本,因此使用派生类比单独使用基类更全面。
你好,恩里科、
非常感谢你的快速回复。我理解您传递具体类而不是基类的原因。某些在 C++ 中可以直接实现的功能在 MQL 中却无法实现,但事实就是如此。
关于类型不匹配,我没有改动任何东西。我只是下载并编译。你的方法真的很棒。
我是这样开发我的系统的。我将一个信号输出系统视为一个策略。 假设我有一个 MA 交叉系统,如果我用欧元 兑美元 创建一个对象,这就是一个策略。 我将这个策略添加到策略列表中。我可以创建另一个策略,并将其添加到列表中。 但这些策略不是通过 OnTick 调用的,而是观察者模式的一部分。 当特定事件发生时,例如 5 分钟的新条形图、10 Pip Renko 新条形图等,它们会被更新或调用。
再次感谢您抽出时间与我们分享您的知识和技能,以及您的及时回复。
你好,恩里科、
我正在测试您的信号模块。我有一个 SHORT 信号和一个 NEUTRAL 信号。为什么最后会出现 CMD_VOID?CMD_VOID 是什么时候出现的?
实际上,这出现在 CSignalsBase::Check 中。
if(signal.Entry()) { if(m_signal_open>CMD_VOID) { ENUM_CMD signal_open=signal.SignalOpen(); if(m_signal_open==CMD_NEUTRAL) { m_signal_open=signal_open; } else if(m_signal_open!=signal_open) { m_signal_open=CMD_VOID; } } }
只有 2 个信号。前一个信号是 CMD_SHORT。当前信号是 CMD_NEUTRAL。您能否确认 CMD_SHORT 和 CMD_NEUTRAL 的结果是 CMD_VOID?
如果我的第一个信号是 CMD_NEUTRAL,第二个信号是 CMD_SHORT,那么总信号就是 CMD_SHORT。但如果第一个信号是 CMD_SHORT,第二个信号是 CMD_NEUTRAL,那么结果就是 CMD_VOID。
我猜应该是这样的:
if(signal.Entry()) { if(m_signal_open>CMD_VOID) { ENUM_CMD signal_open=signal.SignalOpen(); if(m_signal_open==CMD_NEUTRAL) { m_signal_open=signal_open; } else if(m_signal_open!=signal_open && signal_open!=CMD_NEUTRAL) { m_signal_open=CMD_VOID; } } }
if(m_new_signal) { if(m_signal_open==m_signal_open_last) m_signal_open = CMD_NEUTRAL; if(m_signal_close==m_signal_close_last) m_signal_close= CMD_NEUTRAL; }
就收盘信号而言,这并不完全正确。为什么不能有两个随后的同方向收盘信号?
例如,我有进入信号 "空头",下一个退出信号 "多头"(平仓空头),下一个进入信号 "多头",下一个进入信号 "空头",下一个退出信号 "多头"。因此,最后一个退出空头头寸的信号将不起作用,因为它与前一个退出信号方向相同。
就收盘信号而言,这并不完全正确。为什么不能有两个随后的同方向收盘信号?
例如,我有进入信号 "空头",下一个退出信号 "多头"(平仓空头),下一个进入信号 "多头",下一个进入信号 "空头",下一个退出信号 "多头"。因此,最后一个退出空头头寸的信号将不起作用,因为它与前一个退出信号方向相同。
至于如何评估信号,这取决于你想要达到什么目的。
您发布的最后一段代码只有在类成员 m_new_signal 设置为 true 时才会执行。这仅用于新信号的交易。您可以使用类中的 NewSignal 方法来设置这个受保护的类成员。
这取决于您希望如何评估信号。
您发布的最后一段代码只有在类成员 m_new_signal 设置为 true 时才会执行。这仅用于新信号的交易。您可以使用类中的 NewSignal 方法来设置这个受保护的类成员。
我知道这一点。但如果我将其设置为 false,也会影响我的进入信号。进入信号可以,但退出信号不行,因为退出规则可能不同。它可以是回调信号,也可以是退出信号,所以两个相同方向的退出信号是正常的。
嗨,mbjen、
你好,恩里科、
我正在测试您的信号模块。我有一个 SHORT 信号和一个 NEUTRAL 信号。为什么最后会出现 CMD_VOID?CMD_VOID 是什么时候出现的?
实际上,这出现在 CSignalsBase::Check 中。
只有 2 个信号。前一个信号是 CMD_SHORT。当前信号是 CMD_NEUTRAL。您能否确认 CMD_SHORT 和 CMD_NEUTRAL 的结果是 CMD_VOID?
如果我的第一个信号是 CMD_NEUTRAL,第二个信号是 CMD_SHORT,那么总信号就是 CMD_SHORT。但如果第一个信号是 CMD_SHORT,第二个信号是 CMD_NEUTRAL,结果就是 CMD_VOID。
我猜一定是这样的:
很抱歉忽略了你的第一个问题。我直到现在才注意到。这是一个非常好的反馈。
感谢您指出这一点。是的,您说得没错。我会更新代码并修改文章。
我知道。但如果我将它设为 false,也会影响我的入市信号。进场信号可以,但出场信号不行,因为出场规则可能不同。它可以是回调信号,也可以是退出信号,所以两个相同方向的退出信号是正常的。
你说得有道理。但举例来说,如果我只想在 MA 交叉时发出退出信号,就需要这样做。我认为将它们分开是比当前代码更好的选择:
if(m_new_signal) { if(m_signal_open==m_signal_open_last) m_signal_open = CMD_NEUTRAL; } if(m_new_signal_close) { if(m_signal_close==m_signal_close_last) m_signal_close= CMD_NEUTRAL; }
m_signal_close 中保存的是 SignalBase.mqh 中的前一个信号值。例如,我有一些退出信号。如果对其进行检查,并且 Calculate() 方法返回 false,则会给出上次退出时的最后一个信号值。
Calculate 方法是一个虚拟方法。如果该方法返回 false,则应在方法本身中将这些类成员重置为中性。
新文章 跨平台的EA交易: 信号已发布:
本文讨论了 CSignal 和 CSignals 类,它们将用于创建跨平台的EA交易。它检验了MQL4和MQL5的区别,看它们在评估交易信号时需要怎样特别的数据,这样来确保写出的代码可以兼容两种编译器。
所有生成当前信号所需的计算都移动到 CSignal 和 CSignals 对象中,这样,我们所要做的就是让 CSignals 进行一次检查,然后通过调用它的 CheckOpenLong 和 CheckOpenShort 方法来取得输出。以下屏幕截图显示了在 MetaTrader 4 和 MetaTrader 5 中 EA 的测试结果。
(MT4)
作者:Enrico Lambino