English Русский Deutsch 日本語 Português
preview
DRAKON可视化编程语言 - 面向MQL开发人员和客户的通信工具

DRAKON可视化编程语言 - 面向MQL开发人员和客户的通信工具

MetaTrader 5示例 | 19 三月 2024, 13:14
324 0
Oleh Fedorov
Oleh Fedorov

概述

DRAKON语言是由联邦航天局(Pilyugin 院士中心,莫斯科)和俄罗斯科学院(Keldysh 应用数学研究所,莫斯科)联合开发的,这是在进行 Buran 航天器项目时获得的经验的结果。

Parondzhanov V. D.

曾几何时,开放主义来到苏联,使之前被分类的DRAKON(字面意思是友好的俄罗斯算法语言,提供清晰)语言可供更广泛的公众使用。目前,这种语言的主要普及者是Parondzhanov V.D.。除了参加研讨会和写书外,他还创建了一个专门介绍这种语言的网站。由于他的奉献精神,DRAKON现在被化学家和医生使用。

其他爱好者开始开发从这种语言到更广泛使用的编程语言的翻译器,如C、C++、TCL/TK、Java、JavaScript等。事实上,这个清单要长得多。如果需要,它可以扩展,因为我所知道的所有编辑器都会生成易于阅读的文件(纯文本-*.csv,*.xml;数据库-SQLight…)。其中的许多程序都有用于将规则翻译为其他算法语言的开源代码。

与当今许多其他编程语言不同,DRAKON不是“符号化”的,而是图形化的。其中的任何算法都是使用特殊图标在屏幕上绘制的。这些图标根据直观的规则组合成算法。生成的图表非常简单易懂,即使是非程序员也能理解。然后这些图表可以一键转换为可以运行的程序。。。

让我们回顾一下算法的概念。

算法是一种清晰易懂的描述,可指导执行者完成某些过程以解决特定任务。

可能有更好的定义,但我会坚持这个定义。

根据这个定义,算法是一种通过执行者的努力来解决问题的方法。理想情况下,一个现成的算法也应该对其他人(或某物)是可理解的。

假设我已经为一个利润极高的EA创建了一个算法,该算法使用复杂的正弦马丁格尔进行交易。信号的变化取决于烛形的长度,烛形的长度是一周中某一天与当前烛形的指数分数,以及之前形成的10个峰值的相位。很容易,对吧?不是的???好吧,但我已经解释了一切!!!

如果你是一个开发人员,那么我应该怎么做才能让你理解呢?最有可能的是,我应该画一个图表,这样你就可以理解在编码方面应该做什么。在图表准备好之后,它可以作为一个普通的需求规范,现在您已准备好将其转换为代码。

这就是DRAKON格式的图形的外观。

如果你是一名程序员,并且自己绘制了这张图,那么通常只需按下几个键就可以从中获取操作代码,或者至少创建一个可靠的框架,然后可以使用一系列自动更正来调整该框架。

如果你是一个客户,那么如果你展示一个图表,清楚地描述在某些情况下该做什么,那么你将更容易向程序员解释你想要什么。

例如,当两个MA交叉时,我们只需要记住信号,并在价格从“初级”平均水平反弹的那一刻,但不迟于当地时间19:00的时候进行交易。

当然,你可以用语言来描述这一切。

但你也可以画一张图,问计算机(或者更准确地说,抽象的执行者)一些简单的问题,比如:“现在超过19点吗?”或“平均值交叉了吗?”,并描述如果答案是“是”该怎么办,如果答案是”否“该怎么办。

这不会减少程序员的技术工作负荷,但至少他们会更好地理解你的想法,并且在第一个版本中出错的可能性更小。这些错误最终必须得到纠正,这可能需要额外的时间(和/或金钱)。

一般来说,DRAKON图对程序员和客户都是有益的,他们不熟悉编程,但非常了解他们所希望的EA的工作方式。

