English Русский 中文 Español Deutsch Português
preview
DoEasyライブラリの時系列(第51部): 複数銘柄・複数期間の複合標準指標

DoEasyライブラリの時系列(第51部): 複数銘柄・複数期間の複合標準指標

MetaTrader 5 | 14 12月 2020, 09:43
306 0
Artyom Trishkin
Artyom Trishkin

目次


概念

今日は、複数銘柄・複数期間標準指標のオブジェクトの作成を終了します。最後に、一目均衡表指標を作成する非常に良い例を残しました。描画するには、ターミナルデータウィンドウに表示される重要なバッファをすべて作成するだけでなく、 2つの値の間に描画される2つのヒストグラムを使用して2つのライン「SenkouSpanA」と「SenkouSpanB」の間の領域にペイントするための2つのバッファを追加する必要があります。一方、各ヒストグラムは、関連するラインのスタイルと色を繰り返す必要があります。
このような指標の作成は、このライブラリを使用して独自の複合カスタム指標を作成する方法の良い例になります。
最後に、MetaTrader5ターミナルの標準指標の完全なセットから複数銘柄・複数期間標準指標の最終オブジェクトを作成します。前の記事で検討された、ビルウィリアムズ指標のゲーターオシレーターです。これは、彼の別の指標であるアリゲーター指標に基づいて構築されています。

さまざまな描画タイプのさまざまなラインとそれに対応するバッファオブジェクトを含む、あらゆる複雑差を持つ指標を作成できますが、これらのバッファはすべて単一の指標オブジェクトに属するため、バッファオブジェクトに別のプロパティ(数値)を導入する必要があります。 追加の指標ライン(その設計に役立つ追加の指標ラインを描画するための補助バッファ)の数です。したがって、そのラインの数によって、任意の指標オブジェクトに必要な補助ライン(バッファオブジェクト)を正確に決定します。
たとえば、移動平均を描画する指標に、価格によるラインの交差、他の指標とのラインの相互作用など、メインラインの特定のステータスを表示させたい場合は、カスタム指標に1つまたは複数のバッファオブジェクトを追加できます。 このバッファによって、矢印を配置したり、領域をペイントしたりするなど、必要な時に必要なデータがチャートに表示されます。


ライブラリクラスとメソッドの改善

まず、\MQL5\Include\DoEasy\Data.mqhファイルに新しいライブラリテキストメッセージを入力します。

新しいメッセージインデックスを追加します

//--- CBuffer
   MSG_LIB_TEXT_BUFFER_TEXT_INDEX_BASE,               // Base data buffer index
   MSG_LIB_TEXT_BUFFER_TEXT_INDEX_PLOT,               // Plotted buffer serial number
   MSG_LIB_TEXT_BUFFER_TEXT_INDEX_COLOR,              // Color buffer index
   MSG_LIB_TEXT_BUFFER_TEXT_NUM_DATAS,                // Number of data buffers
   MSG_LIB_TEXT_BUFFER_TEXT_INDEX_NEXT_BASE,          // Index of the array to be assigned as the next indicator buffer
   MSG_LIB_TEXT_BUFFER_TEXT_INDEX_NEXT_PLOT,          // Index of the next drawn buffer
   MSG_LIB_TEXT_BUFFER_TEXT_ID,                       // Indicator buffers ID
   MSG_LIB_TEXT_BUFFER_TEXT_IND_LINE_MODE,            // Indicator line
   MSG_LIB_TEXT_BUFFER_TEXT_IND_HANDLE,               // Indicator handle that uses the buffer
   MSG_LIB_TEXT_BUFFER_TEXT_IND_HANDLE,                 // Indicator type that uses the buffer
   MSG_LIB_TEXT_BUFFER_TEXT_IND_LINE_ADDITIONAL_NUM,  // Number of additional line
   MSG_LIB_TEXT_BUFFER_TEXT_TIMEFRAME,                // Buffer data period (timeframe)


また、新しく追加したインデックスに対応するテキストも追加します。

   {"Index of Base data buffer"},
   {"Plot buffer sequence number"},
   {"Color buffer index"},
   {"Number of data buffers"},
   {"Array index for assignment as the next indicator buffer"},
   {"Index of the next drawable buffer"},
   {"Indicator Buffer Id"},
   {"Indicator line"},
   {"Indicator handle that uses the buffer"},
   {"Indicator type that uses the buffer"},
   {"Additional line number"},
   {"Buffer data Period (Timeframe)"},


\MQL5\Include\DoEasy\Defines.mqhファイルで、指標のラインタイプの列挙に、指標を描画するために、一目均衡表指標の新しいライン補助ラインとして別のラインを追加します。

//+------------------------------------------------------------------+
//| Values of indicator lines in enumeration                         |
//+------------------------------------------------------------------+
enum ENUM_INDICATOR_LINE_MODE
  {
   INDICATOR_LINE_MODE_MAIN         =  0,                   // Main line
   INDICATOR_LINE_MODE_SIGNAL       =  1,                   // Signal line
   INDICATOR_LINE_MODE_UPPER        =  0,                   // Upper line
   INDICATOR_LINE_MODE_LOWER        =  1,                   // Lower line
   INDICATOR_LINE_MODE_MIDDLE       =  2,                   // Middle line
   INDICATOR_LINE_MODE_JAWS         =  0,                   // Jaws line
   INDICATOR_LINE_MODE_TEETH        =  1,                   // Teeth line
   INDICATOR_LINE_MODE_LIPS         =  2,                   // Lips line
   INDICATOR_LINE_MODE_DI_PLUS      =  1,                   // Line +DI
   INDICATOR_LINE_MODE_DI_MINUS     =  2,                   // Line -DI
   INDICATOR_LINE_MODE_TENKAN_SEN   =  0,                   // Line Tenkan-sen
   INDICATOR_LINE_MODE_KIJUN_SEN    =  1,                   // Line Kijun-sen
   INDICATOR_LINE_MODE_SENKOU_SPANA =  2,                   // Line Senkou Span A
   INDICATOR_LINE_MODE_SENKOU_SPANB =  3,                   // Line Senkou Span B
   INDICATOR_LINE_MODE_CHIKOU_SPAN  =  4,                   // Line Chikou Span
   INDICATOR_LINE_MODE_ADDITIONAL   =  5,                   // Additional line
  };
//+------------------------------------------------------------------+


前回の記事では、この列挙で同じタイプの指標ラインに同じ値を設定し、標準指標の異なるオブジェクトのハンドラを1つにまとめたので、バッファオブジェクトからラインタイプの説明を表示すると、この列挙の最初に検出された値に対応するラインの説明が表示されます。たとえば、アリゲーター標準指標の顎(Jaws)ラインの説明を表示し、この列挙のINDICATOR_LINE_MODE_JAWS定数の値がゼロに等しい場合、ゼロに等しいこの列挙の最初の定数(INDICATOR_LINE_MODE_MAIN定数)の説明が表示されます。
これはエラーではなく、不快な混乱です。これを回避するには、列挙定数ごとに一意の値を設定する必要があります。ただし、この場合、ハンドラを再度分割する必要があり、これはさらに悪いことです。したがって、次のようにします。バッファが表示する指標のラインを正確に確認して、バッファオブジェクトラインの別の列挙と表示の説明を追加し、バッファオブジェクトに対応する新しい列挙の値を表示します。

この列挙を追加します。

//+------------------------------------------------------------------+
//| Enumeration of indicator lines                                   |
//+------------------------------------------------------------------+
enum ENUM_INDICATOR_LINE
  {
   INDICATOR_LINE_MAIN,                                     // Main line
   INDICATOR_LINE_SIGNAL,                                   // Signal line
   INDICATOR_LINE_UPPER,                                    // Upper line
   INDICATOR_LINE_LOWER,                                    // Lower line
   INDICATOR_LINE_MIDDLE,                                   // Middle line
   INDICATOR_LINE_JAWS,                                     // Jaws line
   INDICATOR_LINE_TEETH,                                    // Teeth line
   INDICATOR_LINE_LIPS,                                     // Lips line
   INDICATOR_LINE_DI_PLUS,                                  // Line +DI
   INDICATOR_LINE_DI_MINUS,                                 // Line -DI
   INDICATOR_LINE_TENKAN_SEN,                               // Line Tenkan-sen
   INDICATOR_LINE_KIJUN_SEN,                                // Line Kijun-sen
   INDICATOR_LINE_SENKOU_SPANA,                             // Line Senkou Span A
   INDICATOR_LINE_SENKOU_SPANB,                             // Line Senkou Span B
   INDICATOR_LINE_CHIKOU_SPAN,                              // Line Chikou Span
   INDICATOR_LINE_ADDITIONAL,                               // Additional line
  };
//+------------------------------------------------------------------+


この列挙では、各定数に0〜15の範囲の一意の値があり、特定の指標の特定のラインごとに必要な値を簡単に表示できるようになりました。以下でやってみましょう。

同じファイルに別のバッファオブジェクト整数プロパティを追加すると同時に、バッファオブジェクト整数プロパティの数を24から25に増やしました

//+------------------------------------------------------------------+
//| Buffer integer properties                                        |
//+------------------------------------------------------------------+
enum ENUM_BUFFER_PROP_INTEGER
  {
   BUFFER_PROP_INDEX_PLOT = 0,                              // Plotted buffer serial number
   BUFFER_PROP_STATUS,                                      // Buffer status (by drawing style) (from the ENUM_BUFFER_STATUS enumeration)
   BUFFER_PROP_TYPE,                                        // Buffer type (from the ENUM_BUFFER_TYPE enumeration)
   BUFFER_PROP_TIMEFRAME,                                   // Buffer data period (timeframe)
   BUFFER_PROP_ACTIVE,                                      // Buffer usage flag
   BUFFER_PROP_DRAW_TYPE,                                   // Graphical construction type (from the ENUM_DRAW_TYPE enumeration)
   BUFFER_PROP_ARROW_CODE,                                  // Arrow code for DRAW_ARROW style
   BUFFER_PROP_ARROW_SHIFT,                                 // The vertical shift of the arrows for DRAW_ARROW style
   BUFFER_PROP_LINE_STYLE,                                  // Line style
   BUFFER_PROP_LINE_WIDTH,                                  // Line width
   BUFFER_PROP_DRAW_BEGIN,                                  // The number of initial bars that are not drawn and values in DataWindow
   BUFFER_PROP_SHOW_DATA,                                   // Flag of displaying construction values in DataWindow
   BUFFER_PROP_SHIFT,                                       // Indicator graphical construction shift by time axis in bars
   BUFFER_PROP_COLOR_INDEXES,                               // Number of colors
   BUFFER_PROP_COLOR,                                       // Drawing color
   BUFFER_PROP_INDEX_BASE,                                  // Base data buffer index
   BUFFER_PROP_INDEX_NEXT_BASE,                             // Index of the array to be assigned as the next indicator buffer
   BUFFER_PROP_INDEX_NEXT_PLOT,                             // Index of the next plotted buffer
   BUFFER_PROP_ID,                                          // ID of multiple buffers of the same indicator
   BUFFER_PROP_IND_LINE_MODE,                               // Indicator line
   BUFFER_PROP_IND_HANDLE,                                  // Indicator handle that uses the buffer
   BUFFER_PROP_IND_TYPE,                                    // Indicator type that uses the buffer
   BUFFER_PROP_IND_LINE_ADDITIONAL_NUM,                     // Number of indicator additional line
   BUFFER_PROP_NUM_DATAS,                                   // Number of data buffers
   BUFFER_PROP_INDEX_COLOR,                                 // Color buffer index
  }; 
#define BUFFER_PROP_INTEGER_TOTAL (25)                      // Total number of buffer integer properties
#define BUFFER_PROP_INTEGER_SKIP  (2)                       // Number of buffer properties not used in sorting
//+------------------------------------------------------------------+


新しいプロパティでバッファオブジェクトを検索して並べ替えられるようにするには、このプロパティを可能な並べ替え条件の列挙に追加します

//+------------------------------------------------------------------+
//| Possible buffer sorting criteria                                 |
//+------------------------------------------------------------------+
#define FIRST_BUFFER_DBL_PROP          (BUFFER_PROP_INTEGER_TOTAL-BUFFER_PROP_INTEGER_SKIP)
#define FIRST_BUFFER_STR_PROP          (BUFFER_PROP_INTEGER_TOTAL-BUFFER_PROP_INTEGER_SKIP+BUFFER_PROP_DOUBLE_TOTAL-BUFFER_PROP_DOUBLE_SKIP)
enum ENUM_SORT_BUFFER_MODE
  {
//--- Sort by integer properties
   SORT_BY_BUFFER_INDEX_PLOT = 0,                           // Sort by the plotted buffer serial number
   SORT_BY_BUFFER_STATUS,                                   // Sort by buffer drawing style (status) (from the ENUM_BUFFER_STATUS enumeration)
   SORT_BY_BUFFER_TYPE,                                     // Sort by buffer type (from the ENUM_BUFFER_TYPE enumeration)
   SORT_BY_BUFFER_TIMEFRAME,                                // Sort by the buffer data period (timeframe)
   SORT_BY_BUFFER_ACTIVE,                                   // Sort by the buffer usage flag
   SORT_BY_BUFFER_DRAW_TYPE,                                // Sort by graphical construction type (from the ENUM_DRAW_TYPE enumeration)
   SORT_BY_BUFFER_ARROW_CODE,                               // Sort by the arrow code for DRAW_ARROW style
   SORT_BY_BUFFER_ARROW_SHIFT,                              // Sort by the vertical shift of the arrows for DRAW_ARROW style
   SORT_BY_BUFFER_LINE_STYLE,                               // Sort by the line style
   SORT_BY_BUFFER_LINE_WIDTH,                               // Sort by the line width
   SORT_BY_BUFFER_DRAW_BEGIN,                               // Sort by the number of initial bars that are not drawn and values in DataWindow
   SORT_BY_BUFFER_SHOW_DATA,                                // Sort by the flag of displaying construction values in DataWindow
   SORT_BY_BUFFER_SHIFT,                                    // Sort by the indicator graphical construction shift by time axis in bars
   SORT_BY_BUFFER_COLOR_INDEXES,                            // Sort by a number of attempts
   SORT_BY_BUFFER_COLOR,                                    // Sort by the drawing color
   SORT_BY_BUFFER_INDEX_BASE,                               // Sort by the basic data buffer index
   SORT_BY_BUFFER_INDEX_NEXT_BASE,                          // Sort by the index of the array to be assigned as the next indicator buffer
   SORT_BY_BUFFER_INDEX_NEXT_PLOT,                          // Sort by the index of the next drawn buffer
   SORT_BY_BUFFER_ID,                                       // Sort by ID of multiple buffers of the same indicator
   SORT_BY_BUFFER_IND_LINE_MODE,                            // Sort by indicator line
   SORT_BY_BUFFER_IND_HANDLE,                               // Sort by indicator handle that uses the buffer
   SORT_BY_BUFFER_IND_TYPE,                                 // Sort by indicator type that uses the buffer
   SORT_BY_BUFFER_IND_LINE_ADDITIONAL_NUM,                  // Sort by number of additional indicator line
//--- Sort by real properties
   SORT_BY_BUFFER_EMPTY_VALUE = FIRST_BUFFER_DBL_PROP,      // Sort by the empty value for plotting where nothing will be drawn
//--- Sort by string properties
   SORT_BY_BUFFER_SYMBOL = FIRST_BUFFER_STR_PROP,           // Sort by the buffer symbol
   SORT_BY_BUFFER_LABEL,                                    // Sort by the name of the graphical indicator series displayed in DataWindow
   SORT_BY_BUFFER_IND_NAME,                                 // Sort by indicator name that uses the buffer
   SORT_BY_BUFFER_IND_NAME_SHORT,                           // Sort by a short name of indicator that uses the buffer
  };
//+------------------------------------------------------------------+

次に、\MQL5\Include\DoEasy\Objects\Indicators\Buffer.mqhの抽象バッファオブジェクトクラスをわずかに改善します。

クラスのpublicセクションで、追加のラインの番号を設定するメソッドおよび返すメソッドを宣言します。

public:  
//--- Display the description of the buffer properties in the journal (full_prop=true - all properties, false - supported ones only)
   void              Print(const bool full_prop=false);
//--- Display a short buffer description in the journal (implementation in the descendants)
   virtual void      PrintShort(void) {;}
   
//--- Set (1) the arrow code, (2) vertical shift of arrows, (3) symbol, (4) timeframe, (5) buffer activity flag
//--- (6) drawing type, (7) number of initial bars without drawing, (8) flag of displaying construction values in DataWindow,
//--- (9) shift of the indicator graphical construction along the time axis, (10) line style, (11) line width,
//--- (12) total number of colors, (13) one drawing color, (14) color of drawing in the specified color index,
//--- (15) drawing colors from the color array, (16) empty value, (17) name of the graphical series displayed in DataWindow
   virtual void      SetArrowCode(const uchar code)                  { return;                                                               }
   virtual void      SetArrowShift(const int shift)                  { return;                                                               }
   void              SetSymbol(const string symbol)                  { this.SetProperty(BUFFER_PROP_SYMBOL,symbol);                          }
   void              SetTimeframe(const ENUM_TIMEFRAMES timeframe)   { this.SetProperty(BUFFER_PROP_TIMEFRAME,timeframe);                    }
   void              SetActive(const bool flag)                      { this.SetProperty(BUFFER_PROP_ACTIVE,flag);                            }
   void              SetDrawType(const ENUM_DRAW_TYPE draw_type);
   void              SetDrawBegin(const int value);
   void              SetShowData(const bool flag);
   void              SetShift(const int shift);
   void              SetStyle(const ENUM_LINE_STYLE style);
   void              SetWidth(const int width);
   void              SetColorNumbers(const int number);
   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);
   void              SetID(const int id)                             { this.SetProperty(BUFFER_PROP_ID,id);                                  }
   void              SetIndicatorHandle(const int handle)            { this.SetProperty(BUFFER_PROP_IND_HANDLE,handle);                      }
   void              SetIndicatorType(const ENUM_INDICATOR type)     { this.SetProperty(BUFFER_PROP_IND_TYPE,type);                          }
   void              SetIndicatorName(const string name)             { this.SetProperty(BUFFER_PROP_IND_NAME,name);                          }
   void              SetIndicatorShortName(const string name)        { this.SetProperty(BUFFER_PROP_IND_NAME_SHORT,name);                    }
   void              SetLineMode(const ENUM_INDICATOR_LINE_MODE mode){ this.SetProperty(BUFFER_PROP_IND_LINE_MODE,mode);                     }
   void              SetIndicatorLineAdditionalNumber(const int number){this.SetProperty(BUFFER_PROP_IND_LINE_ADDITIONAL_NUM,number);        }
   
//--- 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) index of the next drawn buffer, (6) buffer data period, (7) buffer status,
//--- (8) buffer type, (9) buffer usage flag, (10) arrow code, (11) arrow shift for DRAW_ARROW style,
//--- (12) number of initial bars that are not drawn and values in DataWindow, (13) graphical construction type,
//--- (14) flag of displaying construction values in DataWindow, (15) indicator graphical construction shift along the time axis,
//--- (16) drawing line style, (17) drawing line width, (18) number of colors, (19) drawing color, (20) number of buffers for construction
//--- (21) set empty value, (22) buffer symbol, (23) name of the indicator graphical series displayed in DataWindow
//--- (24) buffer ID, (25) indicator handle, (26) standard indicator type, (27) standard indicator name,
//--- (28) number of standard indicator calculated bars, (29) number of additional indicator line, (30) line type (main, signal, etc.)
   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               IndexNextBaseBuffer(void)                 const { return (int)this.GetProperty(BUFFER_PROP_INDEX_NEXT_BASE);            }
   int               IndexNextPlotBuffer(void)                 const { return (int)this.GetProperty(BUFFER_PROP_INDEX_NEXT_PLOT);            }
   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);                           }
   int               ID(void)                                  const { return (int)this.GetProperty(BUFFER_PROP_ID);                         }
   int               IndicatorHandle(void)                     const { return (int)this.GetProperty(BUFFER_PROP_IND_HANDLE);                 }
   ENUM_INDICATOR    IndicatorType(void)                       const { return (ENUM_INDICATOR)this.GetProperty(BUFFER_PROP_IND_TYPE);        }
   string            IndicatorName(void)                       const { return this.GetProperty(BUFFER_PROP_IND_NAME);                        }
   string            IndicatorShortName(void)                  const { return this.GetProperty(BUFFER_PROP_IND_NAME_SHORT);                  }
   int               IndicatorBarsCalculated(void)             const { return ::BarsCalculated((int)this.GetProperty(BUFFER_PROP_IND_HANDLE));}
   int               IndicatorLineAdditionalNumber(void)       const { return (int)this.GetProperty(BUFFER_PROP_IND_LINE_ADDITIONAL_NUM);    }
   int               IndicatorLineMode(void)                   const { return (int)this.GetProperty(BUFFER_PROP_IND_LINE_MODE);              }


ここから、別の列挙型(上記で実装)からの指標ラインの説明を表示します。これで、IndicatorLineMode()メソッドは列挙値ENUM_INDICATOR_LINE_MODEの代わりに整数値 を返します

クラスの同じpublicセクションで、指標ラインの説明を返すメソッドを宣言します

//--- 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, (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;
   string            GetIndicatorLineModeDescription(void)     const;


クラス本体の外側で実装しましょう。

//+------------------------------------------------------------------+
//| Return description of indicator buffer line                      |
//+------------------------------------------------------------------+
string CBuffer::GetIndicatorLineModeDescription(void) const
  {
   uchar shift=0;
   switch(this.IndicatorType())
     {
      case IND_ENVELOPES   :
      case IND_FRACTALS    :
      case IND_GATOR       :
      case IND_BANDS       :  shift=2; break;
      case IND_ALLIGATOR   :  shift=5; break;
      case IND_ADX         :
      case IND_ADXW        :  shift=8; break;
      case IND_ICHIMOKU    :  shift=10;break;
      default              :  shift=0; break;
     }
   return ::StringSubstr(::EnumToString(ENUM_INDICATOR_LINE(this.GetProperty(BUFFER_PROP_IND_LINE_MODE)+shift)),10);
  }
//+------------------------------------------------------------------+


ここで、シフト値を格納する変数を宣言します。これにより、列挙型定数値ENUM_INDICATOR_LINE_MODEを増やして、列挙型ENUM_INDICATOR_LINEの対応する指標のライン定数の宣言を開始する必要があります。
たとえば、アリゲーター指標の歯のラインの説明を表示する必要がある場合、シフト値は5に等しく、列挙型ENUM_INDICATOR_LINEのINDICATOR_LINE_JAWS定数を指します。

//+------------------------------------------------------------------+
//| Enumeration of indicator lines                                   |
//+------------------------------------------------------------------+
enum ENUM_INDICATOR_LINE
  {
   INDICATOR_LINE_MAIN,                                     // Main line
   INDICATOR_LINE_SIGNAL,                                   // Signal line
   INDICATOR_LINE_UPPER,                                    // Upper line
   INDICATOR_LINE_LOWER,                                    // Lower line
   INDICATOR_LINE_MIDDLE,                                   // Middle line
   INDICATOR_LINE_JAWS,                                     // Jaws line
   INDICATOR_LINE_TEETH,                                    // Teeth line
   INDICATOR_LINE_LIPS,                                     // Lips line
   INDICATOR_LINE_DI_PLUS,                                  // Line +DI
   INDICATOR_LINE_DI_MINUS,                                 // Line -DI
   INDICATOR_LINE_TENKAN_SEN,                               // Line Tenkan-sen
   INDICATOR_LINE_KIJUN_SEN,                                // Line Kijun-sen
   INDICATOR_LINE_SENKOU_SPANA,                             // Line Senkou Span A
   INDICATOR_LINE_SENKOU_SPANB,                             // Line Senkou Span B
   INDICATOR_LINE_CHIKOU_SPAN,                              // Line Chikou Span
   INDICATOR_LINE_ADDITIONAL,                               // Additional line
  };
//+------------------------------------------------------------------+


また、バッファがGetProperty(BUFFER_PROP_IND_LINE_MODE)メソッドから歯のラインの値を返し、この値が1に等しいため、値5を1に追加すると、定数インデックスが6になります。これは、定数INDICATOR_LINE_TEETHを示します

その結果、メソッドは、値「LINE_TEETH」に縮小された受信定数の文字列記述を返します

クラスのクローズドコンストラクタで、デフォルト値をバッファオブジェクトの新しいプロパティに-1として設定します。これは追加の指標ラインがないことを意味します。

//+------------------------------------------------------------------+
//| 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 uchar total_arrays,
                 const int width,
                 const string label)
  {
   this.m_type=COLLECTION_BUFFERS_ID;
   this.m_act_state_trigger=true;
   this.m_total_arrays=total_arrays;
//--- Save integer properties
   this.m_long_prop[BUFFER_PROP_STATUS]                        = buffer_status;
   this.m_long_prop[BUFFER_PROP_TYPE]                          = buffer_type;
   this.m_long_prop[BUFFER_PROP_ID]                            = WRONG_VALUE;
   this.m_long_prop[BUFFER_PROP_IND_LINE_MODE]                 = INDICATOR_LINE_MODE_MAIN;
   this.m_long_prop[BUFFER_PROP_IND_HANDLE]                    = INVALID_HANDLE;
   this.m_long_prop[BUFFER_PROP_IND_TYPE]                      = WRONG_VALUE;
   this.m_long_prop[BUFFER_PROP_IND_LINE_ADDITIONAL_NUM]       = WRONG_VALUE;
   ENUM_DRAW_TYPE type=
     (


バッファオブジェクトの整数プロパティの説明を返すメソッドで、新しいプロパティの説明を返すためのコードブロックを追加し、指標ラインの説明を表示するコードブロックを改善します(ここで、 この目的のために特別に作成された新しいメソッドを使用して説明します)。

//+------------------------------------------------------------------+
//| Return description of a buffer's integer property                |
//+------------------------------------------------------------------+
string CBuffer::GetPropertyDescription(ENUM_BUFFER_PROP_INTEGER property)
  {
   return
     (
      property==BUFFER_PROP_INDEX_PLOT    ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_INDEX_PLOT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==BUFFER_PROP_STATUS        ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_STATUS)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetStatusDescription()
         )  :
      property==BUFFER_PROP_TYPE          ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_TYPE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetTypeBufferDescription()
         )  :
      property==BUFFER_PROP_TIMEFRAME     ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_TIMEFRAME)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetTimeframeDescription()
         )  :
      property==BUFFER_PROP_ACTIVE        ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_ACTIVE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetActiveDescription()
         )  :
      property==BUFFER_PROP_DRAW_TYPE     ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_DRAW_TYPE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetDrawTypeDescription()
         )  :
      property==BUFFER_PROP_ARROW_CODE    ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_ARROW_CODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==BUFFER_PROP_ARROW_SHIFT   ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_ARROW_SHIFT)+
         (!this.SupportProperty(property)    ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      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_DRAW_BEGIN    ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_DRAW_BEGIN)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==BUFFER_PROP_SHOW_DATA     ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_SHOW_DATA)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetShowDataDescription()
         )  :
      property==BUFFER_PROP_SHIFT         ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_SHIFT)+
         (!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_INDEX_COLOR   ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_INDEX_COLOR)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      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)
         )  :
      property==BUFFER_PROP_INDEX_NEXT_BASE ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_INDEX_NEXT_BASE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==BUFFER_PROP_INDEX_NEXT_PLOT ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_INDEX_NEXT_PLOT)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==BUFFER_PROP_ID ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_ID)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==BUFFER_PROP_IND_LINE_MODE ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_IND_LINE_MODE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+this.GetIndicatorLineModeDescription()
         )  :
      property==BUFFER_PROP_IND_HANDLE ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_IND_HANDLE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(string)this.GetProperty(property)
         )  :
      property==BUFFER_PROP_IND_TYPE ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_IND_TYPE)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+::StringSubstr(::EnumToString((ENUM_INDICATOR)this.GetProperty(property)),4)
         )  :
      property==BUFFER_PROP_IND_LINE_ADDITIONAL_NUM ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_IND_LINE_ADDITIONAL_NUM)+
         (!this.SupportProperty(property) ?  ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) :
          ": "+(this.GetProperty(property)==WRONG_VALUE ? CMessage::Text(MSG_LIB_PROP_NOT_SET) : (string)this.GetProperty(property))
         )  :
      property==BUFFER_PROP_NUM_DATAS     ?  CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_NUM_DATAS)+
         (!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()
         )  :
      ""
     );
  }
//+------------------------------------------------------------------+


新しい整数プロパティを1つの追加したので、抽象バッファオブジェクトの子孫オブジェクトのすべてのクラスでこの新しいプロパティのオブジェクトによるサポートのフラグを返す仮想メソッドを改善します(CBufferArrowクラスメソッドを例として使用)。

//+------------------------------------------------------------------+
//| 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_BASE &&
       property!=BUFFER_PROP_IND_LINE_MODE && 
       property!=BUFFER_PROP_IND_HANDLE &&
       property!=BUFFER_PROP_IND_TYPE &&
       property!=BUFFER_PROP_IND_LINE_ADDITIONAL_NUM &&
       property!=BUFFER_PROP_ID
      )
     )
      return false;
   return true;
  }
//+------------------------------------------------------------------+


BufferArrow.mqhBufferBars.mqhBufferCandles.mqhBufferFilling.mqhBufferHistogram.mqhBufferHistogram2.mqh、,BufferLine.mqhBufferSection.mqhBufferZigZag.mqhなど、すべてのバッファオブジェクトのファイルに同じ変更が加えられました。

標準指標オブジェクトを作成するためのすべてのメソッドは、\MQL5\Include\DoEasy\Collections\BuffersCollection.mqhファイルのバッファオブジェクトコレクションクラスにあります。標準指標の一目均衡表とゲーターオシレーターのオブジェクトを作成する2つのメソッドを追加する前に、現在の銘柄チャートに値を設定するための指定された標準指標のデータを準備するメソッドを少し改善しましょう。一目均衡表指標には5つの描画バッファがありますが、標準指標バッファオブジェクトの3つのポインタのみがメソッドに渡され、指標ラインの値を書き込むためのリンク(バッファごとに2つ)によってそれぞれ6つの変数がメソッドに渡されます。メソッドでは、バッファオブジェクトに4つの追加ポインタの受け渡し(描画用および計算用ごとに2つ)およびリンクによるさらに4つの変数の受け渡しを追加する必要があります。

