量化软件:在赫兹量化中视图内/外绘制通道
设置极值
事实上,通道在图表上的位置需通过至少三个极值确定。如果要给极值下个定义,我们认为是:它是函数在指定范围的最大或最小值。达到极值的点称为极值点。相应地,如果达到的是最小值,则该极值点称为最小值点,反之为最大值点。
数学分析定义了另一个术语:局部极值(包括最小值和最大值)。在最大(最小)值点,函数值大于(小于)所有相邻点的值。该定义出自维基百科(译自俄语)。
为绘制通道,我们需要局部极值。让我们通过图表来显示局部极值,无需使用数学公式。在下面的图 1 中,有三个用红色价格水平标示的局部极值。矩形点显示了两个最大值和一个最小值:

编辑
图 1. 局部极值示例
不是所有存在的极值都在图表上标示了出来,仅仅标识那些最重要的。对于烛形图或条形图,使用“分形”术语定义极值十分方便 - 当向左或向右的多个相邻柱严格递减或递增时(请参见图 1)。
由于我们的目的不是建立自动的通道绘制工具,则极值位置将按照图 1 所示进行设置 - 按照时间轴和价格轴上的位置。最适于该目的的是价格标签 -赫兹量化软件客户端的特殊图形对象。价格标签具有时间和价格坐标属性,可以明确地识别图表上的极值。
存储极值的对象 - TExtremum 类
我们首先要做的是建立存储极值的容器类和操作极值组的类。由于我们要尽可能地使用终端中包含的标准类,TExtremum 类将继承自标准类 CObject。类的描述如下所示:
class TExtremum : public CObject { private: datetime extr_datetime; // data/time in an extremum point double extr_price; // price in an extremum point protected: virtual int Compare(const CObject* _node, int _mode = 0) const; public: void TExtremum(); // constructor void ~TExtremum(); // destructor void SetExtremum(datetime _time, double _price); // change date/time and price in an extremum point void SetDateTime(datetime _time); // change date/time in an extremum point void SetPrice(double _price); // change price in an extremum point public: datetime GetDateTime() const; // get date/time in an extremum point double GetPrice() const; // get price in an extremum point public: virtual bool SaveExtremum(string _dt_name, string _p_name); // save extremum virtual bool LoadExtremum(string _dt_name, string _p_name); // load extremum virtual bool DeleteExtremum(string _dt_name, string _p_name);// delete extremum };
大部分方法都是无关紧要的,无需关注它们的实施情况。我们应该关注的是 TExtremum::Compare 方法。该方法在 CObject 类中声明,用于在列表中排序。我们按以下方式实施:
//--------------------------------------------------------------------- // Comparing two extremums by time: //--------------------------------------------------------------------- int TExtremum::Compare(const CObject* _node, int _mode = 0) const { datetime temp = ((TExtremum* )_node).GetDateTime(); datetime curr = GetDateTime(); if(curr > temp) { return(_mode > 0 ? 1 : -1); } else if(curr < temp) { return(_mode > 0 ? -1 : 1); } return(0); }
此处的参数 _mode 用于设置排序方向。如果此参数的值大于零,则排序是正向的(升序),反之为逆向(降序)。
此外,还有两个方法用于保存/加载极值。我们将极值存储在全局变量中。这些方法如下所示:
//--------------------------------------------------------------------- // Save extremum (date/time): //--------------------------------------------------------------------- bool TExtremum::SaveExtremum(string _dt_name, string _p_name) { datetime dt_result = GlobalVariableSet(_dt_name, (double)extr_datetime); datetime p_result = GlobalVariableSet(_p_name, (double) extr_price); if(dt_result != 0 && p_result != 0) { return(true); } return(false); } //--------------------------------------------------------------------- // Load extremum (date/time): //--------------------------------------------------------------------- bool TExtremum::LoadExtremum(string _dt_name, string _p_name) { double dt_temp, p_temp; bool result = GlobalVariableGet(_dt_name, dt_temp); result &= GlobalVariableGet(_p_name, p_temp); if(result != false) { extr_datetime = (datetime)dt_temp; extr_price = p_temp; return(true); } return(false); }
在全局变量读/写的两个方法 TExtremum::LoadExtremum 和 TExtremum::SaveExtremum在成功执行后返回 "true"。
操作极值列表 - TExtremumList 类
由于我们需要按时间存储和排序极值,我们需要从标准类 CList 继承 TExtremumList 类。通过这种继承,我们得到极值的一个通用操控工具,从而不必受限于极值的数量和类型。这可以进一步扩展绘制的通道数量。例如,如果多个极值非线性回归,我们可以增加通道的绘制。
该类的说明如下所示:
class TExtremumList : public CList { private: string channel_prefix; // channel name (prefix) ENUM_TIMEFRAMES chart_timeframe; // current timeframe string chart_symbol; // work symbols of the chart protected: string MakeDTimeName(int _nmb); // get name for saving/reading data/time of an extremum string MakePriceName(int _nmb); // get name for saving/reading price of an extremum public: void TExtremumList(); // конструктор void ~TExtremumList(); // деструктор void SetChannelParams(string _pref, string _symbol = NULL, ENUM_TIMEFRAMES _curr_tf = PERIOD_CURRENT); void AddExtremum(datetime _time, double _price); void DeleteAllExtremum(); void SaveExtremumList(); void LoadExtremumList(); int FindExtremum(datetime _dt); // search extremum by specified time public: datetime GetDateTime(int _index); double GetPrice(int _index); };
TExtremumList::AddExtremum 是类的主方法。它用于向列表中添加新的极值。添加后,列表中极值的排序根据极值点时间进行。该方法的代码如下所示: