外汇EA编写教程:自动机编程作为一种创建自动化交易系统的新方法

_ν_δα_τ_ο_δ_ν_δα(ολ_σοφ_∑ωκρ_τη_)

我知道我什么都不知道(哲学家苏格拉底)

简介

这对于使用metaquotes语言4/5(mql4/5)开发EA的交易者来说是一个新的主题。当我尝试对metaquotes执行相关搜索时,我意识到了这一点。这个主题还有一个空白。

每个交易者都会创建自己的EA事务,并且需要一个严格的方法来处理与编程和非常复杂的程序逻辑相关的各种问题。在一天结束时,程序应该像任何标准和不可抗力的绕线装置一样独立运行。

然而,我们如何才能实现包容性和包容性呢?这太难了。因此,自动控制系统要求对所有的控制系统进行正确的编程,只有采用相应的自动编程编程编程技术,才能达到最佳的效果。近年来,随着对软件质量设置的要求越来越高,实时系统编程技术的发展也越来越受到关注。

1991年,俄罗斯作家A.A.Shalyto(讲师、教授、工程科学博士、SPBSU ITMO学院“编程”技术系主任)开发了一种称为“自动编程”的编程技术。看看简单的自动化编程或交换技术,我认为读者可能会感兴趣。它允许使用元引号语言,使MTS的开发比以往任何时候都更加方便。此外,它还将很好地集成到复杂的决策系统中。

1。对这个问题的深入研究

所有问题制造者和软件开发人员的一个长期梦想是对问题(算法)有一套有计划的解决方案,并与之完全一致地实现算法。但事情往往不会像支持者和开发者所想的那样发展。各种算法往往忽略了开发人员要实现的重要内容,程序文本本身与算法几乎没有相似之处。

因此,有两种算法——一种是编写的(用于记录和记录设计解决方案),通常表示特定的设计结果,而不是用于获得给定结果的方法;另一种是在开发人员的头脑中(但也保存在文本中)。

在程序文本的最终版本之后,通常会有修改文档的尝试,许多事情都会再次被忽略。在这种情况下,程序逻辑可能与算法逻辑不同,因此缺乏一致性。这是“可能的”,因为没有人检查某人的程序文本。

如果程序很大,就不可能只通过文本来检查它与算法的一致性。实现的准确性可以通过一个称为“测试”的过程来检查。基本上,它检查开发人员如何掌握算法(以书面形式),将其转换为他头脑中的另一个算法,并将其输出为一个程序。最终,开发人员是与逻辑相关的宝贵信息和实现的唯一所有者,这些逻辑与以前编译的内容完全无关。

即使开发人员生病(或辞职),情况并非如此。重点是,基本的程序逻辑根据每个开发人员的智能和编程语言的知识而变化。无论如何,开发人员引入并使用他们认为合适的大量中间变量。此外,如果程序较大且逻辑复杂,则需要更高级的专家来发现错误缺陷(这里我指的不是操作系统缺陷或语言功能的错误使用,而是逻辑的不当实现),并通过程序文本本身来解决。

另一方面,大多数开发人员不愿意在编程之前编写算法(甚至是在纸上绘制),可能是因为他们仍然需要考虑一些事情。事实上,为什么要浪费时间画矩形、菱形和箭头?最好马上开始编程,然后在文档准备中制定一个类似或非常通用的算法。

每个人都已经习惯了它——开发人员做它是因为它更简单;问题处理者不一定有必要的编程技能,即使他们这样做了,他们也不能及时地改变开发人员提出的内容。一个方便的编程环境也有助于指定开发序列的有效性。用于调试和监视变量值的高级工具使我们有希望检测逻辑中的任何错误。

随着时间的推移和项目最后期限的临近,开发人员将坐下来为一个给定的逻辑问题起草一个“餐巾纸”解决方案,顺便说一句,这个问题仍然需要实现,更不用说在同一(混乱)场景中进行大量测试后被忽略的错误了。这就是目前的情况。是否有任何解决方案,或者至少有改进?在从标准算法迁移到程序代码的过程中,似乎丢失了一些重要的东西。

2。程序的逻辑部分

本文作者对一个程序的理想逻辑部分提出了以下想法。程序的总体逻辑是基于切换的。简而言之,任何控制算法(automata)都可以按如下方式实现(这里不太考虑注释的含义,只是简单地看一下结构)。