クラス本体で、必要な値を使用してメソッド宣言を追加します。

//--- Set values for the current chart to buffers of the specified standard indicator by the timeseries index in accordance with buffer object symbol/period
   bool                    SetDataBufferStdInd(const ENUM_INDICATOR std_ind,const int id,const int series_index,const datetime series_time,const char color_index=WRONG_VALUE);
private:
//--- Prepare data of the specified standard indicator for setting values on the current symbol chart
   int                     PreparingSetDataStdInd(CBuffer *buffer_data0,CBuffer *buffer_data1,CBuffer *buffer_data2,CBuffer *buffer_data3,CBuffer *buffer_data4,
                                                  CBuffer *buffer_calc0,CBuffer *buffer_calc1,CBuffer *buffer_calc2,CBuffer *buffer_calc3,CBuffer *buffer_calc4,
                                                  const ENUM_INDICATOR ind_type,
                                                  const int series_index,
                                                  const datetime series_time,
                                                  int &index_period,
                                                  int &num_bars,
                                                  double &value00,
                                                  double &value01,
                                                  double &value10,
                                                  double &value11,
                                                  double &value20,
                                                  double &value21,
                                                  double &value30,
                                                  double &value31,
                                                  double &value40,
                                                  double &value41);
public:

//--- Return the buffer (1) by the graphical series name, (2) timeframe,


クラス本体の外にメソッドを実装して、必要な変更を加えます

//+------------------------------------------------------------------+
//| Prepare data of the specified standard indicator                 |
//| for setting values on the current symbol chart                   |
//+------------------------------------------------------------------+
int CBuffersCollection::PreparingSetDataStdInd(CBuffer *buffer_data0,CBuffer *buffer_data1,CBuffer *buffer_data2,CBuffer *buffer_data3,CBuffer *buffer_data4,
                                               CBuffer *buffer_calc0,CBuffer *buffer_calc1,CBuffer *buffer_calc2,CBuffer *buffer_calc3,CBuffer *buffer_calc4,
                                               const ENUM_INDICATOR ind_type,
                                               const int series_index,
                                               const datetime series_time,
                                               int &index_period,
                                               int &num_bars,
                                               double &value00,
                                               double &value01,
                                               double &value10,
                                               double &value11,
                                               double &value20,
                                               double &value21,
                                               double &value30,
                                               double &value31,
                                               double &value40,
                                               double &value41)
  {
     //--- Find bar index on a period which corresponds to the time of current bar beginning
     index_period=::iBarShift(buffer_calc0.Symbol(),buffer_calc0.Timeframe(),series_time,true);
     if(index_period==WRONG_VALUE || index_period>buffer_calc0.GetDataTotal()-1)
        return WRONG_VALUE;
     
     //--- Get the value by this index from indicator buffer
     if(buffer_calc0!=NULL)
        value00=buffer_calc0.GetDataBufferValue(0,index_period);
     if(buffer_calc1!=NULL)
        value10=buffer_calc1.GetDataBufferValue(0,index_period);
     if(buffer_calc2!=NULL)
        value20=buffer_calc2.GetDataBufferValue(0,index_period);
     if(buffer_calc3!=NULL)
        value30=buffer_calc3.GetDataBufferValue(0,index_period);
     if(buffer_calc4!=NULL)
        value40=buffer_calc4.GetDataBufferValue(0,index_period);
     
     int series_index_start=series_index;
     //--- For the current chart we don’t need to calculate a number of bars processed - only one bar is available
     if(buffer_calc0.Symbol()==::Symbol() && buffer_calc0.Timeframe()==::Period())
       {
        series_index_start=series_index;
        num_bars=1;
       }
     else
       {
        //--- Get the bar time which the bar with index_period index falls into on a period and symbol of calculated buffer
        datetime time_period=::iTime(buffer_calc0.Symbol(),buffer_calc0.Timeframe(),index_period);
        if(time_period==0) return false;
        //--- Get the current chart bar which corresponds to the time
        series_index_start=::iBarShift(::Symbol(),::Period(),time_period,true);
        if(series_index_start==WRONG_VALUE) return WRONG_VALUE;
        //--- Calculate the number of bars on the current chart which are to be filled in with calculated buffer data
        num_bars=::PeriodSeconds(buffer_calc0.Timeframe())/::PeriodSeconds(PERIOD_CURRENT);
        if(num_bars==0) num_bars=1;
       }
     //--- Take values for color calculation
     if(buffer_calc0!=NULL)
        value01=(series_index_start+num_bars>buffer_data0.GetDataTotal()-1 ? value00 : buffer_data0.GetDataBufferValue(0,series_index_start+num_bars));
     if(buffer_calc1!=NULL)
        value11=(series_index_start+num_bars>buffer_data1.GetDataTotal()-1 ? value10 : buffer_data1.GetDataBufferValue(0,series_index_start+num_bars));
     if(buffer_calc2!=NULL)
        value21=(series_index_start+num_bars>buffer_data2.GetDataTotal()-1 ? value20 : buffer_data2.GetDataBufferValue(0,series_index_start+num_bars));
     if(buffer_calc3!=NULL)
        value31=(series_index_start+num_bars>buffer_data3.GetDataTotal()-1 ? value30 : buffer_data3.GetDataBufferValue(0,series_index_start+num_bars));
     if(buffer_calc4!=NULL)
        value41=(series_index_start+num_bars>buffer_data4.GetDataTotal()-1 ? value40 : buffer_data4.GetDataBufferValue(0,series_index_start+num_bars));
   
   return series_index_start;
  }
//+------------------------------------------------------------------+


メソッドですでに使用可能なバッファオブジェクトの場合と同じ処理を、メソッドに渡される2つの新しいバッファオブジェクトポインタに追加しただけです。 リンクによってメソッドに渡されるバッファに対応する変数に値を書き込みます。

標準指標で一目均衡表の2本の線の間に網掛けが描かれているので、網掛けの種類とラインの種類と色に対応する色が各ラインに設定されています。


...指標の種類、ID、ラインごとに標準の指標バッファオブジェクトへのポインタを返すメソッドが必要です。これにより、ラインを描画するために設定されたすべてのパラメータを取得して補助バッファオブジェクトに設定し、 カスタム指標の外観をデザインできます。

クラスのpublicセクションで、このメソッドを宣言します

public:

//--- Return the buffer (1) by the graphical series name, (2) timeframe,
//--- (3) Plot index, (4) object index in the collection list, (5) the last created,
//--- (6) standard indicator buffer by indicator type, its ID and line
   CBuffer                *GetBufferByLabel(const string plot_label);
   CBuffer                *GetBufferByTimeframe(const ENUM_TIMEFRAMES timeframe);
   CBuffer                *GetBufferByPlot(const int plot_index);
   CBuffer                *GetBufferByListIndex(const int index_list);
   CBuffer                *GetLastCreateBuffer(void);
   CBuffer                *GetBufferStdInd(const ENUM_INDICATOR indicator_type,const int id,const ENUM_INDICATOR_LINE_MODE line_mode,const char additional_id=WRONG_VALUE);
//--- Return buffer list (1) by ID, (2) standard indicator type, (3) type and ID


クラス本体の外側で実装しましょう。

//+------------------------------------------------------------------+
//| Return standard indicator buffer                                 |
//| by indicator type, its ID and line                               |
//+------------------------------------------------------------------+
CBuffer *CBuffersCollection::GetBufferStdInd(const ENUM_INDICATOR indicator_type,const int id,const ENUM_INDICATOR_LINE_MODE line_mode,const char additional_id=WRONG_VALUE)
  {
   CArrayObj *list=this.GetListBufferByTypeID(indicator_type,id);
   list=CSelect::ByBufferProperty(list,BUFFER_PROP_IND_LINE_MODE,line_mode,EQUAL);
   list=CSelect::ByBufferProperty(list,BUFFER_PROP_IND_LINE_ADDITIONAL_NUM,additional_id,EQUAL);
   if(list==NULL)
      return NULL;
   return list.At(0);
  }
//+------------------------------------------------------------------+


ここでは、すべてが簡単です。最初に、標準指標タイプとそのIDでバッファオブジェクトのリストを取得します。次に取得したリストを標準指標ラインのタイプで並べ替えます。最後に、残りのオブジェクトから、補助バッファのIDを持つオブジェクトのみがリストに残ります(デフォルトでは、すべてのバッファに値-1が割り当てられます。これは、そのようなIDがないことを意味します)。
メソッドから、並び替えられたリストの最初のオブジェクトを返します

一目均衡表とゲーターオシレーター指標を処理するために、指定された標準指標の計算されたバッファデータを準備するメソッドを補足します。
指標タイプに対応する処理を追加するだけで済みます。このような処理はすべての指標で同一であり、メソッドにすでに実装されています。ただし、ゲーターオシレーター標準指標には少し違いがあります。インデックス1のバッファがインデックス0のデータバッファのカラーバッファに属しているため、他の2バッファ指標のように1ではなくその2番目のバッファのインデックスは2だということです。指標ラインの色の処理と設定を既に作成したため、標準指標のカラーバッファは使用しません。さらに、各バーに必要な色を割り当てることができるため、デフォルトでは、ゲーターオシレーター指標の列の色はライブラリによって自動的に計算されます。そして、そのような計算はすでに行われています。必要に応じて各バーに必要な色を標準指標のデータ描画メソッドに渡して、指標の独自の色を作成できます。
一目均衡表の場合、指標データの準備は他の標準指標のデータ準備と同じです。バッファが2つ多いだけです

