DoEasyライブラリの時系列(第43部): 指標バッファオブジェクトクラス
Artyom Trishkin | 7 9月, 2020
内容
概念
前回の記事では、指標バッファのいくつかの一般的なプロパティとそれらを使用するメソッドを含む、抽象指標バッファオブジェクトを作成しました。ここでは、抽象バッファオブジェクトクラスから派生したオブジェクトを作成します。その種類の各オブジェクトは、独自のタイプのグラフィックを持つ独立した指標バッファオブジェクトです。
すでに前述したように、すべての指標バッファは色付けされています。ただし、モノクロの指標バッファが必要な場合、バッファは最初は1色で作成されます。また、指標の使用中に、バッファが使用する色の量を設定することもできます。
まず、新しいライブラリメッセージを追加しましょう。
\MQL5\Include\DoEasy\Datas.mqhを開いて新しいメッセージのインデックスを追加します。
MSG_LIB_SYS_FAILED_CREATE_BAR_OBJ, // Failed to create the \"Bar\" object MSG_LIB_SYS_FAILED_SYNC_DATA, // Failed to synchronize data with the server MSG_LIB_SYS_FAILED_DRAWING_ARRAY_RESIZE, // Failed to change the array size of drawn buffers MSG_LIB_SYS_FAILED_COLORS_ARRAY_RESIZE, // Failed to change the color array size
...
MSG_LIB_TEXT_BUFFER_TEXT_LINE_WIDTH, // Line width MSG_LIB_TEXT_BUFFER_TEXT_ARROW_SIZE, // Arrow size MSG_LIB_TEXT_BUFFER_TEXT_COLOR_NUM, // Number of colors MSG_LIB_TEXT_BUFFER_TEXT_COLOR, // Drawing color MSG_LIB_TEXT_BUFFER_TEXT_EMPTY_VALUE, // Empty value for plotting where nothing will be drawn MSG_LIB_TEXT_BUFFER_TEXT_SYMBOL, // Buffer symbol MSG_LIB_TEXT_BUFFER_TEXT_LABEL, // Name of the graphical indicator series displayed in DataWindow MSG_LIB_TEXT_BUFFER_TEXT_STATUS_NAME, // Indicator buffer with graphical construction type MSG_LIB_TEXT_BUFFER_TEXT_INVALID_PROPERTY_BUFF, // Invalid number of indicator buffers in #property indicator_buffers
...
MSG_LIB_TEXT_BUFFER_TEXT_TYPE_CALCULATE, // Calculated buffer MSG_LIB_TEXT_BUFFER_TEXT_TYPE_DATA, // Colored data buffer MSG_LIB_TEXT_BUFFER_TEXT_BUFFER, // Buffer MSG_LIB_TEXT_BUFFER_TEXT_STYLE_SOLID, // Solid line MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DASH, // Dashed line MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DOT, // Dotted line MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DASHDOT, // Dot-dash line MSG_LIB_TEXT_BUFFER_TEXT_STYLE_DASHDOTDOT, // Dash - two dots };
次に、新しく追加されたインデックスに対応する新しいテキストメッセージも追加します。
{"Не удалось создать объект \"Бар\"","Failed to create object \"Bar\""}, {"Не удалось синхронизировать данные с сервером","Failed to sync data with server"}, {"Не удалось изменить размер массива рисуемых буферов","Failed to resize drawing buffers array"}, {"Не удалось изменить размер массива цветов","Failed to resize color array"},
...
{"Толщина линии отрисовки","Thickness of drawing line"}, {"Размер значка стрелки","Arrow icon size"}, {"Количество цветов","Number of colors"}, {"Цвет отрисовки","Index of buffer containing drawing color"}, {"Пустое значение для построения, для которого нет отрисовки","Empty value for plotting, for which there is no drawing"}, {"Символ буфера","Buffer Symbol"}, {"Имя индикаторной графической серии, отображаемое в окне DataWindow","Name of indicator graphical series to display in DataWindow"}, {"Индикаторный буфер с типом графического построения","Indicator buffer with graphic plot type"}, {"Неправильно указано количество буферов индикатора (#property indicator_buffers)","Number of indicator buffers is incorrect (#property indicator_buffers)"},
...
{"Расчётный буфер","Calculated buffer"}, {"Цветной буфер данных","Colored Data buffer"}, {"Буфер","Buffer"}, {"Сплошная линия","Solid line"}, {"Прерывистая линия","Broken line"}, {"Пунктирная линия","Dotted line"}, {"Штрих-пунктирная линия","Dash-dot line"}, {"Штрих - две точки","Dash - two points"}, }; //+---------------------------------------------------------------------+
\MQL5\Include\DoEasy\Defines.mqhで、マクロ置換セクションに、設定可能な指標バッファの色の最大数を指定するマクロを追加します。
//+------------------------------------------------------------------+ //| Macro substitutions | //+------------------------------------------------------------------+ //--- Describe the function with the error line number #define DFUN_ERR_LINE (__FUNCTION__+(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian" ? ", Page " : ", Line ")+(string)__LINE__+": ") #define DFUN (__FUNCTION__+": ") // "Function description" #define COUNTRY_LANG ("Russian") // Country language #define END_TIME (D'31.12.3000 23:59:59') // End date for account history data requests #define TIMER_FREQUENCY (16) // Minimal frequency of the library timer in milliseconds #define TOTAL_TRY (5) // Default number of trading attempts #define IND_COLORS_TOTAL (64) // Maximum possible number of indicator buffer colors //--- Standard sounds
これは、特に将来的に増加する可能性があることを考慮して、64を超える指定色の数の検証を実装しないようにするために行われます。
次に、抽象バッファオブジェクトクラスを少し改善しましょう。
指標バッファは、現在、データバッファとカラーインデックスバッファの実際のデータ型の配列のクラスのpublicセクションにあります。これらをprotectedセクションに削除します。複数の指標構築バッファがある可能性があるため、単一の配列を含むバッファ構造体を作成します。
これは何故必要なのでしょうか。
指標バッファはdoubleデータの1次元配列でのみ表すことができるため、バッファ配列を作成するために単一の配列で構造を実装します(複数ある場合があります)。この場合、指標の構築に必要なすべてのデータ配列(指標バッファ)が、このような構造体の配列に含まれます。これらは、必要な配列のインデックスによってアクセスされます。
誤ったインデックスを渡して配列を超えないようにするには、インデックスが配列の外を指している場合に、渡された配列のインデックスを調整するメソッドを作成します。インデックスは、構造体配列の最後の要素を指定するように調整され、配列が1つの場合は、それを指します。
抽象バッファオブジェクトのファイル(\MQL5\Include\DoEasy\Objects\Indicators\Buffer.mqh )(privateセクション)で、調整されたバッファ配列インデックスを返すメソッドを宣言します。
protectedセクションでは、バッファ配列の構造, 構造体タイプを持つバッファの配列オブジェクト、カラーバッファ配列、指標構築に着色するのに使用するカラー配列を宣言します。
//+------------------------------------------------------------------+ //| Abstract indicator buffer class | //+------------------------------------------------------------------+ class CBuffer : public CBaseObj { private: long m_long_prop[BUFFER_PROP_INTEGER_TOTAL]; // Integer properties double m_double_prop[BUFFER_PROP_DOUBLE_TOTAL]; // Real properties string m_string_prop[BUFFER_PROP_STRING_TOTAL]; // String properties //--- Return the index of the array the buffer's (1) double and (2) string properties are located at int IndexProp(ENUM_BUFFER_PROP_DOUBLE property) const { return(int)property-BUFFER_PROP_INTEGER_TOTAL; } int IndexProp(ENUM_BUFFER_PROP_STRING property) const { return(int)property-BUFFER_PROP_INTEGER_TOTAL-BUFFER_PROP_DOUBLE_TOTAL; } //--- Set the graphical construction type void SetDrawType(void); //--- Return the adjusted buffer array index int GetCorrectIndexBuffer(const uint buffer_index) const; protected: //--- Structure for storing buffer object buffer arrays struct SDataBuffer { double Array[]; }; //--- Array of (1) all indicator buffer object buffers, (2) color buffer, (3) for storing colors SDataBuffer DataBuffer[]; double ColorBufferArray[]; int ArrayColors[]; public:
不要になったデータとカラー配列をクラスのpublicセクションから削除します。
public: //--- Array of the (1) drawn indicator buffer and (2) color buffer double DataArray[]; double ColorArray[];
前回の記事では、抽象バッファオブジェクトのprotectedコンストラクタをpublicにして、指標プログラムからアクセスできるようにしました。ここでは、指定したタイプの指標バッファを作成するときに、クラスの子孫オブジェクトからアクセスできるように制限します。単に行のコメントを解除し、作成されたバッファプロパティを明確にするためにいくつかの新しい変数をprotectedコンストラクタに追加します。これらのプロパティには、構築に使用されるバッファの数、線幅、およびデータウィンドウのバッファの説明が含まれます。
protected: //--- Protected parametric constructor CBuffer(ENUM_BUFFER_STATUS status_buffer, ENUM_BUFFER_TYPE buffer_type, const uint index_plot, const uint index_base_array, const int num_datas, const int width, const string label); public:
これで、SetColor()指標バッファの単一の色を設定するメソッドが用意されました。ただし、すべてのバッファが色付けされているため、既存のバッファに新しい色を追加したり、バッファが使用するすべての色を一度に設定したりする機能も必要です。
色を設定する2つの追加メソッドを宣言します。
void SetColor(const color colour); void SetColor(const color colour,const uchar index); void SetColors(const color &array_colors[]); void SetEmptyValue(const double value); virtual void SetLabel(const string label);
最初のメソッドは、指定された新しいカラーインデックスによって新しい色をバッファオブジェクトの色の配列に追加し、2番目のメソッドは、バッファオブジェクトによって使用され、配列内のメソッドに渡されるすべての色を設定できるようにします。
バッファオブジェクトのプロパティ値を返すメソッドのブロックで、バッファが使用する色の数を返すNumberColors()メソッドの名前を変更し、バッファオブジェクトデータを描画するのに使用するバッファ配列の数を返すメソッドを追加します。
//--- Return (1) the serial number of the drawn buffer, (2) bound array index, (3) color buffer index, //--- (4) index of the first free bound array, (5) buffer data period (timeframe) (6) buffer status, //--- (7) buffer type, (8) buffer usage flag, (9) arrow code, (10) arrow shift for DRAW_ARROW style, //--- (11) Number of initial bars that are not drawn and values in DataWindow, (12) graphical construction type, //--- (13) flag of displaying construction values in DataWindow, (14) indicator graphical construction shift along the time axis, //--- (15) drawing line style, (16) drawing line width, (17) number of colors, (18) drawing color, number of buffers for construction //--- (19) set empty value, (20) buffer symbol and (21) name of the indicator graphical series displayed in DataWindow int IndexPlot(void) const { return (int)this.GetProperty(BUFFER_PROP_INDEX_PLOT); } int IndexBase(void) const { return (int)this.GetProperty(BUFFER_PROP_INDEX_BASE); } int IndexColor(void) const { return (int)this.GetProperty(BUFFER_PROP_INDEX_COLOR); } int IndexNextBuffer(void) const { return (int)this.GetProperty(BUFFER_PROP_INDEX_NEXT); } ENUM_TIMEFRAMES Timeframe(void) const { return (ENUM_TIMEFRAMES)this.GetProperty(BUFFER_PROP_TIMEFRAME); } ENUM_BUFFER_STATUS Status(void) const { return (ENUM_BUFFER_STATUS)this.GetProperty(BUFFER_PROP_STATUS); } ENUM_BUFFER_TYPE TypeBuffer(void) const { return (ENUM_BUFFER_TYPE)this.GetProperty(BUFFER_PROP_TYPE); } bool IsActive(void) const { return (bool)this.GetProperty(BUFFER_PROP_ACTIVE); } uchar ArrowCode(void) const { return (uchar)this.GetProperty(BUFFER_PROP_ARROW_CODE); } int ArrowShift(void) const { return (int)this.GetProperty(BUFFER_PROP_ARROW_SHIFT); } int DrawBegin(void) const { return (int)this.GetProperty(BUFFER_PROP_DRAW_BEGIN); } ENUM_DRAW_TYPE DrawType(void) const { return (ENUM_DRAW_TYPE)this.GetProperty(BUFFER_PROP_DRAW_TYPE); } bool IsShowData(void) const { return (bool)this.GetProperty(BUFFER_PROP_SHOW_DATA); } int Shift(void) const { return (int)this.GetProperty(BUFFER_PROP_SHIFT); } ENUM_LINE_STYLE LineStyle(void) const { return (ENUM_LINE_STYLE)this.GetProperty(BUFFER_PROP_LINE_STYLE); } int LineWidth(void) const { return (int)this.GetProperty(BUFFER_PROP_LINE_WIDTH); } int ColorsTotal(void) const { return (int)this.GetProperty(BUFFER_PROP_COLOR_INDEXES); } color Color(void) const { return (color)this.GetProperty(BUFFER_PROP_COLOR); } int BuffersTotal(void) const { return (int)this.GetProperty(BUFFER_PROP_NUM_DATAS); } double EmptyValue(void) const { return this.GetProperty(BUFFER_PROP_EMPTY_VALUE); } string Symbol(void) const { return this.GetProperty(BUFFER_PROP_SYMBOL); } string Label(void) const { return this.GetProperty(BUFFER_PROP_LABEL); }
バッファオブジェクトのプロパティの説明を返すメソッドのブロックで、指定されたバッファ描画色の説明を返すメソッドを追加します。
//--- Return descriptions of the (1) buffer status, (2) buffer type, (3) buffer usage flag, (4) flag of displaying construction values in DataWindow, //--- (5) drawing line style, (6) set empty value, (7) graphical construction type and (8) used timeframe and (9) specified colors string GetStatusDescription(bool draw_type=false)const; string GetTypeBufferDescription(void) const; string GetActiveDescription(void) const; string GetShowDataDescription(void) const; string GetLineStyleDescription(void) const; string GetEmptyValueDescription(void) const; string GetDrawTypeDescription(void) const; string GetTimeframeDescription(void) const; string GetColorsDescription(void) const;
クラス本体の最後に、バッファオブジェクトを操作するためのメソッドのブロックを追加します。
//--- Return the size of the data buffer array virtual int GetDataTotal(const uint buffer_index=0) const; //--- Return the value from the specified index of the specified (1) data and (2) color buffer arrays virtual double GetDataBufferValue(const uint buffer_index,const uint series_index) const; virtual color GetColorBufferValue(const uint series_index) const; //--- Set the value to the specified index of the specified (1) data and (2) color buffer arrays virtual void SetBufferValue(const uint buffer_index,const uint series_index,const double value); virtual void SetBufferColorIndex(const uint series_index,const uchar color_index); //--- Initialize all object buffers by (1) a specified value, (2) the empty value specified for the object virtual void InitializeBuffers(const double value,const uchar color_index); virtual void InitializeBuffers(void); //--- Fill all data buffers with empty values in the specified timeseries index void ClearData(const int series_index); }; //+------------------------------------------------------------------+
メソッドの実装は後で検討されます。
closedパラメトリッククラスコンストラクタが変更されました。
//+------------------------------------------------------------------+ //| Closed parametric constructor | //+------------------------------------------------------------------+ CBuffer::CBuffer(ENUM_BUFFER_STATUS buffer_status, ENUM_BUFFER_TYPE buffer_type, const uint index_plot, const uint index_base_array, const int num_datas, const int width, const string label) { this.m_type=COLLECTION_BUFFERS_ID; //--- Save integer properties this.m_long_prop[BUFFER_PROP_STATUS] = buffer_status; this.m_long_prop[BUFFER_PROP_TYPE] = buffer_type; ENUM_DRAW_TYPE type= ( !this.TypeBuffer() || !this.Status() ? DRAW_NONE : this.Status()==BUFFER_STATUS_FILLING ? DRAW_FILLING : ENUM_DRAW_TYPE(this.Status()+8) ); this.m_long_prop[BUFFER_PROP_DRAW_TYPE] = type; this.m_long_prop[BUFFER_PROP_TIMEFRAME] = PERIOD_CURRENT; this.m_long_prop[BUFFER_PROP_ACTIVE] = true; this.m_long_prop[BUFFER_PROP_ARROW_CODE] = 0x9F; this.m_long_prop[BUFFER_PROP_ARROW_SHIFT] = 0; this.m_long_prop[BUFFER_PROP_DRAW_BEGIN] = 0; this.m_long_prop[BUFFER_PROP_SHOW_DATA] = (buffer_type>BUFFER_TYPE_CALCULATE ? true : false); this.m_long_prop[BUFFER_PROP_SHIFT] = 0; this.m_long_prop[BUFFER_PROP_LINE_STYLE] = STYLE_SOLID; this.m_long_prop[BUFFER_PROP_LINE_WIDTH] = width; this.m_long_prop[BUFFER_PROP_COLOR_INDEXES] = (this.Status()!=BUFFER_STATUS_FILLING ? 1 : 2); this.m_long_prop[BUFFER_PROP_COLOR] = clrRed; this.m_long_prop[BUFFER_PROP_NUM_DATAS] = num_datas; this.m_long_prop[BUFFER_PROP_INDEX_PLOT] = index_plot; this.m_long_prop[BUFFER_PROP_INDEX_BASE] = index_base_array; this.m_long_prop[BUFFER_PROP_INDEX_COLOR] = this.GetProperty(BUFFER_PROP_INDEX_BASE)+this.GetProperty(BUFFER_PROP_NUM_DATAS); this.m_long_prop[BUFFER_PROP_INDEX_NEXT] = this.GetProperty(BUFFER_PROP_INDEX_COLOR)+(this.Status()!=BUFFER_STATUS_FILLING ? 1 : 0); //--- Save real properties this.m_double_prop[this.IndexProp(BUFFER_PROP_EMPTY_VALUE)] = EMPTY_VALUE; //--- Save string properties this.m_string_prop[this.IndexProp(BUFFER_PROP_SYMBOL)] = ::Symbol(); this.m_string_prop[this.IndexProp(BUFFER_PROP_LABEL)] = (this.TypeBuffer()>BUFFER_TYPE_CALCULATE ? label : NULL); //--- If failed to change the size of the drawn buffer array, display the appropriate message indicating the string if(::ArrayResize(this.DataBuffer,(int)this.GetProperty(BUFFER_PROP_NUM_DATAS))==WRONG_VALUE) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_FAILED_DRAWING_ARRAY_RESIZE),". ",CMessage::Text(MSG_LIB_SYS_ERROR),": ",(string)::GetLastError()); //--- If failed to change the size of the color array, display the appropriate message indicating the string if(::ArrayResize(this.ArrayColors,(int)this.ColorsTotal())==WRONG_VALUE) ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_SYS_FAILED_COLORS_ARRAY_RESIZE),". ",CMessage::Text(MSG_LIB_SYS_ERROR),": ",(string)::GetLastError()); //--- For DRAW_FILLING, fill in the color array with two default colors if(this.Status()==BUFFER_STATUS_FILLING) { this.SetColor(clrBlue,0); this.SetColor(clrRed,1); } //--- Bind indicator buffers with arrays //--- In a loop by the number of drawn buffers int total=::ArraySize(DataBuffer); for(int i=0;i<total;i++) { //--- calculate the index of the next array and //--- bind the indicator buffer by the calculated index with the dynamic array //--- located by the i loop index in the DataBuffer array int index=(int)this.GetProperty(BUFFER_PROP_INDEX_BASE)+i; ::SetIndexBuffer(index,this.DataBuffer[i].Array,INDICATOR_DATA); //--- Set indexation flag as in the timeseries to all buffer arrays ::ArraySetAsSeries(this.DataBuffer[i].Array,true); } //--- Binding the color buffer with the array if(this.Status()!=BUFFER_STATUS_FILLING) { ::SetIndexBuffer((int)this.GetProperty(BUFFER_PROP_INDEX_COLOR),this.ColorBufferArray,INDICATOR_COLOR_INDEX); ::ArraySetAsSeries(this.ColorBufferArray,true); } //--- Set integer buffer parameters ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_DRAW_TYPE,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_DRAW_TYPE)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_ARROW,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_ARROW_CODE)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_ARROW_SHIFT,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_ARROW_SHIFT)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_DRAW_BEGIN,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_DRAW_BEGIN)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_SHOW_DATA,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_SHOW_DATA)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_SHIFT,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_SHIFT)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_LINE_STYLE,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_LINE_STYLE)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_LINE_WIDTH,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_LINE_WIDTH)); this.SetColor((color)this.GetProperty(BUFFER_PROP_COLOR)); //--- Set real buffer parameters ::PlotIndexSetDouble((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_EMPTY_VALUE,this.GetProperty(BUFFER_PROP_EMPTY_VALUE)); //--- Set string buffer parameters ::PlotIndexSetString((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_LABEL,this.GetProperty(BUFFER_PROP_LABEL)); } //+------------------------------------------------------------------+
バッファタイプを設定します。
ENUM_DRAW_TYPE type=
(
!this.TypeBuffer() || !this.Status() ? DRAW_NONE :
this.Status()==BUFFER_STATUS_FILLING ? DRAW_FILLING :
ENUM_DRAW_TYPE(this.Status()+8)
);
this.m_long_prop[BUFFER_PROP_DRAW_TYPE] = type;
前の記事で詳細に説明したSetDrawType()メソッドを使用すると、描画タイプを決定できます。
すべてのバッファは色付けされます。描画スタイルを設定するには、SetDrawType()メソッドに渡されたバッファステータスと描画タイプを確認し、それらに応じて、描画を設定しないか、2つのレベル間のスペースを色で塗りつぶします。 または、ステータス列挙インデックスを8単位シフトして、定数値が描画スタイル列挙のカラーバッファの定数に対応するようにします。
クラス本体の外で、メソッドを実装します。
//+------------------------------------------------------------------+ //| Set the graphical construction type | //+------------------------------------------------------------------+ void CBuffer::SetDrawType(void) { ENUM_DRAW_TYPE type=(!this.TypeBuffer() || !this.Status() ? DRAW_NONE : this.Status()==BUFFER_STATUS_FILLING ? DRAW_FILLING : ENUM_DRAW_TYPE(this.Status()+8)); this.SetProperty(BUFFER_PROP_DRAW_TYPE,type); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_DRAW_TYPE,type); } //+------------------------------------------------------------------+
バッファタイプがBUFFER_TYPE_CALCULATE(0)またはBUFFER_STATUS_NONE(0)の場合、描画スタイルは「描画なし」に設定されます。バッファステータスがBUFFER_STATUS_FILLING(色で塗りつぶされている)の場合、適切な描画スタイルが設定されます。残りのすべての値は単に8ずつ増加します。このシフトは、カラー描画スタイルの定数を示します。
ここではクラスコンストラクタで、バッファのタイプを計算する同じメソッドを使用します。
現時点では、SetDrawType()メソッドはクラス内にあります。オブジェクトを作成するときにのみ必要なので、完全に削除されることになるかとおもいます。後で描画タイプを変更する必要はありません。
他の使用方法がすぐに見つかる場合に備えて、一時的に残ります。
線の幅がコンストラクタパラメータに渡されるようになりました。したがって、コンストラクタに渡される値はデフォルトとして設定され、すべての描画タイプのデフォルト色の数はDRAW_FILLINGを除いて1に設定されます。この描画タイプでは常に 2色のみが使用されます。 それらを設定しましょう 。
this.m_long_prop[BUFFER_PROP_LINE_WIDTH] = width; this.m_long_prop[BUFFER_PROP_COLOR_INDEXES] = (this.Status()!=BUFFER_STATUS_FILLING ? 1 : 2);
描画データバッファの数もコンストラクタパラメータで渡されるようになりました。追加してみましょう。
this.m_long_prop[BUFFER_PROP_NUM_DATAS] = num_datas; this.m_long_prop[BUFFER_PROP_INDEX_PLOT] = index_plot; this.m_long_prop[BUFFER_PROP_INDEX_BASE] = index_base_array; this.m_long_prop[BUFFER_PROP_INDEX_COLOR] = this.GetProperty(BUFFER_PROP_INDEX_BASE)+this.GetProperty(BUFFER_PROP_NUM_DATAS); this.m_long_prop[BUFFER_PROP_INDEX_NEXT] = this.GetProperty(BUFFER_PROP_INDEX_COLOR)+(this.Status()!=BUFFER_STATUS_FILLING ? 1 : 0);
次の配列のインデックスを計算して、次のバッファオブジェクトの最初のデータバッファ配列として割り当てるには、DRAW_FILLING描画タイプのバッファはカラーバッファを適用しません。したがって、このような描画タイプのバッファからカラーバッファを除外する必要があります。ここではまさしくこれを行います。すべての描画タイプについて、計算されたカラーバッファインデックス値に1を追加します。「Color filling」の場合、次のバッファのインデックスは、オブジェクトに存在しないカラーバッファの既に計算されたインデックスと既に等しいです。
残りのアクションは、コードへのコメントで説明されています。
色はメソッドで直接オブジェクトプロパティに設定されるため、適切なメソッドを使用して色が設定されるようになりました。さらに、インデックスによって目的の色を取得するために後で使用されるカラー配列が入力されます。
//--- Set integer buffer parameters ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_DRAW_TYPE,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_DRAW_TYPE)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_ARROW,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_ARROW_CODE)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_ARROW_SHIFT,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_ARROW_SHIFT)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_DRAW_BEGIN,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_DRAW_BEGIN)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_SHOW_DATA,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_SHOW_DATA)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_SHIFT,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_SHIFT)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_LINE_STYLE,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_LINE_STYLE)); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_LINE_WIDTH,(ENUM_PLOT_PROPERTY_INTEGER)this.GetProperty(BUFFER_PROP_LINE_WIDTH)); this.SetColor((color)this.GetProperty(BUFFER_PROP_COLOR));
整数プロパティの説明を返すメソッドで、指標の幅と色の説明を返すメソッドが変更されました。
//+------------------------------------------------------------------+ //| Return description of a buffer's integer property | //+------------------------------------------------------------------+ string CBuffer::GetPropertyDescription(ENUM_BUFFER_PROP_INTEGER property) { return ( // ... Removed unnecessary strings // ... // ... property==BUFFER_PROP_LINE_STYLE ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_LINE_STYLE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetLineStyleDescription() ) : property==BUFFER_PROP_LINE_WIDTH ? (this.Status()==BUFFER_STATUS_ARROW ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_ARROW_SIZE) : CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_LINE_WIDTH))+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==BUFFER_PROP_COLOR_INDEXES ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_COLOR_NUM)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==BUFFER_PROP_COLOR ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_COLOR)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetColorsDescription() ) : property==BUFFER_PROP_INDEX_BASE ? CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_INDEX_BASE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : // ... // ... // ... Removed unnecessary strings "" ); } //+------------------------------------------------------------------+
線幅の説明を返すために、バッファのステータスが確認されます。これが矢印指標の場合、その中に線はありません。矢印サイズのエントリが返されます。
色を返すにはGetColorsDescription()メソッドが使用されます。このメソッドは、使用されているすべてのバッファの色説明を返します。バッファ自体については以下で説明します。
指定された空の値の説明を返すメソッドは、設定された負のEMPTY_VALUEをバッファの「空の値」と見なすようになりました。
//+------------------------------------------------------------------+ //| Return description of the set empty value | //+------------------------------------------------------------------+ string CBuffer::GetEmptyValueDescription(void) const { double value=fabs(this.EmptyValue()); return(value<EMPTY_VALUE ? ::DoubleToString(this.EmptyValue(),(this.EmptyValue()==0 ? 1 : 8)) : (this.EmptyValue()>0 ? "EMPTY_VALUE" : "-EMPTY_VALUE")); } //+------------------------------------------------------------------+
以下は、バッファオブジェクトに設定された色の説明を返すメソッドです。
//+------------------------------------------------------------------+ //| Return description of specified colors | //+------------------------------------------------------------------+ string CBuffer::GetColorsDescription(void) const { int total=this.ColorsTotal(); if(total==1) return ::ColorToString(this.Color(),true); string res=""; for(int i=0;i<total;i++) { res+=::ColorToString(this.ArrayColors[i],true)+(i<total-1 ? "," : ""); } return res; } //+------------------------------------------------------------------+
1つの色のみが設定されている場合、色の値を格納するバッファオブジェクトプロパティの文字列の説明が返されます。
色の配列に複数の色が含まれる場合、説明で構成される文字列がループで形成され、取得された値が返されます。
以下は、バッファオブジェクトの色の数を返すメソッドです。
//+------------------------------------------------------------------+ //| Set the number of colors | //+------------------------------------------------------------------+ void CBuffer::SetColorNumbers(const int number) { if(number>IND_COLORS_TOTAL) return; int n=(this.Status()!=BUFFER_STATUS_FILLING ? number : 2); this.SetProperty(BUFFER_PROP_COLOR_INDEXES,n); ::ArrayResize(this.ArrayColors,n); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_COLOR_INDEXES,n); } //+------------------------------------------------------------------+
可能な最大量を超えてメソッドに渡された場合は、メソッドを終了します。
描画タイプがDRAW_FILLINGでない場合、数値は渡されたものと同じに設定されます。それ以外の場合は、2に設定されます。
次に、カラー配列のサイズを変更し、バッファの新しい値を設定します。
以下は、バッファオブジェクトに1つの描画色を設定するメソッドです。
//+------------------------------------------------------------------+ //| Set a single specified drawing color for the buffer | //+------------------------------------------------------------------+ void CBuffer::SetColor(const color colour) { if(this.Status()==BUFFER_STATUS_FILLING) return; this.SetColorNumbers(1); this.SetProperty(BUFFER_PROP_COLOR,colour); this.ArrayColors[0]=colour; ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_LINE_COLOR,0,this.ArrayColors[0]); } //+------------------------------------------------------------------+
描画スタイルがDRAW_FILLINGの場合、メソッドを終了します。この描画スタイルは常に2色を備えています。
次に、色の数を1に設定し、渡された色をバッファオブジェクトプロパティに設定し、渡された色を唯一のカラー配列セルに書き込みおよび指標バッファの色を設定します。
指標の線を再描画するには、(使用された色のリストからの)色インデックスを、色を変更する必要がある必要な時系列インデックスに設定します。
たとえば、3つの色を使用する場合、それらには0、1、2のインデックスがあります。指標の線を3色のいずれかに色付けするには、必要な色の数をカラーバッファに書き込むだけです。インデックス0が青を格納し、インデックス1が赤を格納する場合、指標カラーバッファに0(青)または1(赤)を書き込み、指標の線を再描画します。バッファオブジェクトに設定されている色を変更できるようにするには、指定された指標バッファの色インデックスに新しい色を書き込むメソッドが必要です。
以下は、指定したカラーインデックスの描画色を設定するメソッドです。
//+------------------------------------------------------------------+ //| Set the drawing color to the specified color index | //+------------------------------------------------------------------+ void CBuffer::SetColor(const color colour,const uchar index) { if(index>IND_COLORS_TOTAL-1) return; if(index>this.ColorsTotal()-1) this.SetColorNumbers(index+1); this.ArrayColors[index]=colour; if(index==0) this.SetProperty(BUFFER_PROP_COLOR,(color)this.ArrayColors[0]); ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_LINE_COLOR,index,this.ArrayColors[index]); } //+------------------------------------------------------------------+
メソッドは色とそれが書かれている色インデックスを取得します。
渡されたカラーインデックスが指標の色の使用可能な最大数を超えた場合は終了します。
インデックスが既存のバッファオブジェクトの色の数を超える場合は、新しい数のバッファオブジェクトの色を設定します。
次に、渡された色を色の配列に指定されたインデックスで書きます。ゼロインデックスが渡された場合、メソッドに渡された色をバッファの色プロパティに設定し、最後にメソッドに渡されたインデックスによって新しい色の値を指標バッファに設定します。
以下は、渡された色配列からバッファオブジェクトの色を設定するメソッドです。
//+------------------------------------------------------------------+ //| Set drawing colors from the color array | //+------------------------------------------------------------------+ void CBuffer::SetColors(const color &array_colors[]) { //--- Exit if the passed array is empty if(::ArraySize(array_colors)==0) return; //--- Copy the passed array to the array of buffer object colors ::ArrayCopy(this.ArrayColors,array_colors,0,0,IND_COLORS_TOTAL); //--- Exit if the color array was empty and not copied for some reason int total=::ArraySize(this.ArrayColors); if(total==0) return; //--- If the drawing style is not DRAW_FILLING if(this.Status()!=BUFFER_STATUS_FILLING) { //--- if the new number of colors exceeds the currently set one, //--- set the new value for the number of colors if(total>this.ColorsTotal()) this.SetColorNumbers(total); } //--- If the drawing style is DRAW_FILLING, set the number of colors equal to 2 else total=2; //--- Set the very first color from the color array (for a single color) to the buffer object color property this.SetProperty(BUFFER_PROP_COLOR,(color)this.ArrayColors[0]); //--- Set the new number of colors for the indicator buffer ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_COLOR_INDEXES,total); //--- In the loop by the new number of colors, set all colors by their indices for the indicator buffer for(int i=0;i<total;i++) ::PlotIndexSetInteger((int)this.GetProperty(BUFFER_PROP_INDEX_PLOT),PLOT_LINE_COLOR,i,this.ArrayColors[i]); } //+------------------------------------------------------------------+
すべてのメソッド文字列はコメントで詳細に説明されています。
以下は、必要なバッファ配列の調整されたインデックスを返すメソッドです。
//+------------------------------------------------------------------+ //| Return the adjusted buffer array index | //+------------------------------------------------------------------+ int CBuffer::GetCorrectIndexBuffer(const uint buffer_index) const { return int(buffer_index<this.GetProperty(BUFFER_PROP_NUM_DATAS) ? buffer_index : this.GetProperty(BUFFER_PROP_NUM_DATAS)-1); } //+------------------------------------------------------------------+
指標バッファのすべてのデータ配列は、SDataBuffer構造体型のDataBuffer []配列に配置されるため、誤って渡された配列インデックスを調整するメソッドを使用して、配列の制限を超えないようにします。
渡されたインデックスが構築に使用されたバッファの総数より少ない場合、渡されたインデックスが返されます。
それ以外の場合、 最後の配列要素のインデックスが返されます。
単一の配列の場合、最後の要素は最初の要素と同じです。
以下は、指定されたデータバッファ配列のサイズを返すメソッドです。
//+------------------------------------------------------------------+ //| Return the array size of the specified data buffer | //+------------------------------------------------------------------+ int CBuffer::GetDataTotal(const uint buffer_index=0) const { int index=this.GetCorrectIndexBuffer(buffer_index); return(index>WRONG_VALUE ? ::ArraySize(this.DataBuffer[index].Array) : 0); } //+------------------------------------------------------------------+
このメソッドは、デバッグと内部使用に適用されます。
DataBuffer[]配列のインデックスによって指標バッファとして割り当てられた配列のサイズを返します。
OnInit()は常にゼロを受け取ります。OnCalculate()はrates_totalを受け取ります。
以下は、指定された時系列インデックスによって指定されたデータバッファ値を返すメソッドです。
//+------------------------------------------------------------------+ //| Return the value from the specified timeseries index | //| of the specified data buffer array | //+------------------------------------------------------------------+ double CBuffer::GetDataBufferValue(const uint buffer_index,const uint series_index) const { int correct_buff_index=this.GetCorrectIndexBuffer(buffer_index); int data_total=this.GetDataTotal(correct_buff_index); if(data_total==0) return this.EmptyValue(); int data_index=((int)series_index<data_total ? (int)series_index : data_total-1); return this.DataBuffer[correct_buff_index].Array[data_index]; } //+------------------------------------------------------------------+
このメソッドは、指定された指標バッファから時系列インデックスによってデータを取得および受信するために使用されます。まず、必要なバッファの取得されたインデックスを調整し、バッファ内のデータ量を確認し、データがない場合はバッファオブジェクトに設定された空の値を返します 。次に、時系列インデックスがバッファ内のデータ量を超えていないかどうかを確認します。時系列インデックスが配列の制限を超える場合は、最後のバッファ要素を返します。それ以外の場合は、時系列インデックスによって指定されたバッファからデータを返します。
以下は、指定された時系列インデックスによってカラーバッファ値を返すメソッドです。
//+------------------------------------------------------------------+ //| Return the value from the specified timeseries index | //| of the specified color buffer array | //+------------------------------------------------------------------+ color CBuffer::GetColorBufferValue(const uint series_index) const { int data_total=this.GetDataTotal(0); if(data_total==0) return clrNONE; int data_index=((int)series_index<data_total ? (int)series_index : data_total-1); int color_index=(this.ColorsTotal()==1 ? 0 : (int)this.ColorBufferArray[data_index]); return (color)this.ArrayColors[color_index]; } //+------------------------------------------------------------------+
このメソッドは、先ほど検討したメソッドとほぼ同じですが、常に1つのカラーバッファがあり、目的のバッファのインデックスを取得して調整する必要がない点が異なります。ここでは、すぐに時系列インデックスをチェックし、調整されたインデックスによってバッファからデータを返します(無効なインデックスが渡された場合)。
以下は、指定された時系列インデックスによって指定されたデータバッファに値を設定するメソッドです。
//+------------------------------------------------------------------+ //| Set the value to the specified timeseries index | //| for the specified data buffer array | //+------------------------------------------------------------------+ void CBuffer::SetBufferValue(const uint buffer_index,const uint series_index,const double value) { if(this.GetDataTotal(buffer_index)==0) return; int correct_buff_index=this.GetCorrectIndexBuffer(buffer_index); int data_total=this.GetDataTotal(buffer_index); int data_index=((int)series_index<data_total ? (int)series_index : data_total-1); this.DataBuffer[correct_buff_index].Array[data_index]=value; } //+------------------------------------------------------------------+
このメソッドは、上記の時系列インデックスによって指定されたバッファからデータを取得するメソッドと同じです。ただし、メソッドは値を返す代わりに、指定された時系列インデックスによって、指定されたデータバッファに渡された値を書き込みます。
以下は、指定された時系列インデックスによってカラーバッファの値を設定するメソッドです。
//+------------------------------------------------------------------+ //| Set the color index to the specified timeseries index | //| of the color buffer array | //+------------------------------------------------------------------+ void CBuffer::SetBufferColorIndex(const uint series_index,const uchar color_index) { if(this.GetDataTotal(0)==0 || color_index>this.ColorsTotal()-1 || this.Status()==BUFFER_STATUS_FILLING) return; int data_total=this.GetDataTotal(0); int data_index=((int)series_index<data_total ? (int)series_index : data_total-1); if(::ArraySize(this.ColorBufferArray)==0) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_ERROR),": ",CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_INVALID_PROPERTY_BUFF)); this.ColorBufferArray[data_index]=color_index; } //+------------------------------------------------------------------+
このメソッドは、指定された時系列インデックスからカラーインデックスを取得するメソッドと同じです。ただし、メソッドは値を返す代わりに、指定された時系列インデックスによって、渡されたカラーインデックス値をカラーバッファに書き込みます。
さらに、データ配列に適切なデータがない(空である)か、渡されたカラーインデックスがカラー配列を超えるか、バッファオブジェクトの描画スタイルがDRAW_FILLING(カラーバッファなし)の場合は、メソッドを終了します。
カラーバッファサイズがゼロの場合、#property indicator_buffersに設定された値が正しく設定されていない可能性があります。適切なメッセージが表示されて、 配列エントリの制限を超えて終了するとエラーが発生しますが、操作ログエントリによって指標プロパティのバッファ数を正しく設定できるため、このエラーは意図的に処理されません。
以下は、指定されたデータおよびカラーバッファ値によってすべてのバッファオブジェクトバッファを初期化するメソッドです。
//+------------------------------------------------------------------+ //| Initialize all object buffers by the specified value | //+------------------------------------------------------------------+ void CBuffer::InitializeBuffers(const double value,const uchar color_index) { for(int i=0;i<this.GetProperty(BUFFER_PROP_NUM_DATAS);i++) ::ArrayInitialize(this.DataBuffer[i].Array,value); if(this.Status()!=BUFFER_STATUS_FILLING) ::ArrayInitialize(this.ColorBufferArray,(color_index>this.ColorsTotal()-1 ? 0 : color_index)); } //+------------------------------------------------------------------+
すべてのデータバッファの完全なリストによって、ループ内の指定された値で次の各配列を初期化します。
バッファオブジェクトの描画スタイルがDRAW_FILLINGでない場合、カラー配列の制限を超えて終了する場合に備えて、指定された値を調整してカラーバッファを初期化します。
以下は、バッファオブジェクトに指定された「空の」値によってすべてのバッファオブジェクトバッファ配列を初期化するメソッドです。
//+------------------------------------------------------------------+ //| Initialize all object buffers | //| by the empty value set for the object | //+------------------------------------------------------------------+ void CBuffer::InitializeBuffers(void) { for(int i=0;i<this.GetProperty(BUFFER_PROP_NUM_DATAS);i++) ::ArrayInitialize(this.DataBuffer[i].Array,this.EmptyValue()); if(this.Status()!=BUFFER_STATUS_FILLING) ::ArrayInitialize(this.ColorBufferArray,0); } //+------------------------------------------------------------------+
このメソッドは、初期化値がオブジェクトに設定された「空の」値から取得されることを除いて、上記で検討したものと同じです。また、最初のカラーインデックスは初期化に使用されます。
グラフィカルアーティファクトを回避するために、それらを埋める前に指標内のすべてのバッファの値をクリアする必要があることがよくあります。
次のメソッドは、指定された時系列インデックスのすべてのバッファをクリアします。以下は、バッファオブジェクトのすべての指標バッファを空の値で埋めるメソッドです。
//+------------------------------------------------------------------+ //| Fill all data buffers with the empty value | //| in the specified timeseries index | //+------------------------------------------------------------------+ void CBuffer::ClearData(const int series_index) { for(int i=0;i<this.GetProperty(BUFFER_PROP_NUM_DATAS);i++) this.SetBufferValue(i,series_index,this.EmptyValue()); this.SetBufferColorIndex(series_index,0); } //+------------------------------------------------------------------+
バッファオブジェクトの既存のすべてのバッファ配列によるループで、上記で検討したSetBufferValue()メソッドを使用して、指定した時系列インデックスによってバッファオブジェクトに設定された空の値を書き込みます。前述のSetBufferColorIndex()メソッドを使用すると、カラーインデックスを指定した時系列インデックスに設定できます。
これで、クラスの子孫オブジェクトの作成と操作を目的とした抽象バッファオブジェクトクラスの変更が完了しました。
バッファ指標オブジェクト — 抽象バッファオブジェクトの子孫
よくあることですが、ほとんどすべてのライブラリオブジェクトは同様の構造を持っています。一般的な抽象オブジェクトの持つプロパティとメソッドをその子孫が共有し、各子孫オブジェクトが抽象オブジェクトデータを指定します。第1部(抽象オブジェクト)と第2部(子孫オブジェクトとそのコレクション)の記事でライブラリオブジェクトの概念を検討しました。
バッファオブジェクトも例外ではありません。このような各オブジェクトは、固有の描画スタイルを持つ指標バッファです。オブジェクトの名前は、その描画スタイルに基づいて付けられます。
最初のバッファオブジェクトは矢印の描画スタイルを持ち、それに応じて名前が付けらています。
\MQL5\Include\DoEasy\Objects\Indicators\で、基本クラスがCBuffer抽象バッファのオブジェクトであるCBufferArrowクラスのファイル(BufferArrow.mqh)を作成します。です。
//+------------------------------------------------------------------+ //| BufferArrow.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "Buffer.mqh" //+------------------------------------------------------------------+ //| Buffer with the "Drawing with arrows" drawing style | //+------------------------------------------------------------------+ class CBufferArrow : public CBuffer { private: public: //--- Constructor CBufferArrow(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_ARROW,BUFFER_TYPE_DATA,index_plot,index_base_array,1,1,"Arrows") {} //--- Supported integer properties of a buffer virtual bool SupportProperty(ENUM_BUFFER_PROP_INTEGER property); //--- Supported real properties of a buffer virtual bool SupportProperty(ENUM_BUFFER_PROP_DOUBLE property); //--- Supported string properties of a buffer virtual bool SupportProperty(ENUM_BUFFER_PROP_STRING property); //--- Display a short buffer description in the journal virtual void PrintShort(void); }; //+------------------------------------------------------------------+
ご覧のとおり、クラスのコードには余分なものが何も含まれていません。
整数、実数、文字列のプロパティをサポートするオブジェクトのフラグを返す仮想メソッドと、短いバッファの説明を表示する仮想メソッドが宣言されています。
クラスコンストラクタは、作成された描画指標バッファのインデックス(すべての指標バッファのリスト内のバッファシリアル番号)を受け取り、基本バッファ配列のインデックスは、作成された新しいバッファが実際に接続されている、最初のdouble配列です。
コンストラクタの初期化リストは、親クラスの保護されたコンストラクタの初期化を特徴としています。
CBufferArrow(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_ARROW,BUFFER_TYPE_DATA,index_plot,index_base_array,1,1,"Arrows") {}
最初のパラメータは「矢印付きの描画」スタイルのバッファステータスで、2番目のパラメータは「カラーデータバッファ」バッファタイプです。また、描画されたバッファインデックスの値と基本配列、構築するバッファの数、線の幅(ここではパラメータは矢印のサイズを示します)とグラフィカルシリーズの名前がデータウィンドウに表示されます。したがって、新しいバッファオブジェクトを作成するときに、作成されたバッファのタイプとそのパラメータを基本クラスに通知します。
以下は、バッファが整数プロパティをサポートするかどうかのフラグを返すメソッドです。
//+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| integer property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferArrow::SupportProperty(ENUM_BUFFER_PROP_INTEGER property) { if(property==BUFFER_PROP_LINE_STYLE || (this.TypeBuffer()==BUFFER_TYPE_CALCULATE && property!=BUFFER_PROP_TYPE && property!=BUFFER_PROP_INDEX_NEXT)) return false; return true; } //+------------------------------------------------------------------+
「Line style」プロパティがメソッドに渡されるか、これが「バッファタイプ」または「次に描画されるバッファインデックス」プロパティではない計算バッファである場合は、 サポートがないので false が返されます。それ以外の場合は、trueが返されます。
以下は、バッファが実数プロパティをサポートするかどうかのフラグを返すメソッドです。
//+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| real property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferArrow::SupportProperty(ENUM_BUFFER_PROP_DOUBLE property) { if(this.TypeBuffer()==BUFFER_TYPE_CALCULATE) return false; return true; } //+------------------------------------------------------------------+
これが計算バッファの場合、実数プロパティはサポートされていない(実数プロパティは「何も描かれないところをプロットするための空の値」の1つしかありません)ので、falseを返します。 それ以外の場合は、trueを返します。
以下は、バッファが文字列プロパティをサポートするかどうかのフラグを返すメソッドです。
//+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| string property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferArrow::SupportProperty(ENUM_BUFFER_PROP_STRING property) { if(this.TypeBuffer()==BUFFER_TYPE_CALCULATE) return false; return true; } //+------------------------------------------------------------------+
これが計算バッファの場合、文字列プロパティはサポートされていないので、falseを返します。それ以外の場合は、trueを返します。
以下は、操作ログに短いバッファオブジェクトの説明を表示するメソッドです。
//+------------------------------------------------------------------+ //| Display short buffer description in the journal | //+------------------------------------------------------------------+ void CBufferArrow::PrintShort(void) { ::Print ( CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_BUFFER),"(",(string)this.IndexPlot(),"): ", this.GetStatusDescription(true)," ",this.Symbol()," ",TimeframeDescription(this.Timeframe()) ); } //+------------------------------------------------------------------+
このメソッドは、バッファステータス(描画スタイル)、銘柄、および時間枠を記述する描画バッファ(データウィンドウウィンドウのバッファシリアル番号)のインデックスを指定する文字列を、バッファヘッダから作成します。
例として、
Buffer(0): EURUSD H1を矢印で描画
これは、「矢印付きの描画」タイプのバッファオブジェクトクラス全体です。
\MQL5\Include\DoEasy\Objects\Indicators\BufferLine.mqhに、線の描画スタイルのCBufferLine抽象バッファオブジェクトの新しい子孫クラスを作成します。
//+------------------------------------------------------------------+ //| BufferLine.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "Buffer.mqh" //+------------------------------------------------------------------+ //| Buffer of the Line drawing style | //+------------------------------------------------------------------+ class CBufferLine : public CBuffer { private: public: //--- Constructor CBufferLine(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_LINE,BUFFER_TYPE_DATA,index_plot,index_base_array,1,1,"Line") {} //--- Supported integer properties of a buffer virtual bool SupportProperty(ENUM_BUFFER_PROP_INTEGER property); //--- Supported real properties of a buffer virtual bool SupportProperty(ENUM_BUFFER_PROP_DOUBLE property); //--- Supported string properties of a buffer virtual bool SupportProperty(ENUM_BUFFER_PROP_STRING property); //--- Display a short buffer description in the journal virtual void PrintShort(void); }; //+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| integer property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferLine::SupportProperty(ENUM_BUFFER_PROP_INTEGER property) { if((property==BUFFER_PROP_ARROW_CODE || property==BUFFER_PROP_ARROW_SHIFT) || (this.TypeBuffer()==BUFFER_TYPE_CALCULATE && property!=BUFFER_PROP_TYPE && property!=BUFFER_PROP_INDEX_NEXT) ) return false; return true; } //+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| real property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferLine::SupportProperty(ENUM_BUFFER_PROP_DOUBLE property) { if(this.TypeBuffer()==BUFFER_TYPE_CALCULATE) return false; return true; } //+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| string property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferLine::SupportProperty(ENUM_BUFFER_PROP_STRING property) { if(this.TypeBuffer()==BUFFER_TYPE_CALCULATE) return false; return true; } //+------------------------------------------------------------------+ //| Display short buffer description in the journal | //+------------------------------------------------------------------+ void CBufferLine::PrintShort(void) { ::Print ( CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_BUFFER),"(",(string)this.IndexPlot(),"): ", this.GetStatusDescription(true)," ",this.Symbol()," ",TimeframeDescription(this.Timeframe()) ); } //+------------------------------------------------------------------+
取引バッファクラスと比較して、クラスコンストラクタでは、ラインステータスおよびライングラフィカルシリーズ名が初期化リストの基本バッファオブジェクトコンストラクタに渡されます。残りのパラメータは、矢印バッファオブジェクトの場合と同じです。
CBufferLine(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_LINE,BUFFER_TYPE_DATA,index_plot,index_base_array,1,1,"Line") {}
整数プロパティのバッファサポートを示すフラグを返すメソッドも変更されました。
//+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| integer property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferLine::SupportProperty(ENUM_BUFFER_PROP_INTEGER property) { if((property==BUFFER_PROP_ARROW_CODE || property==BUFFER_PROP_ARROW_SHIFT) || (this.TypeBuffer()==BUFFER_TYPE_CALCULATE && property!=BUFFER_PROP_TYPE && property!=BUFFER_PROP_INDEX_NEXT) ) return false; return true; } //+------------------------------------------------------------------+
これが「矢印コード」または「垂直矢印シフト」プロパティである場合、または「バッファタイプ」または「次に描画されるバッファインデックス」プロパティではない計算バッファの場合は 、サポートされておらず、falseが返されます。それ以外の場合は、trueが返されます。
\MQL5\Include\DoEasy\Objects\Indicators\BufferSection.mqhで、セクション描画スタイルのCBufferSection抽象バッファオブジェクトの新しい子孫クラスを作成します。
他のすべては説明されている2つのクラスと同一であるため、新しいクラスのコンストラクタと整数プロパティをサポートするメソッドのみがさらに考慮されます。
クラスコンストラクタで、「セクション」ステータスおよび「セクション」グラフィカルシリーズ名が、初期化リストで基本バッファオブジェクトコンストラクタに渡されます
CBufferSection(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_SECTION,BUFFER_TYPE_DATA,index_plot,index_base_array,1,1,"Section") {}
以下は、バッファが整数プロパティをサポートするかどうかのフラグを返すメソッドです。
//+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| integer property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferSection::SupportProperty(ENUM_BUFFER_PROP_INTEGER property) { if((property==BUFFER_PROP_ARROW_CODE || property==BUFFER_PROP_ARROW_SHIFT) || (this.TypeBuffer()==BUFFER_TYPE_CALCULATE && property!=BUFFER_PROP_TYPE && property!=BUFFER_PROP_INDEX_NEXT) ) return false; return true; } //+------------------------------------------------------------------+
これが「矢印コード」または「垂直矢印シフト」プロパティである場合、または「バッファタイプ」または「次に描画されるバッファインデックス」プロパティではない計算バッファの場合は 、サポートされておらず、falseが返されます。それ以外の場合は、trueが返されます。
\MQL5\Include\DoEasy\Objects\Indicators\BufferHistogram.mqhで「ゼロラインからのヒストグラム」描画スタイルのCBufferHistogram抽象バッファオブジェクトの新しい子孫クラスを作成します。
クラスコンストラクタで、「ゼロラインからのヒストグラム」ステータスと「ヒストグラムグラフィカルシリーズ名」が、初期化リストで基本バッファオブジェクトコンストラクタに渡されます。 ヒストグラムの線幅はデフォルトで2に等しいです。
CBufferHistogram(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_HISTOGRAM,BUFFER_TYPE_DATA,index_plot,index_base_array,1,2,"Histogram") {}
残りのメソッドは、セクションバッファオブジェクトクラスと同じです。
\MQL5\Include\DoEasy\Objects\Indicators\BufferHistogram2.mqhで「2つの指標バッファのヒストグラム」描画スタイルのCBufferHistogram2抽象バッファオブジェクトの新しい子孫クラスを作成します。
クラスコンストラクタで、「2つの指標バッファでのヒストグラム」ステータス、「Histogram2 0; Histogram2 1」グラフィカルシリーズ名、 2つの構築バッファが、初期化リストで基本バッファオブジェクトコンストラクタに渡されます。ヒストグラムの線幅はデフォルトで8です。
CBufferHistogram2(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_HISTOGRAM2,BUFFER_TYPE_DATA,index_plot,index_base_array,2,8,"Histogram2 0;Histogram2 1") {}
ヒストグラムの線幅が8なのは何故でしょうか。
MQL5、つまり2つのバッファに基づくヒストグラム指標では、これは水平チャートスケールに応じた最大ヒストグラム列幅サイズです。
最大チャートスケール(5)では、ヒストグラムの列幅が最大サイズになります。小さいサイズが必要な場合は、バッファの作成後にSetWidth()メソッドを使用して新しい幅の値を設定します。
「Histogram2 0; Histogram2 1」グラフィカルシリーズにこのような名前があるのはなぜでしょうか。
複数のバッファを構築に適用する指標では、各バッファの名前はグラフィカルシリーズ名で指定されます。各バッファに一意の名前を設定する必要がある場合は、グラフィカルシリーズ名を指定するときに、それらをセミコロン(;)で区切ります。
ここでは、「Histogram2 0」という名前が最初のバッファに設定され(ゼロは最初のバッファインデックスを指定)、2番目のバッファは「Histogram2 1」という名前になっています(1つは2番目のバッファインデックスを示します)。
これはDataWindowで次のように見えます。
必要に応じて、バッファの作成後にSetLabel()メソッドを使用して新しいバッファ名を設定できます。
残りのメソッドは、セクションバッファオブジェクトクラスと同じです。
\MQL5\Include\DoEasy\Objects\Indicators\BufferSection.mqhで、セクション描画スタイルのCBufferZigZag抽象バッファオブジェクトの新しい子孫クラスを作成します。
クラスコンストラクタで「2つの指標バッファでのZigzag 」ステータス、「ZigZag 0;ZigZag 1 」グラフィカルシリーズ名、2つの構築バッファが、初期化リストで基本バッファオブジェクトコンストラクタに渡されます。ZigZagの線幅はデフォルトで1です。
CBufferZigZag(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_ZIGZAG,BUFFER_TYPE_DATA,index_plot,index_base_array,2,1,"ZigZag 0;ZigZag 1") {}
残りのメソッドは、セクションバッファオブジェクトクラスと同じです。
\MQL5\Include\DoEasy\Objects\Indicators\BufferFilling.mqhで「2つのレベル間の塗りつぶし」描画スタイルのCBufferFilling抽象バッファオブジェクトの新しい子孫クラスを作成します。
クラスコンストラクタで、「2つのレベル間の塗りつぶし 」ステータス、「Filling 0;Filling 1」グラフィカルシリーズ名、2つの構築バッファが、初期化リストで基本バッファオブジェクトコンストラクタに渡されます。線幅はデフォルトで1です(この描画スタイルには線がないため、このプロパティは無関係です)。
CBufferFilling(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_FILLING,BUFFER_TYPE_DATA,index_plot,index_base_array,2,1,"Filling 0;Filling 1") {}
以下は、整数プロパティのバッファサポートを示すフラグを返すメソッドです。
//+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| integer property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferFilling::SupportProperty(ENUM_BUFFER_PROP_INTEGER property) { if((property==BUFFER_PROP_ARROW_CODE || property==BUFFER_PROP_ARROW_SHIFT) || property==BUFFER_PROP_LINE_STYLE || property==BUFFER_PROP_LINE_WIDTH || property==BUFFER_PROP_INDEX_COLOR || (this.TypeBuffer()==BUFFER_TYPE_CALCULATE && property!=BUFFER_PROP_TYPE && property!=BUFFER_PROP_INDEX_NEXT) ) return false; return true; } //+------------------------------------------------------------------+
これが「矢印コード」または「垂直矢印シフト」プロパティである場合、または「バッファタイプ」または「次に描画されるバッファインデックス」プロパティではない計算バッファの場合は 、サポートされておらず、falseが返されます。それ以外の場合は、trueが返されます。
残りのメソッドは、セクションバッファオブジェクトクラスと同じです。
\MQL5\Include\DoEasy\Objects\Indicators\BufferSection.mqhで、「バーとして表示」描画スタイルのCBufferBars抽象バッファオブジェクトの新しい子孫クラスを作成します。
クラスコンストラクタで、「バーとして表示 」ステータス、「Bar Open;Bar High;Bar Low;Bar Close」グラフィカルシリーズ名、4つの構築バッファが、初期化リストで基本バッファオブジェクトコンストラクタに渡されます。バーの幅はデフォルトで2です。
CBufferBars(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_BARS,BUFFER_TYPE_DATA,index_plot,index_base_array,4,2,"Bar Open;Bar High;Bar Low;Bar Close") {}
以下は、整数プロパティのバッファサポートを示すフラグを返すメソッドです。
//+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| integer property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferBars::SupportProperty(ENUM_BUFFER_PROP_INTEGER property) { if((property==BUFFER_PROP_ARROW_CODE || property==BUFFER_PROP_ARROW_SHIFT) || property==BUFFER_PROP_LINE_STYLE || (this.TypeBuffer()==BUFFER_TYPE_CALCULATE && property!=BUFFER_PROP_TYPE && property!=BUFFER_PROP_INDEX_NEXT) ) return false; return true; } //+------------------------------------------------------------------+
これが「矢印コード」「垂直矢印シフト」「線のスタイル」プロパティである場合、または「バッファタイプ」または「次に描画されるバッファインデックス」プロパティではない計算バッファの場合は 、サポートされておらず、falseが返されます。それ以外の場合は、trueが返されます。
残りのメソッドは、セクションバッファオブジェクトクラスと同じです。
\MQL5\Include\DoEasy\Objects\Indicators\BufferCandles.mqhで、「ローソク足として表示」描画スタイルのCBufferCandles抽象バッファオブジェクトの新しい子孫クラスを作成します。
クラスコンストラクタで、「ローソク足として表示 」ステータス、「Candle Open;Candle High;Candle Low;Candle Close」グラフィカルシリーズ名、4つの構築バッファが、初期化リストの基本バッファオブジェクトコンストラクタに渡されます。ローソク足の幅はデフォルトで1に等しくなります(ローソク足の幅は、水平スケールに応じて常にチャートのローソク足幅に等しいため、実際の描画の幅には影響しません)。
CBufferCandles(const uint index_plot,const uint index_base_array) : CBuffer(BUFFER_STATUS_CANDLES,BUFFER_TYPE_DATA,index_plot,index_base_array,4,1,"Candle Open;Candle High;Candle Low;Candle Close") {}
以下は、整数プロパティのバッファサポートを示すフラグを返すメソッドです。
//+------------------------------------------------------------------+ //| Return 'true' if a buffer supports a passed | //| integer property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CBufferCandles::SupportProperty(ENUM_BUFFER_PROP_INTEGER property) { if((property==BUFFER_PROP_ARROW_CODE || property==BUFFER_PROP_ARROW_SHIFT) || property==BUFFER_PROP_LINE_STYLE || property==BUFFER_PROP_LINE_WIDTH || (this.TypeBuffer()==BUFFER_TYPE_CALCULATE && property!=BUFFER_PROP_TYPE && property!=BUFFER_PROP_INDEX_NEXT) ) return false; return true; } //+------------------------------------------------------------------+
これが「矢印コード」「垂直矢印シフト」「線のスタイル」「線の幅」プロパティのいずれかである場合、または「バッファタイプ」または「次に描画されるバッファインデックス」プロパティではない計算バッファの場合は 、サポートされておらず、falseが返されます。それ以外の場合は、trueが返されます。
残りのメソッドは、セクションバッファオブジェクトクラスと同じです。
抽象バッファオブジェクトの子孫のすべてのバッファオブジェクトクラスが作成されました。
クラスの完全なコードは、下記に添付されているファイルでご覧ください。
チャート上のバッファラインの表示を管理するためのボタンを導入するのではなく、代わりに指標設定で必要なグラフィック構造を設定しましょう。表示するバッファを選択して、指標を起動できます。
テスト
必要なグラフィック構造を選択できるようにするには、英語とロシア語のコンパイル言語の入力列挙ファイル( \MQL5\Include\DoEasy\InpDatas.mqh)に新しい列挙を追加します。
//+------------------------------------------------------------------+ //| InpDatas.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/en/users/artmedia70" //+------------------------------------------------------------------+ //| Macro substitutions | //+------------------------------------------------------------------+ #define COMPILE_EN // Comment out the string for compilation in Russian //+------------------------------------------------------------------+ //| Input enumerations | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| English language inputs | //+------------------------------------------------------------------+ #ifdef COMPILE_EN //+------------------------------------------------------------------+ //| Modes of working with symbols | //+------------------------------------------------------------------+ enum ENUM_SYMBOLS_MODE { SYMBOLS_MODE_CURRENT, // Work only with the current Symbol SYMBOLS_MODE_DEFINES, // Work with a given list of Symbols SYMBOLS_MODE_MARKET_WATCH, // Working with Symbols from the "Market Watch" window SYMBOLS_MODE_ALL // Work with a complete list of Symbols }; //+------------------------------------------------------------------+ //| Mode of working with timeframes | //+------------------------------------------------------------------+ enum ENUM_TIMEFRAMES_MODE { TIMEFRAMES_MODE_CURRENT, // Work only with the current timeframe TIMEFRAMES_MODE_LIST, // Work with a given list of timeframes TIMEFRAMES_MODE_ALL // Work with a complete list of timeframes }; //+------------------------------------------------------------------+ //| "Yes"/"No" | //+------------------------------------------------------------------+ enum ENUM_INPUT_YES_NO { INPUT_NO = 0, // No INPUT_YES = 1 // Yes }; //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Russian language inputs | //+------------------------------------------------------------------+ #else //+------------------------------------------------------------------+ //| Modes of working with symbols | //+------------------------------------------------------------------+ enum ENUM_SYMBOLS_MODE { SYMBOLS_MODE_CURRENT, // Работа только с текущим символом SYMBOLS_MODE_DEFINES, // Работа с заданным списком символов SYMBOLS_MODE_MARKET_WATCH, // Работа с символами из окна "Обзор рынка" SYMBOLS_MODE_ALL // Работа с полным списком символов }; //+------------------------------------------------------------------+ //| Mode of working with timeframes | //+------------------------------------------------------------------+ enum ENUM_TIMEFRAMES_MODE { TIMEFRAMES_MODE_CURRENT, // Работа только с текущим таймфреймом TIMEFRAMES_MODE_LIST, // Работа с заданным списком таймфреймов TIMEFRAMES_MODE_ALL // Работа с полным списком таймфреймов }; //+------------------------------------------------------------------+ //| "Yes"/"No" | //+------------------------------------------------------------------+ enum ENUM_INPUT_YES_NO { INPUT_NO = 0, // Нет INPUT_YES = 1 // Да }; //+------------------------------------------------------------------+ #endif //+------------------------------------------------------------------+
これにより、設定の選択肢が提供されます。
テストを実行するには、前の記事のEAを\MQL5\Experts\TestDoEasy\Part43\でTestDoEasyPart43.mq5として保存します。
作成されたすべてのバッファのファイルを指標ファイルに含め、使用されるバッファの数を27に設定し、描画されるバッファ数は9に設定します。
//+------------------------------------------------------------------+ //| TestDoEasyPart43.mq5 | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" //--- includes #include <DoEasy\Engine.mqh> #include <DoEasy\Objects\Indicators\BufferArrow.mqh> // 1 construction buffer + 1 color buffer #include <DoEasy\Objects\Indicators\BufferLine.mqh> // 1 construction buffer + 1 color buffer #include <DoEasy\Objects\Indicators\BufferSection.mqh> // 1 construction buffer + 1 color buffer #include <DoEasy\Objects\Indicators\BufferHistogram.mqh> // 1 construction buffer + 1 color buffer #include <DoEasy\Objects\Indicators\BufferHistogram2.mqh> // 2 construction buffers + 1 color buffer #include <DoEasy\Objects\Indicators\BufferZigZag.mqh> // 2 construction buffers + 1 color buffer #include <DoEasy\Objects\Indicators\BufferFilling.mqh> // 2 construction buffers + 1 color buffer #include <DoEasy\Objects\Indicators\BufferBars.mqh> // 4 construction buffer + 1 color buffer #include <DoEasy\Objects\Indicators\BufferCandles.mqh> // 4 construction buffer + 1 color buffer //--- In total: 18 construction buffers + 9 color buffers: 27 indicator buffers, of which 9 are drawn ones //--- properties #property indicator_chart_window #property indicator_buffers 27 #property indicator_plots 9
入力ブロックで、sinput修飾子をコメントアウトして、銘柄の操作モードを選択します(現在のものがデフォルトで使用されます)、使用されている銘柄のリストを設定から非表示にします 、デフォルトで現在の作業時間枠選択モードを設定、設定から使用済み時間枠のリストを非表示にして、設定のグラフに表示するバッファを選択する機能を追加します。
//--- classes //--- enums //--- defines //--- structures //--- input variables /*sinput*/ ENUM_SYMBOLS_MODE InpModeUsedSymbols= SYMBOLS_MODE_CURRENT; // Mode of used symbols list /*sinput*/ string InpUsedSymbols = "EURUSD,AUDUSD,EURAUD,EURGBP,EURCAD,EURJPY,EURUSD,GBPUSD,NZDUSD,USDCAD,USDJPY"; // List of used symbols (comma - separator) /*sinput*/ ENUM_TIMEFRAMES_MODE InpModeUsedTFs = TIMEFRAMES_MODE_CURRENT; // Mode of used timeframes list /*sinput*/ string InpUsedTFs = "M1,M5,M15,M30,H1,H4,D1,W1,MN1"; // List of used timeframes (comma - separator) sinput ENUM_INPUT_YES_NO InpDrawArrow = INPUT_YES; // Draw Arrow sinput ENUM_INPUT_YES_NO InpDrawLine = INPUT_NO; // Draw Line sinput ENUM_INPUT_YES_NO InpDrawSection = INPUT_NO; // Draw Section sinput ENUM_INPUT_YES_NO InpDrawHistogram = INPUT_NO; // Draw Histogram sinput ENUM_INPUT_YES_NO InpDrawHistogram2 = INPUT_NO; // Draw Histogram2 sinput ENUM_INPUT_YES_NO InpDrawZigZag = INPUT_NO; // Draw ZigZag sinput ENUM_INPUT_YES_NO InpDrawFilling = INPUT_NO; // Draw Filling sinput ENUM_INPUT_YES_NO InpDrawBars = INPUT_NO; // Draw Bars sinput ENUM_INPUT_YES_NO InpDrawCandles = INPUT_YES; // Draw Candles sinput bool InpUseSounds = true; // Use sounds
指標バッファのdouble配列を宣言する代わりに、CObjectインスタンスへのポインタの動的配列の宣言を追加します。リストは、テスト用に作成された指標バッファオブジェクトを格納するためのものです。
//--- indicator buffers CArrayObj list_buffers; // Temporary list for storing buffer objects //--- global variables CEngine engine; // CEngine library main object string prefix; // Prefix of graphical object names int min_bars; // The minimum number of bars for the indicator calculation int used_symbols_mode; // Mode of working with symbols string array_used_symbols[]; // The array for passing used symbols to the library string array_used_periods[]; // The array for passing used timeframes to the library //+------------------------------------------------------------------+
指標のOnInit()ハンドラで、すべてのバッファオブジェクトを作成してリストに追加し、デフォルト以外の色(3色)を設定して、作成された各バッファオブジェクトのデータを操作ログで表示します。
//+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Initialize DoEasy library OnInitDoEasy(); //--- Set indicator global variables prefix=engine.Name()+"_"; //--- Get the index of the maximum used timeframe in the array, //--- calculate the number of bars of the current period fitting in the maximum used period //--- Use the obtained value if it exceeds 2, otherwise use 2 int index=ArrayMaximum(ArrayUsedTimeframes); int num_bars=NumberBarsInTimeframe(ArrayUsedTimeframes[index]); min_bars=(index>WRONG_VALUE ? (num_bars>2 ? num_bars : 2) : 2); //--- Check and remove remaining indicator graphical objects if(IsPresentObectByPrefix(prefix)) ObjectsDeleteAll(0,prefix); //--- Create the button panel //--- Check playing a standard sound using macro substitutions engine.PlaySoundByDescription(SND_OK); //--- Wait for 600 milliseconds engine.Pause(600); engine.PlaySoundByDescription(SND_NEWS); //--- indicator buffers mapping //--- Create all buffer objects CBuffer *buffer0=new CBufferArrow(0,0); CBuffer *buffer1=new CBufferLine(1,buffer0.IndexNextBuffer()); CBuffer *buffer2=new CBufferSection(2,buffer1.IndexNextBuffer()); CBuffer *buffer3=new CBufferHistogram(3,buffer2.IndexNextBuffer()); CBuffer *buffer4=new CBufferHistogram2(4,buffer3.IndexNextBuffer()); CBuffer *buffer5=new CBufferZigZag(5,buffer4.IndexNextBuffer()); CBuffer *buffer6=new CBufferFilling(6,buffer5.IndexNextBuffer()); CBuffer *buffer7=new CBufferBars(7,buffer6.IndexNextBuffer()); CBuffer *buffer8=new CBufferCandles(8,buffer7.IndexNextBuffer()); //--- Add buffers to the list of indicator buffers list_buffers.Add(buffer0); list_buffers.Add(buffer1); list_buffers.Add(buffer2); list_buffers.Add(buffer3); list_buffers.Add(buffer4); list_buffers.Add(buffer5); list_buffers.Add(buffer6); list_buffers.Add(buffer7); list_buffers.Add(buffer8); //--- Create color array color array_colors[]={clrDodgerBlue,clrRed,clrGray}; //--- Set non-default buffer color values for(int i=0;i<list_buffers.Total();i++) { CBuffer *buff=list_buffers.At(i); buff.SetColors(array_colors); //--- Print data on the next buffer buff.Print(); } //--- Set the label size for the arrow buffer and the line width for ZigZag buffer0.SetWidth(2); buffer5.SetWidth(2); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+
OnCalculate()ハンドラで
履歴データを初期化または変更するときは、作成されたすべてのバッファを初期化し、それらの短縮名を表示します。
新しいバーまたは現在のティックで、 価格値をバッファに書き込みます。
単一のバッファ— 終値
2つのバッファ— 1つ目は始値、2つ目は終値
4つのバッファ — 各バッファに適切なOHLC価格を入力
//+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //+------------------------------------------------------------------+ //| OnCalculate code block for working with the library: | //+------------------------------------------------------------------+ //--- Pass the current symbol data from OnCalculate() to the price structure CopyData(rates_total,prev_calculated,time,open,high,low,close,tick_volume,volume,spread); //--- Check for the minimum number of bars for calculation if(rates_total<min_bars || Point()==0) return 0; //--- Handle the Calculate event in the library //--- If the OnCalculate() method of the library returns zero, not all timeseries are ready - leave till the next tick if(engine.0) return 0; //--- If working in the tester if(MQLInfoInteger(MQL_TESTER)) { engine.OnTimer(rates_data); // Working in the library timer EventsHandling(); // Working with library events } //+------------------------------------------------------------------+ //| OnCalculate code block for working with the indicator: | //+------------------------------------------------------------------+ //--- Set OnCalculate arrays as timeseries ArraySetAsSeries(open,true); ArraySetAsSeries(high,true); ArraySetAsSeries(low,true); ArraySetAsSeries(close,true); ArraySetAsSeries(time,true); ArraySetAsSeries(tick_volume,true); ArraySetAsSeries(volume,true); ArraySetAsSeries(spread,true); //--- Check and calculate the number of calculated bars //--- If limit = 0, there are no new bars - calculate the current one //--- If limit = 1, a new bar has appeared - calculate the first and the current ones //--- limit > 1 means the first launch or changes in history - the full recalculation of all data int limit=rates_total-prev_calculated; //--- Recalculate the entire history if(limit>1) { //--- In a loop by the number of buffers in the list for(int i=0;i<list_buffers.Total();i++) { //--- get the next buffer and display the type of its graphical construction to the journal //--- together with the double array assigned to the buffer (if all is correct, the size is equal to rates_total) CBuffer *buff=list_buffers.At(i); buff.PrintShort(); buff.InitializeBuffers(); } limit=rates_total-1; } //--- Prepare data //--- Calculate the indicator for(int i=limit; i>WRONG_VALUE && !IsStopped(); i--) { //--- In a loop by the number of buffers in the list for(int j=0;j<list_buffers.Total();j++) { //--- get the next buffer and CBuffer *buff=list_buffers.At(j); //--- clear its current data buff.ClearData(0); //--- If drawing is not used, move on to the next one if(!IsUse(buff.Status())) continue; //--- Depending on the number of buffers, fill them with price data //--- one buffer if(buff.BuffersTotal()==1) buff.SetBufferValue(0,i,close[i]); //--- two buffers - the first one is to store the bar open price, while the second one is to store the bar close price else if(buff.BuffersTotal()==2) { buff.SetBufferValue(0,i,open[i]); buff.SetBufferValue(1,i,close[i]); } //--- four buffers - each buffer is to store OHLC bar prices else if(buff.BuffersTotal()==4) { buff.SetBufferValue(0,i,open[i]); buff.SetBufferValue(1,i,high[i]); buff.SetBufferValue(2,i,low[i]); buff.SetBufferValue(3,i,close[i]); } //--- Set the buffer color depending on the candle direction if(open[i]<close[i]) buff.SetBufferColorIndex(i,0); else if(open[i]>close[i]) buff.SetBufferColorIndex(i,1); else buff.SetBufferColorIndex(i,2); } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+
次の関数を使用して、指標の線の描画が有効かどうかを定義します。
//+---------------------------------------------------------------------+ //| Return the flag indicating the appropriate drawing style is enabled | //+---------------------------------------------------------------------+ bool IsUse(const ENUM_BUFFER_STATUS status) { switch(status) { case BUFFER_STATUS_FILLING : return (bool)InpDrawFilling; case BUFFER_STATUS_LINE : return (bool)InpDrawLine; case BUFFER_STATUS_HISTOGRAM : return (bool)InpDrawHistogram; case BUFFER_STATUS_ARROW : return (bool)InpDrawArrow; case BUFFER_STATUS_SECTION : return (bool)InpDrawSection; case BUFFER_STATUS_HISTOGRAM2 : return (bool)InpDrawHistogram2; case BUFFER_STATUS_ZIGZAG : return (bool)InpDrawZigZag; case BUFFER_STATUS_BARS : return (bool)InpDrawBars; case BUFFER_STATUS_CANDLES : return (bool)InpDrawCandles; default: return false; } } //+------------------------------------------------------------------+
関数はバッファステータスを受け取り、関数に渡されたステータスに対応する入力値を返します。
完全な指標コードは、以下に添付されているファイルで提供されます。
指標をコンパイルして、チャート上で起動します。
初期化中、指標は作成された9つの指標バッファのすべてのプロパティを表示します。
Account 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10425.23 USD, 1:100, Hedge, MetaTrader 5 demo --- Initializing "DoEasy" library --- Working with the current symbol only: "EURUSD" Working with the current timeframe only: H1 EURUSD symbol timeseries: - Timeseries "EURUSD" H1: Requested: 1000, Actual: 0, Created: 0, On the server: 0 Library initialization time: 00:00:00.156 ============= Parameter list start: Colored data buffer[0] "Drawing with arrows" ================== Plotted buffer serial number: 0 Buffer status: Indicator buffer with graphical construction type "Drawing with arrows" Buffer type: Colored data buffer Buffer data period (timeframe): Current chart period (H1) Active: Yes Graphical construction type: Drawing with arrows Arrow code: 159 The vertical shift of the arrows: 0 Arrow size: 1 The number of initial bars that are not drawn and values in DataWindow: 0 Display construction values in DataWindow: Yes Indicator graphical construction shift by time axis in bars: 0 Number of colors: 3 Drawing color: clrDodgerBlue,clrRed,clrGray Number of data buffers: 1 Base data buffer index: 0 Color buffer index: 1 Index of the array to be assigned as the next indicator buffer: 2 ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Buffer symbol: EURUSD Name of the graphical indicator series displayed in DataWindow: Arrows ================== Parameter list end: Colored data buffer[0] "Drawing with arrows" ================== ============= Parameter list start: Colored data buffer[1] "Line" ================== Plotted buffer serial number: 1 Buffer status: Indicator buffer with graphical construction type "Line" Buffer type: Colored data buffer Buffer data period (timeframe): Current chart period (H1) Active: Yes Graphical construction type: Line Line style: Solid line Line width: 1 The number of initial bars that are not drawn and values in DataWindow: 0 Display construction values in DataWindow: Yes Indicator graphical construction shift by time axis in bars: 0 Number of colors: 3 Drawing color: clrDodgerBlue,clrRed,clrGray Number of data buffers: 1 Base data buffer index: 2 Color buffer index: 3 Index of the array to be assigned as the next indicator buffer: 4 ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Buffer symbol: EURUSD Name of the graphical indicator series displayed in DataWindow: Line ================== Parameter list end: Colored data buffer[1] "Line" ================== ============= Parameter list start: Colored data buffer[2] "Section" ================== Plotted buffer serial number: 2 Buffer status: Indicator buffer with graphical construction type "Section" Buffer type: Colored data buffer Buffer data period (timeframe): Current chart period (H1) Active: Yes Graphical construction type: Section Line style: Solid line Line width: 1 The number of initial bars that are not drawn and values in DataWindow: 0 Display construction values in DataWindow: Yes Indicator graphical construction shift by time axis in bars: 0 Number of colors: 3 Drawing color: clrDodgerBlue,clrRed,clrGray Number of data buffers: 1 Base data buffer index: 4 Color buffer index: 5 Index of the array to be assigned as the next indicator buffer: 6 ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Buffer symbol: EURUSD Name of the graphical indicator series displayed in DataWindow: Section ================== Parameter list end: Colored data buffer[2] "Section" ================== ============= Parameter list start: Colored data buffer[3] "Histogram from the zero line" ================== Plotted buffer serial number: 3 Buffer status: Indicator buffer with graphical construction type "Histogram from the zero line" Buffer type: Colored data buffer Buffer data period (timeframe): Current chart period (H1) Active: Yes Graphical construction type: Histogram from the zero line Line style: Solid line Line width: 2 The number of initial bars that are not drawn and values in DataWindow: 0 Display construction values in DataWindow: Yes Indicator graphical construction shift by time axis in bars: 0 Number of colors: 3 Drawing color: clrDodgerBlue,clrRed,clrGray Number of data buffers: 1 Base data buffer index: 6 Color buffer index: 7 Index of the array to be assigned as the next indicator buffer: 8 ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Buffer symbol: EURUSD Name of the graphical indicator series displayed in DataWindow: Histogram ================== Parameter list end: Colored data buffer[3] "Histogram from the zero line" ================== ============= Parameter list start: Colored data buffer[4] "Histogram on two indicator buffers" ================== Plotted buffer serial number: 4 Buffer status: Indicator buffer with graphical construction type "Histogram on two indicator buffers" Buffer type: Colored data buffer Buffer data period (timeframe): Current chart period (H1) Active: Yes Graphical construction type: Histogram on two indicator buffers Line style: Solid line Line width: 8 The number of initial bars that are not drawn and values in DataWindow: 0 Display construction values in DataWindow: Yes Indicator graphical construction shift by time axis in bars: 0 Number of colors: 3 Drawing color: clrDodgerBlue,clrRed,clrGray Number of data buffers: 2 Base data buffer index: 8 Color buffer index: 10 Index of the array to be assigned as the next indicator buffer: 11 ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Buffer symbol: EURUSD Name of the graphical indicator series displayed in DataWindow: Histogram2 0;Histogram2 1 ================== Parameter list end: Colored data buffer[4] "Histogram on two indicator buffers" ================== ============= Parameter list start: Colored data buffer[5] "Zigzag" ================== Plotted buffer serial number: 5 Buffer status: Indicator buffer with graphical construction type "Zigzag" Buffer type: Colored data buffer Buffer data period (timeframe): Current chart period (H1) Active: Yes Graphical construction type: Zigzag Line style: Solid line Line width: 1 The number of initial bars that are not drawn and values in DataWindow: 0 Display construction values in DataWindow: Yes Indicator graphical construction shift by time axis in bars: 0 Number of colors: 3 Drawing color: clrDodgerBlue,clrRed,clrGray Number of data buffers: 2 Base data buffer index: 11 Color buffer index: 13 Index of the array to be assigned as the next indicator buffer: 14 ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Buffer symbol: EURUSD Name of the graphical indicator series displayed in DataWindow: ZigZag 0;ZigZag 1 ================== Parameter list end: Colored data buffer[5] "Zigzag" ================== ============= Parameter list start: Colored data buffer[6] "Color filling between two levels" ================== Plotted buffer serial number: 6 Buffer status: Indicator buffer with graphical construction type "Color filling between two levels" Buffer type: Colored data buffer Buffer data period (timeframe): Current chart period (H1) Active: Yes Graphical construction type: Color filling between two levels The number of initial bars that are not drawn and values in DataWindow: 0 Display construction values in DataWindow: Yes Indicator graphical construction shift by time axis in bars: 0 Number of colors: 2 Drawing color: clrDodgerBlue,clrRed Number of data buffers: 2 Base data buffer index: 14 Index of the array to be assigned as the next indicator buffer: 16 ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Buffer symbol: EURUSD Name of the graphical indicator series displayed in DataWindow: Filling 0;Filling 1 ================== Parameter list end: Colored data buffer[6] "Color filling between two levels" ================== ============= Parameter list start: Colored data buffer[7] "Display as bars" ================== Plotted buffer serial number: 7 Buffer status: Indicator buffer with graphical construction type "Display as bars" Buffer type: Colored data buffer Buffer data period (timeframe): Current chart period (H1) Active: Yes Graphical construction type: Display as bars Line width: 2 The number of initial bars that are not drawn and values in DataWindow: 0 Display construction values in DataWindow: Yes Indicator graphical construction shift by time axis in bars: 0 Number of colors: 3 Drawing color: clrDodgerBlue,clrRed,clrGray Number of data buffers: 4 Base data buffer index: 16 Color buffer index: 20 Index of the array to be assigned as the next indicator buffer: 21 ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Buffer symbol: EURUSD Name of the graphical indicator series displayed in DataWindow: Bar Open;Bar High;Bar Low;Bar Close ================== Parameter list end: Colored data buffer[7] "Display as bars" ================== ============= Parameter list start: Colored data buffer[8] "Display as candles" ================== Plotted buffer serial number: 8 Buffer status: Indicator buffer with graphical construction type "Display as candles" Buffer type: Colored data buffer Buffer data period (timeframe): Current chart period (H1) Active: Yes Graphical construction type: Display as candles The number of initial bars that are not drawn and values in DataWindow: 0 Display construction values in DataWindow: Yes Indicator graphical construction shift by time axis in bars: 0 Number of colors: 3 Drawing color: clrDodgerBlue,clrRed,clrGray Number of data buffers: 4 Base data buffer index: 21 Color buffer index: 25 Index of the array to be assigned as the next indicator buffer: 26 ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Buffer symbol: EURUSD Name of the graphical indicator series displayed in DataWindow: Candle Open;Candle High;Candle Low;Candle Close ================== Parameter list end: Colored data buffer[8] "Display as candles" ==================
最初の起動後、ライブラリとすべての指標バッファを初期化すると、操作ログに次のエントリが作成されます。
"EURUSD" H1 timeseries created successfully: - Timeseries "EURUSD" H1: Requested: 1000, Actual: 1000, Created: 1000, On the server: 6230 Buffer(0): Drawing with arrows EURUSD H1 Buffer(1): EURUSD H1 line Buffer(2): EURUSD H1 sections Buffer(3): Histogram from the zero line EURUSD H1 Buffer(4): Histogram on two indicator buffers EURUSD H1 Buffer(5): EURUSD H1 zigzag Buffer(6): Color filling between two levels EURUSD H1 Buffer(7): Display as EURUSD H1 bars Buffer(8): Display as EURUSD H1 candles
設定で指標の線を表示する権限を切り替えましょう。
次の段階
次回の記事では、指標バッファのコレクションクラスの作成を開始します。このクラスは、ライブラリを使用してカスタム指標ープログラムを開発する際に、指標ーバッファを作成し、それらを任意のシンボルおよびチャート期間で使用するときに、最大の柔軟性と利便性を提供します。
現在のバージョンのライブラリのすべてのファイルは、テスト用EAファイルと一緒に以下に添付されているので、テストするにはダウンロードしてください。
質問、コメント、提案はコメント欄にお願いします。テスト指標はMQL5向けに開発されたのでご注意ください。
添付ファイルはMetaTrader 5のみを対象としています。現在のライブラリバージョンはMetaTrader 4ではテストされていません。
指標バッファコレクションを作成してテストした後で、MetaTrader 4にいくつかのMQL5機能を実装してみます。
シリーズのこれまでの記事:
DoEasyライブラリの時系列(第35部): バーオブジェクトと銘柄の時系列リスト
DoEasyライブラリの時系列(第36部): すべての使用銘柄期間の時系列オブジェクト
DoEasyライブラリの時系列(第37部): すべての使用銘柄期間の時系列オブジェクト
DoEasyライブラリの時系列(第38部): 時系列コレクション-リアルタイムの更新とプログラムからのデータへのアクセス
DoEasyライブラリの時系列(第39部): ライブラリに基づいた指標 - データイベントと時系列イベントの準備
DoEasyライブラリの時系列(第40部): ライブラリに基づいた指標 - 実時間でのデータ更新
DoEasyライブラリの時系列(第41部): 複数銘柄・複数期間指標の例
DoEasyライブラリの時系列(第42部): 抽象指標バッファオブジェクトクラス