switch(int STATUS ) // Мulti-valued global state variable of the automaton.
{
  case 0:  // start

  // Checking arc and loop conditions (in order of priority),
  // transition (change of the value of the variable STATUS)
  // and execution of arc and loop actions (output function execution);
  // logging transitions and actions if the condition is met. 0

  // Calling nested automata.
  // Execution of output functions in the state.
  break ;
  
  case 1:
  // Checking arc and loop conditions (in order of priority),
  // transition (change of the value of the variable STATUS)
  // and execution of arc and loop actions (output function execution);
  // logging transitions and actions if the condition is met. 

  // Calling nested automata.
  // Execution of output functions in the state.
  break ;
  
*********
*********
*********

 case N-1:
  // Checking arc and loop conditions (in order of priority),
  // transition (change of the value of the variable STATUS)
  // and execution of arc and loop actions (output function execution);
  // logging transitions and actions if the condition is met. 

  // Calling nested automata.
  // Execution of output functions in the state.
  break ;

 case N:
  // Checking arc and loop conditions (in order of priority),
  // transition (change of the value of the variable STATUS)
  // and execution of arc and loop actions (output function execution);
  // logging transitions and actions if the condition is met.

  // Calling nested automata.
  // Execution of output functions in the state.
  break ;
}

三。作者A.A.Shalyto解释的自动编程

不管开发技术如何,任何程序都有一个状态,由它在任何给定时间点上的所有数据值决定。在大型应用程序中,可能有数百甚至数千个变量和多个控制流。这些变量的完整集合描述了应用程序在任何给定时间点的状态。

程序状态可以作为所有控制变量(参与所有迁移情况)中的一组选定值以更简单的方式处理。如果控制变量的值发生变化,则表示程序的状态发生变化,程序的状态数由程序运行期间发生的控制变量值的最大可能组合确定。假设程序中只使用二进制控制变量(标志)。在这种情况下,包含n个二进制控制变量的程序的状态数在n到2n之间。

开发人员可以提供它来处理控制变量值的所有组合(在这种情况下,是2N组合)。然而,更可能的是,一些控制变量值的组合(高达2N-N)最终未指定。然后,只要发生意外的输入操作组合,就可以将程序迁移到未指定的状态。

在以下情况下,它与交易者EA的不活动具有相同的效果:

  • 缺口
  • 预付款损失,
  • 它与额外的预付款一起进入负平衡状态。
  • 直到它达到零,并进一步变红,它才有好的利润。
  • 买卖头寸的建造和关闭不正确,
  • 其他明显的负面情况。

这种状态称为“不可见”。复杂性使得枚举变得困难,更不可接受的是,程序的所有可能状态都会导致不可靠性……结构的复杂性是构成安全陷阱的各种非可视状态的来源。从内存保护失败到扩展程序的新功能和产生各种属性的副作用,程序在未指定状态下的行为各不相同。

许多PC用户,可能是所有软件开发人员,在使用或开发过程中经常遇到程序进入未指定状态的情况。

为了消除程序中出现这种未指定状态的可能性,必须在设计阶段就明确地指定所有需要的状态,并且只能使用多值控制变量来区分这些状态。在此之后,有必要确定各州之间所有可能的迁移,并根据他们不能“误入歧途”的原则制定一个计划。

为了满足程序行为开发过程中的严格要求,需要三个组件:

  • 允许明确标识程序状态和状态之间可能的迁移的数学模型。
  • 模型的图形标记;
  • 此标记表示实现算法的一般方法。

提出了一种基于“状态”概念的有限自动机作为数学模型。自动化编程支持软件开发阶段,如设计、实现、调试和归档。

近年来,“事件”一词在程序设计中越来越普遍,所提出的方法是基于“状态”的概念。当与术语“输入动作”(同时作为输入变量和事件)结合时,可以引入术语“无输出的自动机”。接下来,将进一步介绍术语“输出作用”和(决定性有限)自动机的概念。基于这种思想的编程领域称为自动编程,开发过程称为自动编程。

当应用时,指定的方法在这方面非常特殊,并且自动机由迁移图表示。为了区分节点,引入了“状态分配”这一术语。如果选择“多值状态分配”(多值状态分配),则只能使用一个变量来区分与所选变量可用值数量一致的状态。有了这个事实,“程序可观测性”这个术语被引入到编程中。

按照建议的方法进行编程将通过“状态”而不是“变量”(标志)来执行,这有助于更好地理解和指定问题及其组件。在这种情况下,调试是根据自动机的记录进行的。

