DoEasy库中的价格(第59部分):存储一跳数据的对象

2021年2月2日,11:53
Artyom Trishkin
0
3 349

目录


概念

从本文开始,开始开发库功能以使用刻度数据。

滴答数据的存储和使用概念将类似于 时间序列数据存储的概念 最小数据单位是小节。条形对象存储在属于相应时间范围的列表中,而相应的时间范围又存储在属于符号的列表中。

在滴答数据存储的概念中,数据量的最小单位应为一滴答的价格结构值。通过使用以下结构描述这些值 通过符号存储最新价格 MqlTick。存储此类值的对象将具有其他属性:点差-卖出价和买价的差额以及该对象描述其价格变动数据的交易品种的符号。

为了更方便地进行列表结构化,将为每个符号创建带有刻度数据的对象自己的列表。当然,滴答数据对象的每个列表都会自动更新,新传入的滴答的新数据将添加到其中。同时,库用户确定的卷中将支持列表的大小。

库中数据存储的概念提供了按列表中存储的任何对象属性进行搜索和排序的功能,从而可以接收所需的数据以供后续使用或进行分析研究。因此,报价数据将具有相同的功能。这将使用户能够快速分析报价数据流以进行跟踪;例如,发生的性质发生任何变化,或搜索设置的模式等。


准备资料

与任何库对象一样,必须添加文本消息以显示其参数的描述并创建对象属性的枚举,从而可以在列表中进行搜索或按这些属性对对象进行排序。

在文件\ MQL5 \ Include \ DoEasy \数据量 添加新的消息索引:

//--- CSeriesDataInd
   MSG_LIB_TEXT_METHOD_NOT_FOR_INDICATORS,            // The method is not intended to work with indicator programs
   MSG_LIB_TEXT_IND_DATA_FAILED_GET_SERIES_DATA,      // Failed to get indicator data timeseries
   MSG_LIB_TEXT_IND_DATA_FAILED_GET_CURRENT_DATA,     // Failed to get current data of indicator buffer
   MSG_LIB_SYS_FAILED_CREATE_IND_DATA_OBJ,            // Failed to create indicator data object
   MSG_LIB_TEXT_IND_DATA_FAILED_ADD_TO_LIST,          // Failed to add indicator data object to list
   
//--- CTick
   MSG_TICK_TEXT_TICK,                                // Tick
   MSG_TICK_TIME_MSC,                                 // Time of the last update of prices in milliseconds
   MSG_TICK_TIME,                                     // Time of the last update of prices
   MSG_TICK_VOLUME,                                   // Volume for the current Last price
   MSG_TICK_FLAGS,                                    // Flags
   MSG_TICK_VOLUME_REAL,                              // Volume for the current Last price with greater accuracy
   MSG_TICK_SPREAD,                                   // Spread
   MSG_LIB_TEXT_TICK_CHANGED_DATA,                    // Changed data on tick:
   MSG_LIB_TEXT_TICK_FLAG_BID,                        // Bid price change
   MSG_LIB_TEXT_TICK_FLAG_ASK,                        // Ask price change
   MSG_LIB_TEXT_TICK_FLAG_LAST,                       // Last deal price change
   MSG_LIB_TEXT_TICK_FLAG_VOLUME,                     // Volume change

  };
//+------------------------------------------------------------------+

讯息文字 对应于新添加的索引:

//--- CSeriesDataInd
   {"The method is not intended for working with indicator programs"},
   {"Failed to get indicator data timeseries"},
   {"Failed to get the current data of the indicator buffer"},
   {"Failed to create indicator data object"},
   {"Failed to add indicator data object to the list"},
   
//--- CTick
   {"Tick"},
   {"Last price update time in milliseconds"},
   {"Last price update time"},
   {"Volume for the current Last price"},
   {"Flags"},
   {"Volume for the current \"Last\" price with increased accuracy"},
   {"Spread"},
   {"Changed data on a tick:"},
   {"Bid price change"},
   {"Ask price change"},
   {"Last price change"},
   {"Volume change"},
   
  };
//+---------------------------------------------------------------------+


在\ MQL5 \ Include \ DoEasy \Defines.mqh 文件添加枚举,用于指定 整数, 真实 报价数据对象的属性:

//+------------------------------------------------------------------+
//| Data for working with tick data                                  |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Tick integer properties                                          |
//+------------------------------------------------------------------+
enum ENUM_TICK_PROP_INTEGER
  {
   TICK_PROP_TIME_MSC = 0,                                  // Time of the last price update in milliseconds
   TICK_PROP_TIME,                                          // Time of the last update
   TICK_PROP_VOLUME,                                        // Volume for the current Last price
   TICK_PROP_FLAGS,                                         // Tick flags
  }; 
#define TICK_PROP_INTEGER_TOTAL (4)                         // Total number of tick integer properties
#define TICK_PROP_INTEGER_SKIP  (0)                         // Number of tick properties not used in sorting
//+------------------------------------------------------------------+
//| Real tick properties                                             |
//+------------------------------------------------------------------+
enum ENUM_TICK_PROP_DOUBLE
  {
   TICK_PROP_BID = TICK_PROP_INTEGER_TOTAL,                 // Tick Bid price
   TICK_PROP_ASK,                                           // Tick Ask price
   TICK_PROP_LAST,                                          // Current price of the last trade (Last)
   TICK_PROP_VOLUME_REAL,                                   // Volume for the current Last price with greater accuracy
   TICK_PROP_SPREAD,                                        // Tick spread (Ask - Bid)
  }; 