//+------------------------------------------------------------------+
//| Prepare calculated buffer data                                   |
//| of the specified standard indicator                              |
//+------------------------------------------------------------------+
int CBuffersCollection::PreparingDataBufferStdInd(const ENUM_INDICATOR std_ind,const int id,const int total_copy)
  {
   CArrayObj *list_ind=this.GetListBufferByTypeID(std_ind,id);
   CArrayObj *list;
   list_ind=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_TYPE,BUFFER_TYPE_CALCULATE,EQUAL);
   if(list_ind==NULL || list_ind.Total()==0)
     {
      ::Print(DFUN_ERR_LINE,CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_NO_BUFFER_OBJ));
      return 0;
     }
   CBufferCalculate *buffer=NULL;
   int copied=WRONG_VALUE;
   int idx0=0,idx1=1,idx2=2;
   switch((int)std_ind)
     {
   //--- Single-buffer standard indicators
      case IND_AC          :
      case IND_AD          :
      case IND_AMA         :
      case IND_AO          :
      case IND_ATR         :
      case IND_BEARS       :
      case IND_BULLS       :
      case IND_BWMFI       :
      case IND_CCI         :
      case IND_CHAIKIN     :
      case IND_DEMA        :
      case IND_DEMARKER    :
      case IND_FORCE       :
      case IND_FRAMA       :
      case IND_MA          :
      case IND_MFI         :
      case IND_MOMENTUM    :
      case IND_OBV         :
      case IND_OSMA        :
      case IND_RSI         :
      case IND_SAR         :
      case IND_STDDEV      :
      case IND_TEMA        :
      case IND_TRIX        :
      case IND_VIDYA       :
      case IND_VOLUMES     :
      case IND_WPR         :
      
        buffer=list_ind.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),0,buffer.Shift(),total_copy);
        return copied;
      
   //--- Multi-buffer standard indicators
      case IND_ENVELOPES   :
      case IND_FRACTALS    :
      case IND_MACD        :
      case IND_RVI         :
      case IND_STOCHASTIC  :
      case IND_GATOR       :
        if(std_ind==IND_GATOR)
          {
           idx0=0;
           idx1=2;
          }
        else
          {
           idx0=0;
           idx1=1;
          }
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,0,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),idx0,buffer.Shift(),total_copy);
        if(copied<total_copy) return 0;
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,1,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),idx1,buffer.Shift(),total_copy);
        if(copied<total_copy) return 0;
        return copied;
      
      case IND_ALLIGATOR   :
      case IND_ADX         :
      case IND_ADXW        :
      case IND_BANDS       :
        if(std_ind==IND_BANDS)
          {
           idx0=1;
           idx1=2;
           idx2=0;
          }
        else
          {
           idx0=0;
           idx1=1;
           idx2=2;
          }
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,0,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),idx0,buffer.Shift(),total_copy);
        if(copied<total_copy) return 0;
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,1,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),idx1,buffer.Shift(),total_copy);
        if(copied<total_copy) return 0;
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,2,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),idx2,buffer.Shift(),total_copy);
        if(copied<total_copy) return 0;
        return copied;
      
      case IND_ICHIMOKU    :
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_TENKAN_SEN,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),TENKANSEN_LINE,buffer.Shift(),total_copy);
        if(copied<total_copy) return 0;
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_KIJUN_SEN,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),KIJUNSEN_LINE,buffer.Shift(),total_copy);
        if(copied<total_copy) return 0;
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_SENKOU_SPANA,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),SENKOUSPANA_LINE,buffer.Shift(),total_copy);
        if(copied<total_copy) return 0;
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_SENKOU_SPANB,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),SENKOUSPANB_LINE,buffer.Shift(),total_copy);
        if(copied<total_copy) return 0;
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_CHIKOU_SPAN,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return 0;
        copied=buffer.FillAsSeries(buffer.IndicatorHandle(),CHIKOUSPAN_LINE,buffer.Shift(),total_copy);
        if(copied<total_copy) return 0;
        return copied;
      
      default:
        break;
     }
   return 0;
  }
//+------------------------------------------------------------------+


指定された標準指標のバッファデータを時系列インデックスで消去するメソッドに一目均衡表指標のバッファ処理を追加します

//+------------------------------------------------------------------+
//| Clear buffer data of the specified standard indicator            |
//| by the timeseries index                                          |
//+------------------------------------------------------------------+
void CBuffersCollection::ClearDataBufferStdInd(const ENUM_INDICATOR std_ind,const int id,const int series_index)
  {
//--- Get the list of buffer objects by type and ID
   CArrayObj *list_ind=this.GetListBufferByTypeID(std_ind,id);
   CArrayObj *list=NULL;
   if(list_ind==NULL || list_ind.Total()==0)
      return;
   list_ind=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_TYPE,BUFFER_TYPE_DATA,EQUAL);
   if(list_ind.Total()==0)
      return;
   CBuffer *buffer=NULL;
   switch((int)std_ind)
     {
   //--- Single-buffer standard indicators
      case IND_AC          :
      case IND_AD          :
      case IND_AMA         :
      case IND_AO          :
      case IND_ATR         :
      case IND_BEARS       :
      case IND_BULLS       :
      case IND_BWMFI       :
      case IND_CCI         :
      case IND_CHAIKIN     :
      case IND_DEMA        :
      case IND_DEMARKER    :
      case IND_FORCE       :
      case IND_FRAMA       :
      case IND_MA          :
      case IND_MFI         :
      case IND_MOMENTUM    :
      case IND_OBV         :
      case IND_OSMA        :
      case IND_RSI         :
      case IND_SAR         :
      case IND_STDDEV      :
      case IND_TEMA        :
      case IND_TRIX        :
      case IND_VIDYA       :
      case IND_VOLUMES     :
      case IND_WPR         :
        buffer=list_ind.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        break;
      
   //--- Multi-buffer standard indicators
      case IND_ENVELOPES   :
      case IND_FRACTALS    :
      case IND_MACD        :
      case IND_RVI         :
      case IND_STOCHASTIC  :
      case IND_GATOR       :
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,0,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,1,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        break;

      case IND_ALLIGATOR   :
      case IND_ADX         :
      case IND_ADXW        :
      case IND_BANDS       :
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,0,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,1,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,2,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        break;
      
      case IND_ICHIMOKU :
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_TENKAN_SEN,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_KIJUN_SEN,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_SENKOU_SPANA,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_SENKOU_SPANB,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_CHIKOU_SPAN,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_ADDITIONAL,EQUAL);
        list=CSelect::ByBufferProperty(list,BUFFER_PROP_IND_LINE_ADDITIONAL_NUM,0,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        
        list=CSelect::ByBufferProperty(list_ind,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_ADDITIONAL,EQUAL);
        list=CSelect::ByBufferProperty(list,BUFFER_PROP_IND_LINE_ADDITIONAL_NUM,1,EQUAL);
        buffer=list.At(0);
        if(buffer==NULL) return;
        buffer.SetBufferValue(0,series_index,buffer.EmptyValue());
        break;
      
      default:
        break;
     }
  }
//+------------------------------------------------------------------+


さらに、一目均衡表標準指標のオブジェクトを作成しますが、これには指標の外観を設計するための2つの追加のヒストグラムバッファがあるため、これら2つの補助バッファのデータ消去メソッドコードブロックは既に追加されています
残りは、以前の記事で実装された他の標準指標のバッファデータの消去と同じです。

現在のチャートの値を、バッファオブジェクトの銘柄/期間に応じた時系列インデックスによって指定された標準指標のバッファに設定する方法を改善します。

メソッドにはより多くのバッファオブジェクトが含まれるようになります。これは、一目均衡表に5つのバッファオブジェクトと指標の外観を設計するための2つの補助ヒストグラムバッファがあるためです。それぞれ、すべてのバッファオブジェクトラインの値を格納するための変数の数が増加しました

//+------------------------------------------------------------------+
//| Sets values for the current chart to buffers of the specified    |
//| standard indicator by the timeseries index in accordance         |
//| with buffer object symbol/period                                 |
//+------------------------------------------------------------------+
bool CBuffersCollection::SetDataBufferStdInd(const ENUM_INDICATOR ind_type,const int id,const int series_index,const datetime series_time,const char color_index=WRONG_VALUE)
  {
//--- Get the list of buffer objects by type and ID
   CArrayObj *list=this.GetListBufferByTypeID(ind_type,id);
   if(list==NULL || list.Total()==0)
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_TEXT_BUFFER_TEXT_NO_BUFFER_OBJ));
      return false;
     }
//--- Get the list of drawn buffers with ID
   CArrayObj *list_data=CSelect::ByBufferProperty(list,BUFFER_PROP_TYPE,BUFFER_TYPE_DATA,EQUAL);
   list_data=CSelect::ByBufferProperty(list_data,BUFFER_PROP_IND_TYPE,ind_type,EQUAL);
//--- Get the list of calculated buffers with ID
   CArrayObj *list_calc=CSelect::ByBufferProperty(list,BUFFER_PROP_TYPE,BUFFER_TYPE_CALCULATE,EQUAL);
   list_calc=CSelect::ByBufferProperty(list_calc,BUFFER_PROP_IND_TYPE,ind_type,EQUAL);
//--- Leave if any of the lists is empty
   if(list_data.Total()==0 || list_calc.Total()==0)
      return false;
  
//--- Declare necessary objects and variables
   CBuffer *buffer_data0=NULL,*buffer_data1=NULL,*buffer_data2=NULL,*buffer_data3=NULL,*buffer_data4=NULL,*buffer_tmp0=NULL,*buffer_tmp1=NULL;
   CBuffer *buffer_calc0=NULL,*buffer_calc1=NULL,*buffer_calc2=NULL,*buffer_calc3=NULL,*buffer_calc4=NULL;
   double value00=EMPTY_VALUE, value01=EMPTY_VALUE;
   double value10=EMPTY_VALUE, value11=EMPTY_VALUE;
   double value20=EMPTY_VALUE, value21=EMPTY_VALUE;
   double value30=EMPTY_VALUE, value31=EMPTY_VALUE;
   double value40=EMPTY_VALUE, value41=EMPTY_VALUE;
   double value_tmp0=EMPTY_VALUE,value_tmp1=EMPTY_VALUE;
   long vol0=0,vol1=0;
   int series_index_start=series_index,index_period=0, index=0,num_bars=1;
   uchar clr=0;
//--- Depending on standard indicator type


