独立子窗口中的指标:大小与层级
到目前为止,我们仅讨论了在主图表窗口中运行的指标,即使用#property indicator_chart_window指令的指标。现在是时候研究位于价格图表下方独立子窗口中的指标。回顾一下,这类指标应使用 #property indicator_separate_window指令来声明。
我们之前所学的一切同样适用于子窗口指标,具体包括描述和绑定缓冲区、设置绘制类型和样式以及选择使用完整或简化形式的OnCalculate函数。但子窗口指标也有一些特性和额外设置。
由于子窗口有其自身的值刻度,MQL5 允许设置其最大值和最小值(用户也可以在指标设置对话框的Scale选项卡中设置类似限制)。这可以通过以下原型的 IndicatorSetDouble函数实现。
bool IndicatorSetDouble(ENUM_CUSTOMIND_PROPERTY_DOUBLE property, double value)
bool IndicatorSetDouble(ENUM_CUSTOMIND_PROPERTY_DOUBLE property, int modifier,
double value)
该函数用于为指标设置double特性值。需要两种形式的函数,因为某些特性可以是多个值,特别是水平层级(稍后会详细讨论)。可用特性已收集在 ENUM_CUSTOMIND_PROPERTY_DOUBLE 枚举中。
标识符 |
说明 |
---|---|
INDICATOR_MINIMUM |
纵轴最小值 |
INDICATOR_MAXIMUM |
纵轴最大值 |
INDICATOR_LEVELVALUE |
水平层级值(通过 modifier 参数设置数值)。 |
许多振荡指标(如 WPR)使用固定刻度范围。我们将通过示例演示本节涉及的所有函数(特性)。
该函数成功时返回 true,否则返回 false。
正如我们所了解的,除了控制刻度范围以外,子窗口指标还可以设置水平层级。要设置水平层级的数量和特性,需使用另一个函数IndicatorSetInteger。用户可以在指标设置对话框的 Levels选项卡中执行类似操作。
bool IndicatorSetInteger(ENUM_CUSTOMIND_PROPERTY_INTEGER property, int value)
bool IndicatorSetInteger(ENUM_CUSTOMIND_PROPERTY_INTEGER property, int modifier,
int value)
该函数也有两种形式,支持为指标设置 int类型或等效类型(例如color 或枚举值)的特性值。可用特性已收集在 ENUM_CUSTOMIND_PROPERTY_INTEGER 枚举中。除了与水平层级相关的特性外,该枚举还包含对所有类型指标通用的 INDICATOR_DIGITS 特性,我们将在 下一节中介绍。
标识符 |
说明 |
---|---|
INDICATOR_DIGITS |
指标值的显示精度(小数点后的位数) |
INDICATOR_HEIGHT |
指标窗口的固定高度,以像素为单位(预处理命令 #property indicator_height) |
INDICATOR_LEVELS |
指标窗口中水平层级的数量 |
INDICATOR_LEVELCOLOR |
水平层级线条颜色(类型为 color,modifier 参数设置水平层级编号) |
INDICATOR_LEVELSTYLE |
水平层级线条风格(类型为 ENUM_LINE_STYLE,modifier参数设置水平层级编号) |
INDICATOR_LEVELWIDTH |
水平层级线条粗细 (1-5)(modifier参数设置水平层级编号) |
水平层级可以是文本标签。要分配它们,使用 IndicatorSetString函数。
bool IndicatorSetString(ENUM_CUSTOMIND_PROPERTY_STRING property, string value)
bool IndicatorSetString(ENUM_CUSTOMIND_PROPERTY_STRING property, int modifier,
string value)
ENUM_CUSTOMIND_PROPERTY_STRING 包含字符串指标参数列表。需注意 INDICATOR_SHORTNAME 特性,它与水平层级无关:它是所有指标共有的特性,我们将在 下一节中介绍。
标识符 |
说明 |
---|---|
INDICATOR_SHORTNAME |
指标公开名称 |
INDICATOR_LEVELTEXT |
水平层级说明(通过 modifier 指定数值) |
所有 int和 double 数值类型的函数都通过特殊指令复制(下面是汇总表):
水平层级特性的 |
模拟函数 |
特性 |
说明 |
---|---|---|---|
indicator_levelN |
IndicatorSetDouble( |
double |
纵轴上第 N 个水平层级的数值 |
indicator_levelcolor |
IndicatorSetInteger( |
color |
水平层级颜色(不同编号的水平层级需通过函数设置不同颜色) |
indicator_levelwidth |
IndicatorSetInteger( |
int |
水平层级线条粗细,以像素为单位(不同编号的水平层级需通过函数设置不同粗细) |
indicator_levelstyle |
IndicatorSetInteger( |
ENUM |
水平层级线条风格(不同编号的水平层级需通过函数设置不同风格) |
indicator_minimum |
IndicatorSetDouble( |
double |
纵轴固定最小值,刻度下限 |
indicator_maximum |
IndicatorSetDouble( |
double |
纵轴固定最大值,刻度上限 |
请注意,使用 #property指令时,特性实例(修饰符)的编号从 1 开始,而函数中使用的编号从 0 开始。
细心的读者会注意到,某些特性没有对应的指令。T它们包括 INDICATOR_LEVELTEXT、INDICATOR_SHORTNAME、INDICATOR_DIGITS。这些特性应根据输入变量以及指标所依附的图表,通过 MQL 代码动态填充。INDICATOR_LEVELS 可通过为水平层级指定多个指令间接设置。
最后,子窗口指标的标志是程序能够“冻结”其窗口的垂直大小。
子窗口大小的 |
模拟函数 |
说明 |
---|---|---|
indicator_height |
IndicatorSetInteger( |
指标子窗口的固定高度,以像素为单位(用户将无法更改高度) |
固定子窗口高度通常仅用于包含通过 图形对象实现的控件(按钮、标志或输入字段)的控制面板。
遗憾的是,特性设置函数没有对应的反函数(IndicatorGetInteger、IndicatorGetDouble、IndicatorGetString)。除此之外,这还导致无法实现某些功能,例如,当用户修改了水平层级的数量和值时,无法获取这些信息。
作为使用固定刻度和水平层级的示例,我们来看看IndWPR.mq5指标。在该指标中,我们将使用标准的 WPR 算法:在指定的历史柱线(WPR 周期)内,找到价格的最高点 H 和最低点 L(即价格区间)。然后,计算当前价格 C 与最低点 L 的差值 C-L(或差值 -(H-C),带负号)与整个价格区间的比值,并将结果归一化到 0 至 -100 的范围内。下面是计算 WPR 的标准公式:
R% = (-(H C) / (H L)) * 100 |
让我们在源代码开头添加一些指令。除了将指标放置在单独窗口的特性外,我们还将值的范围从 0 设置为 -100。
#property indicator_separate_window
|
一个缓冲区和一个折线图就足以存储数值并显示该指标。
#property indicator_buffers 1
|
在 WPR 指标中,通常会划分出两个水平层级:-20 和-80,分别作为超买区和超卖区的边界。我们来为它们创建一对水平线。
#property indicator_level1 -20.0
|
唯一的输入变量允许你设置 WPR 的计算周期。
input int WPRPeriod = 14; // Period |
缓冲区数组在全局层面声明,并向 OnInit注册。
double WPRBuffer[];
|
OnInit处理程序声明为void 类型,这隐含表示初始化成功。但是,如果周期设置小于 1,则无法进行计算,并会向用户发出警告。
为了简化 OnCalculate函数头,我们准备了适用于指标的头文件 IndCommon.mqh,其中包含两个宏,用于描述两种形式的事件处理程序的标准参数列表。
#define ON_CALCULATE_STD_FULL_PARAM_LIST \
|
现在,我们可以该指标和其他指标中使用简洁的 OnCalculate定义(前提是我们接受宏中提议的参数名称)。
#include <MQL5Book/IndCommon.mqh>
|
在 OnCalculate的开始部分,我们会检查是否可以使用当前的 WPRPeriod 和rates_total 值进行计算。如果数据不足或周期过短,函数将返回 0,这会使指标窗口保持空白。
接下来,我们会用空值填充前几个无法计算给定周期 WPR 的柱线。
int OnCalculate(ON_CALCULATE_STD_FULL_PARAM_LIST)
|
最后,我们执行 WPR 计算并将结果存入缓冲区。注意,每笔分时报价都会更新最后一根柱线:这通过从 prev_calculated - 1开始循环实现。
int OnCalculate(ON_CALCULATE_STD_FULL_PARAM_LIST)
|
ArrayMaximum 和 ArrayMinimum函数允许搜索最高点 high 和最低点 low 的索引。
该指标会显示在一个独立窗口中,如下所示。
WPR 指标
在接下来的章节中,我们将继续完善该指标,逐步添加其他常用特性。