文章 "在MQL5程序中使用断言" - 页 3 123 新评论 Alain Verleyen 2015.12.05 20:23 #21 解释。在撰写这篇文章时,MQL5 没有让程序执行紧急停止的机制。作为替代方案,runtime error 被触发,这保证了程序崩溃。 事实并非如此。一个 EA 可以通过 ExpertRemove() 停止,一个指标可以通过 ChartIndicatorDelete() 停止,这对脚本来说微不足道。 Sergey Eremin 2015.12.06 08:09 #22 Alain Verleyen: 事实并非如此。一个 EA 可以通过 ExpertRemove() 停止,一个指标可以通过 ChartIndicatorDelete() 停止,这对脚本来说微不足道。请举例说明,如何在代码中使用 ExpertRemove() 退出。例如,我们有这样一段代码:#property version "1.00" #property strict int OnInit() { for(int i = 0; i < 100; i++) { if(i == 2) { ExpertRemove(); } Print(i); } //--- return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { } void OnTick() { //--- }我们需要在 i == 2 的情况下退出,其他步骤必须停止运行。在日志中,我们必须只看到 "0 "和 "1"。如何使用该函数 实现这一目标?现在,ExpertRemove() 不会在需要的时候停止 EA,所有步骤都将运行,之后 EA 将停止。但这对于断言机制来说是错误的,我们必须立即停止 EA。是的,我们不能只使用 "break",因为我们需要通用宏或函数来处理任何 EA 的任何部分。关于指标--请向我展示定义指标短名的通用机制。因为如果没有这种机制,我们就无法在断言中使用该函数。是的,我们可以在我们的具体指标中定义 ShortName(例如使用全局变量,很多人都这么做,尽管这是很糟糕的做法),但我们没有通用函数 "GetShortName()"。因此,我们无法用 ChartIndicatorDelete() 制作通用机制(我指的是适用于所有指标的宏或函数,只需添加一行 "assert(...) "即可)。请向我展示用于任何代码部分的脚本的 "琐碎 "变体。脚本的任何部分都必须是一个(!)函数或宏:1) 对于 cicles 2) 对于任何返回类型的函数 3) 对于无返回类型(void)的函数。因此,我们必须在脚本的任何部分添加一行 "assert(...)",就像这样:#property version "1.00" #property strict void OnStart() { assert(...); } double SomeDouble() { assert(...); return 0.0; } color SomeColor() { assert(...); return clrNONE; } string SomeString() { assert(...); return ""; } void SomeVoid() { assert(...); return; } void SomeCicle() { while(!IsStopped()) { assert(...); } }附注:抱歉我的英语不好。 Sergey Eremin 2015.12.06 08:58 #23 或其他使用 ExpertRemove() 的 EA 示例,而不是 cicle :)例如,如果交易量大于我们的需求,我们必须 停止应用程序(这只是一个例子,在实际情况中,我们应该以不同的方式处理这种情况):#property version "1.00" #property strict int OnInit() { OpenTrade(); //--- return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { } void OnTick() { //--- } bool OpenTrade() { double volume = GetVolume(); if(volume > 1) { Print("Volume > 1, stop EA!"); ExpertRemove(); } Print("Opening position ..."); return true; } double GetVolume() { return 999.0; }我们必须 在代码需要的地方瞬间停止 EA(这是断言 的意思)。但 ExpertRemove() 在这种情况下不是正确的变体,我们有:2015.12.06 10:53:22.253 Test EURUSD,H1: Volume > 1, stop EA!<br/ translate="no">2015.12.06 10:53:22.253 Test EURUSD,H1: ExpertRemove function called 2015.12.06 10:53:22.253 Test EURUSD,H1: Opening position ...因此,请告诉我如何使用ExpertRemove() 函数(不带 return、break 等,必须通用于代码的任何部分)来处理这个顶点。 Alain Verleyen 2015.12.06 11:34 #24 Sergey Eremin:请举例说明,如何在 cicle 中使用 ExpertRemove() 退出。例如,我们有这样一段代码:我们需要在 i == 2 的情况下退出,而所有其他步骤都必须停止运行。在日志中,我们必须只看到 "0 "和 "1"。如何使用该函数实现这一目标?现在,ExpertRemove() 不会在需要的时候停止 EA,所有步骤都将运行,之后 EA 将停止。但这对于断言机制来说是错误的,我们必须立即停止 EA。是的,我们不能只使用 "break",因为我们需要通用宏或函数来处理任何 EA 的任何部分。您不必在 OnInit() 中使用ExpertRemove(),只需使用 return(INIT_FAILED);int OnInit() { //--- ... if(somethign wrong) { //ExpertRemove(); return(INIT_FAILED); //--- 无需在 OnInit() 中使用 ExpertRemove() } ... }在代码的其他部分,只需返回 : ExpertRemove(); return; //--- 只需返回即可完成当前事件处理程序 or ExpertRemove(); return(x); //--- 只需返回即可完成当前事件处理程序 关于指标 - 请向我展示定义指标 ShortName 的通用机制。因为如果没有这种机制,我们就无法将该函数用于断言。是的,我们可以在我们的具体指标中定义 ShortName(例如使用全局变量,很多人都这么做,尽管这是个坏习惯),但我们没有通用函数 "GetShortName()"。因此,我们无法用 ChartIndicatorDelete() 制作通用机制(我指的是适用于所有指标的宏或函数,只需添加一行 "assert(...) "即可)。问题出在哪里?你正在处理你的指标,这是你的代码,所以你知道它的简短名称。我发帖是想说,你说没有办法立即终止程序是不对的。你应该为你的断言项目找到解决方案。在指示器中使用全局变量绝对不是一个坏习惯。当然,如果你想用 "这是不好的做法 "这样的断言来创造自己的新限制,你会发现很多不可能的事情。请向我展示脚本中任何代码部分的 "琐碎 "变体。脚本的任何部分都必须是一个(!)函数或宏:1) 对于 cicles 2) 对于任何返回类型的函数 3) 对于无返回类型(void)的函数。因此,我们必须在脚本的任何部分添加一行 "assert(...)",就像这样:与 EA 相同。 附加的文件: ImmediateStopEA.mq5 4 kb Sergey Eremin 2015.12.06 12:30 #25 Alain Verleyen:我发帖是想说,你说没有办法立即终止程序是不对的。你应该为你的 Assertion 项目找到解决方案。在指标中使用全局变量绝对不是一个坏习惯。当然,如果你想用 "这是不好的做法 "这样的断言来创建自己的新限制,你会发现很多不可能的事情。好的,我明白了。谢谢,你说得对。但在我的文章中,我指的是断言的解决方案:在代码的任何地方(包括 OnInit 和 cicles)停止 MQL4/5 应用程序的通用 机制。只需在任何 部分添加一行 即可完成。就像在许多编程语言中的任何断言机制中一样;)是的,你的变体是正确的。但不适合我对断言 的理解,因为它不是针对任何 代码的任何部分 的通用解决方案。谢谢你的 EA 例子。 Alain Verleyen 2015.12.06 13:20 #26 Sergey Eremin:好的,我明白了。谢谢,你说得对。但在我的文章中,我指的是断言的解决方案:在代码的任何地方(包括 OnInit 和 cicles)停止 MQL4/5 应用程序的通用 机制。只需在任何 部分添加一行 即可完成。就像在许多编程语言中的任何断言机制中一样;)是的,你的变体是正确的。但不适合我对断言 的理解,因为它不是针对任何 代码的任何部分 的通用解决方案。谢谢你的 EA 例子。我知道你想做什么,而且完全可以做到,你只需根据我提供的代码进行归纳即可。通过分析宏中的调用上下文,检测它是 EA 还是指标,并解析__FUNCSIG__。能否将其变成一种通用机制取决于您。 Sergey Eremin 2015.12.06 13:36 #27 Alain Verleyen:我知道你想做什么,而且完全可以做到,你只需根据我提供的代码进行归纳。通过分析宏中的调用上下文,检测它是 EA 还是指标,并解析 __FUNCSIG__。能否将其变成一种通用机制取决于您。 是的,起初我也考虑过这样的问题,但最终我做到了我们在文章中看到的那样:)感谢您的评论! mktr8591 2021.04.13 19:38 #28 如果有人要使用这段代码,请记住这一点:下面的脚本 if(true) assert(1==1, "") else Print("Never executed"); 会导致 else 分支出现 "从未执行 "的信息。 为了能正确使用assert,您应该对其进行修正,例如,以这种形式: #define assert(condition, message) \ do if(!(condition)) \ { \ string fullMessage= \ #condition+", " \ +__FILE__+", " \ +__FUNCSIG__+", " \ +"line: "+(string)__LINE__ \ +(message=="" ? "" : ", "+message); \ \ Alert("Assertion failed! "+fullMessage); \ double x[]; \ ArrayResize(x, 0); \ x[1] = 0.0; \ } while(false) #else #define assert(condition, message) #endif (else分支中的宏也已更正:它返回空字符串(而不是";")。 在此变体中,应在 assert(...) 后面加上";")。 123 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
事实并非如此。一个 EA 可以通过 ExpertRemove() 停止,一个指标可以通过 ChartIndicatorDelete() 停止,这对脚本来说微不足道。
请举例说明,如何在代码中使用 ExpertRemove() 退出。
例如,我们有这样一段代码:
我们需要在 i == 2 的情况下退出,其他步骤必须停止运行。在日志中,我们必须只看到 "0 "和 "1"。如何使用该函数 实现这一目标?
现在,ExpertRemove() 不会在需要的时候停止 EA,所有步骤都将运行,之后 EA 将停止。但这对于断言机制来说是错误的,我们必须立即停止 EA。是的,我们不能只使用 "break",因为我们需要通用宏或函数来处理任何 EA 的任何部分。
关于指标--请向我展示定义指标短名的通用机制。因为如果没有这种机制,我们就无法在断言中使用该函数。是的,我们可以在我们的具体指标中定义 ShortName(例如使用全局变量,很多人都这么做,尽管这是很糟糕的做法),但我们没有通用函数 "GetShortName()"。因此,我们无法用 ChartIndicatorDelete() 制作通用机制(我指的是适用于所有指标的宏或函数,只需添加一行 "assert(...) "即可)。
请向我展示用于任何代码部分的脚本的 "琐碎 "变体。脚本的任何部分都必须是一个(!)函数或宏:
1) 对于 cicles
2) 对于任何返回类型的函数
3) 对于无返回类型(void)的函数。
因此,我们必须在脚本的任何部分添加一行 "assert(...)",就像这样:
附注:抱歉我的英语不好。
或其他使用 ExpertRemove() 的 EA 示例,而不是 cicle :)
例如,如果交易量大于我们的需求,我们必须 停止应用程序(这只是一个例子,在实际情况中,我们应该以不同的方式处理这种情况):
我们必须 在代码需要的地方瞬间停止 EA(这是断言 的意思)。但 ExpertRemove() 在这种情况下不是正确的变体,我们有:
2015.12.06 10:53:22.253 Test EURUSD,H1: Opening position ...
因此,请告诉我如何使用ExpertRemove() 函数(不带 return、break 等,必须通用于代码的任何部分)来处理这个顶点。
请举例说明,如何在 cicle 中使用 ExpertRemove() 退出。
例如,我们有这样一段代码:
我们需要在 i == 2 的情况下退出,而所有其他步骤都必须停止运行。在日志中,我们必须只看到 "0 "和 "1"。如何使用该函数实现这一目标?
现在,ExpertRemove() 不会在需要的时候停止 EA,所有步骤都将运行,之后 EA 将停止。但这对于断言机制来说是错误的,我们必须立即停止 EA。是的,我们不能只使用 "break",因为我们需要通用宏或函数来处理任何 EA 的任何部分。
您不必在 OnInit() 中使用ExpertRemove(),只需使用 return(INIT_FAILED);
在代码的其他部分,只需返回 :
关于指标 - 请向我展示定义指标 ShortName 的通用机制。因为如果没有这种机制,我们就无法将该函数用于断言。是的,我们可以在我们的具体指标中定义 ShortName(例如使用全局变量,很多人都这么做,尽管这是个坏习惯),但我们没有通用函数 "GetShortName()"。因此,我们无法用 ChartIndicatorDelete() 制作通用机制(我指的是适用于所有指标的宏或函数,只需添加一行 "assert(...) "即可)。
问题出在哪里?你正在处理你的指标,这是你的代码,所以你知道它的简短名称。
我发帖是想说,你说没有办法立即终止程序是不对的。你应该为你的断言项目找到解决方案。
在指示器中使用全局变量绝对不是一个坏习惯。当然,如果你想用 "这是不好的做法 "这样的断言来创造自己的新限制,你会发现很多不可能的事情。
请向我展示脚本中任何代码部分的 "琐碎 "变体。脚本的任何部分都必须是一个(!)函数或宏:
1) 对于 cicles
2) 对于任何返回类型的函数
3) 对于无返回类型(void)的函数。
因此,我们必须在脚本的任何部分添加一行 "assert(...)",就像这样:
与 EA 相同。
我发帖是想说,你说没有办法立即终止程序是不对的。你应该为你的 Assertion 项目找到解决方案。
在指标中使用全局变量绝对不是一个坏习惯。当然,如果你想用 "这是不好的做法 "这样的断言来创建自己的新限制,你会发现很多不可能的事情。
好的,我明白了。谢谢,你说得对。
但在我的文章中,我指的是断言的解决方案:在代码的任何地方(包括 OnInit 和 cicles)停止 MQL4/5 应用程序的通用 机制。只需在任何 部分添加一行 即可完成。就像在许多编程语言中的任何断言机制中一样;)
是的,你的变体是正确的。但不适合我对断言 的理解,因为它不是针对任何 代码的任何部分 的通用解决方案。
谢谢你的 EA 例子。
好的,我明白了。谢谢,你说得对。
但在我的文章中,我指的是断言的解决方案:在代码的任何地方(包括 OnInit 和 cicles)停止 MQL4/5 应用程序的通用 机制。只需在任何 部分添加一行 即可完成。就像在许多编程语言中的任何断言机制中一样;)
是的,你的变体是正确的。但不适合我对断言 的理解,因为它不是针对任何 代码的任何部分 的通用解决方案。
谢谢你的 EA 例子。
我知道你想做什么,而且完全可以做到,你只需根据我提供的代码进行归纳即可。
通过分析宏中的调用上下文,检测它是 EA 还是指标,并解析__FUNCSIG__。
能否将其变成一种通用机制取决于您。
我知道你想做什么,而且完全可以做到,你只需根据我提供的代码进行归纳。
通过分析宏中的调用上下文,检测它是 EA 还是指标,并解析 __FUNCSIG__。
能否将其变成一种通用机制取决于您。
是的,起初我也考虑过这样的问题,但最终我做到了我们在文章中看到的那样:)
感谢您的评论!
如果有人要使用这段代码,请记住这一点:下面的脚本
会导致 else 分支出现 "从未执行 "的信息。
为了能正确使用assert,您应该对其进行修正,例如,以这种形式:
(else分支中的宏也已更正:它返回空字符串(而不是";")。
在此变体中,应在 assert(...) 后面加上";")。