標準指標のセットを処理する各コードブロックで、バッファデータ準備メソッドPreparingSetDataStdInd()により多くの値を渡すようになりました。

        series_index_start=PreparingSetDataStdInd(buffer_data0,buffer_data1,buffer_data2,buffer_data3,buffer_data4,
                                                  buffer_calc0,buffer_calc1,buffer_calc2,buffer_calc3,buffer_calc4,
                                                  ind_type,series_index,series_time,index_period,num_bars,
                                                  value00,value01,value10,value11,value20,value21,value30,value31,value40,value41);


メソッドの最後に、一目均衡表標準指標のハンドラゲーターオシレーターのハンドラを追加します。

      case IND_ICHIMOKU :
        list=CSelect::ByBufferProperty(list_data,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_TENKAN_SEN,EQUAL);
        buffer_data0=list.At(0);
        list=CSelect::ByBufferProperty(list_data,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_KIJUN_SEN,EQUAL);
        buffer_data1=list.At(0);
        list=CSelect::ByBufferProperty(list_data,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_SENKOU_SPANA,EQUAL);
        buffer_data2=list.At(0);
        list=CSelect::ByBufferProperty(list_data,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_SENKOU_SPANB,EQUAL);
        buffer_data3=list.At(0);
        list=CSelect::ByBufferProperty(list_data,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_CHIKOU_SPAN,EQUAL);
        buffer_data4=list.At(0);
        
        //--- Get the list of buffer objects which have ID of auxiliary line, and from it - buffer object with line number as 0
        list=CSelect::ByBufferProperty(list_data,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_ADDITIONAL,EQUAL);
        list=CSelect::ByBufferProperty(list,BUFFER_PROP_IND_LINE_ADDITIONAL_NUM,0,EQUAL);
        buffer_tmp0=list.At(0);
        //--- Get the list of buffer objects which have ID of auxiliary line, and from it - buffer object with line number as 1
        list=CSelect::ByBufferProperty(list_data,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_ADDITIONAL,EQUAL);
        list=CSelect::ByBufferProperty(list,BUFFER_PROP_IND_LINE_ADDITIONAL_NUM,1,EQUAL);
        buffer_tmp1=list.At(0);
        
        list=CSelect::ByBufferProperty(list_calc,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_TENKAN_SEN,EQUAL);
        buffer_calc0=list.At(0);
        list=CSelect::ByBufferProperty(list_calc,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_KIJUN_SEN,EQUAL);
        buffer_calc1=list.At(0);
        list=CSelect::ByBufferProperty(list_calc,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_SENKOU_SPANA,EQUAL);
        buffer_calc2=list.At(0);
        list=CSelect::ByBufferProperty(list_calc,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_SENKOU_SPANB,EQUAL);
        buffer_calc3=list.At(0);
        list=CSelect::ByBufferProperty(list_calc,BUFFER_PROP_IND_LINE_MODE,INDICATOR_LINE_MODE_CHIKOU_SPAN,EQUAL);
        buffer_calc4=list.At(0);
        
        if(buffer_calc0==NULL || buffer_data0==NULL || buffer_calc0.GetDataTotal(0)==0)
           return false;
        if(buffer_calc1==NULL || buffer_data1==NULL || buffer_calc1.GetDataTotal(0)==0)
           return false;
        if(buffer_calc2==NULL || buffer_data2==NULL || buffer_calc2.GetDataTotal(0)==0)
           return false;
        if(buffer_calc3==NULL || buffer_data3==NULL || buffer_calc3.GetDataTotal(0)==0)
           return false;
        if(buffer_calc4==NULL || buffer_data4==NULL || buffer_calc4.GetDataTotal(0)==0)
           return false;
        
        series_index_start=PreparingSetDataStdInd(buffer_data0,buffer_data1,buffer_data2,buffer_data3,buffer_data4,
                                                  buffer_calc0,buffer_calc1,buffer_calc2,buffer_calc3,buffer_calc4,
                                                  ind_type,series_index,series_time,index_period,num_bars,
                                                  value00,value01,value10,value11,value20,value21,value30,value31,value40,value41);
        if(series_index_start==WRONG_VALUE)
           return false;
        //--- In a loop, by the number of bars in  num_bars fill in the drawn buffer with a value from the calculated buffer taken by index_period index
        //--- and set the drawn buffer color depending on a proportion of value00 and value01 values
        for(int i=0;i<num_bars;i++)
          {
           index=series_index_start-i;
           buffer_data0.SetBufferValue(0,index,value00);
           buffer_data1.SetBufferValue(0,index,value10);
           buffer_data2.SetBufferValue(0,index,value20);
           buffer_data3.SetBufferValue(0,index,value30);
           buffer_data4.SetBufferValue(0,index,value40);
           buffer_data0.SetBufferColorIndex(index,color_index==WRONG_VALUE ? uchar(value00>value01 ? 0 : value00<value01 ? 1 : 2) : color_index);
           buffer_data1.SetBufferColorIndex(index,color_index==WRONG_VALUE ? uchar(value10>value11 ? 0 : value10<value11 ? 1 : 2) : color_index);
           buffer_data2.SetBufferColorIndex(index,color_index==WRONG_VALUE ? uchar(value20>value21 ? 0 : value20<value21 ? 1 : 2) : color_index);
           buffer_data3.SetBufferColorIndex(index,color_index==WRONG_VALUE ? uchar(value30>value31 ? 0 : value30<value31 ? 1 : 2) : color_index);
           buffer_data4.SetBufferColorIndex(index,color_index==WRONG_VALUE ? uchar(value40>value41 ? 0 : value40<value41 ? 1 : 2) : color_index);
           
           //--- Set values for indicator auxiliary lines depending on mutual position of  Senkou Span A and Senkou Span B lines
           value_tmp0=buffer_data2.GetDataBufferValue(0,index);
           value_tmp1=buffer_data3.GetDataBufferValue(0,index);
           if(value_tmp0<value_tmp1)
             {
              buffer_tmp0.SetBufferValue(0,index,buffer_tmp0.EmptyValue());
              buffer_tmp0.SetBufferValue(1,index,buffer_tmp0.EmptyValue());
              
              buffer_tmp1.SetBufferValue(0,index,value_tmp0);
              buffer_tmp1.SetBufferValue(1,index,value_tmp1);
             }
           else
             {
              buffer_tmp0.SetBufferValue(0,index,value_tmp0);
              buffer_tmp0.SetBufferValue(1,index,value_tmp1);
              
              buffer_tmp1.SetBufferValue(0,index,buffer_tmp1.EmptyValue());
              buffer_tmp1.SetBufferValue(1,index,buffer_tmp1.EmptyValue());
             }
           
          }
        return true;
      
      case IND_GATOR    :
        list=CSelect::ByBufferProperty(list_data,BUFFER_PROP_IND_LINE_MODE,0,EQUAL);
        buffer_data0=list.At(0);
        list=CSelect::ByBufferProperty(list_data,BUFFER_PROP_IND_LINE_MODE,1,EQUAL);
        buffer_data1=list.At(0);
           
        list=CSelect::ByBufferProperty(list_calc,BUFFER_PROP_IND_LINE_MODE,0,EQUAL);
        buffer_calc0=list.At(0);
        list=CSelect::ByBufferProperty(list_calc,BUFFER_PROP_IND_LINE_MODE,1,EQUAL);
        buffer_calc1=list.At(0);
           
        if(buffer_calc0==NULL || buffer_data0==NULL || buffer_calc0.GetDataTotal(0)==0)
           return false;
        if(buffer_calc1==NULL || buffer_data1==NULL || buffer_calc1.GetDataTotal(0)==0)
           return false;
        
        series_index_start=PreparingSetDataStdInd(buffer_data0,buffer_data1,buffer_data2,buffer_data3,buffer_data4,
                                                  buffer_calc0,buffer_calc1,buffer_calc2,buffer_calc3,buffer_calc4,
                                                  ind_type,series_index,series_time,index_period,num_bars,
                                                  value00,value01,value10,value11,value20,value21,value30,value31,value40,value41);
        if(series_index_start==WRONG_VALUE)
           return false;
        //--- In a loop, by the number of bars in  num_bars fill in the drawn buffer with a value from the calculated buffer taken by index_period index
        //--- and set the drawn buffer color depending on a proportion of value00 and value01 values
        for(int i=0;i<num_bars;i++)
          {
           index=series_index_start-i;
           buffer_data0.SetBufferValue(0,index,value00);
           buffer_data1.SetBufferValue(1,index,value10);
           buffer_data0.SetBufferColorIndex(index,color_index==WRONG_VALUE ? uchar(value00>value01 ? 0 : value00<value01 ? 1 : 2) : color_index);
           buffer_data1.SetBufferColorIndex(index,color_index==WRONG_VALUE ? uchar(value10<value11 ? 0 : value10>value11 ? 1 : 2) : color_index);
          }
        return true;
      
      default:
        break;


コードには、以前の記事で検討された他の標準指標を処理するためのコードブロックとは異なるアクションに関するコメントが含まれています。これは、一目均衡表指標の設計のためのデータの取得と処理のみに関係しています。ゲーターオシレーター指標の場合、すべてのロジックは他の標準指標の場合と同じままです。

ここで、標準指標一目均衡表とゲーターオシレーターのオブジェクトを作成するためのメソッドを記述します。

以下は、ゲーターオシレーターの作成メソッドです。