简单地说:

  • 这种语言的结构确实有助于你思考。当我看到形式的算法时,我更容易理解模块中各部分之间以及模块本身之间的关系,发现错误并使用没有图可能看起来不明显的解决方案。
  • DRAKON有助于更好地了解客户。
  • 如果出现任何问题,将我的建议传达给客户会更容易。
  • 客户更容易批评我的错误。
  • 如果客户绘制了DRAKON图,则可以将其转换为代码,并且可以认为需求规范已完成。这比处理编码过程中出现的问题要容易得多。可能有一些功能对客户来说是显而易见的,但对开发人员来说却不是。该图消除了潜在的误解。

对我来说,算法中的图形是不可或缺的通信工具。当两个人对结果感兴趣并进行对话时,最好说相同的语言。你一旦理解了DRAKON图的语言,就会发现它对于任何知识分支的专家来说都是通用的。


DRAKON的基本开发环境

在准备这篇文章时,我使用了三个主要工具。

  • 首先,我们有Drakonhub。这是一个在线编辑器,允许绘制所有类型的DRAKON图,具有非常方便的界面,但不能将图导出为代码。还有一个单独面向程序员的项目 - drakon.tech。但它只适用于JavaScript(至少根据我的发现如此)。此外,非程序员可以使用的图表数量似乎比Drakonhub少得多。一般来说,如果客户渴望在生成后手动实现变量类型,那么这对他们来说是完美的,对开发人员来说也是正常的。有俄语、英语和挪威语界面。
  • 还有Fabula下载链接)。该程序是免费的,具有俄语和英语界面,以及适用于Windows的离线应用程序(虽然它是使用QT库编写的,但它是封闭源代码的)。这个界面对我来说几乎是完美的。数据保存在用zip归档器打包的XML中(这意味着您可以编写XSLT并在必要时直接发布程序)。它可以跟踪算法,这些算法可以用于演示或创建伪代码。一个伪代码,反过来,可以使用一系列的自动更正变成一个完全工作的程序。本文中的大多数图表都将使用Fabula创建。
  • 第三,我们有DRAKON Editor。它的界面稍微不那么方便,因为图标应该手动放置。此外,一些图标是不存在的,而一些标题并没有以最佳方式实现。另一方面,我可以将图表转换为MQL5代码,而无需做太多准备工作。此外,它还可以突出显示一些关键字。还有,它是用TCL/TK编写的,这意味着它是跨平台的,因此可以自然地在Linux上运行,而不需要Wine。这个编辑器的主要优点是它支持许多编程语言。DRAKON图可以很容易地转换成C++、Java、JavaScript、D、TCL、Go和一堆其他语言。因此,如果你喜欢DRAKON,这对程序员来说是一件非常有用的事情。然而,它生成的代码并不总是看起来很漂亮。准备文件的方法也不明显,您需要阅读文档。但一旦你弄清楚了,它就会非常有效。界面有俄语和英语两种语言。
  • 还有IS Drakon。对我来说,它的主要缺点是它是一种付费产品。我没有深入研究它的界面。对我来说,它似乎与DRAKON Editor相似,但我在研究它时并没有发现任何特别的优势。

正如我已经提到的,这里的大多数图表都是使用Fabula制作的。在我看来,它的图表是最漂亮的,不需要任何复杂的准备工作。

如果要从图表中生成代码,我将在DRAKON编辑器中执行此操作。


基本语言命令

DRAKON语言是基于当时程序员所熟知的流程图开发的。因此,主要语言元素通常遵循GOST(全联盟国家)方块图标准。但这种开发的主要力量在于将这些元素放置在平面上的规则。

语言的第一个功能元素是“图标”。图标是一种特殊的图形符号,用于定义算法的某些动作、条件或操作。