#define TICK_PROP_DOUBLE_TOTAL  (5)                         // Total number of real tick properties
#define TICK_PROP_DOUBLE_SKIP   (0)                         // Number of tick properties not used in sorting
//+------------------------------------------------------------------+
//| String tick properties                                           |
//+------------------------------------------------------------------+
enum ENUM_TICK_PROP_STRING
  {
   TICK_PROP_SYMBOL = (TICK_PROP_INTEGER_TOTAL+TICK_PROP_DOUBLE_TOTAL), // Tick symbol
  };
#define TICK_PROP_STRING_TOTAL  (1)                         // Total number of string tick properties
//+------------------------------------------------------------------+

为每个枚举指定属性的总数 用过的未使用 in sorting.

为了通过上述指定的属性启用搜索和排序,请添加另一个枚举,其中将指定滴答数据排序的可能标准:

//+------------------------------------------------------------------+
//| Possible tick sorting criteria                                   |
//+------------------------------------------------------------------+
#define FIRST_TICK_DBL_PROP          (TICK_PROP_INTEGER_TOTAL-TICK_PROP_INTEGER_SKIP)
#define FIRST_TICK_STR_PROP          (TICK_PROP_INTEGER_TOTAL-TICK_PROP_INTEGER_SKIP+TICK_PROP_DOUBLE_TOTAL-TICK_PROP_DOUBLE_SKIP)
enum ENUM_SORT_TICK_MODE
  {
//--- Sort by integer properties
   SORT_BY_TICK_TIME_MSC = 0,                               // Sort by the time of the last price update in milliseconds
   SORT_BY_TICK_TIM,                                        // Sort by the time of the last price update
   SORT_BY_TICK_VOLUME,                                     // Sort by volume for the current Last price
   SORT_BY_TICK_FLAGS,                                      // Sort by tick flags
//--- Sort by real properties
   SORT_BY_TICK_BID = FIRST_TICK_DBL_PROP,                  // Sort by tick Bid price
   SORT_BY_TICK_ASK,                                        // Sort by tick Ask price
   SORT_BY_TICK_LAST,                                       // Sort by current price of the last trade (Last)
   SORT_BY_TICK_VOLUME_REAL,                                // Sort by volume for the current Last price with greater accuracy
   SORT_BY_TICK_SPREAD,                                     // Sort by tick spread
//--- Sort by string properties
   SORT_BY_TICK_SYMBOL = FIRST_TICK_STR_PROP,               // Sort by tick symbol
  };
//+------------------------------------------------------------------+


之前,我们已经创建了 第38条中的“新刻度”对象 这可以跟踪新的滴答声到达指定交易品种。
该对象位于\ MQL5 \ Include \ DoEasy \ Objects \cks虫\ 文件中库目录的文件夹 NewTickObj.mqh.
改进对象类,以便 空值 值(或空字符串)可以传递到用于为对象指定当前符号的符号设置方法:

//--- Set a symbol
   void              SetSymbol(const  symbol)   { this.m_symbol=(symbol==空值 || symbol=="" ? ::Symbol() : symbol);  }

并在类构造函数的初始化列表中 的价值 m_new_tick 存储新的刻度标记的变量:

//+------------------------------------------------------------------+
//| Parametric constructor CNewTickObj                               |
//+------------------------------------------------------------------+
CNewTickObj::CNewTickObj(const  symbol) : m_symbol(symbol),m_new_tick()
  {
//--- Reset the structures of the new and previous ticks
   ::ZeroMemory(this.m_tick);
   ::ZeroMemory(this.m_tick_prev);
//--- If managed to get the current prices to the tick structure -
//--- copy data of the obtained tick to the previous tick data and reset the first launch flag
  if(::SymbolInfoTick(this.m_symbol,this.m_tick))
     { 
      this.m_tick_prev=this.m_tick;
      this.m_first_start=;
     }
  }
//+------------------------------------------------------------------+

在此之前,此变量未在任何地方通过初始值初始化。这是不正确的。


刻度数据对象类

在“新刻度”对象的类位置文件夹中\ MQL5 \ Include \ DoEasy \ Objects \cks虫\ 创建一个新的滴答数据对象类文件 数据提示.

该对象对于库类而言不是什么新东西。一切都是标准的。让我们分析一下课堂内容:

//+------------------------------------------------------------------+
//|                                                     DataTick.mqh |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                             //tbxfkj.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property 链接      "//tbxfkj.com/ru/users/artmedia70"
#property version   "1.00"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "..\BaseObj.mqh"
#include "..\..\Services\DELib.mqh"
//+------------------------------------------------------------------+
//| “Tick” class                                                     |
//+------------------------------------------------------------------+
class CDataTick : public CBaseObj
  {
private:
   MqlTick           m_tick;                                      // Structure for obtaining current prices
   int               m_digits;                                    // Symbol's digits value
   long              m_long_prop[TICK_PROP_INTEGER_TOTAL];        // Integer properties
   double            m_double_prop[TICK_PROP_DOUBLE_TOTAL];       // Real properties
               m_string_prop[TICK_PROP_STRING_TOTAL];       // String properties

//--- Return the index of the array the tick’s (1) double and (2) string properties are actually located at
   int               IndexProp(ENUM_TICK_PROP_DOUBLE property)       const { return(int)property-TICK_PROP_INTEGER_TOTAL;                       }
   int               IndexProp(ENUM_TICK_PROP_STRING property)       const { return(int)property-TICK_PROP_INTEGER_TOTAL-TICK_PROP_DOUBLE_TOTAL;}

public:
//--- Set tick’s (1) integer, (2) real and (3) string property
   void              SetProperty(ENUM_TICK_PROP_INTEGER property,long value)  { this.m_long_prop[property]=value;                               }
   void              SetProperty(ENUM_TICK_PROP_DOUBLE property,double value) { this.m_double_prop[this.IndexProp(property)]=value;             }
   void              SetProperty(ENUM_TICK_PROP_STRING property, value) { this.m_string_prop[this.IndexProp(property)]=value;             }
//--- Return tick’s (1) integer, (2) real and (3) string property from the properties array
   long              GetProperty(ENUM_TICK_PROP_INTEGER property)    const { return this.m_long_prop[property];                                 }
   double            GetProperty(ENUM_TICK_PROP_DOUBLE property)     const { return this.m_double_prop[this.IndexProp(property)];               }
               GetProperty(ENUM_TICK_PROP_STRING property)     const { return this.m_string_prop[this.IndexProp(property)];               }

//--- Return the flag of the tick supporting this property
   virtual bool      SupportProperty(ENUM_TICK_PROP_INTEGER property)      { return 真正; }
   virtual bool      SupportProperty(ENUM_TICK_PROP_DOUBLE property)       { return 真正; }
   virtual bool      SupportProperty(ENUM_TICK_PROP_STRING property)       { return 真正; }
//--- Return itself
   CDataTick        *GetObject(void)                                       { return &this;}

//--- Compare CDataTick objects with each other by the specified property (for sorting the lists by a specified object property)
   virtual int       Compare(const CObject *node,const int mode=0) const;
//--- Compare CDataTick objects with each other by all properties (to search equal objects)
   bool              IsEqual(CDataTick* compared_obj) const;
//--- Constructors
                     CDataTick(){;}
                     CDataTick(const  symbol,const MqlTick &tick);
        
//+------------------------------------------------------------------+
//| Descriptions of object tick data properties                      |
//+------------------------------------------------------------------+
//--- Return description of tick's (1) integer, (2) real and (3) string property
               GetPropertyDescription(ENUM_TICK_PROP_INTEGER property);
               GetPropertyDescription(ENUM_TICK_PROP_DOUBLE property);
               GetPropertyDescription(ENUM_TICK_PROP_STRING property);

//--- Display the description of tick properties in the journal (full_prop=true - all properties, false - supported ones only)
   void              Print(const bool full_prop=);
//--- Display a short description of the tick in the journal
   virtual void      PrintShort(void);
//---  Return the (1) short name and (2) description of tick data object flags
   virtual     Header(void);
               FlagsDescription(void);
   
//+------------------------------------------------------------------+ 
//| Methods of simplified access to tick data object properties      |
//+------------------------------------------------------------------+
//--- Return tick’s (1) Time, (2) time in milliseconds, (3) volume, (4) flags
   datetime          Time(void)                                         const { return (datetime)this.GetProperty(TICK_PROP_TIME);           }
   long              TimeMSC(void)                                      const { return this.GetProperty(TICK_PROP_TIME_MSC);                 }
   long              Volume(void)                                       const { return this.GetProperty(TICK_PROP_VOLUME);                   }
   uint              Flags(void)                                        const { return (uint)this.GetProperty(TICK_PROP_FLAGS);              }
   
//--- Return tick’s (1) Bid, (2) Ask, (3) Last price, (4) volume with greater accuracy, (5) spread of the tick
//--- size of the (9) candle upper, (10) lower wick
   double            Bid(void)                                          const { return this.GetProperty(TICK_PROP_BID);                      }
   double            Ask(void)                                          const { return this.GetProperty(TICK_PROP_ASK);                      }
   double            Last(void)                                         const { return this.GetProperty(TICK_PROP_LAST);                     }
   double            VolumeReal(void)                                   const { return this.GetProperty(TICK_PROP_VOLUME_REAL);              }
   double            Spread(void)                                       const { return this.GetProperty(TICK_PROP_SPREAD);                   }
   
//--- Return tick symbol
               Symbol(void)                                       const { return this.GetProperty(TICK_PROP_SYMBOL);                   }

//--- Return bar (1) time, (2) index on the specified timeframe the tick time falls into
   datetime          TimeBar(const ENUM_TIMEFRAMES timeframe)const
                       { return ::iTime(this.Symbol(),timeframe,this.Index(timeframe));                                                      }
   int               Index(const ENUM_TIMEFRAMES timeframe)  const
                       { return ::iBarShift(this.Symbol(),(timeframe==PERIOD_CURRENT ? ::Period() : timeframe),this.Time());                 }  

//--- Return the flag of (1) Bid, (2) Ask, (3) Last price, (4) volume change; (5) buy and (6) sell trades
   bool              IsChangeBid()                                      const { return((this.Flags() & TICK_FLAG_BID)==TICK_FLAG_BID);       }
   bool              IsChangeAsk()                                      const { return((this.Flags() & TICK_FLAG_ASK)==TICK_FLAG_ASK);       }
   bool              IsChangeLast()                                     const { return((this.Flags() & TICK_FLAG_LAST)==TICK_FLAG_LAST);     }
   bool              IsChangeVolume()                                   const { return((this.Flags() & TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME); }
   bool              IsChangeBuy()                                      const { return((this.Flags() & TICK_FLAG_BUY)==TICK_FLAG_BUY);       }
   bool              IsChangeSell()                                     const { return((this.Flags( )& TICK_FLAG_SELL)==TICK_FLAG_SELL);     }
//---
  };
//+------------------------------------------------------------------+

库对象的组成及其创建在以下内容中进行了详细讨论 第一篇文章。现在,让我们浏览主要的变量和方法,并在类中进一步分析其实现。

私有类部分包含辅​​助变量,用于存储对象整数,实数和字符串属性的值的数组;以及返回它们实际位于数组中的实际属性索引的方法。

公共类部分包含用于设置指定属性的值并将其返回到相应对象属性数组的方法;返回支持一个或另一个属性的对象的标志的方法;搜索,比较和排序对象的方法以及类构造函数。

显示对象属性描述的方法简化访问对象属性的方法 也位于那里。

现在,让我们看一下类方法的实现。

符号 并用当前的报价数据填充结构 应传递给参数类构造函数:

//+------------------------------------------------------------------+
//| Parametric constructor                                           |
//+------------------------------------------------------------------+
CDataTick::CDataTick(const  symbol,const MqlTick &tick)
  {
//--- Save symbol’s Digits
   this.m_digits=(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS);
//--- Save integer tick properties
   this.SetProperty(TICK_PROP_TIME,tick.time);
   this.SetProperty(TICK_PROP_TIME_MSC,tick.time_msc);
   this.SetProperty(TICK_PROP_VOLUME,tick.volume);
   this.SetProperty(TICK_PROP_FLAGS,tick.flags);
//--- Save real tick properties
   this.SetProperty(TICK_PROP_BID,tick.bid);
   this.SetProperty(TICK_PROP_ASK,tick.ask);
   this.SetProperty(TICK_PROP_LAST,tick.last);
   this.SetProperty(TICK_PROP_VOLUME_REAL,tick.volume_real);
//--- Save additional tick properties
   this.SetProperty(TICK_PROP_SPREAD,tick.ask-tick.bid);
   this.SetProperty(TICK_PROP_SYMBOL,(symbol==空值 || symbol=="" ? ::Symbol() : symbol));
  }
//+------------------------------------------------------------------+

在构造函数中,只需在对象属性中填写刻度结构的相应值以及从中获取刻度数据的符号。

通过指定属性比较对象的两个参数的方法:

//+----------------------------------------------------------------------+
//| Compare CDataTick objects with each other by the specified property  |
//+----------------------------------------------------------------------+
int CDataTick::Compare(const CObject *node,const int mode=0) const
  {
   const CDataTick *obj_compared=node;
//--- compare integer properties of two objects
   if(mode<TICK_PROP_INTEGER_TOTAL)
     {
      long value_compared=obj_compared.GetProperty((ENUM_TICK_PROP_INTEGER)mode);
      long value_current=this.GetProperty((ENUM_TICK_PROP_INTEGER)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- compare real properties of two objects
   else if(mode<TICK_PROP_DOUBLE_TOTAL+TICK_PROP_INTEGER_TOTAL)
     {
      double value_compared=obj_compared.GetProperty((ENUM_TICK_PROP_DOUBLE)mode);
      double value_current=this.GetProperty((ENUM_TICK_PROP_DOUBLE)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
//--- compare string properties of two objects
   else if(mode<TICK_PROP_DOUBLE_TOTAL+TICK_PROP_INTEGER_TOTAL+TICK_PROP_STRING_TOTAL)
     {
       value_compared=obj_compared.GetProperty((ENUM_TICK_PROP_STRING)mode);
       value_current=this.GetProperty((ENUM_TICK_PROP_STRING)mode);
      return(value_current>value_compared ? 1 : value_current<value_compared ? -1 : 0);
     }
   return 0;
  }
//+------------------------------------------------------------------+

指向必须与当前对象进行比较的对象的指针以及将与之比较两个对象的属性的类型应传递给该方法。

根据当前对象比较的模式,比较两个对象的这些属性,如果当前对象的属性值分别大于/小于或等于比较对象的属性值,则返回1 / -1 / 0。

比较两个对象的身份的方法:

//+------------------------------------------------------------------+
//| Compare CDataTick objects with each other by all properties      |
//+------------------------------------------------------------------+
bool CDataTick::IsEqual(CDataTick *compared_obj) const
  {
   int beg=0, end=TICK_PROP_INTEGER_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_TICK_PROP_INTEGER prop=(ENUM_TICK_PROP_INTEGER)i;
      if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return ; 
     }
   beg=end; end+=TICK_PROP_DOUBLE_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_TICK_PROP_DOUBLE prop=(ENUM_TICK_PROP_DOUBLE)i;
      if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return ; 
     }
   beg=end; end+=TICK_PROP_STRING_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_TICK_PROP_STRING prop=(ENUM_TICK_PROP_STRING)i;
      if(this.GetProperty(prop)!=compared_obj.GetProperty(prop)) return ; 
     }
   return 真正;
  }
//+------------------------------------------------------------------+

此处:将要比较的对象的指针传递给该方法。然后,在每个属性组的三个循环中,比较两个对象的每个连续属性。如果至少一个属性不等于所比较对象的相同属性,则返回 。完成所有三个循环后 真正 返回—两个对象的所有属性都相等。这意味着对象是相同的。

在日志中显示所有对象属性的方法:

//+------------------------------------------------------------------+
//| Display tick properties in the journal                           |
//+------------------------------------------------------------------+
void CDataTick::Print(const bool full_prop=)
  {
   ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_BEG)," (",this.Header(),") =============");
   int beg=0, end=TICK_PROP_INTEGER_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_TICK_PROP_INTEGER prop=(ENUM_TICK_PROP_INTEGER)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("------");
   beg=end; end+=TICK_PROP_DOUBLE_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_TICK_PROP_DOUBLE prop=(ENUM_TICK_PROP_DOUBLE)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("------");
   beg=end; end+=TICK_PROP_STRING_TOTAL;
   for(int i=beg; i<end; i++)
     {
      ENUM_TICK_PROP_STRING prop=(ENUM_TICK_PROP_STRING)i;
      if(!full_prop && !this.SupportProperty(prop)) continue;
      ::Print(this.GetPropertyDescription(prop));
     }
   ::Print("============= ",CMessage::Text(MSG_LIB_PARAMS_LIST_END)," (",this.Header(),") =============\n");
  }
//+------------------------------------------------------------------+

此处:每个对象属性组在三个循环中,使用相应的方法GetPropertyDescription()在日记中显示每个连续属性的描述。如果在方法参数中 值传递 full_prop 变量,仅显示对象支持的属性。对于不受支持的属性,日记记录显示该属性不受支持,尽管此对象支持所有属性。但这可以在类后代对象中更改。

返回指定对象描述的方法 整数, 真实 property:

//+------------------------------------------------------------------+
//| Return description of tick's integer property                    |
//+------------------------------------------------------------------+
 CDataTick::GetPropertyDescription(ENUM_TICK_PROP_INTEGER property)
  {
   return
     (
      property==TICK_PROP_TIME_MSC           ?  CMessage::Text(MSG_TICK_TIME_MSC)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+TimeMSCtoString(this.GetProperty(property),TIME_DATE|TIME_MINUTES|TIME_SECONDS)
         )  :
      property==TICK_PROP_TIME               ?  CMessage::Text(MSG_TICK_TIME)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::TimeToString(this.GetProperty(property),TIME_DATE|TIME_MINUTES|TIME_SECONDS)
         )  :
      property==TICK_PROP_VOLUME             ?  CMessage::Text(MSG_TICK_VOLUME)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+()this.GetProperty(property)
         )  :
      property==TICK_PROP_FLAGS              ?  CMessage::Text(MSG_TICK_FLAGS)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+()this.GetProperty(property)+"\n"+CMessage::Text(MSG_LIB_TEXT_TICK_CHANGED_DATA)+this.FlagsDescription()
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return description of tick's real property                       |
//+------------------------------------------------------------------+
 CDataTick::GetPropertyDescription(ENUM_TICK_PROP_DOUBLE property)
  {
   int dg=(this.m_digits>0 ? this.m_digits : 1);
   return
     (
      property==TICK_PROP_BID                ?  CMessage::Text(MSG_LIB_PROP_BID)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==TICK_PROP_ASK                ?  CMessage::Text(MSG_LIB_PROP_ASK)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==TICK_PROP_LAST               ?  CMessage::Text(MSG_LIB_PROP_LAST)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      property==TICK_PROP_VOLUME_REAL        ?  CMessage::Text(MSG_TICK_VOLUME_REAL)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),2)
         )  :
      property==TICK_PROP_SPREAD             ?  CMessage::Text(MSG_TICK_SPREAD)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::DoubleToString(this.GetProperty(property),dg)
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+
//| Return description of tick's string property                     |
//+------------------------------------------------------------------+
 CDataTick::GetPropertyDescription(ENUM_TICK_PROP_STRING property)
  {
   return(property==TICK_PROP_SYMBOL ? CMessage::Text(MSG_LIB_PROP_SYMBOL)+": \""+this.GetProperty(property)+"\"" : "");
  }
