自定义指标的基础知识 | IFCM
IFC Markets 網上CFD經紀商

自定义指标的基础知识

引言

本文的通过举例来解释创建自定义指标的原理, 程序员可以在语言NTL+中开始创建的第一步.


在创建自定义指标时, 您需要确定指标的算法, 如何计算指标缓冲区的值, 并如何显示在屏幕中. 这些值的正确编辑是指标的最终目的


作为创建指标的例子, 将展示大量收盘价大于收盘价的柱图和收盘价小于开盘价的柱图的区别 ; 这些区别在n个区间中积累. 我们将展示该指标以直方图的形式显示在单独的窗口中.


编写脚本代码

我们的算法非常简单并且直观, 可以在图表中轻松查看指标的工作. 对于每个第i个柱图, 我们将分析前n个柱图并形成统计, 如果检测到柱图上升, 则加1, 相反则减1.

img

让我们来看一下指标的代码.


开始需要声明指标用到的所有参数.

#set_indicator_separate
double ExtMapBuffer1[];
int ExtCountedBars=0;
extern int period = 10;

预处理指令#set_indicator_separate指示我们将在单独的窗口中输出图表, 并不在主图表中叠加. 在下一行声明了一个全局数组ExtMapBuffer1, 其中将保存指标缓存区的值. 注意我们不会设置该数组的大小, 因为编辑器自动分配存储器 .


在数组ExtMapBuffer1 中实际保存的是点的坐标值, 数组索引确定横坐标. 之后我们初始化参数ExtCountedBars为0. 该参数将保存已经计算的数量. 因此我们不需要每次都计算所有的柱图, 这大大加快了指标值的计算; 指标图表的运行将更快. 在下一行声明全局变量period , 其用来保存计算设定统计的区间的数量. 注意extern的使用使得我们可以不需要编译通过指标属性直接修改参数.


分析函数Initialize(), 将指定每个指标的基础设置.


int Initialize() { Indicator.SetIndexCount(1); Indicator.SetIndexBuffer(0,ExtMapBuffer1); Indicator.SetIndexStyle(0,ltHistogram,lsSolid,5,clrBlue); return(0); }

Indicator 的对象SetIndexCount 放置指标的值的缓存数量. 带有值的缓存ExtMapBuffer1我们只有一个, 因此指明作为唯一参数为1. 同样我们需要将缓存的号码与带有缓存值的数字联系起来. 该联系将在行SetIndexBuffer(0,ExtMapBuffer1)给出, 在该处定义描述来自缓存ExtMapBuffer1非零指标的属性.


下面一行中, 我们设置指标的属性. SetIndexStyle的第一个参数提供缓冲号; 我们指定SetIndexBuffer值为0. 第二个参数指定渲染类型:柱状图。第三参数指定lsSolid的样式(事实上, 可以设置为任意值, 因此该选项只影响线和宽度)。下一个参数设定clrBlue线宽度5和颜色为蓝色(颜色也可设定为RGB格式, 例如, 0x0000FF).


之后运行函数Run(), 该函数完成基本的检测并执行用户函数draw(). 函数draw() 完成所有计算.


int Run() { ExtCountedBars=Indicator.Calculated; if (ExtCountedBars < 0) { System.Print("Error"); return(-1); } draw(); return(0); }

在全局变量ExtCountedBars 导入柱图数, 该数在最后调用后不会改变. 对于这些值, 我们已经全部计算过, 因此不需要再次计算. 之后, 当ExtCountedBars < 0 , 停止指标的工作. 之后引用函数draw(), 计算数值并将起放置到指标的缓存区.


void draw() { int pos=Chart.Bars-ExtCountedBars-1; int value; while(pos>=0) { value=0; for(int i=pos;i < pos+period && i < Chart.Bars-1;i++) { if(Open[i] < Close[i]) value+=1; else value-=1; } ExtMapBuffer1[pos]=value; pos--; } }

