目录
概念
从本文开始,开始开发库功能以使用刻度数据。
滴答数据的存储和使用概念将类似于 时间序列数据存储的概念 最小数据单位是小节。条形对象存储在属于相应时间范围的列表中,而相应的时间范围又存储在属于符号的列表中。
在滴答数据存储的概念中,数据量的最小单位应为一滴答的价格结构值。通过使用以下结构描述这些值 通过符号存储最新价格 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)