//+------------------------------------------------------------------+

此处:根据传递给方法的属性,返回其字符串描述。

返回带有刻度的所有标志的描述的字符串的方法:

//+------------------------------------------------------------------+
//| Display the description of flags                                 |
//+------------------------------------------------------------------+
 CDataTick::FlagsDescription(void)
  {
    flags=
     (
      (this.IsChangeAsk()     ? "\n - "+CMessage::Text(MSG_LIB_TEXT_TICK_FLAG_ASK)     : "")+
      (this.IsChangeBid()     ? "\n - "+CMessage::Text(MSG_LIB_TEXT_TICK_FLAG_BID)     : "")+
      (this.IsChangeLast()    ? "\n - "+CMessage::Text(MSG_LIB_TEXT_TICK_FLAG_LAST)    : "")+
      (this.IsChangeVolume()  ? "\n - "+CMessage::Text(MSG_LIB_TEXT_TICK_FLAG_VOLUME)  : "")+
      (this.IsChangeBuy()     ? "\n - "+CMessage::Text(MSG_DEAL_TO_BUY)                : "")+
      (this.IsChangeSell()    ? "\n - "+CMessage::Text(MSG_DEAL_TO_SELL)               : "")
     );
  return flags; 
  }
//+------------------------------------------------------------------+

