English Русский Español Deutsch 日本語 Português 한국어 Français Italiano Türkçe
preview
迁移至 MQL5 Algo Forge(第 4 部分):使用版本和发布

迁移至 MQL5 Algo Forge(第 4 部分):使用版本和发布

MetaTrader 5示例 |
416 0
Yuriy Bykov
Yuriy Bykov

概述

我们继续向 MQL5 Algo Forge 过渡。我们已经使用个人仓库建立了我们的工作流程,并转向了这一举措的主要原因之一 —— 能够轻松使用社区贡献的代码。在第 3 部分中,我们探讨了如何将另一个仓库中的公有库添加到我们自己的项目中。

将 SmartATR 库连接到 SimpleCandles EA 交易的实验清楚地表明,简单的克隆并不总是方便,尤其是当代码需要修改时。相反,我们遵循了正确的工作流程:我们创建了一个派生,它成为我们对其他人仓库的个人副本,用于修复错误和进行修改,同时保留稍后通过合并请求向作者提出这些更改的选项。

尽管我们在 MetaEditor 界面中遇到了某些限制,但将其与 MQL5 Algo Forge 网页界面相结合使我们能够成功完成整个操作链,从克隆到提交编辑,最后将项目与外部库链接。因此,我们解决了一个特定的任务,并研究了集成任何第三方组件的通用模板。

在今天的文章中,我们将仔细研究发布仓库中所做编辑的阶段,即形成完整解决方案的一组更改,无论是向项目添加新功能还是修复发现的问题。这是提交或发布新产品版本的过程。我们将了解如何组织此过程,以及 MQL5 Algo Forge 为其提供了哪些功能。


寻找分支

在前面的部分中,我们建议使用单独的仓库分支来进行一系列解决特定任务的编辑。但是,在完成此类分支的工作后,最好将其合并到另一个(主)分支,然后将其删除。否则,仓库很快就会变成一片茂密的灌木丛,甚至连所有者都很容易迷路。因此,应该删除过时的分支。但有时,您可能需要将代码恢复到删除某个分支之前的状态。如何做到这一点?

首先,让我们澄清一下,分支只是按时间顺序排列的一系列提交。从技术上讲,分支是指向连续提交链中最新提交的指针。因此,删除分支并不会删除提交本身。在最坏的情况下,它们可能会被重新分配到另一个分支,甚至合并为一个摘要提交;但无论如何,它们都会继续存在于仓库中(极少数例外)。因此,返回到“删除分支之前”的状态本质上意味着恢复到某个分支中存在的提交之一。那么问题就变成了:我们如何找到这种承诺?

让我们看一下在进行第 3 部分中提到的更改之后 SimpleCandles 仓库的状态:

我们可以在左侧看到提交的历史和分支之间关系的彩色可视化状态。每个提交都由其哈希值(或更确切地说,是其一部分)标识,即一个将其与所有其他提交区分开的大的唯一数字。为了缩短其表示形式,哈希以十六进制形式显示(例如, b04ebd1257 )。 

可以在 MQL5 Algo Forge web 界面的专用页面上查看任何仓库的此类提交树。所示的屏幕截图是不久前拍摄的,因此现在访问此页面将显示一张略有不同的图片:新的提交将出现在树中,分支的交织将因额外的合并提交而发生变化。

我们还可以在一些提交旁边看到分支名称。这些显示每个分支中的最新提交。在提供的屏幕截图中,我们可以数出六个不同的分支: maindevelopconvert-to-utf8article-17608-close-managerarticle-17607article-19436-forge3 。最后一个是编写第 3 部分时所做更改所使用的分支。但是在编写第 2 部分时,我们还为计划的更改创建了一个单独的分支。它被命名为 article-17698-forge2 ,后来被删除,这就是为什么现在没有提交带有这个分支名称的原因。那么,我们在哪里可以找到它?

如果我们查看 58beccf233 的完整提交消息,它会提到这个分支名称并表明它已合并到 develop 中。