由于上述方案提出了用形式化和同构化的方法从迁移图到程序代码,如果使用高级编程语言,采用切换结构似乎更为合理。这就是为什么我们在提到自动机编程范式时决定使用“开关技术”这个术语。

4。显式状态规划

自动机方案的应用进一步扩展到了事件驱动系统,也称为“反应式”系统。响应系统使用相关信息以环境设定的速度与环境交互(EA可以包含在同一类中)。

事件驱动系统是利用自动机开发的,采用过程化的方法,并以显式状态规划命名。在这种方法中,输出动作被分配到迁移图的弧、循环或节点(使用混合自动机-摩尔和Mealy自动机)。此方法允许获取动作序列的紧凑表示(作为对相关输入动作的响应)。

为设置给定的系统类而建议的场景的逻辑更加集中,因为它从事件处理程序中移除,并生成由处理程序调用的相互连接的自动化系统。系统中自动机之间的交互可以通过嵌套、调用和交换状态数来实现。

互联的自动化系统将形成独立于系统的程序部分,而依赖于系统的部分则由输入输出动作函数、处理程序等组成。

给定方案的另一个关键特征是,当应用时,自动机以三位一体的方式使用:

  • 用于规范;
  • 用于实施(它们仍在程序代码中);
  • 用于基于automata(上面指定)的日志记录。

后者允许控制自动化系统操作的准确性。日志记录是基于开发程序的自动执行,可以用于具有复杂程序逻辑的大规模问题。在这种情况下,可以将每个日志视为相关脚本。

日志允许监视正在运行的程序,并澄清自动机不是“图片”,而是实际活动实体的事实。提出了用自动机方法不仅可以建立控制系统,而且可以对控制对象进行建模。

5。自动机编程的基本概念

自动机编程的基本概念是状态。系统状态在任何特定时间t0的主要属性是“分离”未来(t>t0)和过去(t<t0),这意味着当前状态包含有关系统过去的所有相关信息,这对于确定其对任何给定时间t0生成的任何输入操作的响应至关重要。

使用术语state时不需要知道历史数据。状态可以被视为一个特殊的特性,它不显式地组合所有过去影响实体当前响应的输入操作。当前响应仅取决于输入操作和当前状态。

“输入动作”的概念也是自动机编程领域的关键概念之一。最常见的输入动作是向量。根据意义和生成机制,将其组成部分划分为事件和输入变量。

有限状态集和有限输入动作集的组合,构成无输出的(有限)自动机。自动机通过某种方式改变其当前状态来响应输入动作。状态更改所基于的规则称为自动迁移函数。

自动机编程是指“无输出自动机”和“输入动作”的组合。这个自动机通过改变输入动作的状态并在输出端生成特定的值来对其做出反应。生成输出动作的规则称为自动输出函数。

在设计具有复杂行为的系统时,有必要以现有的控制对象、特定的操作集和在外部(市场)环境中可能发生的给定事件集为起点。

实际上,设计通常基于控制对象和事件:

  1. 这个问题的初始数据不仅是目标系统行为的语言描述,而且(或多或少)是来自外部环境和所有控制对象的大量请求和命令进入系统的事件集的精确规范。
  2. 已建立一组控制状态。
  3. 控制对象的每个请求都被分配一个对应的自动机输入变量,每个命令都被分配一个对应的输出变量。用于确保所需系统行为的自动机基于控制状态、事件、输入和输出变量。

6。程序特点及优点

自动化程序的第一个特点是必须有一个外部循环。基本上,没有什么新的;这里的主要内容是这个循环将是整个程序逻辑部分中唯一的循环!(这是新订单号。)

第二个特性来自第一个特性。任何自动机都包含一个由所有逻辑操作组成的交换结构(事实上,它就是从这个结构来的)。当一个自动机被调用时,控件被传递到一个“case”标签,在相关操作之后,自动机(子例程)操作将在下一次启动之前完成。这些操作存在于检查迁移条件的过程中。如果满足特定条件,将调用相关的输出函数,并更改自动机的状态。

综上所述,主要结论是自动机的实现不仅简单,而且最重要的是,程序的实现不需要许多中间逻辑变量(标志,每个自动机中的函数由一个多值状态变量提供)。

最后一条语句令人难以置信,因为我们习惯于直接使用大量全局和局部变量。没有他们我们该怎么办?!这些通常是通知程序已满足某个条件的信号。如果开发人员认为有必要,将设置标志(真),但随后(通常只有在标志始终为真并开始产生所需效果后),必须在程序的其他地方将其费力地重置为假。