在其属性中,每个刻度都具有一个包含一组标志的变量。这些标志描述了引起此滴答的事件:

MqlTick user-guide

要找出当前滴答更改了哪些特定数据,请对其标志进行分析:

  • TICK_FLAG_BID-报价变动的价格变动
  • TICK_FLAG_ASK —勾号已更改要价
  • TICK_FLAG_LAST-报价变动了最后交易价格
  • TICK_FLAG_VOLUME-变动刻度
  • TICK_FLAG_BUY —买入交易产生的价格变动
  • TICK_FLAG_SELL-卖出交易产生的报价

我们有六个方法(按标志的数量)返回每个标志的变量内的状态标志:

//--- Return the flag of (1) Bid, (2) Ask, (3) Last price, (4) volume change; (5) buy and (6) sell trades
   bool IsChangeBid()    const { return((this.Flags() & TICK_FLAG_BID)==TICK_FLAG_BID);       }
   bool IsChangeAsk()    const { return((this.Flags() & TICK_FLAG_ASK)==TICK_FLAG_ASK);       }
   bool IsChangeLast()   const { return((this.Flags() & TICK_FLAG_LAST)==TICK_FLAG_LAST);     }
   bool IsChangeVolume() const { return((this.Flags() & TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME); }
   bool IsChangeBuy()    const { return((this.Flags() & TICK_FLAG_BUY)==TICK_FLAG_BUY);       }
   bool IsChangeSell()   const { return((this.Flags() & TICK_FLAG_SELL)==TICK_FLAG_SELL);     }

在所描述的方法中,首先检查变量中标志存在的标志。取决于是否可以进行这种更改,结果文本字符串应添加换行符+标志说明或空字符串。在检查完所有标志之后,最后我们有了已编译的字符串,其中包含变量中存在的标志的描述。如果有几个标记可用,则每个标记的描述将从日志中的新行开始。

在日志中显示报价数据对象的简短描述的方法:

//+------------------------------------------------------------------+
//| Display a short description of the tick in the journal           |
//+------------------------------------------------------------------+
void CDataTick::PrintShort(void)
  {
   ::Print(this.Header());
  }
//+------------------------------------------------------------------+

该方法仅显示在日记中 简称 通过以下方法返回其自身:

//+------------------------------------------------------------------+
//| Return a short name of tick data object                          |
//+------------------------------------------------------------------+
 CDataTick::Header(void)
  {
   return
     (
      CMessage::Text(MSG_TICK_TEXT_TICK)+" \""+this.Symbol()+"\" "+TimeMSCtoString(TimeMSC())
     );
  }
//+------------------------------------------------------------------+

在此阶段,完成滴答数据对象的创建。


测试滴答数据对象

为了进行测试,让我们使用 上一篇文章的EA 并将其保存在新文件夹\ MQL5 \ Experts \ TestDoEasy \Part59 \ 用新名字 TestDoEasyPart59.mq5.

在此EA中,不再需要指标及其时间序列数据。在这里,只需创建报价数据对象,在日志中显示其完整描述,并在图表的注释中显示简短描述。随着每个新的勾号,其在图表上的描述将更改;而在日记中,将显示EA启动后出现的第一个刻度。

由于尚未将此新库对象与EA连接,因此我将 将同类文件连接到EA:

//+------------------------------------------------------------------+
//|                                             TestDoEasyPart59.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                             //tbxfkj.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property 链接      "//tbxfkj.com/ru/users/artmedia70"
#property version   "1.00"
//--- includes
#include <DoEasy\Engine.mqh>
#include <DoEasy\Objects\Ticks\DataTick.mqh>

在EA的全局变量方面 代替自定义指标参数数组

//--- Arrays of custom indicator parameters
MqlParam       param_ma1[];
MqlParam       param_ma2[];
//+------------------------------------------------------------------+

声明“ New tick”类的对象 —在将来的库报价数据收集类中模拟工作将是必需的:

//--- global variables
CEngine        engine;
SDataButt      butt_data[TOTAL_BUTT];
         prefix;
double         lot;
double         withdrawal=(InpWithdrawal<0.1 ? 0.1 : InpWithdrawal);
ushort         magic_number;
uint           stoploss;
uint           takeprofit;
uint           distance_pending;
uint           distance_stoplimit;
uint           distance_pending_request;
uint           bars_delay_pending_request;
uint           slippage;
bool           trailing_on;
bool           pressed_pending_buy;
bool           pressed_pending_buy_limit;
bool           pressed_pending_buy_stop;
bool           pressed_pending_buy_stoplimit;
bool           pressed_pending_close_buy;
bool           pressed_pending_close_buy2;
bool           pressed_pending_close_buy_by_sell;
bool           pressed_pending_sell;
bool           pressed_pending_sell_limit;
bool           pressed_pending_sell_stop;
bool           pressed_pending_sell_stoplimit;
bool           pressed_pending_close_sell;
bool           pressed_pending_close_sell2;
bool           pressed_pending_close_sell_by_buy;
bool           pressed_pending_delete_all;
bool           pressed_pending_close_all;
bool           pressed_pending_sl;
bool           pressed_pending_tp;
double         trailing_stop;
double         trailing_step;
uint           trailing_start;
uint           stoploss_to_modify;
uint           takeprofit_to_modify;
int            used_symbols_mode;
         array_used_symbols[];
         array_used_periods[];
bool           testing;
uchar          group1;
uchar          group2;
double         g_point;
int            g_digits;

//--- "New tick" object
CNewTickObj    check_tick;
//+------------------------------------------------------------------+

OnInit() 处理程序 删除指标创建块:

//--- Create indicators
   ArrayResize(param_ma1,4);
   //--- Name of indicator 1
   param_ma1[0].type=TYPE_STRING;
   param_ma1[0].string_value="例子\\Custom Moving Average.ex5";
   //--- Calculation period
   param_ma1[1].type=TYPE_INT;
   param_ma1[1].integer_value=13;
   //--- Horizontal shift
   param_ma1[2].type=TYPE_INT;
   param_ma1[2].integer_value=0;
   //--- Smoothing method
   param_ma1[3].type=TYPE_INT;
   param_ma1[3].integer_value=MODE_SMA;
   //--- Create indicator 1
   engine.GetIndicatorsCollection().CreateCustom(空值,PERIOD_CURRENT,MA1,1,INDICATOR_GROUP_TREND,param_ma1);
   
   ArrayResize(param_ma2,5);
   //--- Name of indicator 2
   param_ma2[0].type=TYPE_STRING;
   param_ma2[0].string_value="例子\\Custom Moving Average.ex5";
   //--- Calculation period
   param_ma2[1].type=TYPE_INT;
   param_ma2[1].integer_value=13;
   //--- Horizontal shift
   param_ma2[2].type=TYPE_INT;
   param_ma2[2].integer_value=0;
   //--- Smoothing method
   param_ma2[3].type=TYPE_INT;
   param_ma2[3].integer_value=MODE_SMA;
   //--- Calculation price
   param_ma2[4].type=TYPE_INT;
   param_ma2[4].integer_value=PRICE_OPEN;
   //--- Create indicator 2
   engine.GetIndicatorsCollection().CreateCustom(空值,PERIOD_CURRENT,MA2,1,INDICATOR_GROUP_TREND,param_ma2);
   
   //--- Create indicator 3
   engine.GetIndicatorsCollection().CreateAMA(空值,PERIOD_CURRENT,AMA1);
   //--- Create indicator 4
   engine.GetIndicatorsCollection().CreateAMA(空值,PERIOD_CURRENT,AMA2,14);
   
   //--- Display descriptions of created indicators
   engine.GetIndicatorsCollection().Print();
   engine.GetIndicatorsCollection().PrintShort();

在最后 OnInit() 为“新刻度”对象设置当前符号 as the working one:

//--- Set the current symbol for "New tick" object
   check_tick.SetSymbol(Symbol());
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+

OnTick() EA经理 添加一个代码块,用于确定新的价格变动(作为将来的价格变动集合类别中的工作模拟)并创建新的价格变动数据对象,并在图表和日记帐中显示其说明:

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Handle the NewTick event in the library
   engine.OnTick(rates_data);

//--- If working in the tester
   if(MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer(rates_data);   // Working in the timer
      PressButtonsControl();        // Button pressing control
      engine.EventsHandling();      // Working with events
     }

//--- Create a temporary list for storing “Tick data” objects,
//--- a variable for obtaining tick data and
//--- a variable for calculating incoming ticks
   static int tick_count=0;
   CArrayObj list;
   MqlTick tick_struct;
//--- Check a new tick on the current symbol
   if(check_tick.IsNewTick())
     {
      //--- If failed to get the price - exit
      if(!SymbolInfoTick(Symbol(),tick_struct))
         return;
      //--- Create a new tick data object
      CDataTick *tick_obj=new CDataTick(Symbol(),tick_struct);
      if(tick_obj==空值)
         return;
      //--- Increase tick counter (simply to display on the screen, no other purpose is provided)
      tick_count++;
      //--- Limit the number of ticks in the counting as one hundred thousand (again, no purpose is provided)
      if(tick_count>100000) tick_count=1;
      //--- In the comment on the chart display the tick number and its short description
      Comment("--- №",在tegerToString(tick_count,5,'0'),": ",tick_obj.Header());
      //--- If this is the first tick (which follows the first launch of EA) display its full description in the journal
      if(tick_count==1)
         tick_obj.Print();
      //--- Remove if failed to put the created tick data object in the list
      if(!list.Add(tick_obj))
         delete tick_obj;
     }
   
//--- If the trailing flag is set
   if(trailing_on)
     {
      TrailingPositions();          // Trailing positions
      TrailingOrders();             // Trailing of pending orders
     }
  }
