来自专业程序员的提示(第一部分):代码存储、调试和编译。 操控项目和日志
内容
- 概述
- 将您的代码存储在单独的子目录之中
- 一套代码用于多个终端
- 使用版本控制系统
- 使用带有模拟帐户的单独终端来调试代码
- 一次性编译所有代码文件
- 使用项目和任务管理系统
- 日志选择
- 日志高亮
- 上下文搜索
- 结束语
概述
将您的代码存储在单独的子目录之中
终端程序文件位于 MQL5 目录下。 这种编制就是所谓的“沙盒”。 来自外部的数据访问被关闭。 这是一个很好的决定。 不过,运用 DLL 可以访问任何地方。
例如,这里是 Cayman 项目的结构:
- /Experts/Cayman/ - 智能交易系统
- /Files/Cayman/ - 数据文件 (设置、参数)
- /Include/Cayman/ - 类库(函数)
- /Scripts/Cayman/ - 主要操作脚本
- /Scripts/CaymanDev/ - 开发者脚本(用于调试)
这种布局的主要优点是:
- 通过 TotalCommander 仅在项目文件中进行上下文搜索
- 通过 Git 进行版本控制(仅对项目文件启用控制,而忽略所有其他文件)
- 轻松复制到另一个终端(模拟 -> 实盘 – 发布)
一套代码用于多个终端
编程中的最佳实践之一是避免重复代码。 如果相同的代码行出现在若干不同之处,那么您最好将这些代码行“包裹”在一个函数当中。 这同样适用于 MQL5 文件:程序文件应该只有一个文本。 这可以利用指向 MQL5 目录的符号链接来实现。
假设项目类别位于D:\Project,而终端数据目录位于 C:\Users\Pro\AppData\Roaming\MetaQuotes\Terminal\9EB2973C469D24060397BB5158EA73A5
- 关闭终端
- 进入数据目录
- 将 MQL5 目录移到项目目录
- 在数据目录中,运行 cmd,并输入以下命令
mklink /D MQL5 D:\Project\MQL5 - 启动终端
终端甚至不会注意到“沙箱”(程序文件)已移至 D:\Project\MQL5。
这种布局的主要优点是,所有个人项目都集中在同一目录 (D:\Project) 之下。
使用版本控制系统
专业程序员不会怀疑需要用到这种系统。 它是必不可少的工具,尤其是当一个团队程序员在同一个项目上工作时。 问题是您将采用哪个系统。 事实上这个就是 Git。
Git 的主要优点是:
- 本地存储库。 实验性分支的能力。 一键切换到任意分支(版本)。
- 便捷的图形界面 (TortoiseGit)。 用鼠标控制。
- 个人项目的免费云端存储库 (Bitbucket)。 不用担心您的 PC 硬盘会出现故障
- 文件更改历史具有恢复或查看旧版本的能力(可在 Bitbucket 中方便查看)
我不会在这里提供详细的安装和配置说明,但我会提到一些特殊的功能。 安装 Git(用于命令行操作),和 TortoiseGit(为了使用鼠标)。 在 D:\Project\MQL5 目录下,创建 .gitignore 文件,内容如下
# exclude files *.ex4 *.ex5 *.dat log.txt # exclude directories completely Images Indicators Libraries Logs Presets Profiles Services "Shared Projects" Levels Params # exclude directory contents Experts/* Files/* Include/* Scripts/* # except for directories !Experts/Cayman !Files/Cayman !Include/Cayman !Scripts/Cayman !Scripts/CaymanDev
该文件将启用项目 (*.mq?) 程序文件的版本跟踪。 在 MQL5 目录中创建一个本地存储库。 添加文件,并进行首次提交(提交版本)。 本地存储库已准备就绪。 操控代码时,不要忘记经常提交,以及更改的简述。 注释可令今后的浏览和搜索历史变得更容易。
为了连接到云端存储库,您首先需要创建一个 Bitbucket 帐户和存储库。 从逻辑上讲,存储库名称应与项目名称匹配。 就我的情况,它是 CaymanMQL5,同时还有 CaymanMQL4。 将本地存储库导入到云端。 现在,云端存储库已准备就绪。 TortoiseGit(TG) 的基本操作:
- 操控代码(一项任务 - 一次性提交)
- 检查修改(TG/Check 修改...)
- 添加新文件(Add)
- 删除不需要(缺失)的文件(Delete)
- 提交到本地存储库(Commit)
- 推送到云端存储库(Push)
使用带有模拟帐户的单独终端来调试代码
您应该在真实账户上运行最新的代码版本(只有 *.ex? 文件,没有 *.mq?)。 代码调试过程则的应在模拟账户上进行。 为了从模拟账户复制到实盘账户,您可以使用以下批处理文件:
@echo off setlocal set PROJECT=Cayman set SOURCE=d:\Project\MQL5 set TARGET=c:\Users\Pro\AppData\Roaming\MetaQuotes\Terminal\2E8DC23981084565FA3E19C061F586B2\MQL5 set PARAMS=/MIR /NJH /NJS rem MIR - MIRror a directory tree and delete dest files/folders that no longer exist in source rem NJH - No Job Header rem NJS - No Job Summary echo Copy *.ex? // Source to Production echo Source = %SOURCE% echo Production = %TARGET% robocopy %SOURCE%\Experts\%PROJECT% %TARGET%\Experts\%PROJECT% *.ex? %PARAMS% robocopy %SOURCE%\Scripts\%PROJECT% %TARGET%\Scripts\%PROJECT% *.ex? %PARAMS% rem Copy all files except AppSettings.txt, [Levels], [Params] robocopy %SOURCE%\Files\%PROJECT% %TARGET%\Files\%PROJECT% *.* %PARAMS% /XF AppSettings.txt /XD Levels Params robocopy %SOURCE%\Scripts\Cayman %TARGET%\Scripts\Cayman *.ex? /NJH /NJS robocopy %SOURCE%\Scripts\CaymanDev %TARGET%\Scripts\CaymanDev *.ex? /NJH /NJS echo. endlocal pause
一次性编译所有代码文件
目标是维持代码一致性。 故此,您应该避免某些修改,例如函数参数。 智能交易系统能够顺利地编译,但也有可能某个脚本会调用旧版函数。 脚本(之前编译的)可以运行良好,但它不会执行所需的功能。 对于批处理编译,您可以采用以下文件:
@echo off setlocal set METAEDITOR="C:\Program Files\RoboForex - MetaTrader 5\metaeditor64.exe" set CAYMAN=d:\Project\MQL5\Scripts\Cayman set CAYMAN_DEV=d:\Project\MQL5\Scripts\CaymanDev echo METAEDITOR=%METAEDITOR% echo CAYMAN=%CAYMAN% echo CAYMAN_DEV=%CAYMAN_DEV% echo. echo Wait compile... D: cd %CAYMAN% echo %CAYMAN% for %%F in (*.mq?) do ( %METAEDITOR% /compile:%%F /log type %%~dpnF.log ) del *.log cd %CAYMAN_DEV% echo %CAYMAN_DEV% for %%F in (*.mq?) do ( %METAEDITOR% /compile:%%F /log type %%~dpnF.log ) del *.log endlocal echo. pause
使用项目和任务管理系统
这样的系统对于开发团队来说是必须的。 它们对个人项目也很有用。 有众多不同的项目管理系统和方法。 我个人采用 ZenKit。 它对于小型团队是免费的。 它提供了一个非常方便的 Kanban 板面。
我曾经有多个 Kanban 板面(每个项目均有一个)。 采用多板面的缺点是您无法看到全局画面。 然后我决定添加一个项目作为开发阶段。 这样的方式很容易就能管理任务了。 例如,我的板面有 5 个开发阶段:
- Legend - 项目描述、链接和说明。 整体不会移到其他阶段。 您始终可以查看板面的常规用途,并可轻松访问有用资源的链接。
- Cayman – MQL5 和 MQL4 项目
- Website – 我的个人网站项目
- Accepted - 任务正在进行中
- Done - 任务已完成
版面的使用过程非常简单直观。 我发现了一个有趣的思路、解决方案或程序错误。 然后我简单地制定它,并将其添加到板面里相应的项目之中。 您还可以在此处添加图像和文件。 接下来,我选择一个任务,并将其移至 “Accepted” 阶段。 我操控任务,测试并将其移入 “Done” 阶段。
通过分析项目中的任务数量,您可以轻松判断问题和瓶颈。 我尝试从 “overloaded” 项目中执行任务。 我的目标是找齐项目,令它们的任务拥有相似的数量。 团队开发还有一个称为 “Testing” 的阶段,但它与我的个人工作无关。
日志选择
如您所知,Print 函数的所有输出都写入终端日志 MQL5\Logs\yyyyMMdd.log。 所有品种(在此文件中所有交易的金融产品均混合在一起)。 我利用以下批处理文件为所需品种选择日志:
echo off if "%2"=="" goto Help find /I "%2" < %1 > "%~n1-%2.log" goto Exit :Help echo. echo Filter log-file echo findLog.cmd logFile text echo Example echo findLog.cmd 20200515.log gbpjpy echo Result echo 20200515-gbpjpy.log echo. pause :Exit
日志高亮
当我执行调试时,很多信息都会写入日志。 在运行当中的终端里分析它可能非常棘手。 此处是您可以采取的措施来简化该过程:
- 清除工具箱/智能系统选项卡中的日志
- 模拟打印记录
- 将所有行复制到 log.txt 文件当中
- 在 Notepad++ (NPP) 中分析此文件,此刻可用高亮显示
NPP 支持不同的文本高亮显示变体
- 双击一个单词会令该其在整个文本中高亮显示
- 搜索/标记/使用样式 - 所选样式应用于整个文档中所需的文本
- 自定义语法以特定令牌高亮显示
上下文搜索
为了查找特定文本,我用 TotalCommander 文件管理器。 这种方法的主要优点如下:
- 搜索仅在项目文件中执行(所有其他文件不会出现在搜索结果当中)
- 能够在搜索中运用正则表达式
结束语
这是我的首篇文章。 我计划继续这个系列。 下次我会分享一些成功的解决方案,提供相关的论述和解释。 我邀请大家来分享他们的编程经验,并讨论其他有用的技巧和解决方案。
本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/9266