有点耳熟,不是吗?现在让我们来看一个例子:这里不使用其他变量;更改只涉及状态数的值,并且只在满足逻辑条件时才使用。它不是一个有价值的标志替代品吗?!

算法在程序逻辑的生成过程中起着重要的作用。这里要记住的关键词是“逻辑部分”。在这种情况下,国家是一切的基础。要添加的另一个词是“等待”。此外,在我看来,我们对“等待状态”有一个相当充分的定义。在这种状态下,我们等待输入操作(属性、值或事件)的发生。等待或长或短。换句话说,有稳定和不稳定的状态。

此状态的第一个属性是有一组有限的输入操作在状态中等待。任何算法(显然,任何程序)都有输入和输出信息。输出操作可以分为两类:变量(如对象属性操作)和函数(如应用程序启动函数、报表函数等)。

这种状态的第二个属性是提供一组输出变量的精确值。这将揭示一种非常简单但极其重要的情况,即在任何给定时间都可以确定所有输出变量的值,因为算法(程序)在每个时间点都处于特定状态。

状态数据是有限的,输出变量值的数量也是有限的。记录迁移的函数被平滑地集成到自动机函数中,因此状态之间的迁移顺序和输出动作的转移总是可以确定的。

有关完整的功能列表,请参阅第2章。拟议技术的功能和第3章。拟议技术的优势。关于这一主题的信息太多,本文无法涵盖。在彻底研究了安纳托利·沙利托的所有研究论文之后,如果你有任何理论问题,你可以给shalyto@mail.ifmo.ru发一封私人信件,直接联系他。

此外,作为一个坚持自己的科学思想并牢记我们的目标和问题的用户,我将提供三个进一步的例子来说明我的自动化编程技术的实现。

7。自动机编程示例

7.1。一个容易理解的例子

所谓的状态是系统的一种模式。例如,水有三种状态:固态、液态或气态。从一种状态到另一种状态的转变受变温(恒压)的影响。

假设我们有一个基于时间的温度(t)图(在本例中,是价格值):