因此,我们已经找到了所需的提交,但以这种方式定位它并不方便。此外,如果我们使用控制台命令(如 git merge”)而不是通过合并请求手动合并分支,我们可以为合并提交编写任意注释。在这种情况下,找到正确的提交将更加困难,因为分支名称可能根本没有包含在消息中。

现在我们已经找到了所需的提交,我们可以切换到它,将我们的本地仓库恢复到提交之后的状态。为此,我们可以在 “git checkout” 命令中使用提交哈希。然而,这里有一些细微差别。如果我们试图在 MetaEditor 中通过从项目的上下文菜单选项 “Git Log” 打开的历史记录中选择它来切换到此提交:

...我们会遇到一条错误消息:

或许,这是有原因的。让我们仔细看看发生了什么。我们首先介绍 “tag” 和 “HEAD 指针” 的新概念。


标签(tag)

Git 版本控制系统中的标签是分配给特定提交的附加名称。您还可以将标签视为仓库中特定版本代码的指针或引用,因为它直接指向特定的提交。使用标签允许您随时返回与标记的提交相对应的代码的确切状态。标签有助于标记项目开发中的重要里程碑,例如版本发布、完成阶段或稳定构建。在 MQL5 Algo Forge 网页界面中,您可以在单独的页面上查看所选仓库的所有标签。

Git 中有两种类型的标签:轻量级和带注释的。轻量级标签仅包含名称,而带注释的标签可以包含其他信息,如作者、日期、评论,甚至签名。大多数情况下,使用轻量级标签。

要通过 Web 界面创建标签,您可以打开任何提交的页面(例如, 这个),单击“操作”按钮,然后选择“创建标签”。

但是,稍后我们将再回到标签创建。

要通过 Git 控制台命令创建标签,请使用 “git tag” 命令。要创建轻量级标签,只需指定标签的名称:

git tag <tag-name>

# 例子
git tag v1.0

要创建带注释的标签,您需要添加一些额外的参数:

git tag -a <tag-name> -m "Tag description"

# 例子:
git tag -a v1.0 -m "版本 1.0 发布"

除了标记用于发布或部署(发布)的代码版本外,标签还可以用于向 CI/CD 管道发出信号,以便在出现具有特定标签的提交时触发预定义的操作,或者标记重要的开发里程碑,例如主要功能的完成或关键错误的修复,即使它们并不代表新版本的发布。


HEAD 指针

讨论了标签之后,值得一提的是另一个重要概念 —— HEAD 指针。它的行为类似于具有固定名称 HEAD 的标签,它会自动移动到当前签出的分支中的最新提交。HEAD 通常被称为“当前分支的标记”或“指向活动分支的指针”。它本质上回答了这个问题:“我们现在位于仓库的什么位置?”然而,从技术上来说它并不是一个标签。

物理上,该指针存储在仓库中的 .git/HEAD 文件中。HEAD 的内容可能包含符号引用(标签或分支名称)或提交哈希。在分支之间切换时,HEAD 指针会自动更新以指向当前分支中的最新提交。当添加新的提交时,Git 不仅会创建提交对象,还会将 HEAD 指针移动到该对象。

因此,HEAD 名称可以在 Git 控制台命令中使用,而不是最新提交的哈希值或当前分支名称。使用特殊符号 ~ 和 ^,您可以引用最新提交之前的提交。例如,HEAD~2 指的是最近一次提交之前两步的提交。我们现在不会深入探讨这些细节。

为了进一步讨论,我们还应该提到仓库可能处于的两种状态。正常状态称为“attached HEAD”,意味着新的提交将出现在当前分支中的最新提交之前。在这种状态下,所有编辑都会按顺序添加到分支中,不会发生冲突。

另一种状态称为“detached HEAD”,当 HEAD 指针指向任何分支中不是最新的提交时,就会发生这种情况。例如,在以下情况下可能会发生: 
  • 将仓库切换到特定的过去提交(例如,使用“git checkout <commit-hash>”),
  • 通过标签名称切换(例如,'git checkout tags/<tag-name>'),
  • 切换到远程仓库中仍然存在但已从本地仓库中删除的分支(例如,“git checkout origin/<branch-name>”)。

