【零基础】MT4量化入门三:写一个双均线指标

一、前言

  原本已经放弃的,但因为一些需要又写了一个MT4的指标,所以这里就继续总结一下为后来人铺路。

  现在发现除了用C语言、不好使的公用函数外,MT4写指标或者EA其实难度都不大,就是很多地方超出你的预计很难受。

  这里我写一个双均线的指标,逻辑就是一个均线用最大值MA(HMA),另一个均线用最小值的MA(LMA),当最新值下穿HMA做空,上穿LMA做多,跟BOLL的逻辑有点像。由于自带函数不好使,所以这里我自己还写了一些功能函数。

二、新建一个指标

  在MT4里,指标与EA是有点区别的,具体区别后面再说,这里先新建一个指标。

  1)在MQ编辑窗口中:文件->新建

 

  2)选“自定义指标”->下一步

  3)指标命名成“DMA”。

  这里的参数就是指标启动时可以修改的参数,这里我们不添加参数,在代码里可以手写。

 

   4)默认就只要个OnCalculate(),意思是每当有一个行情更新就触发执行一次这个函数。继续下一步。

 

   5)这里的“独立窗口指标”,意思是这个指标在副图绘制,如果不勾选就在K线图(主图)上绘制,我们这个是在主图绘制的,自然是不勾选了,而且代码里也是可以修改的。

  另外,这里可以提前设置你需要绘制的指标线颜色和类型,一共也就那么几种,我也是在代码里设置,不在这里添加。继续下一步。

 

   6)一个全新的指标就建好了。所有的指标文件都在Indicators目录中。

 

 

三、基本说明

  在看到MT4这一简短的初始代码时,当然会有点懵的,其实逻辑不复杂。每当有一个bar来到时,就触发一下OnCalculate()这个函数,同时这个函数使用参数传递了你可能会需要的一些资源。

  rates_total:当前累计有多少个bar

  prev_calculated:上一次处理到第几个bar

  time:当前bar的时间

  open:bar开盘价

  high:bar最高价

  low:bar最低价

  close:bar收盘价

  那么整个运行逻辑是怎样的呢?

  1)第一次触发OnCalculate()时,其实是处理历史数据,比如1000个bar,那么rates_total=1000。但是prev_calculated=0,因为还没有处理过数据。需要注意历史数据就触发一次,后面再触发就是最新数据了。

  2)第二次触发OnCalculate()时,我们晓得是收到最新数据了,rates_total=1001,而prev_calculated=1000。

  3)如果你觉得第三次触发时,是收到新的bar,那你就太天真了,第三次触发时rates_total=1001,而prev_calculated=1001。这是为什么呢?因为一个bar是会多次触发OnCalculate()的。比如你的K线周期设置为1分钟,那么一个bar的成型可能需要十次或数十次数据更新,因为最新价是一直在变得啊,所以触发OnCalculate()大概率是bar的最新价更新了,不一定是有了新的bar。

四、代码的基本结构

  1)历史数据和即时数据的区分处理

  综合前面的说明,我们需要建立一个基本结构,分别来处理历史数据和最新数据。官方自带的示例呢就有点复杂,让人看不明白,这里我就用非常简单的办法来判断历史数据和最新数据。

 

  有了基本代码结构,下面就该处理数据了,但是在处理数据前还有个问题要解决,那就是怎么绘制指标线和买卖信号。

  2)指标线和买卖信号绘制

  在MT4绘制指标和买卖信号是一回事,只是显示方式不同。完成这个过程需要做四步工作:

  第一步:声明当前存在的指标线和买卖信号。需要注意指标线是line,而买卖信号是arrow

 

  第二步:声明数据缓存容器

 

  第三步:为容器分配buffer,注意顺序,其次这里还对买入和卖出的arrow类型做了指定

   第四步:向对应的buffer中存入数值即可绘制指标线和买卖箭头,这一步在后面操作。

  3)中间数据的缓存

  在指标的计算中,往往还存在中间数据的保存,在MT4里面如果不晓得这个小技巧的话,中间数据存取会很让人崩溃(亲身经历)。

 

  增加存数据的buffer

 

 

 

   分配内存,要注意buffer的数量由4变为6

 

 

四、处理历史数据

  逻辑是简单的:

  1)从high中取30个周期内的最大值做为highest

  2)在highest的基础上求MA5

  3)从low中取30个周期内的最小值作为lowest

  4)在lowest的基础上求MA5

  5)close上穿lowest的MA5则做多,下穿highest的MA5做空

  6)所以将lowest的MA5称为支撑线,highest的MA5称为压力线

  代码不多:

 

   这里需要注意的就是,在MT4中,数据在数组中是反着放的,比如现在有1000个数据,最新数据是close[0],而不是close[999]。所以你看到我这里处理历史数据是反序处理的,同时功能函数也都是反序处理的。

  那么可否转成正序呢,是可以的,有个自带的函数可以做,不过因为我在发现这个函数前就把功能函数都做好了,也懒得改了。

五、处理即时数据

  直接上代码。可以看到即时数据处理跟历史数据是一样的,只是将i全部改成了0。

 

六、回顾

  在写MT4指标时,最痛苦莫过于所有数据在数组里都是反序的,折腾了好久才明白。结果很快又发现一个函数可以把反序转成正序,痛苦啊。

  然后你可能会注意到,这里使用数组是不需要按顺序添加数据,甚至还可以间隔着填数据进去。这是咋回事呢?我也不知道,可能为了方便使用吧,结果我一开始按C语言那样使用动态数组来存储中间数据,可把我折腾了半天。

  MT4在外汇领域称霸很年了,我感觉该有一款用python编程的国产平台来取代它才对。

  文中代码可以关注公众号“零基础爱学习”回复“MT2”获取。

 

 

 

  

 

posted @ 2020-05-09 22:53  布兰姥爷  阅读(2527)  评论(0编辑  收藏  举报