• 【零基础】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”获取。

      

  • 相关阅读:
    python入门-数据类型
    jmeter进行简单性能测试
    Charles抓包工具
    jemter分布式部署及linux下分布式脚本执行
    Java-List
    重载
    static关键字
    pycharm问题
    charles安装使用及问题
    安装pipenv
  • 原文地址:https://www.cnblogs.com/cation/p/12855684.html
Copyright © 2020-2023  润新知