//+------------------------------------------------------------------+

在清单的注释中详细说明了逻辑。我相信这很简单。

编译EA并将其在图表中启动,并对其进行了初步设置,以使用当前的交易品种和时间范围。启动新的报价后,报价数据对象(到达的报价)的描述将显示在日志中:

Account 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10426.13 USD, 1:100, Hedge, Demo account MetaTrader 5
--- Initialize "DoEasy" library ---
Work with the current symbol only: "EURUSD"
Work with the current timeframe only: H1
EURUSD symbol timeseries: 
- "EURUSD" H1 timeseries: Requested: 1000, Actually: 1000, Created: 1000, On the server: 5153
Library initialize time: 00:00:00.000
============= Beginning of parameter list (Tick "EURUSD" 2020.12.16 13:22:32.822) =============
Last price update time in milliseconds: 2020.12.16 13:22:32.822
Last price update time: 2020.12.16 13:22:32
Volume for the current Last price: 0
Flags: 6
Changed data on the tick:
 - Ask price change
 - Bid price change
------
Bid price: 1.21927
Ask price: 1.21929
Last price: 0.00000
Volume for the current Last price with greater accuracy: 0.00
Spread: 0.00002
------
Symbol: "EURUSD"
============= End of parameter list (Tick "EURUSD" 2020.12.16 13:22:32.822) =============