图片
名称(括号中显示了备选方案)
描述
Open
Start
程序的起点,者是算法开始执行的地方。
End
End
程序完成,算法的执行在此结束。
Action
Action (process)
一个常规的动作块。它包含按顺序执行的命令。
Problem
Problem (condition, solution)
Problem(问题)图标用于检查状况。如果满足条件,程序将执行一个分支,否则将执行另一个分支。
Selection
Selection (parsing)
Selection(选择)是几个选项的分布节点。程序根据“Selection”中定义的条件执行不同的操作。与Problem不同,可能有两种以上的选项。
Option
Option
Option(选项)图标表示与DRAKON语言中的Selection(选择)图标相关联的条件或执行分支。它定义了如果“Selection”块中的某个条件为true,则应执行哪些操作。
Branch name
Branch name
Branch name(分支名称)图标描述给定模块中某个片段的名称、算法的某个阶段或程序的状态。
Address
Address
Address(地址)指示执行分支后的位置。
Insert
Insert
Insert(插入)用于将另一个图表或动作块插入到当前算法中。这允许更密集和逻辑地排列和构造代码。
Shelf
Shelf
Shelf(工具架)图标可以有多个值。
Value Top Bottom
给执行者的命令 执行者. 例如,一个会计。 命令. 例如,打印一张发票
把消息从发送者发送给接收者 发送者和接收者例如,浏览器和应用服务器 消息,例如“使用脸书账号登录”的请求
在对象上进行一项操作 带有操作的关键短语 将对其执行操作的对象。
为变量赋值 Variable Value
有时,也会使用“三层架”。作者
Parameters
Parameters

参数包含算法的输入数据。

例如,要建立一条路线,我们需要知道起点和终点

有些程序允许分离输入和输出参数。然后输入将位于左侧,输出参数将位于右侧

"For" loop start
FOR loop start
该图标通常与以下图标一起使用。某个动作重复已知(可计算)次数

例如,如果我们需要从1到10计数,或者迭代某个数组中的所有元素
"For" loop end
FOR loop end
该图标通常与上一个图标一起使用。某个动作重复已知(可计算)次数。
Output
Output
Output 图标表示程序的数据或结果传输给用户、程序的另一部分或外部设备的点。

顶部包含关键字或关键短语。通常那里有一个动词。

底部包含对象或描述性信息。


  Input  Input Input 指示程序等待接收来自用户、其他程序或外部源的输入的位置。就像 Output 一样,它包含一个顶部和一个底部。
  Pause  Pause Pause表示程序暂停到某个事件或时间的时刻。
  Timer  Timer Timer 用于控制时间间隔和计划操作。经常与“Time”图标一起使用。
  Time  Time Time 将与时间及其账户相关的操作可视化。它允许程序跟踪时间间隔和事件。
  Parallel process Parallel process

Parallel process(并行进程)控制与主程序同时运行的任务的执行。
顶部可能包含StartBreakpointStopRestart

Parallel process 在后台运行,其算法在另一个DRAKON图中定义。主进程在不等待并行任务完成的情况下继续运行。可以使用输入和输出图标建立与 parallel process 的通信。

 
  Main line comment Main line comment Main line comment (主线注释)有助于使图表更清晰。它不会影响程序操作,但可以澄清不清楚的片段。
  Right comment Left comment Right and left comments.
右侧和左侧的注释图标允许对任何动作进行注释,特别是在动作发生的地方。通常,会对变量和参数进行解释。
  Caption Caption
如果需要解释算法的某些片段,最常用的是 Caption(标题)图标,而不是左右注释。它很少用于转换为程序的算法。更常见的情况是,这是一种在用人类语言编写的算法中吸引注意力的方式(例如,对于医生),或者如果客户想借助一些突出的要点来澄清他们的描述。
  Parallel processes Parallel processes
Parallel process(并行进程)图标用于启动同时运行的多个任务或进程。此图标中的每个箭头都可以表示不同的线程或任务。
  Loop arrow Loop arrow
arrow(箭头)表示重复的事件,具体的重复次数未知。

例如,检查水壶是否沸腾,直到沸腾为止
  Silhouette arrow Silhouette arrow
它只在图中的一个位置使用:表示动作的继续和过渡到轮廓的下一个分支(见下文)。

有时,也会使用其他图标,例如“简单输入”(看起来像输出图标的顶部)或圆形矩形。有些程序不允许使用所有图标。但总的来说,该表提供了一组几乎详尽无遗的片段图示。


创建简单的视觉图(“基元”)

DRAKON语言图是根据一定的规律构建的。

如前所述,该图的主要构建块是图标。然而,为了让它们正确互动,它们需要沟通渠道。

沟通线可以是水平的或垂直的,但是

操作只能垂直进行。

只有在选择几个选项中的一个或某些其他辅助操作时,才会指示水平连接。如果没有辅助操作,例如在函数中输入参数或对给定算法进行注释,那么整个算法将被放置在一个垂直的“串”上。

例如,我们需要得到两个数字的和。我们从用户那里接收这两个数字,并使用printf或Print函数将数据输出到控制台。在DRAKON语言中,图表会是什么样子?很简单:

两个数字之和

图 1. 两个数字求和的算法

如果我们想编程这个代码,那么很可能我们需要一个函数,它必须接受参数(辅助操作)。然后我们将这样画:

总和(作为函数)

图 2. 求和的函数。

程序根据我的图表生成的代码:

double Summ(double a, double b) {
        // item 6
        return (a+b);
    }

因此,第一条规则:DRAKON图的主要方向是从上到下。也就是说,如果算法是线性执行的,那么它的基元总是垂直绘制的,并且必须从上到下执行。因此,该图不需要箭头。没有它们,一切都很清楚。

但如果我们需要分支呢?如果某些操作仅在特定条件下发生,该怎么办?例如,仅根据移动平均线的交叉点进场交易将使用问题图标确定:

通过交叉平均值进场交易

图 3. 通过交叉移动平均线进场交易的算法

每个条件图标总是有两个输出:一个从底部输出,一个从右侧输出。换句话说,算法中的任何操作总是从上到下、从左到右发生。还是不需要箭头。在测试一个算法时,我们只需跟着线走,直到到达终点。

有时,必须根据三个或三个以上的选择而不是两个来做出决定。假设用户按下了某个键,根据用户按下的键,程序应该执行某些操作。当然,我们可以用普通的问题来画这个,但图表会变得很繁琐。

选择构造更适合这种情况。

处理按键

图 4. 处理按键

请注意,最后一个选项图标为空。在MQL中,此选项对应于default运算符。如果没有其他合适的选项,则执行默认操作。

使用此示例,可以跟踪另一个DRAKON规则:所有垂直分支都位于从左到右的位置,选项越向右,情况就越糟。最左边的选项有时被称为“皇家之路”或“幸福之路”。

如果这些选项是等效的,那么它们只是根据某种标准进行排列。例如,我按照按钮字母的字母顺序排列它们。

有时,有必要在没有到达程序末尾的情况下转到块的开头。这些是DO-WHILE循环。

等待循环(DO WHILE)

图 5. 等待信号出现。在任何情况下,“等待信号”操作至少执行一次。

或者,可以重写同一个循环,以便它首先检查条件,然后再执行一些操作。

DO-WHILE 循环

图 6. 等待信号出现。如果信号已经到达,则可能永远不会执行“等待信号”操作。

无论如何,这里的箭头已经是一个必要的元素。如果没有它,图表将更难阅读。

关于循环还有一条更重要的规则。循环可以有任意数量的出口,但可能只有一个入口。换句话说,我们不能将箭头从程序中的任意位置拖动到循环中的任意地方。我们必须始终回到最初。


DRAKON轮廓图

由于DRAKON是一种可视化语言,因此其图表易于阅读是很重要的。为了实现这一点,最好将整个图表完全包含在屏幕(或表格)上。

这一要求并不总是可行的,但我们必须努力实现。另一种放置语言图标的方法叫做轮廓图(Silhouette),可以帮助解决这个问题。

轮廓只是将复杂的功能分解为其组成部分和执行阶段的一种方式,但同时将其作为一个整体。

例如,这里是以轮廓图的形式编写的标准EA中的分时处理。

轮廓图

图7.轮廓图是DRAKON语言中的第二个主图配置

在每个分支的顶部都是它在人类语言中的传统名称。下面是转移地址-此分支完成后重定向命令流的位置。通常,会过渡到相邻的分支,但有时您需要去其他地方。

如果转移进一步向右,则只指示分支的名称。

如果转移发生在同一分支的开头或左侧的分支,则相应分支的开头和结尾的标记将用黑色三角形标记:

一个分支中的循环

图8.一个分支轮廓中的循环

如果必须使用这样的循环,请确保您有一个将程序带到另一个分支的退出条件。否则,循环可能会变得无穷无尽。

我尽量避免在我的图表中出现这样的循环。在我解决的问题中,我可以不使用它们在95.4%的情况下。。。