在行«int pos=Chart.Bars-ExtCountedBars-1;» 中确定头寸, 开始计算从旧的数据到新的数据的值. 当总的柱图数量相同, Chart.Bars''最远的''的元素具有指数Chart.Bars-1, 而考虑到已经计算的柱图数: Chart.Bars-ExtCountedBars-1. 参数value 用于收集统计信息. 然后, Chart.Bars-ExtCountedBars - 1至0的循环, 对于每个柱图收集统计不超过period头寸(我们不需要计算未加载数据的值).


收集全部整体代码:


#set_indicator_separate double ExtMapBuffer1[]; int ExtCountedBars=0; extern int period = 10; int Initialize() { Indicator.SetIndexCount(1); Indicator.SetIndexBuffer(0,ExtMapBuffer1); Indicator.SetIndexStyle(0,ltHistogram,lsDot,5,clrBlue); return(0); } int Run() { ExtCountedBars=Indicator.Calculated; if (ExtCountedBars < 0) { System.Print("Error"); return(-1); } draw(); System.Print("ExtCountedBars="+ExtCountedBars); return(0); } void draw() { int pos=Chart.Bars-ExtCountedBars-1; int value; while(pos>=0) { value=0; for(int i=pos;i < pos+period && i < Chart.Bars-1;i++) { if(Open[i] < Close[i]) value+=1; else value-=1; } ExtMapBuffer1[pos]=value; pos--; } }

现在让我们做一个略有改善的指标:负的行会显示一种颜色, 正面的 - 另一种. 与此同时,每种柱体也将具有两种颜色. 对此我们需要建立4个缓冲器。


#set_indicator_separate double ExtMapBuffer1[]; double ExtMapBuffer2[]; double ExtMapBuffer3[]; double ExtMapBuffer4[]; int ExtCountedBars=0; extern int period = 10; int Initialize() { Indicator.SetIndexCount(4); Indicator.SetIndexBuffer(0,ExtMapBuffer1); Indicator.SetIndexStyle(0,ltHistogram,lsDot,5,clrBlue); Indicator.SetIndexBuffer(1,ExtMapBuffer2); Indicator.SetIndexStyle(1,ltHistogram,lsDot,5,clrGreen); Indicator.SetIndexBuffer(2,ExtMapBuffer3); Indicator.SetIndexStyle(2,ltHistogram,lsDot,5,clrRed); Indicator.SetIndexBuffer(3,ExtMapBuffer4); Indicator.SetIndexStyle(3,ltHistogram,lsDot,5,clrLime); return(0); } int Run() { ExtCountedBars=Indicator.Calculated; if (ExtCountedBars < 0) { System.Print("Error"); return(-1); } draw(); return(0); } void draw() { int pos=Chart.Bars-ExtCountedBars-1; int value; while(pos>=0) { value=0; for(int i=pos;i < pos+period && i < Chart.Bars-1;i++) { if(Open[i] < Close[i]) value+=1; else value-=1; } if(value>0) { ExtMapBuffer1[pos]=value; ExtMapBuffer2[pos]=0; ExtMapBuffer3[pos]=1; ExtMapBuffer4[pos]=0; } if(value==0) { ExtMapBuffer1[pos]=0; ExtMapBuffer2[pos]=0; ExtMapBuffer3[pos]=0; ExtMapBuffer4[pos]=0; } if(value < 0) { ExtMapBuffer1[pos]=0; ExtMapBuffer2[pos]=value; ExtMapBuffer3[pos]=0; ExtMapBuffer4[pos]=-1; } } pos--; } }

带有不同颜色柱体的新版本指标:

img

在编写指标代码时, 您可能会看到在''运行函数调用失败消息(run函数调用不成功).这个错误是最有可能是存储值至不存在的指标. 因此, 如果出现这样的消息, 您需要仔细检查缓冲区数组的索引值.


指标

在本文中, 我们详细的创建了第一个指标. 并且实现最大简化NTL+的脚本代码. 为大家提供了一个详细创建指标的实践.

Close support
Call to Skype Call to QQ Call Back