//+------------------------------------------------------------------+
//| Create multi-symbol multi-period Gator                           |
//+------------------------------------------------------------------+
int CBuffersCollection::CreateGator(const string symbol,const ENUM_TIMEFRAMES timeframe,
                                    const int jaw_period,
                                    const int jaw_shift,
                                    const int teeth_period,
                                    const int teeth_shift,
                                    const int lips_period,
                                    const int lips_shift,
                                    const ENUM_MA_METHOD ma_method,
                                    const ENUM_APPLIED_PRICE applied_price,
                                    const int id=WRONG_VALUE)
  {
//--- Create indicator handle and set default ID
   int num_bars=::PeriodSeconds(timeframe)/::PeriodSeconds(PERIOD_CURRENT);
   int shift=::fmin(jaw_shift,teeth_shift);
   int handle=::iGator(symbol,timeframe,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price);
   int identifier=(id==WRONG_VALUE ? IND_GATOR : id);
   color array_colors[3]={clrGreen,clrRed,clrGreen};
   CBuffer *buff=NULL;
   if(handle!=INVALID_HANDLE)
     {
      //--- Create histogram buffer from the zero line
      this.CreateHistogram();
      //--- Get the last created buffer object (drawn) and set to it all the necessary parameters of Up
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetShift(shift*num_bars);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_GATOR);
      buff.SetShowData(true);
      buff.SetLineMode(INDICATOR_LINE_MODE_UPPER);
      buff.SetIndicatorName("Gator Oscillator");
      buff.SetIndicatorShortName("Gator("+symbol+","+TimeframeDescription(timeframe)+": "+(string)jaw_period+","+(string)teeth_period+","+(string)lips_period+")");
      buff.SetLabel("Gator("+symbol+","+TimeframeDescription(timeframe)+": "+(string)jaw_period+","+(string)teeth_period+","+(string)lips_period+","+") Up");
      buff.SetColors(array_colors);
      
      //--- Create histogram buffer from the zero line
      this.CreateHistogram();
      //--- Get the last created buffer object (drawn) and set to it all the necessary parameters of Down
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetShift(shift*num_bars);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_GATOR);
      buff.SetShowData(true);
      buff.SetLineMode(INDICATOR_LINE_MODE_LOWER);
      buff.SetIndicatorName("Gator Oscillator");
      buff.SetIndicatorShortName("Gator("+symbol+","+TimeframeDescription(timeframe)+": "+(string)jaw_period+","+(string)teeth_period+","+(string)lips_period+")");
      buff.SetLabel("Gator("+symbol+","+TimeframeDescription(timeframe)+": "+(string)jaw_period+","+(string)teeth_period+","+(string)lips_period+","+") Down");
      buff.SetColors(array_colors);
      
      //--- Create calculated buffer of Up, in which standard indicator data will be stored
      this.CreateCalculate();
      //--- Get the last created buffer object (calculated) and set to it all the necessary parameters of Up
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetShift(shift);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_GATOR);
      buff.SetEmptyValue(EMPTY_VALUE);
      buff.SetLineMode(INDICATOR_LINE_MODE_UPPER);
      buff.SetIndicatorName("Gator Oscillator");
      buff.SetLabel("Gator("+symbol+","+TimeframeDescription(timeframe)+": "+(string)jaw_period+","+(string)teeth_period+","+(string)lips_period+","+") Up");
      
      //--- Create calculated buffer of Teeth in which standard indicator data will be stored
      this.CreateCalculate();
      //--- Get the last created buffer object (calculated) and set to it all the necessary parameters of Teeth
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetShift(shift);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_GATOR);
      buff.SetEmptyValue(EMPTY_VALUE);
      buff.SetLineMode(INDICATOR_LINE_MODE_LOWER);
      buff.SetIndicatorName("Gator Oscillator");
      buff.SetLabel("Gator("+symbol+","+TimeframeDescription(timeframe)+": "+(string)jaw_period+","+(string)teeth_period+","+(string)lips_period+","+") Down");
     }
   return handle;
  }
//+------------------------------------------------------------------+


指標ハンドルの作成時に、指標が「非ネイティブ」時間軸に描画される可能性があるかどうかに関係なく、入力にあるため、ゲーター計算のデータ元となるアリゲーター指標ラインのシフトのデータを渡します。 これらのデータはすべて、指標の内部計算に必要です。ゲーター標準指標のラインの視覚的シフトは、ゲーターの計算元となるアリゲーター指標の顎と歯のラインのシフトの値から最小値として計算されますそして、この視覚的なシフトを、現在の時間軸で表示されるべきバーの数で乗算します。そして、指標のプロットされたバッファオブジェクトのシフト値を設定します計算バッファオブジェクトの場合、バーの数を掛けずにシフトを設定します

以下は、一目均衡表を作成するメソッドです。

//+------------------------------------------------------------------+
//| Create multi-symbol multi-period Ichimoku                        |
//+------------------------------------------------------------------+
int CBuffersCollection::CreateIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe,
                                       const int tenkan_sen,
                                       const int kijun_sen,
                                       const int senkou_span_b,
                                       const int id=WRONG_VALUE)
  {
//--- Create indicator handle and set default ID
   int num_bars=::PeriodSeconds(timeframe)/::PeriodSeconds(PERIOD_CURRENT);
   int handle=::iIchimoku(symbol,timeframe,tenkan_sen,kijun_sen,senkou_span_b);
   int identifier=(id==WRONG_VALUE ? IND_ICHIMOKU : id);
   color array_colors[1]={clrRed};
   CBuffer *buff=NULL;
   if(handle!=INVALID_HANDLE)
     {
      //--- Create line buffer
      this.CreateLine();
      //--- Get the last created buffer object (drawn) and set to it all the necessary parameters of Tenkan-Sen
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_TENKAN_SEN);
      buff.SetShowData(true);
      buff.SetLabel("Tenkan-Sen("+symbol+","+TimeframeDescription(timeframe)+": "+(string)tenkan_sen+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      buff.SetColors(array_colors);
      
      //--- Create line buffer
      this.CreateLine();
      //--- Get the last created buffer object (drawn) and set to it all the necessary parameters of Kijun-Sen
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_KIJUN_SEN);
      buff.SetShowData(true);
      buff.SetLabel("Kijun-Sen("+symbol+","+TimeframeDescription(timeframe)+": "+(string)kijun_sen+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      array_colors[0]=clrBlue;
      buff.SetColors(array_colors);
      
      //--- Create line buffer
      this.CreateLine();
      //--- Get the last created buffer object (drawn) and set to it all the necessary parameters of Senkou Span A
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetShift(kijun_sen*num_bars);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_SENKOU_SPANA);
      buff.SetShowData(true);
      buff.SetLabel("Senkou Span A("+symbol+","+TimeframeDescription(timeframe)+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      array_colors[0]=clrSandyBrown;
      buff.SetColors(array_colors);
      buff.SetStyle(STYLE_DOT);
      
      //--- Create line buffer
      this.CreateLine();
      //--- Get the last created buffer object (drawn) and set to it all the necessary parameters of Senkou Span B
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetShift(kijun_sen*num_bars);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_SENKOU_SPANB);
      buff.SetShowData(true);
      buff.SetLabel("Senkou Span B("+symbol+","+TimeframeDescription(timeframe)+": "+(string)senkou_span_b+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      array_colors[0]=clrThistle;
      buff.SetColors(array_colors);
      buff.SetStyle(STYLE_DOT);
      
      //--- Create line buffer
      this.CreateLine();
      //--- Get the last created buffer object (drawn) and set to it all the necessary parameters of Chikou Span
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_CHIKOU_SPAN);
      buff.SetShowData(true);
      buff.SetLabel("Chikou Span("+symbol+","+TimeframeDescription(timeframe)+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      array_colors[0]=clrLime;
      buff.SetColors(array_colors);
      
      //--- Create histogram buffer on two lines for displaying the histogram of Senkou Span A
      this.CreateHistogram2();
      //--- Get the last created buffer object (drawn) and set to it all the necessary parameters
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetShift(kijun_sen*num_bars);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_ADDITIONAL);
      buff.SetShowData(false);
      buff.SetLabel("Senkou Span A("+symbol+","+TimeframeDescription(timeframe)+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      buff.SetIndicatorLineAdditionalNumber(0);
      //--- Get buffer data of Senkou Span A and set values of line color, width and style to the histogram
      CBuffer *tmp=GetBufferStdInd(IND_ICHIMOKU,identifier,INDICATOR_LINE_MODE_SENKOU_SPANA);
      array_colors[0]=(tmp!=NULL ? tmp.Color() : clrSandyBrown);
      buff.SetColors(array_colors);
      buff.SetWidth(tmp!=NULL ? tmp.LineWidth() : 1);
      buff.SetStyle(tmp!=NULL ? tmp.LineStyle() : STYLE_DOT);
      
      //--- Create histogram buffer on two lines for displaying the histogram of Senkou Span B
      this.CreateHistogram2();
      //--- Get the last created buffer object (drawn) and set to it all the necessary parameters
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetShift(kijun_sen*num_bars);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_ADDITIONAL);
      buff.SetShowData(false);
      buff.SetLabel("Senkou Span B("+symbol+","+TimeframeDescription(timeframe)+": "+(string)senkou_span_b+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      buff.SetIndicatorLineAdditionalNumber(1);
      //--- Get buffer data of Senkou Span B and set values of line color, width and style to the histogram
      tmp=GetBufferStdInd(IND_ICHIMOKU,identifier,INDICATOR_LINE_MODE_SENKOU_SPANB);
      array_colors[0]=(tmp!=NULL ? tmp.Color() : clrThistle);
      buff.SetColors(array_colors);
      buff.SetWidth(tmp!=NULL ? tmp.LineWidth() : 1);
      buff.SetStyle(tmp!=NULL ? tmp.LineStyle() : STYLE_DOT);
      
      //--- Create calculated buffer in which data of Tenkan-Sen line will be stored
      this.CreateCalculate();
      //--- Get the last created buffer object (calculated) and set to it all the necessary parameters
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_TENKAN_SEN);
      buff.SetEmptyValue(EMPTY_VALUE);
      buff.SetLabel("Tenkan-Sen("+symbol+","+TimeframeDescription(timeframe)+": "+(string)tenkan_sen+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      
      //--- Create calculated buffer in which data of Kijun-Sen line will be stored
      this.CreateCalculate();
      //--- Get the last created buffer object (calculated) and set to it all the necessary parameters
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_KIJUN_SEN);
      buff.SetEmptyValue(EMPTY_VALUE);
      buff.SetLabel("Kijun-Sen("+symbol+","+TimeframeDescription(timeframe)+": "+(string)kijun_sen+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      
      //--- Create calculated buffer in which data of Senkou Span A line will be stored
      this.CreateCalculate();
      //--- Get the last created buffer object (calculated) and set to it all the necessary parameters
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetShift(kijun_sen);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_SENKOU_SPANA);
      buff.SetEmptyValue(EMPTY_VALUE);
      buff.SetLabel("Senkou Span A("+symbol+","+TimeframeDescription(timeframe)+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      
      //--- Create calculated buffer in which data of Senkou Span B line will be stored
      this.CreateCalculate();
      //--- Get the last created buffer object (calculated) and set to it all the necessary parameters
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetShift(kijun_sen);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_SENKOU_SPANB);
      buff.SetEmptyValue(EMPTY_VALUE);
      buff.SetLabel("Senkou Span B("+symbol+","+TimeframeDescription(timeframe)+": "+(string)senkou_span_b+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
      
      //--- Create calculated buffer in which data of Chikou Span line will be stored
      this.CreateCalculate();
      //--- Get the last created buffer object (calculated) and set to it all the necessary parameters
      buff=this.GetLastCreateBuffer();
      if(buff==NULL)
         return INVALID_HANDLE;
      buff.SetSymbol(symbol);
      buff.SetTimeframe(timeframe);
      buff.SetID(identifier);
      buff.SetIndicatorHandle(handle);
      buff.SetIndicatorType(IND_ICHIMOKU);
      buff.SetLineMode(INDICATOR_LINE_MODE_CHIKOU_SPAN);
      buff.SetEmptyValue(EMPTY_VALUE);
      buff.SetLabel("Chikou Span("+symbol+","+TimeframeDescription(timeframe)+")");
      buff.SetIndicatorName("Ichimoku Kinko Hyo");
      buff.SetIndicatorShortName("Ichimoku("+symbol+","+TimeframeDescription(timeframe)+")");
     }
   return handle;
  }