应尽可能避免这种状态,因为当切换到另一个分支时,这种状态中与任何分支无关的任何更改都可能丢失。但是,如果你不打算在这种状态下进行更改,那么这样也可以。


目前没有标签

现在让我们回到尝试将本地仓库切换到特定的提交,该提交曾经是已删除分支 article-17698-forge2 中的最新提交。

将仓库切换到特定的过去提交并不是开发人员在日常 Git 工作流程中通常会做的事情。在正常情况下,您很少需要执行这样的操作。但是,如果您选择这样做,存储库将进入所谓的 “detached HEAD” 状态。在这种情况下,该提交属于 develop 分支,该分支之后已经有较新的提交,因此它不再是分支中的最新提交。

不过,如果我们使用 Git 的命令行界面执行此切换,操作将成功完成。尽管 Git 会明确警告我们处于 “detached HEAD: 状态:

 

细心的读者可能会注意到,在最后一张截图中,我们切换到了哈希值为 58beccf233 的提交,但 Git 报告 HEAD 指针现在位于 58beccf 。最后三位数字去哪儿了?没什么不对,它们并没有消失。Git 允许使用缩短的提交哈希,只要它们在仓库中保持唯一即可。根据界面的不同,您可能会看到哈希缩短到 4 到 10 个字符之间。

如果您需要查看完整的提交哈希,您可以通过运行 “git log” 命令来实现。每个完整的提交哈希包含 40 位数字。

因为每个哈希都是随机和唯一生成的,所以即使是前几个数字在仓库中也几乎可以保证是不同的。这就是为什么仅提供哈希的短前缀通常就足以让 Git 准确识别您在命令中引用的提交。


使用 UTF-8 编码

这是另一个有趣的方面。在早期版本中,MetaEditor 使用 UTF-16LE 编码来保存源代码文件。然而,出于某种原因,Git 将以这种编码保存的文件视为二进制文件而不是文本文件。因此,无法查看在提交中修改的确切代码行(尽管这在 Visual Studio code 中运行良好)。显示的唯一信息是提交中更改前后的文件大小。

MQL5 Algo Forge 网页界面如下所示:

现在,在 MetaEditor 中创建的新文件使用 UTF-8 编码保存,甚至使用国家字母字符也不再触发自动切换到 UTF-16LE。因此,将早期项目遗留到新仓库的旧文件转换为 UTF-8 是有意义的。执行这样的转换后,从下一次提交开始,您将能够准确地看到哪些行和字符被更改了。例如,在 MQL5 Algo Forge 网页界面中,它可能看起来像这样:

但这只是一个简短的题外话,让我们回到如何在仓库中发布新版本代码的讨论。


返回主线任务

因此,在我们仓库的分支中,让我们关注这两个: article-17608-close-managerarticle-17607 。这些分支中所做的更改尚未合并到 develop 中,因为与它们相关的任务仍在进行中。这些分支将继续开发,因此将它们合并到 develop 中还为时过早。我们将继续其中的一篇( article-17607 ),使其达到逻辑上的完成点,然后将其与 develop 合并。代码的最终状态将被标记为版本号。

为此,我们首先需要准备所选分支以进行进一步编辑,因为虽然它存在,但其他分支也引入了更改。这些变化已经合并到 develop 中。因此,我们必须确保来自 develop 的这些更新也纳入到我们选择的分支中。

有几种方法可以将来自 develop 的更改合并到 article-17607 中。例如,我们可以通过 Web 界面创建一个合并请求,并重复上一节中描述的合并过程。然而,当您想将新的、未经测试的代码合并到包含稳定的、经过测试的代码的分支中时,最好使用这种方法。在我们的例子中,情况正好相反:我们希望将开发中稳定、经过验证的更新带入一个仍然包含新的、未经检查的代码的分支中。因此,使用 Git 控制台命令执行合并是完全没问题的。我们将使用控制台并监控 Visual Studio Code 中的进程。

首先,让我们检查仓库的当前状态。在版本控制面板中,我们可以看到带有分支名称的提交历史。当前分支是 article-19436-forge3 ,其中进行了最新的更改。在终端的右侧,显示了 “git status” 命令的输出:

该命令确认我们的存储库当前位于 article-19436-forge3 分支上,并且其状态与远程仓库中的相应分支同步。

接下来,我们使用命令 “git checkout article-17607” 切换到 article-17607 分支:

然后使用 “git merge develop” 将其与 develop 合并:

由于外部更改影响了我们在 article-17607 中工作时未修改的代码部分,因此合并期间没有出现冲突。结果,Git 创建了一个新的合并提交。

现在我们运行 “git push” 将更新的信息发送到远程仓库:

如果我们检查 MQL5 Algo Forge 仓库,我们将看到我们的合并步骤已成功反映在远程仓库中:

屏幕截图中显示的最后一次提交是 developarticle-17607 之间的合并提交。 

还要注意 article-19436-forge3 分支的自由端,它尚未连接到任何其他分支。该分支的更改尚未合并到 develop 中,因为那里的工作仍在进行中。我们暂时保持现状,时机成熟时,我们会重返那里。

这就完成了在 article-17607 中继续开发的准备,现在我们可以继续进行编码工作本身。与此分支相关的任务的解决方案在另一篇文章中描述。所以,我不会在这里重复。相反,让我们继续描述如何在完成任务后最终确定和记录代码的实现状态。


执行合并

在发布特定状态的代码之前,我们首先需要将其合并到主分支中。我们的主分支是 main 。来自 develop 分支的所有更新最终都会流入 main 分支。来自各个任务分支的更改被合并到 develop 中。目前,我们还没有准备好将新代码合并到 main中,因此我们只能将更新合并到 develop 中。为了演示这种机制,具体选择哪个分支作为主要分支并不是特别重要。

完成所选任务后,让我们看看 SimpleCandles 仓库的状态:

如图所示,最新的提交是在 article-17607 分支中进行的。使用 MQL5 Algo Forge 网页界面,我们创建一个合并请求以将此分支合并到开发中,如前所述。

让我们验证一下一切是否按预期进行。我们再次打开带有分支树视图的提交历史记录页面:

我们可以看到,哈希值为 432d8a0fd7 的提交在 article-17607 中不再被标记为最新的。相反,哈希值为 001d35b4a7 的新提交在 develop 中显示为最新提交。由于此提交记录了两个分支的合并,我们将其称为合并提交。

接下来,打开合并提交页面并创建一个新标签。在文章的前面,我们展示了在哪里做这件事;现在是时候真正去做了:

在弹出的窗口中输入标签名称 “v0.1”,因为这距离最终版本还很远。我们还不知道该项目还将增加多少内容,但希望会增加很多。因此,如此小的版本号提醒我们,前面还有很多工作要做。顺便说一句,Web 界面目前似乎不支持创建带注释的标签。

现在标签已经创建成功,您可以在以下页面看到结果:

 或者在仓库的专用标签页面上。

如果我们使用 “git pull” 更新本地仓库,新创建的标签也会出现在那里。但是,由于 MetaEditor 目前不显示存储库标签,让我们检查一下它们在 Visual Studio Code 中的外观。如果将鼠标悬停在提交树中所需的提交上,则工具提示中会出现带有相关标签名称的彩色标签:

现在标签已经创建,我们可以在这里停下来并在 “git checkout” 命令中使用它的名称来切换到该精确的代码状态,或者进一步基于它创建一个版本。 


创建发布

发布(Release)是一种标记和分发特定版本软件的机制,与使用何种编程语言无关。提交和分支代表开发工作流程,而发布是其官方结果,即我们想要发布的版本。使用版本的主要目的如下:

  • 版本控制。我们将仓库代码中的特定代码状态标记为稳定,这意味着它们没有严重错误(至少是明显的错误)并且具有已验证的功能。其他用户可以使用这些特定版本。

  • 分发二进制文件。版本可以包含编译或打包的文件(如.ex5、.dl l或 .zip),这样用户就不必自己编译项目。

  • 用户沟通。发布应该包含描述,通常列出更改、新功能、已修复的错误以及有关该版本的其他相关信息。本说明的主要目的是帮助用户决定是否应该更新到它。
