MQL4 里 EA 和指标编程架构基本的异同点

楼主  收藏   举报   帖子创建时间:  2019-05-05 05:30 回复:0 关注量:616
对编写 MT4 EA 或指标的交易者而言, 把自己的交易思维写成程序外, 最根本还是需要了解这两种在 MQL4 语言里的架构异同, 和每个公用函数被调用的原理, 这样当有错误时, 调试时才容易知道问题出在那里.

在 MQL4 一个指标的基本架构依序为:

1. input 可以外部改变的参数

2. 全局参数

3. int onInit() - 程序初始化, 一般是设定画线等的 array 数组的类别等

4. void onDeinit(const int reason) - 程序退出的动作, 指标删除改变周期或改变外部设定参数都会先作退出工作, 一般是把原来指标画的文字或趋势线或标签这类的 objects 给删除, 或把 Comment(...) 写的字用 Comment("") 给移除, 不然指标删除后这些 objects 或 comment 文字或趋势线等还会留在图表上

退出时 MT4 会给 reason 值, 在 MQL4 文档网站上可以查到表, 可以细分到那些特别状况作不同的退出功能.

5. int onCalculate(...) 这是指标的主体, 在 MT4 build 600 前是用 start(), 会改为 On 开头表示 MT4 把 MT5 的 onXXXX 系列的函数观念引进过来, 代表为事件驱动, 在指标里的 onCalculate(...) 表示当价格有变动时就会驱动来触发这个函数.

如果当图表商品在休市时没有价格跳动想作特殊的功能, 如之前设计的每几分钟自动截取新闻或经济数据网站, 这时就不是用 onCalculate 而是用另一个定时器功能 onTimer() 函数来驱动. 另外新版 MT4 还提供另一个有用的 onChartEvent() 函数, 在图表上作了按键鼠标点击等动作也能触发 onChartEvent() 来作相应的处理, 之前用这个功能来作检测按键或鼠标点击来作强制新闻更新或看下一日经济数据表等, 也利用这个功能来自动检测有新的趋势线 objects 加到图表来作趋势线突破 EA 处理等好用的功能. 总体来说新版的 MT4 比旧版多的功能让指标和 EA 设计的范围变大许多.


再看看 EA 的架构:

(1) & (2) & (3) & (4) 都是一样的, 只差别 EA 用了 onTick() (在旧版也是用 start()).

onTick() 和指标 onCalculate() 一样, 都是图表商品的价格有变动才会驱动, 但最大的差别是, 在指标挂到图表作初始化时, 除了 onInit() 会被调用, onCalculat() 就算没有价格跳动也会被调用第一次, 但 EA 的 onTick() 就一定要等到有价格跳动才会被调用.

接下来来看一基本上在绝大部分指标都会出现的很典型写法:

      int limit, i;
      int counted_bars=IndicatorCounted();
      if(counted_bars>0) counted_bars--;
      limit=Bars-counted_bars;

      for (i=0;i<limit;i++)

      {  //.... 指标计算程序内容.....
      }


这个的目的就是在第一次 onCalculate() 被调用时 (也就是指标被挂到图表时), i 会对 k 棒 index = 0 也就是最新的那根 k 棒计算到 limit = Bars (即全部图表上的 k 棒, Bars 就是全部 k 棒数量的值), 因为第一次调用时 IndicatorCounted() 返回值是零, 第二次才是返回已经计算过的 k 棒数量.

当第二次被调用时, limit 就变成了 2 (因为 counted_bar 多作了个 -- 动作, 让 limit 为 2), 也就是 for-loop 变成了 for (i=0;i<2;i++), 指标也将只对 i=0, i=1 作两次计算, 对过去所有的 k 棒就不再重复计算, 这是减低系统复荷的写法, 如果你不在乎, 也可以一直都是用 for (i=0;i小于Bars;i++)

想观察这样的关系, 最快的方法就是在程序内加一行参数输出, 到 log 那里看实际的变化:

Print("Bars: ",Bars," IndicatorCounted(): ",IndicatorCounted()," limit: ", limit);

既然指标和 EA 的 onCalculate() vs onTick() 都是被价格跳动驱动, 如果懒的另外作 EA, 同样可以在指标内把 EA 的通知提示功能都作了,也就是在指标计算完后, 对于最新的价格 Close[0] 与其他指标条件符合时作通知型的窗口声音或电邮通知等.

但指标无法作交易功能,因为 MT4 会拒绝执行从指标发出交易行为,MT4 只接受 EA 和 脚本发出的交易动作.


同样的, 在设计 EA 时如果想作点指标计算的事, 也是可以的, 但因为 onTick() 在挂到图表上不作第一次, 所以把主体功能写到另一函数, 在 onInit() 开始时就调用一次就可以达成指标的行为,如下面简单范例。但 EA 无法画出正常指标图形,只能够调用图形类的 objects 如显示字符号线段等等来表示当前的指标状态。

如:

onInit() {

DoSomething();
}

onTick() {
DoSomething();
}

void DoSomething(){
///功能写在这里
}


而 script 脚本也同样可以作到像 EA 或指标一样, 只要设计成无限循环让 script 不要只执行一次即可, MQL4 官方写的 PeriodConvertr script 转换图表周期的 script 就是这样写的, 不过 script 最多的用途还是用来快速平仓等下单功能, 或一次性的统计数据作 log 功能.

打赏