int STATUS=0; // a global integer is by all means always a variable !!! STATUS is a multi-valued flag
//----------------------------------------------------------------------------------------------//
int start() // outer loop is a must
  {
   switch(STATUS)
     {
      case 0:  //--- start state of the program
         if(T>0 && T<100) STATUS=1;
         if(T>=100)       STATUS=2;
         if(T<=0)         STATUS=3;
         break;

      case 1:  //---  liquid
         // set of calculations or actions in this situation (repeating the 1st status -- a loop in automata-based programming) //
         // and calls of other nested automata A4, A5;
         if(T>=100 )      { STATUS=2; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         if(T<0)          { STATUS=3; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         // logging transitions and actions when the condition is met.
         break;

      case 2:  //--- gas
         // set of calculations or actions in this situation (repeating the 2nd status -- a loop in automata-based programming) //
         // and calls of other nested automata A4, A5;
         if(T>0 && T<100) { STATUS=1; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         if(T<=0)         { STATUS=3; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         // logging transitions and actions when the condition is met.
         break;

      case 3:  //--- solid
         // set of calculations or actions in this situation (repeating the 3rd status -- a loop in automata-based programming) //
         // and calls of other nested automata A4, A5;
         if(T>0 && T<100) {STATUS=1; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         if(T>=100)       {STATUS=2; /* set of actions when transitioning, calls of other nested automata A2, A3;*/}
         // logging transitions and actions when the condition is met.
         break;
     }
   return(0);
  }

通过增加压力参数P和新状态,引入图中所示的复杂依赖关系,可以提高程序的复杂度。

自动机有32=9个迁移条件,因此没有遗漏或忽略任何内容。写指令和规则的时候,这种风格也很方便!这里不允许有漏洞和规则规避——必须涉及事件变量序列的所有组合,并描述所有情况。

自动机编程要求我们考虑所有方面,即使在其他情况下不考虑事件序列中的某些变量。因此,它是检查规则、指令和控制系统的一致性和完整性的主要工具。还有一个数学定理:

如果系统中有 N 种状态(非零开始),则迁移条件的总数为 N2

迁移图:n=3个状态,迁移和循环数为n2=9(等于箭头数)。

如果示例中的变量数量不同,则:

结果表明,表中所有计算值均呈指数增长,即设计是一个复杂的过程,在选择主系统变量时需要完整性。

即使只有两个参数,也很难全部描述!然而,事实上,一切都要简单得多!根据逻辑和意义,50-95%的迁移实际上是不可能的,状态数应该减少60-95%。这种逻辑和意义的分析将大大降低描述所有迁移和状态的难度。

在更复杂的情况下,需要计算EA中所有已知输入和输出数据的最大状态数。应用组合学和组合学、排列、排列和数学组合学公式可以找到这个问题的解决办法。

7.2。延时继电器

在EA中,继电器、触发器、寄存器、计数器、译码器、比较器和其他非线性数字和模拟控制系统组件的编程非常简单。

  • xmax=100-最大拾取值;
  • xmin=100-最小拾取值;
  • x=x(t)——输入时间信号;
  • y=y(t)-输出时间信号。
int   status=0;  // at the beginning of the program we globally assign
//------------------------------------------------------------------//
switch(status)
  {
   case 0: //  start  
      Y=x;
      if(x>xmax)  {status=1;}
      if(x<xmin)  {status=2;}
      break;

   case 1: //++++++++++++++++++++
      if(x>xmax)  Y=x;
      if(x<xmax)  Y=xmin;
      if(x<=xmin) {status=2; Y=xmin;}
      break;

   case 2: //--------------------
      if(x<xmin)  Y=x;
      if(x>xmin)  Y=xmax;
      if(x>=xmax) {status=1; Y=xmax;}
      break;
  }

继电器特性:

7.3。9个状态和一系列事件的81个变量模板

y是automata从1到9的当前输入状态。y值由给定子例程外部的ea生成。MegaStatus是Y的过去状态。

int MEGASTATUS=0; // at the beginning of the program we globally assign
//---------------------------------------------------------------------//
void A0(int Y) // automaton template
  {
   switch(MEGASTATUS)
     {
      case 0:  // start
          MEGASTATUS=Y;
          break;

      case 1: // it was the past
          // it became current, repeating
          if(Y=1) { /*set of actions in this situation, calls of other nested automata A2, A3, ... */ } // Loop//
          // new current
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 2: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ } //Loop//
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          // e.g. if the transition from 2 to 6 is in essence impossible or does not exist, do not write anything
          if(Y=6) { /* set of actions in this situation */ }
          // the automaton will then be reduced but the automaton template shall be complete to count in everything
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 3: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ } //Loop//
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 4: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ } //Loop//
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 5: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ } //Loop//
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 6: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ } //Loop//
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 7: // it was the past  
          //it has become current  
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ } //Loop//
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 8: // it was the past
          // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ } //Loop//
          if(Y=9) { /* set of actions in this situation */ }
          // logging transitions and actions when the condition is met.
          break;

      case 9: // it was the past
         // it has become current
          if(Y=1) { /* set of actions in this situation */ }
          if(Y=2) { /* set of actions in this situation */ }
          if(Y=3) { /* set of actions in this situation */ }
          if(Y=4) { /* set of actions in this situation */ }
          if(Y=5) { /* set of actions in this situation */ }
          if(Y=6) { /* set of actions in this situation */ }
          if(Y=7) { /* set of actions in this situation */ }
          if(Y=8) { /* set of actions in this situation */ }
          if(Y=9) { /* set of actions in this situation */ } //Loop//
          // logging transitions and actions when the condition is met.
          break;
     }
   MEGASTATUS=Y;
  }

7.4。自动音频播放器

让我们研究一个简单的音频播放器。

设备可以处于六种状态:

  1. 准备好了;
  2. 无音频跟踪;
  3. 正在播放。
  4. 快进;
  5. 重绕;
  6. 暂停。

这个音频播放器控制系统被表示为一个自动装置。按下按钮被视为对自动化有影响的事件。音频曲目、播放、显示控件等之间的迁移都是输出操作。