事实上,轮廓是一个状态图。通常,编辑器正是这样理解每个分支的——将其理解为流程在给定时刻的某些状态,并将轮廓解释为一个无休止的循环,其中可以使用内部的switch-case运算符选择状态。这就是为什么我们在入口和出口处需要标签:程序需要知道在哪里切换,用户需要看到哪个片段在某个时间处于活动状态。

只有才能通过分支的开始进入分支。通过“end”图标退出最后一个分支。


DRAKON图的一些细微差别

我希望你注意到,在上面的图表中,除非有连接,否则线不会相交。这是增加图表清晰度的一个基本点。不应该有交叉点。只能通过标记进行路径合并或移动。在有交叉的地方,我们可以在走向解决方案时选择这条路径。

图7中,用于添加额外仓位的分支(从左起第三个)有点不准确,图中的平行线应尽可能少。这条规则也增加了清晰度。令我遗憾的是,Fabula不知道如何正确地绘制分支。虽然这不是一个错误,但这是一种解释上的不准确。

“向下或向右移动”规则的例外是图表的最下面一行,它将轮廓图“串”成一个整体。它总是将过程返回到选择新状态的开始。因此,我们沿着它从右向左,朝着箭头移动。

原则上,几乎所有的程序都允许我们在一张纸上创建多个图表。有时,这是合理的。

如果图表很小,而且大多是垂直的(轮廓可以做得很紧凑),图表之间有足够的距离(或者它们用颜色标记得很好,甚至更好——有额外的边界),如果所有这些条件都得到满足,组合后的图的清晰度可以提高。

如果你的图表要打印在纸上,那么使用上一段中的建议,尽可能紧凑地排列它们是有意义的。

然而,在所有其他情况下,最好将每个图放置在单独的空间中。特别是,如果其中有大的“轮廓图”,或者这些图表是用来打印在黑白纸上的。大多数情况下,DRAKON更多的是清晰度,而不是紧凑性。正是可视化减少了脑力劳动,并使这些努力能够直接用于开发有效的解决方案。


将图表从DRAGON导入MQL

当我使用图形图标编写一个好的大型算法时,我希望尽量减少将图表转换为代码的工作量。

通常,我使用DRAKON编辑器来实现这些目的。

打开编辑器后,您需要做的第一件事就是创建(或打开现有的)文件。

DrakonEditor-“文件创建”对话框

图9.DRAKON Editor-文件创建对话框

DRAKON Editor(DE)使用自动保存:屏幕上的所有更改都会立即保存到文件中。

请注意以红色突出显示的有关SMART编辑模式的文本

我们将把这些图表转换成Java。如果您不想为MQL编写特殊的解析器(我当然不想),这是最简单的选项。Java文件的结构尽可能接近MQL5程序的结构,因此生成的文件将以最小的修改进行编译。

在主程序窗口的左上角,有一个按钮可以打开文件描述和“文件”菜单,您也可以在其中找到此项目:

文件属性菜单和按钮

图10.DRAKON Editor</s>0-文件属性菜单和按钮

文件描述是有效的!!!

除了一般的解释外,我们还可以插入两个部分,这些部分将完全转移到现成的程序中。虽然还没有什么,但这些部分看起来非常简单:

===header===