值得一提的是,包括 MQL5 Algo Forge 在内的 CI/CD 系统可以在分支合并到 main 分支时自动创建发布,执行自动构建并发布二进制文件。然而,这种自动化需要事先设置和配置事件处理脚本。这些都是更高级的(虽然不是必需的)功能,所以我们暂时把它们放在一边。
可以基于现有标签创建发布,也可以在发布创建过程中生成新标签。由于我们已经有一个标签,我们将使用它创建一个新版本。为此,请转到存储库标签页面,然后单击所需标签旁边的 “发布新版”:

在发布创建表单中,您可以指定几个基本属性:
  • 发布名称、目标分支和标签(现有或要创建的新标签),
  • 发布说明,即新功能、已修复内容以及已解决的已知问题的摘要,
  • 附加文件,例如编译的程序、文档或外部资源的链接。
以下是 MQL5 Algo Forge 网页界面中的样子:

您可以将发布保存为草稿并稍后更新其详细信息,或立即发布。即使你现在发布它,你也可以稍后进行编辑:例如,你仍然可以在之后调整发布描述。发布之后,该版本发布将出现在仓库的版本发布页面上,其他用户可见:

就是这样!新版本现已上线并可供使用。稍后,我们更新了版本发布名称(不必与标签名称匹配),并添加了指向上述描述已实施解决方案的文章的链接。


结论

让我们暂停一下,回想一下我们取得的进展。我们不仅仅探索版本控制的技术方面,我们完成了全面的转型,从分散的编辑转变为结构化的、连贯的代码管理工作流程。我们达到的最重要的里程碑是最后一步:将完成的作品作为官方产品版本发布给最终用户。我们当前的仓库可能尚未代表一个完全成熟的项目,但我们已经奠定了达到该水平的所有基础。

这种方法从根本上改变了我们对项目的看法。曾经是一个松散的源文件集合,现在是一个有组织的系统,具有清晰的更改历史和定义良好的检查点,使我们能够随时恢复到任何稳定的状态。这对每个人都有好处:成品解决方案的开发人员和用户。

通过掌握这些工具,我们将 MQL5 Algo Forge 仓库的工作提升到了一个新的水平,为未来更复杂、更大规模的项目打开了大门。

感谢您的关注!下次再见!

本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/19623

价格行为分析工具包开发(第11部分):基于Heikin Ashi(平均K线)信号的智能交易系统(EA) 价格行为分析工具包开发(第11部分):基于Heikin Ashi(平均K线)信号的智能交易系统(EA)
MQL5为开发者提供了无限可能,助您构建高度定制化的自动化交易系统。您是否知道,它甚至能执行复杂的数学运算?本文将介绍如何将日本Heikin-Ashi(平均K线)技术转化为自动化交易的策略。
从头开始以 MQL5 实现 SHA-256 加密算法 从头开始以 MQL5 实现 SHA-256 加密算法
长期以来,构建无 DLL 的加密货币兑换集成一直是一个挑战,但该解决方案为直接市场对接提供了一个完整的框架。
MQL5 交易工具包(第 4 部分):开发历史管理 EX5 库 MQL5 交易工具包(第 4 部分):开发历史管理 EX5 库
通过详细的分步方法创建扩展的历史管理 EX5 库,学习如何使用 MQL5 检索、处理、分类、排序、分析和管理已平仓头寸、订单和交易历史。
基于LSTM的趋势预测在趋势跟踪策略中的应用 基于LSTM的趋势预测在趋势跟踪策略中的应用
长短期记忆网络(LSTM)是一种特殊的循环神经网络(RNN),其设计初衷是通过有效捕捉数据中的长期依赖关系,并解决传统RNN存在的梯度消失问题,从而实现对时序数据的高效建模。本文将系统阐述如何利用LSTM进行未来趋势预测,进而提升趋势跟踪策略的实战表现。具体内容涵盖这些模块:LSTM关键概念介绍与发展契机、从MetaTrader 5平台提取数据、在Python中构建并训练模型、将机器学习模型嵌入MQL5中、基于统计回测的结果分析与改进方向。