//+------------------------------------------------------------------+


ここでは、ゲーター標準指標のオブジェクトの作成と同様に、ハンドルを作成する場合は変更なしで入力を渡し先行スパンAと先行スパンBのラインを表示するためのバッファオブジェクトを作成する場合はこれら2つのラインの間の領域をヒストグラムとして設計するための追加のバッファを渡し、シフトを乗算して、現在のチャートに表示する必要のあるバーの数を取得します計算バッファオブジェクトを作成するときは、現在のチャートのバーの数を乗算せずにシフトを設定します
基準線の計算期間は、先行スパンA線と先行スパンB線のシフトとして機能します。
追加のヒストグラムバッファを作成する場合、最初にすべての指標の標準パラメータを設定し、次にヒストグラムに対応するラインのバッファオブジェクトを取得し、ラインの取得されたバッファから値を取得する指標ラインについて、ヒストグラムの描画パラメータを同じに設定します。

ヒストグラムのバッファオブジェクトの場合、ラインをデータウィンドウに表示しないようにプロパティを設定します。これらのバッファはデザインにのみ必要であり、その値はデータ取得元の指標ラインに完全に対応しています。

これで、複数銘柄・複数期間標準指標を作成するためのライブラリのクラスとメソッドの改善が完了しました。カスタムプログラムで標準およびカスタムのマルチ指標を作成するための完全なメソッドセットができました。確かに、欠点がまだありますが、これらは、ライブラリ機能のさらなる開発で徐々に修正されます。

検証

テストを実行するには、前の記事から指標を取得し、新しい\MQL5\Indicators\TestDoEasy\Part51\ フォルダーにTestDoEasyPart51_1.mq5およびTestDoEasyPart51_2.mq5という名前で2つの新しい指標を作成します。

1つはメインチャートに描画され、もう1つはサブウィンドウに描画されるため、パラメータ#propertyindicator_chart_windowまたは#propertyindicator_separate_windowによってのみ異なります。また、1番目のケースでは一目均衡表指標を作成し、2番目のケースではゲーターオシレーターを作成します。

指標タイプとラインのシフトを設定する文字列を入力から削除します

sinput   ENUM_INDICATOR       InpIndType        =  IND_AC;        // Type standard indicator
sinput   int                  InpShift          =  0;             // Indicator line shift


TestDoEasyPart51_1.mq5ファイルのOnInit()で一目均衡表のオブジェクトを作成します

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Write the name of the working timeframe selected in the settings to the InpUsedTFs variable
   InpUsedTFs=TimeframeDescription(InpPeriod);
//--- Initialize DoEasy library
   OnInitDoEasy();
   
//--- Set indicator global variables
   prefix=engine.Name()+"_";
   //--- 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 num_bars=NumberBarsInTimeframe(InpPeriod);
   min_bars=(num_bars>2 ? num_bars : 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 the necessary buffer objects for constructing the selected standard indicator
   if(!engine.BufferCreateIchimoku(InpUsedSymbols,InpPeriod,9,26,52,1))
     {
      Print(TextByLanguage("Error. Indicator not created"));
      return INIT_FAILED;
     }
//--- Check the number of buffers specified in the 'properties' block
   if(engine.BuffersPropertyPlotsTotal()!=indicator_plots)
      Alert(TextByLanguage("Attention! Value of \"indicator_plots\" should be "),engine.BuffersPropertyPlotsTotal());
   if(engine.BuffersPropertyBuffersTotal()!=indicator_buffers)
      Alert(TextByLanguage("Attention! Value of \"indicator_buffers\" should be "),engine.BuffersPropertyBuffersTotal());
      
//--- Create the color array and set non-default colors to all buffers within the collection
//--- (commented out since default colors are already set in methods of standard indicator creation)
//--- (we can always set required colors either for all indicators like here or for each one individually)
   //color array_colors[]={clrGreen,clrRed,clrGray};
   //engine.BuffersSetColors(array_colors);

//--- Display short descriptions of created indicator buffers
   engine.BuffersPrintShort();

//--- Set a short name for the indicator, data capacity and levels
   string label=engine.BufferGetIndicatorShortNameByTypeID(IND_ICHIMOKU,1);
   IndicatorSetString(INDICATOR_SHORTNAME,label);
   SetIndicatorLevels(InpUsedSymbols,IND_ICHIMOKU);

//--- Succeeded
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+


OnCalculate()ハンドラでは、作成された指標を1つのみ処理します

//+------------------------------------------------------------------+
//| 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 and set the "as timeseries" flag to the arrays
   CopyDataAsSeries(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.OnCalculate(rates_data)==0)
      return 0;
   
//--- If working in the tester
   if(MQLInfoInteger(MQL_TESTER)) 
     {
      engine.OnTimer(rates_data);   // Working in the library timer
      engine.EventsHandling();      // Working with library events
     }
//+------------------------------------------------------------------+
//| OnCalculate code block for working with the indicator:           |
//+------------------------------------------------------------------+
//--- 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
//--- If 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)
     {
      limit=rates_total-1;
      engine.BuffersInitPlots();
      engine.BuffersInitCalculates();
     }
//--- Prepare data
//--- Fill in calculated buffers of all created standard indicators with data
   int bars_total=engine.SeriesGetBarsTotal(InpUsedSymbols,InpPeriod);
   int total_copy=(limit<min_bars ? min_bars : fmin(limit,bars_total));
   if(!engine.BufferPreparingDataAllBuffersStdInd())
      return 0;

//--- Calculate the indicator
//--- Main calculation loop of the indicator
   for(int i=limit; i>WRONG_VALUE && !IsStopped(); i--)
     {
      engine.GetBuffersCollection().SetDataBufferStdInd(IND_ICHIMOKU,1,i,time[i]);
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+


TestDoEasyPart51_2.mq5ファイルでは同じ変更を加えますが、作成して処理するのは一目均衡表ではなく、ゲーターオシレーターです。プリプロセッサがサブウィンドウで指標を作成するためのヒントを設定します

//+------------------------------------------------------------------+
//|                                           TestDoEasyPart51_2.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                             https://mql5.com/ja/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://mql5.com/ja/users/artmedia70"
#property version   "1.00"
//--- includes
#include <DoEasy\Engine.mqh>
//--- properties
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_plots   2


EURUSD H4のデータを計算に使用するには、指標設定で示されたEURUSDH1チャートで両方の指標を起動します。標準指標と比較します。


ご覧のとおり、両方の指標のデータは標準指標のデータと一致しています。

両方の指標の完全なコードは、ここに添付されているファイルに記載されています。

次の段階

次の記事では、標準指標オブジェクトクラスとMQL4の互換性のために作業を開始します。

ライブラリの現在のバージョンのすべてのファイルは、テスト指標ファイルと一緒に以下に添付されています。ダウンロードし、すべてを検証することが可能です。
質問や提案は記事のコメント欄にお願いします。
テスト指標はMQL5向けに開発されたのでご注意ください
添付ファイルはMetaTrader 5のみを対象としています。現在のライブラリバージョンはMetaTrader 4ではテストされていません。

目次に戻る

シリーズのこれまでの記事:

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部): シフト付き複数銘柄・複数期間標準指標

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/8354

添付されたファイル |
MQL5.zip (3770.76 KB)
トレーディングアルゴリズム開発への科学的アプローチ トレーディングアルゴリズム開発への科学的アプローチ
この記事では、一貫した科学的アプローチを用いて価格パターンを分析し、それに基づいてトレードアルゴリズムを構築するという、トレードアルゴリズムを開発するための方法論を考察します。 開発の理想を事例を用いて示します。
DoEasyライブラリの時系列(第50部): シフト付き複数銘柄・複数期間標準指標 DoEasyライブラリの時系列(第50部): シフト付き複数銘柄・複数期間標準指標
本稿では、複数銘柄・複数期間標準指標を正しく表示するためのライブラリメソッドを改善して、設定されたシフトによってシフトされたラインが現在の銘柄チャートに表示されるようにします。また、標準指標を使用するメソッドを整理し、最終的な指標プログラムのライブラリにある冗長なコードを削除します。
並列粒子群最適化 並列粒子群最適化
本稿では、粒子群アルゴリズムを使用した高速最適化の手法について説明しています。また、この手法のMQLでの実装を提示します。これは、エキスパートアドバイザー内のシングルスレッドモードとローカルテスターエージェントで実行されるアドオンとしての並列マルチスレッドモードの両方ですぐに使用できます。
DoEasyライブラリの時系列(第49部): 複数銘柄・複数期間の複数バッファ標準指標 DoEasyライブラリの時系列(第49部): 複数銘柄・複数期間の複数バッファ標準指標
本稿では、ライブラリクラスを改善して、データを表示するために複数の指標バッファを必要とする複数銘柄・複数期間標準指標を開発する機能を実装します。