switch(STATUS)
  {
   case 0: //--- "Ready"
      if(Event == 3) { STATUS = 3; } //«>>» button pressed
      if(Event == 6) { STATUS = 1; } //Audio file not found 
      if(Event == 1) { STATUS = 2; } //«PLAY» button pressed
   
      z1();  // Set the indicator to the initial state
      break;

   case 1: //--- "No Track"
      z6();  // Give the «No Track» message
      break;

   case 2: //--- "Playing"
      if(Event == 4) { STATUS = 4; } //«<<» button pressed
      if(Event == 5) { STATUS = 5; } //«PAUSE»( | | ) button pressed
      if(Event == 3) { STATUS = 3; } //«>>» button pressed
      if(Event == 2) { STATUS = 0; } //«STOP» button pressed
      z2(); // Playing
      break;

   case 3: //--- "Fast-Forward"
      z3();  // Next track
      { STATUS=2; }
      break;

   case 4: //--- "Rewind"
      z4(); // Previous track
      { STATUS=2; }
      break;

   case 5: //--- "Pause"
      if(Event == 5) { STATUS = 2; } //«PAUSE» button pressed
      if(Event == 1) { STATUS = 2; } //«PLAY» button pressed
      if(Event == 2) { STATUS = 0; } //«STOP» button pressed
      if(Event == 3) { STATUS = 3; } //«>>» button pressed
      if(Event == 4) { STATUS = 4; } //«<<» button pressed
      z5(); //Pause
      break;
  }

理论上,这个自动机包含36个迁移变量,但只有15个是真实的。有关详细信息,请参阅作者提供的说明。

8.Shalyto关于项目实施的建议

有关如何准备和编译项目文档的完整信息,请参阅https://project.ifmo.ru/books/3。在本文中,我将只为读者摘录一小段:

  1. “逻辑控制。算法的硬件和软件实现方法。SPB.:Nauka,2000年”,由.编制。Shalyto,可以从指定网站的图书部分获得原型。它实现了相关信息的正确表达,因为它是由俄罗斯最古老和最负盛名的出版公司出版的。
  2. 简报为选择主题提供了基础,概述了研究中的问题,并指定了项目中使用的编程语言和操作系统。
  3. 有关手头问题的语言描述的详细信息,请参阅“问题描述”部分,以及澄清问题的数据、图表和屏幕截图。
  4. 当使用面向对象编程时,“设计”部分应该包含一个类图。应该仔细描述主类。最好为每一个类准备一个“类的方框图”,这些类希望呈现与自动化方法指令一起使用的接口和方法。
  5. “automata”部分中的每个自动机都应该提供三个文档:语言描述、自动机链接图和迁移图。
  6. 语言描述应该相当详细,但如果复杂自动机的行为难以清晰地描述,则通常表示为“意向声明”。
  7. 自动机链接图提供了接口的详细描述。图的左侧部分应该包括:数据源;每个输入变量的全名;每个事件的全名;具有其他自动机状态数的谓词(用作给定自动机中的输入操作)。例如,可以使用y8==6谓词,当第八状态自动机迁移到第六状态时,值为1;输入具有相关索引并标记为x的变量;具有相关索引并标记为e的事件;具有数字n并标记为y n的变量来存储自动机状态。
    的右部分应包括:用相关索引标记Z的输出变量;每个输出变量的全名;由给定自动机生成的事件(如果有);每个生成事件的全名;以及数据接收设备。
  8. 如果在节点或迁移中使用复杂算法,“计算算法”部分将解释所选算法并提供相关描述(包括数学描述)。这些算法由x和z变量指定,根据输入或输出时是否执行计算。
  9. 程序执行的特殊性应在“实现”一节中规定。特别是,它为自动机的形式化和同构实现提供了一个模板。这里还应该提供自动机的实现。
  10. “结论”是指已完成项目的优缺点。它还将提供各种方法来改进项目。

9。总结

我鼓励大家:

  • 在编程中尝试这个新方法。
  • 实施这个新的和有吸引力的方法来规划你的想法和交易策略。

我希望自动化编程能够:

  • 随着时间的推移,它成为了一个编程标准,专门为所有交易者设计,甚至是元引号语言开发人员。
  • 它成为设计EA时复杂决策过程的基础。
  • 未来将演变成一种新的语言——元报价语言6——并支持自动编程和一个新的平台——元交易员6。

如果所有的事务开发人员都能遵循这种编程方法,那么创建一个无损失的EA的目标肯定会实现。在本文的第一篇文章中,我将向您展示一个全新的自动化设计领域的创新和研究渠道,以及作为新发明和探索的驱动力的编程。