===class===
class Main {

After "===class===", it is sufficient to add "class Main {". 请注意,这里有一个花括号。第二个由编辑器在生成期间安装。

文件中只能有一个类。

“===header===”字符串之后插入的所有内容都由DE直接粘贴到文件中。因此,如果您完全用DRAKON语言编写程序,则应在本节中放置所有全局变量、#include语句、结构和枚举的描述等。

“===header===”部分之前的所有内容都被忽略。我们真的可以在此处插入任何文本描述

如果编写简单指标,则“class Main{”和右花括号应从最终文件中删除

如果您了解OOP是如何工作的,那么您可以像往常一样直接在同一个头中使用类描述,不包括函数的实现。这些函数将在图表中实现。请记住,Java有一个类,而MQL有在全局范围内操作的函数。

想要演示如何创建一个简单的NR4指标,如果烛形的大小小于前面其他烛形的大小,则该指示器会标记此烛形。“大”蜡烛的数量在输入参数中指定。这种蜡烛的出现通常表示即将发生剧烈变化的可能性。

这是我的描述代码:

===header===
//+------------------------------------------------------------------+
//|                                                          NR4.mq5 |
//|                                       Oleg Fedorov (aka certain) |
//|                                   mailto:coder.fedorov@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Oleg Fedorov (aka certain)"
#property link      "mailto:coder.fedorov@gmail.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot NRBars
#property indicator_label1  "NRBarsUp"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  0
//--- plot NRBars
#property indicator_label2  "NRBarsDn"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  0
//--- input variables
input int NRPeriod=4;

//--- indicator buffers
double         NRBarsBufferUp[];
double         NRBarsBufferDn[];

===class===
class Main {

关闭文件描述。

现在我们需要通知编辑器,我们的文件应该转换成Java。

转到“File”->“File properties”并在新对话框窗口的顶行中选择Java。

选择图表转换成的语言

图11.选择图表转换为的语言

设置已完成,现在我们可以开始编程算法了。

我们可以在图标中写入任何文本,但在这种情况下,每个图标都将包含一个进入最终文件的代码片段。如果这是为客户进行的演示,只需用人类语言编写注释就足够了,但如果您想将编译后的代码存储在图表中,请充分详细地编写应该发生的事情。对我来说是第二种情况。

DE中的Insert图标在编译过程中不起作用,因此我们需要使用Action图标。

每个函数都必须有自己的图表。

DE显式地需要这一点(其他编辑器更“忠诚”)。在这里,如果不使用工具栏按钮或按Ctrl+N创建多个图表实体,就无法创建多个图。

在我的例子中,只有两个函数:OnInit 和 OnCalculate,它们在这里:

OnInit

图 12. OnInit 函数

OnCalculate

图 13. OnCalculate 函数

如果图像文本太小,请下载并安装DRAKON编辑器(网站有详细说明,并描述了所有依赖项)。然后打开带有以下图表的文件。

将图表转换为已编译的代码(DRAKON->Generate code)。如果图表中有错误(例如,一条线没有到达另一条线或图标),DE会在下面的面板中警告您。如果没有错误,项目文件夹中将显示一个扩展名为*.java的文件。

将其保存到 indicators 目录中,将扩展名更改为*.mq5,必要时删除类描述,编译并运行。。

以下是在删除不必要的元素之前我的文件的内容:

// Autogenerated with DRAKON Editor 1.31
//+------------------------------------------------------------------+
//|                                                          NR4.mq5 |
//|                                       Oleg Fedorov (aka certain) |
//|                                   mailto:coder.fedorov@gmail.com |
//+------------------------------------------------------------------+
#property copyright "Oleg Fedorov (aka certain)"
#property link      "mailto:coder.fedorov@gmail.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot NRBars
#property indicator_label1  "NRBarsUp"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  0
//--- plot NRBars
#property indicator_label2  "NRBarsDn"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  0
//--- input variables
input int NRPeriod=4;

//--- indicator buffers
double         NRBarsBufferUp[];
double         NRBarsBufferDn[];

class Main {

    int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) {
        // item 15
        int i,j, limit;
        // item 16
        if (rates_total < NRPeriod) {
            // item 19
            return 0;
        } else {
            // item 20
            if (prev_calculated < NRPeriod) {
                // item 23
                limit = NRPeriod;
                // item 24
                ArrayInitialize(NRBarsBufferUp, EMPTY_VALUE); 
                ArrayInitialize(NRBarsBufferDn, EMPTY_VALUE);
            } else {
                // item 25
                limit = rates_total - NRPeriod;
            }
            // item 310001
            i = limit;
            while (true) {
                // item 310002
                if (i<rates_total-1) {
                    
                } else {
                    break;
                }
                // item 340001
                j=1;
                while (true) {
                    // item 340002
                    if (j<NRPeriod) {
                        
                    } else {
                        break;
                    }
                    // item 36
                    if (high[i]-low[i]>high[i-j]-low[i-j]) {
                        // item 39
                        break;
                    } else {
                        
                    }
                    // item 340003
                    j++;
                }
                // item 40
                if (j==NRPeriod) {
                    // item 43
                    NRBarsBufferUp[i]=high[i];
                    NRBarsBufferDn[i]=low[i];
                } else {
                    
                }
                // item 310003
                i++;
            }
        }
        // item 48
        return(rates_total);
    }

    int OnInit() {
        // item 11
        //--- indicator buffers mapping
        SetIndexBuffer(0,NRBarsBufferUp,INDICATOR_DATA);
        SetIndexBuffer(1,NRBarsBufferDn,INDICATOR_DATA);
        // item 12
        //--- setting a code from the Wingdings charset as the property of PLOT_ARROW
           PlotIndexSetInteger(0,PLOT_ARROW,218);
           PlotIndexSetInteger(1,PLOT_ARROW,217);
        // item 13
        //---
           IndicatorSetString(INDICATOR_SHORTNAME,"NR4 ("+IntegerToString(NRPeriod)+")");
        // item 14
        //---
           return(INIT_SUCCEEDED);
    }
}

让我再次提醒您:要使简单指标工作,请删除上面和下面以黄色突出显示的文本。在这里,我故意不使用样式器,这样读者就可以准确地评估DE自动化将如何格式化这个文件。

阅读这个代码比我手工写的要困难,但它是有效的。但我们不必阅读它,我们应该看看图表。;-)


结论

如果您是一名开发人员,并且喜欢DRAKON,请随意使用我上面提到的任何图表创建工具。我建议你自己测试每一个列出的编辑器,并就什么对你个人更有利形成自己的看法。事实上,它们都相对简单。

如果你想有序地安排与客户的工作,请给他们一个Drakon.Techdrakonhub,简要解释如何用人类语言创建项目,以及图标如何相互关联,并告诉他们可以用文字描述他们想要看到的内容。最重要的是要有一个清晰的结构。

如果你是一个客户,并且已经达到了这一点,那么你已经知道该怎么做了。;-)

