MQL:引用指标的方式

在MQL中,指标(Indicator)用一个文件组织
对指标的引用归根结底是MQL跨文件组织代码的形式。

对于指标的引用方式与#include这样的文本包含的思路不同,文本包含会造成很多问题,如名字冲突。MQL利用一种类似模块的方式来引用指标。

获取指标引用(句柄)

获取指标引用需要一个叫做iCustom的函数。
我想,这里的“i”应该是指“指标”(Indicator);

iCustom函数具有一个自由的参数列表,但有三个必须指定的参数:品种、周期、指标名。

一个典型的调用是这样的:
int ExtHandle = iCustom(_Symbol, _Period, "AAA.mq5");

它会去引用 Indicators 目录下的 AAA.mq5,即访问文件 Indicators/AAA.mq5

指标参数设定

之前提到的方法并没有指定该指标的参数,即,一切参数使用默认值。但是如果要自定义参数又该如何呢?
iCustom具有一个自由的参数列表,在三个必须指定的参数后面有一个缺省的参数列表,可以指定引用指标的参数,顺序按照指标内 input 的顺序给出。
一旦使用自定义参数,就一定要给出所有的参数,不能出现“部分指派”的形式

我们假定AAA指标需要两个参数,且它们是这样被定义的:

input int a = 1;
input double b = 2.0;

那么在其他的文件里,要这样引用:

int h1 = iCustom(_Symbol, _Peroid, "AAA.mq5"); // 使用默认值: a = 1, b = 2.0;
int h2 = iCustom(_Symbol, _Peroid, "AAA.mq5", 2, 1.0); // 指定 a = 2, b = 1.0;

再给几个反面教材:

int h1 = iCustom(_Symbol, _Peroid, "AAA.mq5", 2); //Error: 不能仅指定 a = 2;
int h2 = iCustom(_Symbol, _Peroid, "AAA.mq5", 1.1, 2.0); // Error: a不是浮点数。

取出数据

在获得指标的引用(句柄)了之后,就可以从中拷贝数据了。
此时需要使用CopyBuffer 函数。

一个指标可以有复数个缓冲区(Buffer),所谓缓冲区也就是变长数组的概念(在MQL中是用链表实现的)。

每一个缓冲区通常代表一条线或者是一个柱子。

例如双线MACD就使用了至少三个缓冲区(DIFF、DMA、MACD)。
布林线也使用了三个缓冲区(Upper,Middle,Lower)。

所以——一个指标引用中可以取出多个数组的数据,在CopyBuffer的时候需要指定从几号缓冲区中取数据。

那么,怎么知道要取得数据在几号缓冲区呢?如果是别人写的指标,直接看指标自带的文档,上面通常会有;如果是自己写的……
是用SetIndexBuffer 函数绑定缓冲区的……还记得你做过类似的事情吗……

SetIndexBuffer(0, DIFFBuffer, INDICATOR_DATA);
SetIndexBuffer(1, DMABuffer, INDICATOR_DATA);
SetIndexBuffer(2, MACDBuffer, INDICATOR_DATA);

没错,设定索引,这本质就是模块导出的一种实现。

类比 CommonJS 的 module.exports 规范。
注意:Buffer都是double数组。

在设定索引之后,外界就可以对这个数据进行引用了。

引用的例子,比如:

int MACDHandle = iCustom(_Symbol, _Period, "MACD.mq5"); // 获取指标引用
double diff[2]; // 定义数组。
CopyBuffer(MACDHandle, 0, 0, 2, diff); // 将MACD指标中的0号缓冲(DIFF)从0号位置(最新的数据),拷贝2个数据到diff数组 

注意,缓冲区是时间逆序的,即最新的数据会在0号位置。而数组中的数据却是时间正序的。
若DIFF指标的最新的数据是a,次新的数据是b;则拷贝到数组diff中,有diff[0] = b, diff[1] = a;

经过封装的指标引用函数

MQL中有一堆经过封装的,以小写i 开头的函数,具有跟iCustom类似的功能,例如iMA, iMACD, iBands 等,它们的参数就不一定是之前提过的“3+N”模式了,具体的要查文档。但之后如何从中取出数据却是如出一辙。

你可能感兴趣的:(指标,mql)