量化软件下载:赫兹量化中开发多交易品种波动指标
现在,我们来看当 prev_calculated 变量等于零时还会使用哪些函数。这些函数会:
加载并生成必要的数据量(柱形);
检查所有句柄的可用性;
检查是否已具备需要的数据量;
与服务器同步数据;
确定从哪个柱开始绘制标图序列。
另外,我们还将确认每个交易品种的首个“真实”柱。我们创造这个简洁的术语是为了方便今后使用。它的意思是,MetaTrader 5 中的所有时间表都是用分钟数据建立的。但是,若服务器能提供自1993 年以来的每日数据,却只能提供 2000 年以来的分钟数据,然后若我们选择小时图时间表,则会自有分钟数据的当日建立柱,也就是从 2000 年起建立柱。2000 年之前的所有东西都会以每日数据或最接近当前时间表数据的形式呈现。因此,为避免混淆,不得显示与当前时间表无关的指标数据。这就是我们为什么要找出当前时间表的第一个“真实”柱,并用与交易品种指标缓冲区颜色相同的垂直线标记这个“真实”柱。
在开发“EA 交易”时,找出“真实”柱同样非常重要,因为如果在某个时间表内对参数进行了优化,则来自其它时间表的数据也将不再适用。
执行上述检查前,我们会在指标子窗口中添加画布。因此,我们首先要编写管理画布需要的所有函数。将画布添加到子窗口前,我们需要确定画布的大小以及文本消息将显示于画布的坐标。为此,我们来编写 GetSubwindowGeometry() 函数:
//+------------------------------------------------------------------+ //| Getting geometry of the indicator subwindow | //+------------------------------------------------------------------+ void GetSubwindowGeometry() { //--- Get the indicator subwindow number subwindow_number=ChartWindowFind(0,subwindow_shortname); //--- Get the subwindow width and height chart_width=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS); subwindow_height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,subwindow_number); //--- Calculate the center of the subwindow subwindow_center_x=chart_width/2; subwindow_center_y=subwindow_height/2; }
获得子窗口属性后,你可以添加画布。画布背景为 100% 透明(不透明度为 0),仅当加载并生成数据从而让用户了解当前进度时才会显露画布。可见时,背景的不透明度为 190。你可以在 0 到 255 之间任意设置不透明度值。更多信息,请参考位于 Help(帮助)选项下的 ColorToARGB() 函数说明。
下面我们编写一个 SetCanvas() 函数来设置画布:
//+------------------------------------------------------------------+ //| Setting canvas | //+------------------------------------------------------------------+ void SetCanvas() { //--- If there is no canvas, set it if(ObjectFind(0,canvas_name)<0) { //--- Create the canvas canvas.CreateBitmapLabel(0,subwindow_number,canvas_name,0,0,chart_width,subwindow_height,clr_format); //--- Make the canvas completely transparent canvas.Erase(ColorToARGB(canvas_background,0)); //--- Redraw the canvas canvas.Update(); } }
我们还需要一个函数,用来检查是否重新调整了指标子窗口的大小。如果调整了指标子窗口大小,则会自动调整画布大小以适应新的子窗口大小。下面我们来调用 OnSubwindowChange()函数:
//+------------------------------------------------------------------+ //| Checking the subwindow size | //+------------------------------------------------------------------+ void OnSubwindowChange() { //--- Get subwindow properties GetSubwindowGeometry(); //--- If the subwindow size has not changed, exit if(!SubwindowSizeChanged()) return; //--- If the subwindow height is less than one pixel or if the center has been calculated incorrectly, exit if(subwindow_height<1 || subwindow_center_y<1) return; //--- Set the new canvas size ResizeCanvas(); //--- Show the last message ShowCanvasMessage(msg_last); }
我们会在下面探讨上述代码中强调的几个函数。请注意在重新调整子窗口大小前运行的检查类型。如果任何属性发生错误,则该函数会停止运算。
SubwindowSizeChanged() 函数代码如下:
//+------------------------------------------------------------------+ //| Checking if the subwindow has been resized | //+------------------------------------------------------------------+ bool SubwindowSizeChanged() { //--- If the subwindow size has not changed, exit if(last_chart_width==chart_width && last_subwindow_height==subwindow_height) return(false); //--- If the size has changed, save it else { last_chart_width=chart_width; last_subwindow_height=subwindow_height; } //--- return(true); }
ResizeCanvas() 函数代码如下:
//+------------------------------------------------------------------+ //| Resizing canvas | //+------------------------------------------------------------------+ void ResizeCanvas() { //--- If the canvas has already been added to the indicator subwindow, set the new size if(ObjectFind(0,canvas_name)==subwindow_number) canvas.Resize(chart_width,subwindow_height); }
}
尝试加载需要的数据量后,我们再一次检查指标句柄。为此,我们使用上述 GetIndicatorHandles() 函数。
句柄检查完毕后,程序会用 CheckAvailableData() 函数检查特定交易品种数据的可用性以及每个交易品种的指标数值。下面请仔细观察整个检查过程:
//+------------------------------------------------------------------+ //| Checking the amount of available data for all symbols | //+------------------------------------------------------------------