幕后有很多话题:DRAGON在交互式演示中的使用,安排任何信息(不仅仅是计算机程序)以便于记忆的方法,对DRAKON语言和所有图形语言的批评,等等。

如果你感兴趣,可以给我私信或给本文留下你的评论。我愿意讨论。您也可以访问V.D. Parondzhanov 的网站,在那里您可以找到更多的内容。

我希望我能够激发人们对这种方法的兴趣,并且至少有几个读过这篇文章的人会开始在他们的工作中使用这种奇妙的工具。

如果有人需要本文中描述的其他算法的源代码,请联系我,我会把它们发给你。

附件. 存档包含 DRAKON Editor 项目文件,该文件包含上一节中所述的指标算法 。该文件可以为 NR4 指标生成一个完全可运行的代码。

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

附加的文件 |
FullIndicator.zip (3.28 KB)
用置信区间估计未来效能 用置信区间估计未来效能
在这篇文章中,我们深入研究自举法技术的应用,作为评估自动化策略未来效能的一种手段。
开发回放系统 — 市场模拟(第 20 部分):外汇(I) 开发回放系统 — 市场模拟(第 20 部分):外汇(I)
本文的最初目标不是涵盖外汇交易的所有可能性,而更是出于适配系统,如此您就至少可以执行一次市场回放。我们把模拟留待其它时刻。不过,如果我们没有跳价而仅有柱线的话,稍加努力,我们就可以模拟外汇市场中可能发生的交易。直到我们研究如何适配模拟器之前,情况一直如此。不经修改就尝试在系统内处理外汇数据会导致一系列错误。
价格走势模型及其主要规定。(第 3 部分):计算股票证券博弈的最优参数 价格走势模型及其主要规定。(第 3 部分):计算股票证券博弈的最优参数
在作者基于概率论开发的工程方式框架内,找到了开立盈利仓位的条件,并计算了最优(利润最大化)止盈和止损值。
MQL5 中的范畴论 (第 13 部分):数据库制程的日历事件 MQL5 中的范畴论 (第 13 部分):数据库制程的日历事件
本文在 MQL5 中遵循范畴论实现秩序,研究如何在 MQL5 中结合数据库制程进行分类。我们介绍了当辨别交易相关的文本(字符串)信息时,如何把数据库制程概念与范畴论相结合。日历事件是焦点。