
从新手到专家:MQL5中的协作式调试指南
核心内容
概述:
通常,每位作者都试图在文章中自始至终围绕某个具体问题展开探讨。今天的标题虽为“调试”,但请勿轻视其深度——我们将超越基础流程,深入挖掘实战精髓。我将分享多年来在多个成功项目中被验证有效的调试策略。在软件编程的所有领域中,调试都是不可回避的核心议题。我注意到,许多作者习惯展示完美无瑕的最终成果,却鲜少提及代码从混乱到稳定所经历的挣扎。
无论是神经网络系统、人工智能(AI)还是其他相关软件领域,调试都是关键能力。我相信,最有价值的技能是即时解决问题的能力,这种能力会演变为您的本能,助您从容应对类似的挑战。因此,系统性的解决问题能构建强大的技能体系,让新手逐渐蜕变为专家。
协作式调试
在撰写本文时,我正参与一个项目,期间编译代码时屡遇错误。有时调试器会抛出多达50行错误提示,令人应接不暇。但通过反复试错,我总结出一套高效的排错流程,如今能在数秒至数分钟内定位并解决问题,让程序顺畅运行。
我的目标是向您揭示加速调试进程的技术工具。根据我的经验,主动参与调试项目是快速掌握MQL5的捷径。我特意保留了一份带漏洞的示例程序,我们将共同逐步优化。
一个长期存在的挑战是:许多人难以坚持读完免费提供的MQL5长篇教程,但这并不意味着它们缺乏价值。这些书籍系统涵盖了从基础到进阶的MQL5编程知识。为了取得最佳的效果,明智的做法是在参与现有项目的同时,参考这些书籍中与您正在进行的工作相关的特定主题。这样一来,当您完成这些项目后,您将自然而然地掌握了大量的相关知识。
我们的错误报告通常按照下表中的四列结构呈现。
列(名称) | 解释说明 |
---|---|
描述 | 这一列提供了代码中遇到的错误或警告的简要说明。它可以用来描述问题的性质,例如语法错误、未声明的变量、类型不匹配或其他编程错误。理解描述有助于程序员快速识别问题。 |
文件 | 这里指出了发生错误的文件名称(例如D1 PriceMarker.mq5)。在一个项目中有多个文件的情况下,知道哪个文件有问题对于有效的调试和修正至关重要。 |
行 | 具体说明在指定文件中找到错误的确切行号。这种精确定位允许程序员快速导航到需要关注的代码的具体部分,减少了定位问题所需的时间。 |
列 | 指出了通过逐行检测找到错误的具体列号。尽管它不如前面的列常用,但在识别复杂语句中的错误或当前行包含的许多元素(如多个函数调用或参数)时,它可能特别有用。 |
它们通常从左到右排列,如下所示。我们还拿到了完整的错误报告,该报告包含20个错误和4个警告(见代码片段底部),这是我们将在本次讨论中调试程序的错误报告,位于表格下方。您会发现报告的特征很容易识别。如果您读到了最后,我们将探讨如何解决以下代码段中呈现的错误。
描述 | 文件 | 行 | 列 |
'D1 PriceMarker.mq5' 1 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 70 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 70 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 71 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 71 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 72 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 72 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 73 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 73 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 74 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 74 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 75 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 75 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 76 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 76 5 'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 77 5 built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 77 5 'ObjectCreate' - wrong parameters count D1 PriceMarker.mq5 15 9 built-in: bool ObjectCreate(long,const string,ENUM_OBJECT,int,datetime,double,...) D1 PriceMarker.mq5 15 9 'ObjectCreate' - wrong parameters count D1 PriceMarker.mq5 27 9 built-in: bool ObjectCreate(long,const string,ENUM_OBJECT,int,datetime,double,...) D1 PriceMarker.mq5 27 9 'ObjectSetText' - undeclared identifier D1 PriceMarker.mq5 37 5 ',' - unexpected token D1 PriceMarker.mq5 37 28 'labelName' - some operator expected D1 PriceMarker.mq5 37 19 '+' - illegal operation use D1 PriceMarker.mq5 37 36 ',' - unexpected token D1 PriceMarker.mq5 37 69 result of expression not used D1 PriceMarker.mq5 37 43 ',' - unexpected token D1 PriceMarker.mq5 37 73 expression has no effect D1 PriceMarker.mq5 37 71 ',' - unexpected token D1 PriceMarker.mq5 37 82 expression has no effect D1 PriceMarker.mq5 37 76 ')' - unexpected token D1 PriceMarker.mq5 37 87 expression has no effect D1 PriceMarker.mq5 37 84 'OBJPROP_Y' - undeclared identifier D1 PriceMarker.mq5 41 36 'ObjectSetInteger' - no one of the overloads can be applied to the function call D1 PriceMarker.mq5 41 5 could be one of 2 function(s) D1 PriceMarker.mq5 41 5 built-in: bool ObjectSetInteger(long,const string,ENUM_OBJECT_PROPERTY_INTEGER,long) D1 PriceMarker.mq5 41 5 built-in: bool ObjectSetInteger(long,const string,ENUM_OBJECT_PROPERTY_INTEGER,int,long) D1 PriceMarker.mq5 41 5 20 errors, 4 warnings 21 5
在探讨该主题时需要了解的一些常见术语:
- 语法(Syntax):指的是规定程序(如交易算法、指标和脚本)必须如何编写,以便MetaTrader 5平台能够正确理解和执行的一组特定规则。
- 错误(Error):指的是代码中的一个错误或问题,它会阻止代码正确执行。错误可以分为几种类型,如语法错误、运行时错误、逻辑错误、类型错误和编译错误。
什么是调试?
我相信大多数人都熟悉这个广为人知的术语,但对于初学者来说,详细理解这个概念至关重要。现在,我将定义一个“漏洞(bug)”,以便你们能更好地理解调试的过程。
- 漏洞:
计算机程序或系统中的一个错误或缺陷,导致其行为出乎意料或不正确。
- 调试:
调试是识别、隔离并修复计算机程序或系统中的错误或“bug”的过程,目的是确保程序按预期运行,并在各种条件下产生正确的输出。
MQL5编程中的调试
以下是与MQL5相关调试的一些方面:
1. MQL5中常见的错误类型:
- 语法错误(Syntax Errors):MQL5代码结构中的错误,导致脚本无法编译。
该示例展示了一个简单的语法错误,其中Print()函数缺少闭合括号。因此,脚本将无法编译,这就突显了仔细检查代码结构的必要性。
void OnStart() { Print("Hello, World!" // Missing closing parenthesis }
- 逻辑错误(Logical Errors):代码可以编译和运行,但产生错误的交易信号或行为出乎意料。
这里是一个逻辑错误,条件错误地触发了一个买入订单。程序员原本打算利用更复杂的逻辑,这取决于市场条件,但当前的实现导致了不必要的交易。
void OnTick() { double currentPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double targetPrice = currentPrice + 100; // Intended to use a different logic // Mistakenly placing a buy when conditions aren't right if (currentPrice < targetPrice) // Logic Error { OrderSend(_Symbol, OP_BUY, 0.1, currentPrice, 3, 0, 0, "Buy order", 0, 0, clrGreen); } }
- 运行时错误(Runtime Errors):在执行过程中发生的错误,例如尝试访问数组的越界元素或未正确处理交易订单。
在该示例中,尝试访问一个只有五个有效索引的数组的第六个元素。这将导致运行时错误,说明在处理数组时进行边界检查的重要性。
void OnStart() { double prices[5]; // Attempt to access out-of-range index (e.g., index 5) double value = prices[5]; // Runtime error: Array out of range }
2. MQL5中的调试工具:
- MetaEditor:这是MQL5的集成开发环境(IDE)。它提供了语法高亮、代码补全和错误指示,可以帮助快速识别语法错误。
以下代码允许在result变量计算处设置断点。在MetaEditor中调试时,您可以在此处检查变量,以确认它们是否按预期设置,便于逐行执行分析程序的运行过程。
void OnStart() { double startValue = 10.0; // Set a breakpoint here to inspect value double result = startValue * 2; Print("Result: ", result); // Check the value of result }
- 打印语句(Print Statements):使用Print()函数将变量值和执行流程日志输出到“Experts”日志。这是一种直接追踪问题的方法。
在下面的代码片段中,我们使用Print()函数记录当前的买入价和卖出价。这种方法有助于在执行过程中追踪变量值,并且可以通过比较预期值和实际值来帮助诊断逻辑错误。
void OnTick() { double bidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID); double askPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK); // Logging prices for debugging Print("Bid: ", bidPrice, ", Ask: ", askPrice); }
- 注释掉代码(Commenting Out Code):临时禁用代码的某些部分以隔离问题区域。
在该示例中,注释掉一行代码以专注于替代逻辑。在无需完全移除的情况下,这种技术对于隔离错误和测试代码的不同部分非常有用。
void OnTick() { // double result = SomeFunction(); // Temporarily disabling this line // Run alternate logic while debugging Print("Running alternative logic."); }3. 在MetaEditor中使用调试器:
MetaEditor包含一个内置的调试器,允许:4. 测试和优化:
- 断点(Breakpoints):在代码中设置断点可以让您在特定行暂停执行并检查变量值。
- 逐步执行(Step Through Execution):您可以逐行逐步执行代码,观察变量如何变化以及逻辑流程如何展开。
- 监视窗口(Watch Expressions):在代码执行过程中监控特定变量的值。
5. 错误处理:
- 策略测试器(Strategy Tester):MQL5提供了一个策略测试器,允许您使用历史数据对交易策略进行回测。它可以帮助模拟交易并分析性能,这样可能会揭示出隐藏的错误。
- 优化(Optimization):您可以优化参数以提高交易算法的性能,这也可能会突出逻辑或执行中的潜在错误。
- 处理MQL5特定的错误代码,例如检查与交易操作相关的函数的返回值。常见的函数包括订单执行函数(OrderSend、OrderClose等),其中适当的错误处理可以防止崩溃或不期望的结果。
MQL5调试的最佳实例:
1. 代码模块化(Code Modularity):将代码分解为函数,编写模块化代码。这使得测试和调试各个组件变得更加容易。2. 代码注释(Documenting Code):在代码中添加注释以解释每个部分的作用,这在一段时间后重新查看代码时会很有帮助。3. 定期测试(Regular Testing):在开发过程中频繁测试代码,而不是等到一切都完成后再测试。这有助于尽早发现错误。在MQL5中实现调试
不久前,我和我的朋友创建了一个脚本的草稿,用于绘制标记关键价格水平(如最高价、最低价、开盘价和收盘价)的前一日(D1)K线图的价格线。这是我为本文保留的版本。
通常,当编写EA代码时,MetaEditor提供了模板和参数建议,以帮助开发人员并减少错误的可能性,前提是按照正确的语言语法输入详细信息。然而,有时您可能会得到论坛上的代码,这些代码包含错误。以下是带有错误的脚本程序的代码段:
//+------------------------------------------------------------------+ //| D1 PriceMarker.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property strict // Function to create a price line with a label void CreatePriceLine(string name, double price, color clr, string label) { // Create a horizontal line if(!ObjectCreate(name, OBJ_HLINE, 0, 0, price)) { Print("Failed to create line: ", GetLastError()); return; } // Set line properties ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_WIDTH, 2); // Create a label for the price string labelName = name + "_label"; if(!ObjectCreate(labelName, OBJ_LABEL, 0, 0, 0)) { Print("Failed to create label: ", GetLastError()); return; } // Set label properties ObjectSetInteger(0, labelName, OBJPROP_XSIZE, 70); ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 10); ObjectSetInteger(0, labelName, OBJPROP_COLOR, clr); ObjectSetText(labelName, label + ": " + DoubleToString(price, 2), 10, "Arial", clr); // Position the label double yPos = price; // Positioning along the price axis ObjectSetInteger(0, labelName, OBJPROP_Y, yPos); ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, 5); } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { // Get the previous D1 candle's open, high, low, and close prices datetime prevCandleTime = iTime(NULL, PERIOD_D1, 1); double openPrice = iOpen(NULL, PERIOD_D1, 1); double highPrice = iHigh(NULL, PERIOD_D1, 1); double lowPrice = iLow(NULL, PERIOD_D1, 1); double closePrice = iClose(NULL, PERIOD_D1, 1); // Draw labeled price lines for open, high, low, and close prices CreatePriceLine("PrevCandle_Open", openPrice, clrBlue, "Open"); CreatePriceLine("PrevCandle_High", highPrice, clrRed, "High"); CreatePriceLine("PrevCandle_Low", lowPrice, clrGreen, "Low"); CreatePriceLine("PrevCandle_Close", closePrice, clrOrange, "Close"); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Remove the drawn price lines and labels upon indicator deinitialization ObjectDelete("PrevCandle_Open"); ObjectDelete("PrevCandle_High"); ObjectDelete("PrevCandle_Low"); ObjectDelete("PrevCandle_Close"); ObjectDelete("PrevCandle_Open_label"); ObjectDelete("PrevCandle_High_label"); ObjectDelete("PrevCandle_Low_label"); ObjectDelete("PrevCandle_Close_label"); } //+------------------------------------------------------------------+
(1)查找漏洞(bug)
我发现当尝试编译一个有错误的程序时,MetaEditor内置的调试器相当好用。大多数错误在您点击MetaEditor中的“编译”或“实时分析”按钮时被捕获。然而,有些性能错误并不会阻止程序编译;这些错误只能在您尝试运行程序时在平台或测试器上被识别出。
开发人员可以从头开始编写整个程序,然后进行调试,也可以简单地调试一个已有的程序。在下图中,我们利用MetaEditor内置的编译器和调试器来获取错误摘要(见工具箱窗口底部)。双击错误行,光标将移动到并突出显示包含错误的相应代码行。我很少在点击“编译”按钮之前注意到代码中的错误,此时调试器会报告出现的任何问题。
在MetaEditor中定位错误
有时程序会成功编译,但可能不会产生期望的结果。在这种情况下,通过检查MetaTrader 5平台工具箱窗口中可用的“专家日志”和“日志记录”来识别潜在错误是明智之举。这些日志可以提供关于执行过程中可能出现问题的宝贵见解,帮助您有效地进行故障排除和解决问题。
(2)三种调试技术
错误通常源于人为输入错误或术语的误用,调试器通常会提供解释说明和部分解决提示。如果您能理解这些信息,通常可以直接返回代码中并进行必要的修正。然而,有些更复杂的情况可能难以诊断,或许需要参考文献或依靠社区专家。
在我的经验中,我在调试复杂问题时通常使用几种策略。我将这些步骤分为三种主要方法,尽管这个列表并不全面;它是为了本次讨论的目的而特别设计的。让我详细地解释每一步流程。
1. 重新查阅文档:
通过提供关于语法、函数使用和错误消息的清晰说明,有助于调试MQL5程序。提供了详细的解释和示例,帮助识别错误的实现并增强对内置函数的理解。此外,文档通常包括有关常见错误、最佳实践和替代解决方案的信息,使开发人员能够有效地解决故障并优化代码以获得更好的性能。对于该项目,查看以下图片,看看我们如何轻松地访问文档。
重新查阅文档
错误报告:
'ObjectDelete' - wrong parameters count D1 PriceMarker.mq5 70 5
解决方案提示:
built-in: bool ObjectDelete(long,const string) D1 PriceMarker.mq5 70 5
当前情况:
ObjectDelete("PrevCandle_Open");
从解决方案提示中可以看出,ObjectDelete函数期望包含两个参数,但目前我们只提供了一个。这种差异表明了问题所在,我们可以相应地解决。根据文档,MQL5中的ObjectDelete函数需要两个参数:
- 名称:要删除的对象名称,以字符串形式指定。
- 图表ID:要从中删除对象的图表的ID,指定为整数形式。如果省略,函数默认为当前图表。
为了解决此问题,我们需要确保在调用ObjectDelete时传递两个参数。通过这样做,我们使函数调用与预期的语法一致,从而消除了错误。
解决方案:
ObjectDelete(0, "PrevCandle_Open");
现在,查看主代码,我们注意到ObjectDelete函数有多个实例。利用从研究中收集到的信息,我们可以对它们进行必要的调整。通过确保我们为每个实例提供两个所需的参数,我们可以有效地解决这些错误。
参考以下图片,看看我们如何通过减少10个错误总数来取得显著进展。这表明我们在调试脚本方面取得了显著进展,并展示了基于适当的文档进行彻底检查和修正的重要性。
ObjectDelete函数错误已解决
完成!当您遇到报错时,每次尝试解决后点击“编译”按钮是一个好习惯。这样允许您检查错误是否仍然存在,并帮助识别其他余下的问题。
现在,让我们继续来查看下一个报错。
错误报告:
'ObjectSetText' - undeclared identifier D1 PriceMarker.mq5 29 5 'ObjectSetText' - undeclared identifier D1 PriceMarker.mq5 29 5 ',' - unexpected token D1 PriceMarker.mq5 29 28 'labelName' - some operator expected D1 PriceMarker.mq5 29 19 '+' - illegal operation use D1 PriceMarker.mq5 29 36 ',' - unexpected token D1 PriceMarker.mq5 29 69 result of expression not used D1 PriceMarker.mq5 29 43 ',' - unexpected token D1 PriceMarker.mq5 29 73 expression has no effect D1 PriceMarker.mq5 29 71 ',' - unexpected token D1 PriceMarker.mq5 29 82 expression has no effect D1 PriceMarker.mq5 29 76 ')' - unexpected token D1 PriceMarker.mq5 29 87 expression has no effect D1 PriceMarker.mq5 29 84
这一次,我收集了多个报告,因为如果您来查看,会发现错误发生在同一行。这通常表明有一个共同的问题需要在代码的那部分解决。让我们更仔细地查看相关行,以定位潜在问题并明确必要的修正方法。
解决方案提示:
在这种情况下,我们遇到了以下错误:(未声明的标识符、期望的操作符、表达式无效以及意外的标记)。
当前情况:
ObjectSetText(labelName, label + ": " + DoubleToString(price, 2), 10, "Arial", clr);
我查阅了文档,但没有找到有关ObjectSetText的任何引用。然而,当我开始输入ObjectSet...时,出现了几个建议,其中ObjectSetString是最合适的选择。最终证明该函数是正确的,并且按照预期工作。
您可以通过以下内容看到我们付出的努力。
ObjectSetText在文档中不可用
ObjectSetString
根据文档,ObjectSetString函数的参数如下:
bool ObjectSetString( long chart_id, // chart identifier string name, // object name ENUM_OBJECT_PROPERTY_STRING prop_id, // property int prop_modifier, // modifier string prop_value // value );
解决方案:
通过进行必要的调整,就像我们应对第一个错误的方式,我们几乎能够解决所有问题。现在,只剩下几行需要修正。让我们专注于这些最后的调整,以完全清除剩余的错误。
ObjectSetString(0, labelName, OBJPROP_TEXT, label + ": " + DoubleToString(price, 2));
只剩下几个漏洞需要解决:
还剩2个错误
最后,修复剩余的错误:
ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, price); // Position label at the price level
应该是OBJPROP_YDISTANCE,而不是OBJPROP_Y。
参考文档成功完成调试
我们最终清理完成后的代码如下:
//+------------------------------------------------------------------+ //| D1 PriceMarker.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/en/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/en/users/billionaire2024/seller" #property version "1.00" #property strict // Function to create a price line with a label void CreatePriceLine(string name, double price, color clr, string label) { // Create a horizontal line if(!ObjectCreate(0, name, OBJ_HLINE, 0, 0, price)) { Print("Failed to create line: ", GetLastError()); return; } // Set line properties ObjectSetInteger(0, name, OBJPROP_COLOR, clr); ObjectSetInteger(0, name, OBJPROP_WIDTH, 2); // Create a label for the price string labelName = name + "_label"; if(!ObjectCreate(0, labelName, OBJ_LABEL, 0, 0, 0)) { Print("Failed to create label: ", GetLastError()); return; } // Set label properties ObjectSetInteger(0, labelName, OBJPROP_XSIZE, 70); ObjectSetInteger(0, labelName, OBJPROP_FONTSIZE, 10); ObjectSetInteger(0, labelName, OBJPROP_COLOR, clr); ObjectSetInteger(0, labelName, OBJPROP_YDISTANCE, price); // Position label at the price level ObjectSetInteger(0, labelName, OBJPROP_XDISTANCE, 5); // Set the text of the label ObjectSetString(0, labelName, OBJPROP_TEXT, label + ": " + DoubleToString(price, 2)); } //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ void OnInit() { // Get the previous D1 candle's open, high, low, and close prices datetime prevCandleTime = iTime(NULL, PERIOD_D1, 1); double openPrice = iOpen(NULL, PERIOD_D1, 1); double highPrice = iHigh(NULL, PERIOD_D1, 1); double lowPrice = iLow(NULL, PERIOD_D1, 1); double closePrice = iClose(NULL, PERIOD_D1, 1); // Draw labeled price lines for open, high, low, and close prices CreatePriceLine("PrevCandle_Open", openPrice, clrBlue, "Open"); CreatePriceLine("PrevCandle_High", highPrice, clrRed, "High"); CreatePriceLine("PrevCandle_Low", lowPrice, clrGreen, "Low"); CreatePriceLine("PrevCandle_Close", closePrice, clrOrange, "Close"); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { // Remove the drawn price lines and labels upon indicator deinitialization ObjectDelete(0, "PrevCandle_Open"); ObjectDelete(0, "PrevCandle_High"); ObjectDelete(0, "PrevCandle_Low"); ObjectDelete(0, "PrevCandle_Close"); ObjectDelete(0, "PrevCandle_Open_label"); ObjectDelete(0, "PrevCandle_High_label"); ObjectDelete(0, "PrevCandle_Low_label"); ObjectDelete(0, "PrevCandle_Close_label"); } //+------------------------------------------------------------------+
D1 PriceMarker是一个我们设计的MQL5脚本程序,用于通过在前一日(D1)K线图的最高价、最低价、开盘价和收盘价处绘制水平线来强化交易图表上的技术分析。在初始化时,脚本检索这四个价格点,并使用辅助函数以不同颜色(开盘价为蓝色,最高价为红色,最低价为绿色,收盘价为橙色)创建相应的价格线,每条线都附带一个标记文本,指示价格值。当脚本从图表中移除时,它会自动清理,删除所有绘制的线条和标签,确保为交易者提供一个整洁的界面。
2. 使用AI进行调试:
我知道每个人都渴望了解我们如何利用现有的AI模型,所以我会简要提及这个话题,以便之后进行更深入地探讨。幸运的是,这些模型中的大多数都能比我们更快、更准确地理解语法。然而,需要注意的是,它们有时会产生意想不到的结果,并且可能需要更密切地人工监控来指导它们的下一步行动。尽管如此,当合理地使用AI模型时,它们仍然是出色的工具,我通过审慎参考它们的建议解决了许多编码挑战。
本质上,在编写AI提示时,您应该首先提供想要调试的程序。然后,通过利用从MetaEditor报告中复制错误行的能力,您可以将这些行粘贴到提示中,让AI协助调试过程。虽然这种方法可以取得成功的结果,但它也可能导致进一步的复杂情况,因此至关重要的一点是要批判性地斟酌,并在AI建议的基础上更进一步。我们之前取得的结果与有效使用其他调试工具应该产生的结果是一致的。
将错误复制到AI提示中
3. 访问论坛:
与我们上述做法类似,论坛成员需要信息才能提供有价值的调试见解。就编码挑战进行探讨是向其他专家学习的绝佳方式。通过提交您的程序,您可以邀请其他人分享他们的明智建议和解决方案。这种协作方法不仅能帮助您解决问题,还能扩展每个人的知识和技能。
在MetaTrader 5上的程序:
D1 PriceMarker脚本
结论
在创建D1 PriceMarker脚本的过程中,团队合作在MQL5编程中被证明是开发稳健交易算法的一个重要实践。调试过程严重依赖于错误报告和全面的MQL5参考文档,使我们能够系统地识别和解决开发过程中遇到的问题。
这种方法有助于解决具体错误,并促进了对编程环境更深入地理解。此外,我们简要提及了利用AI作为未来调试辅助工具的潜力,强调了其提供见解和建议的能力,这样可以简化调试过程。
社区支持,特别是MQL5论坛,发挥了不可估量的作用,使我们能够向其他经验丰富的开发人员寻求建议并分享知识。通过采用这些协作和资源驱动的方法,我们可以显著提高调试工作的效率,最终在竞争激烈的算法交易领域中开发出更可靠、更具创新性的交易解决方案。交易顺利,朋友们!
本文由MetaQuotes Ltd译自英文
原文地址: https://www.mql5.com/en/articles/15325
注意: MetaQuotes Ltd.将保留所有关于这些材料的权利。全部或部分复制或者转载这些材料将被禁止。
本文由网站的一位用户撰写,反映了他们的个人观点。MetaQuotes Ltd 不对所提供信息的准确性负责,也不对因使用所述解决方案、策略或建议而产生的任何后果负责。

对初学者来说是篇好文章,但我认为有点啰嗦。一些评论 :
感谢您的反馈,Alain Verleyen!我真心感谢您的真知灼见,尤其是作为一名版主,我同意清晰是至关重要的,尤其是对于初学者。
关于合作方面,我的目的是鼓励读者在评论或论坛上相互交流,分享自己的调试经验和解决方案。我会努力提高自己在论坛上的知名度。
我非常重视你们的建设性批评和参与!这样的讨论对我们的集体成长和进步至关重要。
早上好
算法交易者可能没有意识到。
那就是,他们很少会花时间去编写神奇的指标或利润丰厚的 EA。
现实情况是,他们主要花时间修正、改进代码,从而进行调试。
如果没有强大的工具,他们很快就会花费数天时间来查找代码错误,而这些时间本来就已经很充裕了。
大家好,你们认为什么乐器功能强大?
鼓组。
您好,欢迎来到 MQL5 论坛!关于您的问题,不允许推荐市场产品。您必须自己进行研究。祝您好运😊