缓冲区和图表映射规则
在使用 PlotIndexSetInteger(i, PLOT_DRAW_TYPE, type)注册图表时,每次调用会根据渲染 type 的需求数量,按顺序为第 i 个图表分配一定数量的缓冲区(请参阅 上一节中的 ENUM_DRAW_TYPE 表格)。因此,在将缓冲区链接到后续图表时(在后续调用 PlotIndexSetInteger时),这些已分配的缓冲区将不再参与分配。
例如,如果第一个绘图(索引为 0)是 DRAW_CANDLES,它需要 4 个指标缓冲区,则会精确分配 4 个缓冲区与之关联。因此,索引 0 至 3(含边界值)的缓冲区将被绑定,下一个可供绑定的空闲缓冲区索引为 4。
如果接下来注册一个简单折线图 DRAW_LINE(其在图表序列中的索引为 1),它将仅占用 1 个缓冲区,即索引为 4 的缓冲区。
如果进一步配置一个 DRAW_ZIGZAG 图表(下一个图表索引为 2),由于它需要使用两个缓冲区,因此索引为 5 和 6 的缓冲区将分配给它。
当然,缓冲区数量必须足够满足所有已注册绘图的需求。上述示例在下表中进行了说明。它仅有 7 个缓冲区和 3 个绘图(图表)。
SetIndexBuffer 中的缓冲区索引 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
PlotIndexSetInteger 中的 图表索引 |
0 |
1 |
2 |
||||
渲染类型 |
DRAW_CANDLES |
DRAW |
DRAW_ZIGZAG |
缓冲区索引与图表索引是相互独立的,即缓冲区索引不必与图表索引相同。同时,随着图表索引的递增,绑定到这些图表的缓冲区索引也会递增,如果使用的渲染类型需要占用多个缓冲区,则索引之间的差异会越来越大。
虽然习惯上在调用 PlotIndexSetInteger函数之前先调用SetIndexBuffer 函数,但这并非强制要求。唯一重要的是缓冲区索引与图表索引的正确对应关系。当使用指令(请参阅 下一节)替代调用 PlotIndexSetInteger时,无论如何,指令都会在 OnInit 处理程序之前执行。
为了演示缓冲区索引与图表索引的区别,我们让我们来看一个简单的示例IndHighLowClose.mq5。在该文件中,我们将以 DRAW_HISTOGRAM2 类型直方图的形式绘制每个柱线的 High和 Low 之间的区间,并使用 DRAW_LINE 的简单线条标记Close 价格。要访问不同类型的价格时间序列,我们还需要将 OnCalculate函数的形式从简化版改为完整版。
由于直方图需要 2 个缓冲区,再加上用于 Close线条的缓冲区,我们应该定义三个缓冲区。
#property indicator_chart_window
|
在 OnInit中按优先级顺序注册这些缓冲区。
int OnInit()
|
同时,将直方图的宽度设置为 5 像素,线条宽度设置为 2 像素。未明确指定风格,因此将默认使用 STYLE_SOLID。
现在,让我们来看看实际的 OnCalculate函数。
int OnCalculate(const int rates_total,
|
该指标的效果如下图所示:

高低价直方图与收盘价线
请注意一个重要细节:图表将按照其索引顺序进行绘制,这可能导致某些图表在视觉上位于其他图表的上方(产生重叠)。在这种情况下,首先绘制索引为 0 的直方图,然后在其上方绘制索引为 1 的线条。有时,调整图表的注册顺序是有意义的,这样可以让较小的图形结构获得更好的可见性,因为它们可能会被较大(较宽)的图形覆盖。
沿着假想的 Z 轴(垂直于屏幕、向屏幕纵深方向)设置此类优先级的方式,称为Z 轴顺序。我们在学习 图形对象时再此遇到这种方法。
另外,请记住,指标默认显示在价格图表的上方,但可以通过以下设置更改此行为:Chart Properties对话框 Common 选项卡Chart on foreground 选项。在软件界面中有一个类似选项(ChartSetInteger(CHART_FOREGROUND),请参阅 图表显示模式)。