并在每个新的勾上加上简短说明的注释将显示在图表上:



下一步是什么?

在下一篇文章中,我们将开始为一个符号创建报价数据集合。

下面附有当前库版本的所有文件以及MQL5的测试EA文件。您可以下载它们并测试所有内容。
在文章的评论中留下您的评论,问题和建议。

返回目录

该系列中的先前文章:

DoEasy库中的时间序列(第35部分):条对象和符号时间序列列表
DoEasy库中的时间序列(第36部分):所有使用的符号周期的时间序列对象
DoEasy库中的时间序列(第37部分):时间序列集合-按符号和周期的时间序列数据库
DoEasy库中的时间序列(第38部分):时间序列集合-实时更新和从程序访问数据
DoEasy库中的时间序列(第39部分):基于库的指标-准备数据和时间序列事件
DoEasy库中的时间序列(第40部分):基于库的指标-实时更新数据
DoEasy库中的时间序列(第41部分):样本多符号多周期指示器
DoEasy库中的时间序列(第42部分):抽象指示器缓冲区对象类
DoEasy库中的时间序列(第43部分):指标缓冲区对象的类
DoEasy库中的时间序列(第44部分):指标缓冲区对象的集合类
DoEasy库中的时间序列(第45部分):多周期指示器缓冲区
DoEasy库中的时间序列(第46部分):多周期多符号指示符缓冲区
DoEasy库中的时间序列(第47部分):多周期多符号标准指标
DoEasy库中的时间序列(第48部分):子窗口中一个缓冲区上的多周期多符号指示器
DoEasy库中的时间序列(第49部分):多周期多符号多缓冲区标准指标
DoEasy库中的时间序列(第50部分):带有偏移的多周期多符号标准指标
DoEasy库中的时间序列(第51部分):复合多周期多符号标准指标
DoEasy库中的时间序列(第52部分):多周期多符号单缓冲区标准指标的跨平台性质
DoEasy库中的时间序列(第53部分):抽象基础指标类
DoEasy库中的时间序列(第54部分):抽象基础指示器的后代类
DoEasy库中的时间序列(第55部分):指标集合类
DoEasy库中的时间序列(第56部分):自定义指标对象,从集合中的指标对象获取数据
DoEasy库中的时间序列(第57部分):指标缓冲区数据对象
DoEasy库中的时间序列(第58部分):指标缓冲区数据的时间序列


由MetaQuotes Software Corp.从俄语翻译而来。
来源文章: //www.tbxfkj.com/ru/articles/8818

附加的文件 |
MQL5.zip (3868.71 KB)
使用电子表格制定交易策略 使用电子表格制定交易策略

本文介绍了基本原理和方法,使您可以使用电子表格(Excel,Calc,Google)分析任何策略。将获得的结果与MetaTrader 5测试仪进行比较。

DoEasy库中的时间序列(第58部分):指标缓冲区数据的时间序列 DoEasy库中的时间序列(第58部分):指标缓冲区数据的时间序列

在有关使用时间序列的主题的最后,组织存储,搜索和分类存储在指标缓冲区中的数据,这将允许根据将在程序库中基于库创建的指标值进一步执行分析。库的所有集合类的一般概念允许轻松地在相应的集合中找到必要的数据。分别地,在今天创建的类中同样可能。

神经网络变得简单(第8部分):注意机制 神经网络变得简单(第8部分):注意机制

在之前的文章中,我们已经测试了用于组织神经网络的各种选项。我们还考虑了从图像处理算法中借用的卷积网络。在本文中,我建议考虑注意力机制,它的出现为语言模型的发展提供了动力。

开发自适应算法(第一部分):找到基本模式 开发自适应算法(第一部分):找到基本模式

在接下来的系列文章中,我将演示考虑大多数市场因素的自适应算法的开发,并展示如何将这些情况系统化,在逻辑上进行描述并在您的交易活动中加以考虑。我将以一个非常简单的算法开始,该算法将逐步掌握理论并发展成为一个非常复杂的项目。