还有一件事-我完全同意作者文章的内容,并认为以简洁的方式提供给您非常重要(请参阅https://i s.ifmo.ru/works/open_-doc/):

为什么源代码不是理解程序的解决方案?

实际程序设计的核心问题是对程序代码的理解。知道源代码总是很好的,但问题是它常常不够。此外,通常需要额外的文档来了解非常规程序。随着代码数量的增加,这种需求将呈指数级增长。

恢复开发人员的原始设计决策,理解程序代码分析是编程技术的两个重要分支。当没有足够的源代码来理解程序时,它们是相互依赖的。

每个参与过大型软件重构项目的人都永远不会忘记当他们第一次看到许多写得不好(尽管并非总是写得不好)的源代码时所产生的无助感和尴尬感。如果没有主要开发人员的访问,源代码的可用性在很大程度上是无用的。如果程序是用一种相对低级的语言编写的,再加上编程质量差,那么所有主要的设计决策通常都分散在编程细节中,需要重新构造。同样,更高级别的文档(如接口规范和体系结构描述)可能比源代码本身更有价值。

由于认识到源代码不足以理解程序,因此出现了将代码与某种高级文档相结合的尝试。

如果您错过了项目的早期阶段,那么它的复杂性和工作负载将几乎完全将您与源代码隔离开来——如果没有高级文档的话。如果没有最初操作项目的开发人员或足够的文档来筛选体系结构决策,理解“史前”代码可能是程序员面临的最困难的挑战。

为什么程序缺乏设计

虽然缺乏源代码并不好,但它的可用性也同样差。“幸福结局”生活中缺少什么?答案很简单——将编程文档作为一个组件纳入详细而准确的设计文档中。

如果没有文件,桥梁、道路和摩天大楼通常不会建造,但程序却不会。

在编程中发生的事情可以定义为:“如果一个建筑师按照程序员的编程方法建造一座建筑,第一只啄木鸟在路上可以摧毁整个文明。”

出版大量详细、清晰的硬件设计文档,经过多年的出版,专业人士可以相对容易地理解和修改。但是,为什么软件中没有这样的文档,或者它们不是以非常正式的方式编写的,或者需要复杂的专家来修改它们(如果找不到开发人员的话)?

显然,这可以解释如下。首先,硬件开发和制造是由不同的组织执行的两个不同的过程。因此,如果文档质量不好,开发工程师将在“工厂”中度过余生,当然这不是他想要的。说到软件开发,事情就变了。在这种情况下,软件开发人员和生产者通常是一个人或一家公司,因此无论文档列表如何,内容通常都非常简单。

其次,硬件“硬”,软件“软”。这将使程序的修改更加容易,但仍然不能为不同的设计文件出版提供依据。众所周知,大多数程序员病态地不愿意阅读,当然他们不喜欢文档。

经验表明,很少有新的程序员(甚至是最聪明的程序员)能够准备设计文档。此外,尽管他们中的许多人学习和经历了漫长而复杂的数学课程,但对他们的文档的逻辑性和严格性影响甚微。他们可以在整个文档中对同一件事情使用不同的标记,不管大小,这样他们就可以随意调用它们,不管大小。例如,灯泡和灯泡、灯或灯等。很难想象当他们充分发挥想象力时会是什么样子!

显然,这是因为编译器标记在编程时不一致,并且编写的设计文档没有任何提示。

软件文档质量已逐渐成为一个社会性问题,其重要性也越来越大。软件开发越来越像一个以利润为导向的娱乐产业。不管产品将来会是什么样子,一切都是匆忙完成的。与娱乐业类似,节目设计以“盈亏”而不是“好坏”衡量一切。在大多数情况下,好的技术并不是很好,而是有人愿意为此付出代价。

项目越严格(无文件记录),作者就越不可或缺。不愿意编写设计文档可能与此有关。

不幸的是,这种风格已经扩展到主要系统软件的开发中。这主要是因为在大多数情况下,程序是编写的,而不是设计的。”在设计中,任何比CRC卡或用例图更复杂的技术都被认为过于复杂,无法采用。如果有任何现有的技术需要向领导汇报,可能导致程序员不能按时完成,那么他将拒绝应用该技术。”

这导致了这样一种情况,即用户也不会考虑软件中的一般错误。

目前的观点是,设计和适当的文档适用于大型建筑,而不是软件。

综上所述,应该注意的是,这种情况在过去没有出现过(早期使用大型计算机时),编程、编程或开发应该非常谨慎,因为如果出现错误,下一次尝试通常会在一天内发生。因此,技术进步使我们进入了一个不那么严重的编程环境。

不幸的是,我们的问题和担忧无法在A.A.Shalyto工作的研究所的网站上找到。他们有自己的问题和目标,完全不熟悉我们的概念和定义,因此没有与我们的主题相关的例子。

A.A.Shalyto的主要书籍/教科书:

  1. 基于自动机的编程。https://is.ifmo.ru/books//u book.pdf
  2. 在逻辑控制算法的实现中使用流程图和转换图。网址:https://is.ifmo.ru/download/gsgp.pdf
  3. 基于自动机的编程。https://is.ifmo.ru/works//u 2010_09_08_automata_progr.pdf
  4. 将迭代算法转换为基于自动机的算法。网址:https://is.ifmo.ru/download/iter.pdf
  5. 交换技术:基于自动机的无功系统软件开发方法。网址:https://is.ifmo.ru/download/switch.pdf
  6. 基于自动机的程序设计。逻辑控制问题的算法化和编程。网址:https://is.ifmo.ru/download/app-aplu.pdf
  7. 用遗传算法设计直升机简化模型的自动驾驶仪。https://is.ifmo.ru/works/2008/vestnik/53/05-genetic-hopper.pdf
  8. 显式基于状态的编程。网址:https://is.ifmo.ru/download/mirpk1.pdf
  9. 逻辑控制和无功系统的算法化和编程。网址:https://is.ifmo.ru/download/arew.pdf
  10. 面向对象的自动化编程方法。网址:https://is.ifmo.ru/works/ooaut.pdf
  11. 基于自动机的类继承的图形符号。https://is.ifmo.ru/works//u 12_12_2007_shopyrin.pdf
  12. 正在编程…1(一)分钟。https://is.ifmo.ru/progeny/1分钟/?I0=后代&I1=1分钟

项目:

  1. ATM的建模操作。&nbsp;https://is.ifmo.ru/unimod-projects/bankomat/
  2. 核反应堆控制过程建模。https://is.ifmo.ru/projects/reactor/反应堆/
  3. 电梯控制系统。https://is.ifmo.ru/projects/电梯/
  4. 基于自动机的咖啡机控制系统开发。https://is.ifmo.ru/projects/coffee2/
  5. 自动驾驶仪的设计与研究。https://is.ifmo.ru/projects/novohatko/
  6. 使用基于自动机的编程对数码相机进行建模。https://project.ifmo.ru/shared/files/200906/5 U 80.pdf
  7. 采用基于自动机的编程方法对无人驾驶车辆多智能体系统进行建模。https://project.ifmo.ru/shared/files/200906/5_41.pdf
  8. 可视化魔方解决方案系统。https://is.ifmo.ru/projects/rubik/

以及其他有趣的文章和项目:https://project.ifmo.ru/projects/、、https://is.ifmo.ru/projects/和https://is.ifmo.ru/articles/en/。

附言:

一个魔方可能发生的不同事件的数量是(8!*(38)1,(12)!*212_1)/2=43 252 003 274 489 856 000。然而,这个数字没有考虑到中心晶格的不同方向。

因此,如果考虑到中心平面的方向,事件数量将增加2048次,即88 580 102 706 155 225 088 000。

外汇市场和交易没有那么多连续的事件变量,但是与之相关的问题可以通过100-200个步骤使用这个编程范式来解决。这是真的!整个市场一直在与EA竞争。就像下棋一样。没有人知道对手下一步会做什么(就像我们一样)。但是也有一些很棒的计算机程序,比如基于alpha-beta修剪算法的ribka(一个非常强大的国际象棋引擎)。

希望其他人在其他编程领域的成就也能给你精力集中在你的工作上!尽管我们知道我们对此一无所知。

本文由MetaQuotes Software Corp.翻译自俄语原文
,网址为https://www.mql5.com/ru/articles/446。

 

 


MyFxtop迈投(www.myfxtop.com)-靠谱的外汇跟单社区,免费跟随高手做交易!

 

免责声明:本文系转载自网络,如有侵犯,请联系我们立即删除,另:本文仅代表作者个人观点,与迈投财经(www.myfxtop.cn)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。

著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。

風險提示

MyFxtops邁投所列信息僅供參考,不構成投資建議,也不代表任何形式的推薦或者誘導行為。MyFxtops邁投非外匯經紀商,不接觸妳的任何資金。 MYFXTOPS不保證客戶盈利,不承擔任何責任。從事外彙和差價合約等金融產品的槓桿交易具有高風險,損失有可能超過本金,請量力而行,入市前需充分了解潛在的風險。過去的交易成績並不代表以後的交易成績。依據各地區法律法規,MyFxtops邁投不向中國大陸、美國、加拿大、朝鮮居民提供服務。

邁投公眾號

聯繫我們

客服QQ:981617007
Email: service@myfxtop.com

MyFxtops 邁投