量化软件下载:在赫兹量化中标准库和重用代码
正如我在本文简介部分中所述,我们在构建用于包装之前下载的峰谷指标的新的类组时受到 的面向对象风格的启发。这很简单,我们只需看一看 Include\Indicators 中的文件,学习和理解 MQL5 标准库背后的某些理念。当您查看 文件中的内容时,您很快会发现里面全是代表某些技术指标的类:ADX、布林带、SAR、移动平均线等。所有这些类都继承自 CIndicatr。那么,让我们来实现这个方案。顺便一提,从 MQL5 的类 CiCustom 扩展新的面向对象指标是实现此练习的另一个备选方案。
我将在下文中讨论一些编码所需的技术。
//+------------------------------------------------------------------+ //| Include\Indicators\Custom\Trend.mqh | //| Copyright 2013, Laplacianlab - Jordi Bassagañas | //| https://www.mql5.com/en/users/laplacianlab | //+------------------------------------------------------------------+ #include <..\Include\Indicators\Indicator.mqh> //+------------------------------------------------------------------+ //| Class CiZigZag. | //| Purpose: Class of the "ZigZag" indicator. | //| Derives from class CIndicator. | //+------------------------------------------------------------------+ class CiZigZag : public CIndicator { protected: int m_depth; int m_deviation; int m_backstep; public: CiZigZag(void); ~CiZigZag(void); //--- methods of access to protected data int Depth(void) const { return(m_depth); } int Deviation(void) const { return(m_deviation); } int Backstep(void) const { return(m_backstep); } //--- method of creation bool Create(const string symbol,const ENUM_TIMEFRAMES period, const int depth,const int deviation_create,const int backstep); //--- methods of access to indicator data double ZigZag(const int index) const; double High(const int index) const; double Low(const int index) const; //--- method of identifying virtual int Type(void) const { return(IND_CUSTOM); } protected: //--- methods of tuning virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]); bool Initialize(const string symbol,const ENUM_TIMEFRAMES period, const int depth,const int deviation_init,const int backstep); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CiZigZag::CiZigZag(void) : m_depth(-1), m_deviation(-1), m_backstep(-1) { } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CiZigZag::~CiZigZag(void) { } //+------------------------------------------------------------------+ //| Create indicator "Zig Zag" | //+------------------------------------------------------------------+ bool CiZigZag::Create(const string symbol,const ENUM_TIMEFRAMES period, const int depth,const int deviation_create,const int backstep) { //--- check history if(!SetSymbolPeriod(symbol,period)) return(false); //--- create m_handle=iCustom(symbol,period,"zigzag",depth,deviation_create,backstep); //--- check result if(m_handle==INVALID_HANDLE) return(false); //--- indicator successfully created if(!Initialize(symbol,period,depth,deviation_create,backstep)) { //--- initialization failed IndicatorRelease(m_handle); m_handle=INVALID_HANDLE; return(false); } //--- ok return(true); } //+------------------------------------------------------------------+ //| Initialize the indicator with universal parameters | //+------------------------------------------------------------------+ bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]) { return(Initialize(symbol,period,(int)params[0].integer_value,(int)params[1].integer_value,(int)params[2].integer_value)); } //+------------------------------------------------------------------+ //| Initialize indicator with the special parameters | //+------------------------------------------------------------------+ bool CiZigZag::Initialize(const string symbol,const ENUM_TIMEFRAMES period, const int depth,const int deviation_init,const int backstep) { if(CreateBuffers(symbol,period,3)) { //--- string of status of drawing m_name ="ZigZag"; m_status="("+symbol+","+PeriodDescription()+","+ IntegerToString(depth)+","+IntegerToString(deviation_init)+","+ IntegerToString(backstep)+") H="+IntegerToString(m_handle); //--- save settings m_depth=depth; m_deviation=deviation_init; m_backstep=backstep; //--- create buffers ((CIndicatorBuffer*)At(0)).Name("ZIGZAG"); ((CIndicatorBuffer*)At(1)).Name("HIGH"); ((CIndicatorBuffer*)At(2)).Name("LOW"); //--- ok return(true); } //--- error return(false); } //+------------------------------------------------------------------+ //| Access to ZigZag buffer of "Zig Zag" | //+------------------------------------------------------------------+ double CiZigZag::ZigZag(const int index) const { CIndicatorBuffer *buffer=At(0); //--- check if(buffer==NULL) return(EMPTY_VALUE); //--- return(buffer.At(index)); } //+------------------------------------------------------------------+ //| Access to High buffer of "Zig Zag" | //+------------------------------------------------------------------+ double CiZigZag::High(const int index) const { CIndicatorBuffer *buffer=At(1); //--- check if(buffer==NULL) return(EMPTY_VALUE); //--- return(buffer.At(index)); } //+------------------------------------------------------------------+ //| Access to Low buffer of "Zig Zag" | //+------------------------------------------------------------------+ double CiZigZag::Low(const int index) const { CIndicatorBuffer *buffer=At(2); //--- check if(buffer==NULL) return(EMPTY_VALUE); //--- return(buffer.At(index)); } //+------------------------------------------------------------------+
3.1. 面向对象封装
面向对象封装是一个良好的编程实践,意味着对象的数据成员只能由为其定义的操作所修改。所有在 MetaQuotes 的 中定义的类均实施此理念,所以我们也在做着同样的事情。
一方面是 CiZigZag 的特定受保护属性:
protected: int m_depth; int m_deviation; int m_backstep;
其后是 CiZigZag 的公共接口,用于从 CiZigZag 类型的给定对象的外部访问上文中定义的受保护属性:
public: //--- methods of access to protected data int Depth(void) const { return(m_depth); } int Deviation(void) const { return(m_deviation); } int Backstep(void) const { return(m_backstep); }
这是用于隔离对象的一个安全措施。此封装防止不允许访问对象数据的人或物对数据进行的任意修改。
3.2. 访问峰谷指标的数据
正如本文的第一节所述,名为 zigzag.mq5 的源代码文件创建了三个缓冲区:
//--- indicator buffers mapping SetIndexBuffer(0,ZigzagBuffer,INDICATOR_DATA); SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS);