
DoEasyライブラリの時系列(第54部): 抽象基本指標の子孫クラス
目次
概念
前の記事では、基本抽象指標オブジェクトを作成しました。今日は、作成された特定の指標オブジェクトに関する情報が指定される子孫オブジェクトを作成します。これらすべてのオブジェクトを指標コレクションに配置します。これにより、作成された各指標のデータとプロパティを取得できるようになります。
子孫オブジェクトの概念は、ライブラリ内のオブジェクト構築の概念とそれらの相互接続に完全に対応しています。一方、指標コレクションを使用すると、すべての指標オブジェクトにイベント機能をすばやく追加できます。これにより、追跡する指標イベントを簡単に設定し、これらのイベントをプログラムで使用できるようになります。
ライブラリクラスの改善
通常どおり、最初にライブラリの必要なテキストメッセージを追加します。
\MQL5\Include\DoEasy\Data.mqhファイルに、新しいメッセージインデックスを追加します。
//--- CIndicatorDE MSG_LIB_TEXT_IND_TEXT_STATUS, // Indicator status MSG_LIB_TEXT_IND_TEXT_STATUS_STANDART, // Standard indicator MSG_LIB_TEXT_IND_TEXT_STATUS_CUSTOM, // Custom indicator MSG_LIB_TEXT_IND_TEXT_TYPE, // Indicator type MSG_LIB_TEXT_IND_TEXT_TIMEFRAME, // Indicator timeframe MSG_LIB_TEXT_IND_TEXT_HANDLE, // Indicator handle MSG_LIB_TEXT_IND_TEXT_GROUP, // Indicator group MSG_LIB_TEXT_IND_TEXT_GROUP_TREND, // Trend indicator MSG_LIB_TEXT_IND_TEXT_GROUP_OSCILLATOR, // Oscillator MSG_LIB_TEXT_IND_TEXT_GROUP_VOLUMES, // Volumes MSG_LIB_TEXT_IND_TEXT_GROUP_ARROWS, // Arrow indicator MSG_LIB_TEXT_IND_TEXT_EMPTY_VALUE, // Empty value for plotting where nothing will be drawn MSG_LIB_TEXT_IND_TEXT_SYMBOL, // Indicator symbol MSG_LIB_TEXT_IND_TEXT_NAME, // Indicator name MSG_LIB_TEXT_IND_TEXT_SHORTNAME, // Indicator short name //--- CIndicatorsCollection MSG_LIB_SYS_FAILED_ADD_IND_TO_LIST, // Error. Failed to add indicator object to list }; //+------------------------------------------------------------------+
次に、新しく追加されたインデックスに対応する新しいメッセージも追加します。
{"Indicator status"}, {"Standard indicator"}, {"Custom indicator"}, {"Indicator type"}, {"Indicator timeframe"}, {"Indicator handle"}, {"Indicator group"}, {"Trend indicator"}, {"Solid lineOscillator"}, {"Volumes"}, {"Arrow indicator"}, {,"Empty value for plotting, for which there is no drawing"}, {"Indicator symbol"}, {"Indicator name"}, {"Indicator shortname"}, {"Error. Failed to add indicator object to list"}, }; //+---------------------------------------------------------------------+
前回の記事で抽象指標オブジェクトクラスを作成したときには、オブジェクトの整数プロパティの1つである標準指標タイプを追加しませんでした。このタイプは列挙型ENUM_INDICATORに対応し、特定の指標を検索するのに必要になります。
コレクションに保存されているすべてのMACD指標を検索する場合は、まず、コレクションにあるすべてのMACD指標のリストを取得する必要があります。これを行うには、指標コレクションの完全なリストをタイプIND_MACDで並べ替える必要があります。次に、IND_MACDのみを含む結果リストで、他のターゲットプロパティによる選択が行われます。
ファイル\MQL5\Include\DoEasy\Defines.mqhに指標オブジェクトの新しいプロパティを追加します。
//+------------------------------------------------------------------+ //| Indicator integer properties | //+------------------------------------------------------------------+ enum ENUM_INDICATOR_PROP_INTEGER { INDICATOR_PROP_STATUS = 0, // Indicator status (from enumeration ENUM_INDICATOR_STATUS) INDICATOR_PROP_TYPE, // Indicator type (from enumeration ENUM_INDICATOR) INDICATOR_PROP_TIMEFRAME, // Indicator timeframe INDICATOR_PROP_HANDLE, // Indicator handle INDICATOR_PROP_GROUP, // Indicator group }; #define INDICATOR_PROP_INTEGER_TOTAL (5) // Total number of indicator integer properties #define INDICATOR_PROP_INTEGER_SKIP (0) // Number of indicator properties not used in sorting //+------------------------------------------------------------------+
整数プロパティの総数を4から5に増やします。
オブジェクトに新しいプロパティを追加するときは、このプロパティでオブジェクトを検索および並べ替える機能を設定する必要があります。
列挙の新しい並べ替え基準を追加します。
//+------------------------------------------------------------------+ //| Possible indicator sorting criteria | //+------------------------------------------------------------------+ #define FIRST_INDICATOR_DBL_PROP (INDICATOR_PROP_INTEGER_TOTAL-INDICATOR_PROP_INTEGER_SKIP) #define FIRST_INDICATOR_STR_PROP (INDICATOR_PROP_INTEGER_TOTAL-INDICATOR_PROP_INTEGER_SKIP+INDICATOR_PROP_DOUBLE_TOTAL-INDICATOR_PROP_DOUBLE_SKIP) enum ENUM_SORT_INDICATOR_MODE { //--- Sort by integer properties SORT_BY_INDICATOR_INDEX_STATUS = 0, // Sort by indicator status SORT_BY_INDICATOR_TYPE, // Sort by indicator type SORT_BY_INDICATOR_TIMEFRAME, // Sort by indicator timeframe SORT_BY_INDICATOR_HANDLE, // Sort by indicator handle SORT_BY_INDICATOR_GROUP, // Sort by indicator group //--- Sort by real properties SORT_BY_INDICATOR_EMPTY_VALUE = FIRST_INDICATOR_DBL_PROP,// Sort by the empty value for plotting where nothing will be drawn //--- Sort by string properties SORT_BY_INDICATOR_SYMBOL = FIRST_INDICATOR_STR_PROP, // Sort by indicator symbol SORT_BY_INDICATOR_NAME, // Sort by indicator name SORT_BY_INDICATOR_SHORTNAME, // Sort by indicator short name }; //+------------------------------------------------------------------+
\MQL5\Include\DoEasy\Objects\Indicators\IndicatorDE.mqhの抽象指標オブジェクトクラスを少し改善します。
指標パラメータ構造の配列をクラスのprivateセクションからprotectedセクションに移動します(この配列は子孫クラスで使用できるようになります)。privateセクションで指標タイプの説明を格納する変数を宣言します。
//+------------------------------------------------------------------+ //| Abstract indicator class | //+------------------------------------------------------------------+ class CIndicatorDE : public CBaseObj { protected: MqlParam m_mql_param[]; // Array of indicator parameters private: long m_long_prop[INDICATOR_PROP_INTEGER_TOTAL]; // Integer properties double m_double_prop[INDICATOR_PROP_DOUBLE_TOTAL]; // Real properties string m_string_prop[INDICATOR_PROP_STRING_TOTAL]; // String properties string m_ind_type; // Indicator type description
クラスのpublicセクションに、指標タイプの戻すメソッドと指標タイプの説明を戻すメソッドの2つを追加します。
public: //--- Default constructor CIndicatorDE(void){;} //--- Destructor ~CIndicatorDE(void); //--- Set buffer's (1) integer, (2) real and (3) string property void SetProperty(ENUM_INDICATOR_PROP_INTEGER property,long value) { this.m_long_prop[property]=value; } void SetProperty(ENUM_INDICATOR_PROP_DOUBLE property,double value) { this.m_double_prop[this.IndexProp(property)]=value; } void SetProperty(ENUM_INDICATOR_PROP_STRING property,string value) { this.m_string_prop[this.IndexProp(property)]=value; } //--- Return (1) integer, (2) real and (3) string buffer property from the properties array long GetProperty(ENUM_INDICATOR_PROP_INTEGER property) const { return this.m_long_prop[property]; } double GetProperty(ENUM_INDICATOR_PROP_DOUBLE property) const { return this.m_double_prop[this.IndexProp(property)]; } string GetProperty(ENUM_INDICATOR_PROP_STRING property) const { return this.m_string_prop[this.IndexProp(property)]; } //--- Return description of buffer's (1) integer, (2) real and (3) string property string GetPropertyDescription(ENUM_INDICATOR_PROP_INTEGER property); string GetPropertyDescription(ENUM_INDICATOR_PROP_DOUBLE property); string GetPropertyDescription(ENUM_INDICATOR_PROP_STRING property); //--- Return the flag of the buffer supporting the property virtual bool SupportProperty(ENUM_INDICATOR_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_INDICATOR_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_INDICATOR_PROP_STRING property) { return true; } //--- Compare CIndicatorDE objects by all possible properties (for sorting the lists by a specified indicator object property) virtual int Compare(const CObject *node,const int mode=0) const; //--- Compare CIndicatorDE objects by all properties (to search for equal indicator objects) bool IsEqual(CIndicatorDE* compared_obj) const; //--- Set indicator’s (1) group, (2) empty value of buffers, (3) name, (4) short name void SetGroup(const ENUM_INDICATOR_GROUP group) { this.SetProperty(INDICATOR_PROP_GROUP,group); } void SetEmptyValue(const double value) { this.SetProperty(INDICATOR_PROP_EMPTY_VALUE,value); } void SetName(const string name) { this.SetProperty(INDICATOR_PROP_NAME,name); } void SetShortName(const string shortname) { this.SetProperty(INDICATOR_PROP_SHORTNAME,shortname); } //--- Return indicator’s (1) status, (2) group, (3) timeframe, (4) handle, (5) empty value of buffers, (6) name, (7) short name, (8) symbol, (9) type ENUM_INDICATOR_STATUS Status(void) const { return (ENUM_INDICATOR_STATUS)this.GetProperty(INDICATOR_PROP_STATUS);} ENUM_INDICATOR_GROUP Group(void) const { return (ENUM_INDICATOR_GROUP)this.GetProperty(INDICATOR_PROP_GROUP); } ENUM_TIMEFRAMES Timeframe(void) const { return (ENUM_TIMEFRAMES)this.GetProperty(INDICATOR_PROP_TIMEFRAME); } ENUM_INDICATOR TypeIndicator(void) const { return (ENUM_INDICATOR)this.GetProperty(INDICATOR_PROP_TYPE); } int Handle(void) const { return (int)this.GetProperty(INDICATOR_PROP_HANDLE); } double EmptyValue(void) const { return this.GetProperty(INDICATOR_PROP_EMPTY_VALUE); } string Name(void) const { return this.GetProperty(INDICATOR_PROP_NAME); } string ShortName(void) const { return this.GetProperty(INDICATOR_PROP_SHORTNAME); } string Symbol(void) const { return this.GetProperty(INDICATOR_PROP_SYMBOL); } //--- Return description of indicator’s (1) type, (2) status, (3) group, (4) timeframe, (5) empty value string GetTypeDescription(void) const { return m_ind_type; } string GetStatusDescription(void) const; string GetGroupDescription(void) const; string GetTimeframeDescription(void) const; string GetEmptyValueDescription(void) const; //--- Display the description of indicator object properties in the journal (full_prop=true - all properties, false - supported ones only) void Print(const bool full_prop=false); //--- Display a short description of indicator object in the journal (implementation in the descendants) virtual void PrintShort(void) {;} }; //+------------------------------------------------------------------+
クローズドパラメトリックコンストラクタでは、指標タイプの入力から部分文字列を取得して指標名のみを残し(たとえば、MACDのみがIND_MACD から残り、これは指標タイプの説明になります)、オブジェクトプロパティに指標タイプを書き込みます。
//+------------------------------------------------------------------+ //| Closed parametric constructor | //+------------------------------------------------------------------+ CIndicatorDE::CIndicatorDE(ENUM_INDICATOR ind_type, string symbol, ENUM_TIMEFRAMES timeframe, ENUM_INDICATOR_STATUS status, ENUM_INDICATOR_GROUP group, string name, string shortname, MqlParam &mql_params[]) { //--- Set collection ID to the object this.m_type=COLLECTION_INDICATORS_ID; //--- Write description of indicator type this.m_ind_type=::StringSubstr(::EnumToString(ind_type),4); //--- If parameter array size passed to constructor is more than zero //--- fill in the array of object parameters with data from the array passed to constructor int count=::ArrayResize(m_mql_param,::ArraySize(mql_params)); for(int i=0;i<count;i++) { this.m_mql_param[i].type=mql_params[i].type; this.m_mql_param[i].double_value=mql_params[i].double_value; this.m_mql_param[i].integer_value=mql_params[i].integer_value; this.m_mql_param[i].string_value=mql_params[i].string_value; } //--- Create indicator handle int handle=::IndicatorCreate(symbol,timeframe,ind_type,count,this.m_mql_param); //--- Save integer properties this.m_long_prop[INDICATOR_PROP_STATUS] = status; this.m_long_prop[INDICATOR_PROP_TYPE] = ind_type; this.m_long_prop[INDICATOR_PROP_GROUP] = group; this.m_long_prop[INDICATOR_PROP_TIMEFRAME] = timeframe; this.m_long_prop[INDICATOR_PROP_HANDLE] = handle; //--- Save real properties this.m_double_prop[this.IndexProp(INDICATOR_PROP_EMPTY_VALUE)]=EMPTY_VALUE; //--- Save string properties this.m_string_prop[this.IndexProp(INDICATOR_PROP_SYMBOL)] = (symbol==NULL || symbol=="" ? ::Symbol() : symbol); this.m_string_prop[this.IndexProp(INDICATOR_PROP_NAME)] = name; this.m_string_prop[this.IndexProp(INDICATOR_PROP_SHORTNAME)]= shortname; } //+------------------------------------------------------------------+
指標の整数プロパティの説明を返すメソッドに指標タイプの説明を返すためのコードブロックを追加します。
//+------------------------------------------------------------------+ //| Return description of indicator's integer property | //+------------------------------------------------------------------+ string CIndicatorDE::GetPropertyDescription(ENUM_INDICATOR_PROP_INTEGER property) { return ( property==INDICATOR_PROP_STATUS ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_STATUS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetStatusDescription() ) : property==INDICATOR_PROP_TYPE ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_TYPE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetTypeDescription() ) : property==INDICATOR_PROP_GROUP ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_GROUP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetGroupDescription() ) : property==INDICATOR_PROP_TIMEFRAME ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_TIMEFRAME)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetTimeframeDescription() ) : property==INDICATOR_PROP_HANDLE ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_HANDLE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : "" ); } //+------------------------------------------------------------------+
指標オブジェクトクラス
次に、作成された指標オブジェクトに関するすべての情報を指定する基本抽象指標の子孫オブジェクトを作成します。そして、これらのクラスは、さまざまなタイプ指標を作成し、それらからデータを取得するのに役立ちます。
In directory \MQL5\Include\DoEasy\Objects\Indicators\で、新しいStandartフォルダを作成して、その中に新しいIndAC.mqhファイル(抽象指標の基本クラスから継承されたAccelerator Oscillator標準指標のCIndACクラス)を作成します。 ファイルはこのクラスにリンクされます。
クラスは大きくないので、その完全なコードを分析しましょう。
//+------------------------------------------------------------------+ //| IndAC.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/en/users/artmedia70" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "..\\IndicatorDE.mqh" //+------------------------------------------------------------------+ //| Standard indicator Accelerator Oscillator | //+------------------------------------------------------------------+ class CIndAC : public CIndicatorDE { private: public: //--- Constructor CIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe,MqlParam &mql_param[]) : CIndicatorDE(IND_AC,symbol,timeframe, INDICATOR_STATUS_STANDART, INDICATOR_GROUP_OSCILLATOR, "Accelerator Oscillator", "AC("+symbol+","+TimeframeDescription(timeframe)+")",mql_param) {} //--- Supported indicator properties (1) real, (2) integer virtual bool SupportProperty(ENUM_INDICATOR_PROP_DOUBLE property); //--- Display a short description of indicator object in the journal virtual void PrintShort(void); }; //+------------------------------------------------------------------+ //| Return 'true' if indicator supports a passed | //| integer property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CIndAC::SupportProperty(ENUM_INDICATOR_PROP_INTEGER property) { return true; } //+------------------------------------------------------------------+ //| Return 'true' if indicator supports a passed | //| real property, otherwise return 'false' | //+------------------------------------------------------------------+ bool CIndAC::SupportProperty(ENUM_INDICATOR_PROP_DOUBLE property) { return true; } //+------------------------------------------------------------------+ //--- Display a short description of indicator object in the journal | //+------------------------------------------------------------------+ void CIndAC::PrintShort(void) { ::Print(GetStatusDescription()," ",this.Name()," ",this.Symbol()," ",TimeframeDescription(this.Timeframe())); } //+------------------------------------------------------------------+
標準指標の数に応じて、合計で38のクラスを作成する必要があります(実装がわずかに異なるため、カスタム指標はまだ作成していません)。
これらのクラスはすべて同じメソッドを持ち、コンストラクタから親クラスに渡されるパラメータのみが異なります。
//--- Constructor CIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe,MqlParam &mql_param[]) : CIndicatorDE(IND_AC,symbol,timeframe, INDICATOR_STATUS_STANDART, INDICATOR_GROUP_OSCILLATOR, "Accelerator Oscillator", "AC("+symbol+","+TimeframeDescription(timeframe)+")",mql_param) {}
クラス入力では、銘柄名、時間軸、指標パラメータが既に入力されている構造体を渡します(この例ではAccelerator Oscillator)。
リストの初期化で、親クラスのクローズドパラメトリックコンストラクタに(順番に)渡します。
- 指標タイプ - IND_AC、銘柄名、時間軸
- 指標ステータス - 標準
- 指標グループ - オシレータ
- 指標名 - Accelerator Oscillator
- 指標の短縮名 - AC(銘柄、時間枠)および指標パラメータの入力された構造体
以前に作成したライブラリオブジェクトによる残りのすべてのメソッドはすでにわかっており、それらは同じタスクを実行します。
オブジェクトによって整数プロパティと実プロパティをサポートするフラグを返すメソッドは、trueを返します。すべてのプロパティは指標オブジェクトによってサポートされます。
指標の短い説明を返すメソッドは、次の文字列タイプを返します。
標準指標Accelerator Oscillator EURUSD H4
同様の指標オブジェクトクラスの残りのすべてのファイルでは、クラスコンストラクタのみに違いがあります。親クラスコンストラクタには、指標に対応するパラメータが渡されます。
たとえば、指標Accumulation/Distributionの場合、クラスコンストラクタは次のようになります。
//--- Constructor CIndAD(const string symbol,const ENUM_TIMEFRAMES timeframe,MqlParam &mql_param[]) : CIndicatorDE(IND_AD,symbol,timeframe, INDICATOR_STATUS_STANDART, INDICATOR_GROUP_VOLUMES, "Accumulation/Distribution", "AD("+symbol+","+TimeframeDescription(timeframe)+")",mql_param) {}
ご覧のとおり、ここでは標準指標ADに対応するパラメータが渡されます。
- 指標タイプ - IND_AD、銘柄名、時間軸
- 指標ステータス - 標準
- 指標グループ - ボリューム
- 指標名 - Accumulation/Distribution
- 指標の短縮名 - AC(銘柄、時間枠)および指標パラメータの入力された構造体
抽象指標基本クラスの子孫クラスのすべてのファイルはすでに実装されており、記事に添付されている\MQL5\Include\DoEasy\Objects\Indicators\Standartファイルで表示できます。
指標オブジェクトコレクション
現在のライブラリオブジェクトの構築と保存の一般的な概念に従って、作成されたすべての指標オブジェクトをコレクションリストに追加する必要があります。このリストから、指定されたプロパティまたは共通の同じプロパティを持つ指標のリストによって、必要な指標へのポインタを常に取得できます。指標への受信ポインタによって、指標によって返されたすべてのデータを取得して、さらに計算することができます。
\MQL5\Include\DoEasy\Collections\フォルダで、IndicatorsCollection.mqhという名前のファイルに新しいクラスを作成します。
コレクションから必要なオブジェクトリストを返すライブラリの標準メソッドとは別に、クラスには、指標オブジェクトを作成するための1つのprivateメソッドと、タイプに応じて特定の指標オブジェクトを作成するための複数のメソッドが含まれます。 また、作成された指標オブジェクトへのポインタをそのタイプごとに取得するための複数のメソッドもあります。各グループのすべてのメソッドは、それらのロジックに従って互いに同一であるため、例としてそれらの一部のみを検討してください。
指標のコレクションクラスが上記で作成した指標クラスにアクセスできるようにするには、それらをファイルリストに接続する必要があります。
//+------------------------------------------------------------------+ //| IndicatorsCollection.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "ListObj.mqh" #include "..\Objects\Indicators\Standart\IndAC.mqh" #include "..\Objects\Indicators\Standart\IndAD.mqh" #include "..\Objects\Indicators\Standart\IndADX.mqh" #include "..\Objects\Indicators\Standart\IndADXW.mqh" #include "..\Objects\Indicators\Standart\IndAlligator.mqh" #include "..\Objects\Indicators\Standart\IndAMA.mqh" #include "..\Objects\Indicators\Standart\IndAO.mqh" #include "..\Objects\Indicators\Standart\IndATR.mqh" #include "..\Objects\Indicators\Standart\IndBands.mqh" #include "..\Objects\Indicators\Standart\IndBears.mqh" #include "..\Objects\Indicators\Standart\IndBulls.mqh" #include "..\Objects\Indicators\Standart\IndBWMFI.mqh" #include "..\Objects\Indicators\Standart\IndCCI.mqh" #include "..\Objects\Indicators\Standart\IndChaikin.mqh" #include "..\Objects\Indicators\Standart\IndDEMA.mqh" #include "..\Objects\Indicators\Standart\IndDeMarker.mqh" #include "..\Objects\Indicators\Standart\IndEnvelopes.mqh" #include "..\Objects\Indicators\Standart\IndForce.mqh" #include "..\Objects\Indicators\Standart\IndFractals.mqh" #include "..\Objects\Indicators\Standart\IndFRAMA.mqh" #include "..\Objects\Indicators\Standart\IndGator.mqh" #include "..\Objects\Indicators\Standart\IndIchimoku.mqh" #include "..\Objects\Indicators\Standart\IndMA.mqh" #include "..\Objects\Indicators\Standart\IndMACD.mqh" #include "..\Objects\Indicators\Standart\IndMFI.mqh" #include "..\Objects\Indicators\Standart\IndMomentum.mqh" #include "..\Objects\Indicators\Standart\IndOBV.mqh" #include "..\Objects\Indicators\Standart\IndOsMA.mqh" #include "..\Objects\Indicators\Standart\IndRSI.mqh" #include "..\Objects\Indicators\Standart\IndRVI.mqh" #include "..\Objects\Indicators\Standart\IndSAR.mqh" #include "..\Objects\Indicators\Standart\IndStDev.mqh" #include "..\Objects\Indicators\Standart\IndStoch.mqh" #include "..\Objects\Indicators\Standart\IndTEMA.mqh" #include "..\Objects\Indicators\Standart\IndTRIX.mqh" #include "..\Objects\Indicators\Standart\IndVIDYA.mqh" #include "..\Objects\Indicators\Standart\IndVolumes.mqh" #include "..\Objects\Indicators\Standart\IndWPR.mqh" //+------------------------------------------------------------------+
さらに、クラス本体の完全なコードを見てから、各グループの2つのメソッドを分析します。
//+------------------------------------------------------------------+ //| Indicator collection | //+------------------------------------------------------------------+ class CIndicatorsCollection : public CObject { private: CListObj m_list; // Indicator object list MqlParam m_mql_param[]; // Array of indicator parameters //--- Create a new indicator object CIndicatorDE *CreateIndicator(const ENUM_INDICATOR ind_type,MqlParam &mql_param[],const string symbol_name=NULL,const ENUM_TIMEFRAMES period=PERIOD_CURRENT); public: //--- Return (1) itself, (2) indicator list, (3) list of indicators by type CIndicatorsCollection *GetObject(void) { return &this; } CArrayObj *GetList(void) { return &this.m_list; } //--- Return indicator list by (1) status, (2) type, (3) timeframe, (4) group, (5) symbol, (6) name, (7) short name CArrayObj *GetListIndByStatus(const ENUM_INDICATOR_STATUS status) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_STATUS,status,EQUAL); } CArrayObj *GetListIndByType(const ENUM_INDICATOR type) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TYPE,type,EQUAL); } CArrayObj *GetListIndByTimeframe(const ENUM_TIMEFRAMES timeframe) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } CArrayObj *GetListIndByGroup(const ENUM_INDICATOR_GROUP group) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_GROUP,group,EQUAL); } CArrayObj *GetListIndBySymbol(const string symbol) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SYMBOL,symbol,EQUAL); } CArrayObj *GetListIndByName(const string name) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_NAME,name,EQUAL); } CArrayObj *GetListIndByShortname(const string shortname) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SHORTNAME,shortname,EQUAL); } //--- Return the list of indicator objects by type of indicator, symbol and timeframe CArrayObj *GetListAC(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAD(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListADX(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAO(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListATR(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBands(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListCCI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListForce(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListFractals(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListGator(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMFI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMACD(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListOBV(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListSAR(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListRSI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListRVI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListTriX(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListWPR(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListVIDYA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Return the pointer to indicator object in the collection by indicator type and by its parameters CIndicatorDE *GetIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe); CIndicatorDE *GetIndAD(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndADX(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); CIndicatorDE *GetIndADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); CIndicatorDE *GetIndAlligator(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); CIndicatorDE *GetIndAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ama_period, const int fast_ema_period, const int slow_ema_period, const int ama_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndAO(const string symbol,const ENUM_TIMEFRAMES timeframe); CIndicatorDE *GetIndATR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndBands(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const double deviation, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ma_period, const int slow_ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndCCI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price, const double deviation); CIndicatorDE *GetIndForce(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndFractals(const string symbol,const ENUM_TIMEFRAMES timeframe); CIndicatorDE *GetIndFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndGator(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); CIndicatorDE *GetIndIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe, const int tenkan_sen, const int kijun_sen, const int senkou_span_b); CIndicatorDE *GetIndBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe, const int mom_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndMACD(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndOBV(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndSAR(const string symbol,const ENUM_TIMEFRAMES timeframe, const double step, const double maximum); CIndicatorDE *GetIndRSI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndRVI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe, const int Kperiod, const int Dperiod, const int slowing, const ENUM_MA_METHOD ma_method, const ENUM_STO_PRICE price_field); CIndicatorDE *GetIndTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndTriX(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndWPR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int calc_period); CIndicatorDE *GetIndVIDYA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int cmo_period, const int ema_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); //--- Create a new indicator object by indicator type and places it to collection list int CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe); int CreateAD(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); int CreateADX(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); int CreateADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); int CreateAlligator(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); int CreateAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ama_period, const int fast_ema_period, const int slow_ema_period, const int ama_shift, const ENUM_APPLIED_PRICE applied_price); int CreateAO(const string symbol,const ENUM_TIMEFRAMES timeframe); int CreateATR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateBands(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const double deviation, const ENUM_APPLIED_PRICE applied_price); int CreateBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ma_period, const int slow_ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); int CreateCCI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); int CreateDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price, const double deviation); int CreateForce(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); int CreateFractals(const string symbol,const ENUM_TIMEFRAMES timeframe); int CreateFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int 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); int CreateIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe, const int tenkan_sen, const int kijun_sen, const int senkou_span_b); int CreateBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); int CreateMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe, const int mom_period, const ENUM_APPLIED_PRICE applied_price); int CreateMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_VOLUME applied_volume); int CreateMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); int CreateOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); int CreateMACD(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); int CreateOBV(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); int CreateSAR(const string symbol,const ENUM_TIMEFRAMES timeframe, const double step, const double maximum); int CreateRSI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); int CreateRVI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); int CreateStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe, const int Kperiod, const int Dperiod, const int slowing, const ENUM_MA_METHOD ma_method, const ENUM_STO_PRICE price_field); int CreateTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateTriX(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); int CreateWPR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int calc_period); int CreateVIDYA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int cmo_period, const int ema_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); //--- Constructor CIndicatorsCollection(); }; //+------------------------------------------------------------------+
コードは印象的ですが、実際には、必要な指標のタイプが互いに異なる類似タイプのメソッドのグループがいくつかあります。
必要な指標タイプのリストを返すメソッドはライブラリの標準であり、繰り返し分析しました。
//--- Return (1) itself, (2) indicator list, (3) list of indicators by type CIndicatorsCollection *GetObject(void) { return &this; } CArrayObj *GetList(void) { return &this.m_list; } //--- Return indicator list by (1) status, (2) type, (3) timeframe, (4) group, (5) symbol, (6) name, (7) short name CArrayObj *GetListIndByStatus(const ENUM_INDICATOR_STATUS status) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_STATUS,status,EQUAL); } CArrayObj *GetListIndByType(const ENUM_INDICATOR type) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TYPE,type,EQUAL); } CArrayObj *GetListIndByTimeframe(const ENUM_TIMEFRAMES timeframe) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } CArrayObj *GetListIndByGroup(const ENUM_INDICATOR_GROUP group) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_GROUP,group,EQUAL); } CArrayObj *GetListIndBySymbol(const string symbol) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SYMBOL,symbol,EQUAL); } CArrayObj *GetListIndByName(const string name) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_NAME,name,EQUAL); } CArrayObj *GetListIndByShortname(const string shortname) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SHORTNAME,shortname,EQUAL); }
クラスコンストラクタで、指標パラメータ構造体の配列をリセット、コレクションリストをクリア、リストの並び替え済みリストフラグを設定、そして、指標コレクションIDを割り当てます。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CIndicatorsCollection::CIndicatorsCollection() { ::ArrayResize(this.m_mql_param,0); this.m_list.Clear(); this.m_list.Sort(); this.m_list.Type(COLLECTION_INDICATORS_ID); } //+------------------------------------------------------------------+
指標オブジェクトを作成するためのprivateメソッドは、メソッドに渡される作成された指標のタイプに応じて新しい指標オブジェクトを作成し、作成されたオブジェクトへのポインタを返します。
//+------------------------------------------------------------------+ //| Create a new indicator object | //+------------------------------------------------------------------+ CIndicatorDE *CIndicatorsCollection::CreateIndicator(const ENUM_INDICATOR ind_type,MqlParam &mql_param[],const string symbol_name=NULL,const ENUM_TIMEFRAMES period=PERIOD_CURRENT) { string symbol=(symbol_name==NULL || symbol_name=="" ? ::Symbol() : symbol_name); ENUM_TIMEFRAMES timeframe=(period==PERIOD_CURRENT ? ::Period() : period); CIndicatorDE *indicator=NULL; switch(ind_type) { case IND_AC : indicator=new CIndAC(symbol,timeframe,mql_param); break; case IND_AD : indicator=new CIndAD(symbol,timeframe,mql_param); break; case IND_ADX : indicator=new CIndADX(symbol,timeframe,mql_param); break; case IND_ADXW : indicator=new CIndADXW(symbol,timeframe,mql_param); break; case IND_ALLIGATOR : indicator=new CIndAlligator(symbol,timeframe,mql_param); break; case IND_AMA : indicator=new CIndAMA(symbol,timeframe,mql_param); break; case IND_AO : indicator=new CIndAO(symbol,timeframe,mql_param); break; case IND_ATR : indicator=new CIndATR(symbol,timeframe,mql_param); break; case IND_BANDS : indicator=new CIndBands(symbol,timeframe,mql_param); break; case IND_BEARS : indicator=new CIndBears(symbol,timeframe,mql_param); break; case IND_BULLS : indicator=new CIndBulls(symbol,timeframe,mql_param); break; case IND_BWMFI : indicator=new CIndBWMFI(symbol,timeframe,mql_param); break; case IND_CCI : indicator=new CIndCCI(symbol,timeframe,mql_param); break; case IND_CHAIKIN : indicator=new CIndCHO(symbol,timeframe,mql_param); break; case IND_DEMA : indicator=new CIndDEMA(symbol,timeframe,mql_param); break; case IND_DEMARKER : indicator=new CIndDeMarker(symbol,timeframe,mql_param); break; case IND_ENVELOPES : indicator=new CIndEnvelopes(symbol,timeframe,mql_param); break; case IND_FORCE : indicator=new CIndForce(symbol,timeframe,mql_param); break; case IND_FRACTALS : indicator=new CIndFractals(symbol,timeframe,mql_param); break; case IND_FRAMA : indicator=new CIndFRAMA(symbol,timeframe,mql_param); break; case IND_GATOR : indicator=new CIndGator(symbol,timeframe,mql_param); break; case IND_ICHIMOKU : indicator=new CIndIchimoku(symbol,timeframe,mql_param); break; case IND_MA : indicator=new CIndMA(symbol,timeframe,mql_param); break; case IND_MACD : indicator=new CIndMACD(symbol,timeframe,mql_param); break; case IND_MFI : indicator=new CIndMFI(symbol,timeframe,mql_param); break; case IND_MOMENTUM : indicator=new CIndMomentum(symbol,timeframe,mql_param); break; case IND_OBV : indicator=new CIndOBV(symbol,timeframe,mql_param); break; case IND_OSMA : indicator=new CIndOsMA(symbol,timeframe,mql_param); break; case IND_RSI : indicator=new CIndRSI(symbol,timeframe,mql_param); break; case IND_RVI : indicator=new CIndRVI(symbol,timeframe,mql_param); break; case IND_SAR : indicator=new CIndSAR(symbol,timeframe,mql_param); break; case IND_STDDEV : indicator=new CIndStDev(symbol,timeframe,mql_param); break; case IND_STOCHASTIC : indicator=new CIndStoch(symbol,timeframe,mql_param); break; case IND_TEMA : indicator=new CIndTEMA(symbol,timeframe,mql_param); break; case IND_TRIX : indicator=new CIndTRIX(symbol,timeframe,mql_param); break; case IND_VIDYA : indicator=new CIndVIDYA(symbol,timeframe,mql_param); break; case IND_VOLUMES : indicator=new CIndVolumes(symbol,timeframe,mql_param); break; case IND_WPR : indicator=new CIndWPR(symbol,timeframe,mql_param); break; case IND_CUSTOM : break; default: break; } return indicator; } //+------------------------------------------------------------------+
デフォルトでは、一時的にもカスタム指標の場合も(作成は次の記事で実装されます)、メソッドはNULLを返します。
以下は、指標オブジェクトAccelerator Oscillatorを作成するメソッドです。
//+------------------------------------------------------------------+ //| Create a new indicator object Accelerator Oscillator | //| and place it to the collection list | //+------------------------------------------------------------------+ int CIndicatorsCollection::CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe) { //--- AC indicator possesses no parameters - resize the array of parameter structures ::ArrayResize(this.m_mql_param,0); //--- Create indicator object CIndicatorDE *indicator=this.CreateIndicator(IND_AC,this.m_mql_param,symbol,timeframe); if(indicator==NULL) return INVALID_HANDLE; int index=this.m_list.Search(indicator); //--- If such indicator is already in the list if(index!=WRONG_VALUE) { //--- Get indicator object from the list and return indicator handle indicator=this.m_list.At(index); return indicator.Handle(); } //--- If such indicator is not in the list else { //--- If failed to add indicator object to the list //--- display the appropriate message and return INVALID_HANDLE if(!this.m_list.Add(indicator)) { Print(CMessage::Text(MSG_LIB_SYS_FAILED_ADD_IND_TO_LIST)); return INVALID_HANDLE; } //--- Return the handle of a new indicator added to the list return indicator.Handle(); } //--- Return INVALID_HANDLE return INVALID_HANDLE; } //+------------------------------------------------------------------+
メソッドロジックはコードに記載されており、質問はないはずです。指標オブジェクトは、上記で分析したCreateIndicator()の作成メソッドで作成されることに注意してください。メソッドは一種のIND_AC指標を受け取ります。AC指標には入力がないため、ここでは指標パラメータ構造体の配列は必要ありません。したがって、配列はリセットされます。これは、前の記事で検討したCIndicatorDEクラスで指標を作成するときに使用する必要がないことを示しています。
他の標準指標を作成するための残りのメソッドは、ロジックで分析したものと同じであり、必要な指標の指定と、必要に応じて指標パラメータ構造の配列を入力することによってのみ異なります。
例として、8つの入力が必要であり、すべてがアリゲーター指標パラメータの結果の順序に従って指標パラメータの配列に追加され、IND_ALLIGATORタイプが指標オブジェクト作成メソッドに渡される、アリゲーター指標の作成メソッドを考えてみます。
//+------------------------------------------------------------------+ //| Create new indicator object Alligator | //| and place it to the collection list | //+------------------------------------------------------------------+ int CIndicatorsCollection::CreateAlligator(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) { //--- Add required indicator parameters to the array of parameter structures ::ArrayResize(this.m_mql_param,8); this.m_mql_param[0].type=TYPE_INT; this.m_mql_param[0].integer_value=jaw_period; this.m_mql_param[1].type=TYPE_INT; this.m_mql_param[1].integer_value=jaw_shift; this.m_mql_param[2].type=TYPE_INT; this.m_mql_param[2].integer_value=teeth_period; this.m_mql_param[3].type=TYPE_INT; this.m_mql_param[3].integer_value=teeth_shift; this.m_mql_param[4].type=TYPE_INT; this.m_mql_param[4].integer_value=lips_period; this.m_mql_param[5].type=TYPE_INT; this.m_mql_param[5].integer_value=lips_shift; this.m_mql_param[6].type=TYPE_INT; this.m_mql_param[6].integer_value=ma_method; this.m_mql_param[7].type=TYPE_INT; this.m_mql_param[7].integer_value=applied_price; //--- Create indicator object CIndicatorDE *indicator=this.CreateIndicator(IND_ALLIGATOR,this.m_mql_param,symbol,timeframe); if(indicator==NULL) return INVALID_HANDLE; int index=this.m_list.Search(indicator); //--- If such indicator is already in the list if(index!=WRONG_VALUE) { //--- Get indicator object from the list and return indicator handle indicator=this.m_list.At(index); return indicator.Handle(); } //--- If such indicator is not in the list else { //--- If failed to add indicator object to the list //--- display the appropriate message and return INVALID_HANDLE if(!this.m_list.Add(indicator)) { Print(CMessage::Text(MSG_LIB_SYS_FAILED_ADD_IND_TO_LIST)); return INVALID_HANDLE; } //--- Return the handle of a new indicator added to the list return indicator.Handle(); } //--- Return INVALID_HANDLE return INVALID_HANDLE; } //+------------------------------------------------------------------+
それぞれのメソッドの違いはこれですべてです。残りの指標作成メソッドは分析されません。それらは、記事に添付されているファイルで入手できます。
以下は、コレクションリストにあるすべての指標オブジェクトAcceleratorOscillatorのリストを銘柄と時間枠別に返すメソッドです。
//+------------------------------------------------------------------+ //| Return the list of indicator objects Accelerator Oscillator | //| by symbol and timeframe | //+------------------------------------------------------------------+ CArrayObj *CIndicatorsCollection::GetListAC(const string symbol,const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=GetListIndByType(IND_AC); list=CSelect::ByIndicatorProperty(list,INDICATOR_PROP_SYMBOL,symbol,EQUAL); return CSelect::ByIndicatorProperty(list,INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } //+------------------------------------------------------------------+
まず、コレクションリストにあるすべての指標オブジェクトAcceleratorOscillatorのリストを取得します。
次に、受信したリストを銘柄で並べ替えます。
そして今度は時間枠でもう一度並び替えられた受信リストを返します。
残りのメソッドは、最初にメソッド設定に従って必要なすべての指標のリストを取得するという事実を除いて、上記で検討したものと完全に同じです。
たとえば、コレクションリストにあるすべての指標オブジェクトAccumulation/Distributionのリストを銘柄と時間枠別に取得するには、メソッドは次のようになります。
//+------------------------------------------------------------------+ //| Return the list of indicator objects Accumulation/Distribution | //| by symbol and timeframe | //+------------------------------------------------------------------+ CArrayObj *CIndicatorsCollection::GetListAD(const string symbol,const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=GetListIndByType(IND_AD); list=CSelect::ByIndicatorProperty(list,INDICATOR_PROP_SYMBOL,symbol,EQUAL); return CSelect::ByIndicatorProperty(list,INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } //+------------------------------------------------------------------+
ここでは、まずすべてのAD指標のリストを取得し、コレクションに含め、さらに、上記のメソッドと同様に、銘柄と時間枠でリストを並べ替えます。
今日は、コレクション内の指標オブジェクトへのポインタを指標タイプとそのパラメータで返すメソッドを1つだけ実装します。Accelerator Oscillator指標の場合は、次のようになります。
//+------------------------------------------------------------------+ //| Return pointer to indicator object Accelerator Oscillator | //+------------------------------------------------------------------+ CIndicatorDE *CIndicatorsCollection::GetIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=GetListAC(symbol,timeframe); return(list==NULL || list.Total()==0 ? NULL : list.At(0)); } //+------------------------------------------------------------------+
この指標(およびその他の指標)には入力がないため、銘柄および時間枠でコレクションリストから選択する場合、リストには1つの指標オブジェクト(インデックス0)のみが含まれます。タイプIND_ACに対応し、要求された銘柄と時間枠に対応します。
一方、入力を持つ指標は、指定されたパラメータによる検索を実装するために、指標パラメータ構造体の配列による追加の検索メソッドを必要とします。これは、この記事のサイズを超えます。したがって、そのような方法は次の記事で分析されます。
この記事はかなりトレーニング目的であり、完全であるとは主張していないため、1つの指標オブジェクトAccelerator Oscillatorの作成のみをテストします。前回の記事では、バッファのコレクションクラスで指標オブジェクトの作成に関するテストをすでに実行しました。
//+------------------------------------------------------------------+ //| Create multi-symbol multi-period AC | //+------------------------------------------------------------------+ int CBuffersCollection::CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe,const int id=WRONG_VALUE) { //--- To check it, create indicator object, print its data and remove it at once ::ArrayResize(this.m_mql_param,0); CIndicatorDE *indicator=new CIndicatorDE(IND_AC,symbol,timeframe,INDICATOR_STATUS_STANDART,INDICATOR_GROUP_OSCILLATOR,"Accelerator Oscillator","AC("+symbol+","+TimeframeDescription(timeframe)+")",this.m_mql_param); indicator.Print(); delete indicator; //--- Create indicator handle and set default ID
今日は同じことをします。同じメソッドでAcceleratorOscillator指標オブジェクトを作成しますが、今回は新しく追加されたクラスを使用します。
今後の展望: 時系列リストに「ある」バーオブジェクトで作成されたすべての指標のデータのストレージ機能が開かれるように、時系列のコレクションクラスでコレクションリストを「見る」必要があります。
したがって、予備的に、\MQL5\Include\DoEasy\Collections\TimeSeriesCollection.mqhファイルの時系列コレクションクラスに指標のコレクションクラスを含める必要があります。
//+------------------------------------------------------------------+ //| TimeSeriesCollection.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "ListObj.mqh" #include "..\Objects\Series\TimeSeriesDE.mqh" #include "..\Objects\Symbols\Symbol.mqh" #include "IndicatorsCollection.mqh" //+------------------------------------------------------------------+
さらに、クラスのprivatgeセクションで指標のコレクションクラスへのポインタを宣言します。
//+------------------------------------------------------------------+ //| Symbol timeseries collection | //+------------------------------------------------------------------+ class CTimeSeriesCollection : public CBaseObjExt { private: CListObj m_list; // List of applied symbol timeseries CIndicatorsCollection *m_indicators; // Pointer to collection object of indicators //--- Return the timeseries index by symbol name int IndexTimeSeries(const string symbol); public:
そして、クラスリストの最後に、指標コレクションオブジェクトへのポインタがCEngineライブラリのメインオブジェクトのクラスに渡される初期化メソッドを作成します。
//--- Constructor CTimeSeriesCollection(); //--- Get pointers to the indicator collection (the method is called in CollectionOnInit() method of the CEngine object) void OnInit(CIndicatorsCollection *indicators) { this.m_indicators=indicators; } }; //+------------------------------------------------------------------+
バッファコレクションクラスファイル(\MQL5\Include\DoEasy\Collections\BuffersCollection.mqh)でも、指標コレクションオブジェクトへのポインタを宣言します。
//+------------------------------------------------------------------+ //| Collection of indicator buffers | //+------------------------------------------------------------------+ class CBuffersCollection : public CObject { private: CListObj m_list; // Buffer object list CTimeSeriesCollection *m_timeseries; // Pointer to the timeseries collection object CIndicatorsCollection *m_indicators; // Pointer to collection object of indicators MqlParam m_mql_param[]; // Array of indicator parameters //--- Return the index of the (1) last, (2) next drawn and (3) basic buffer int GetIndexLastPlot(void); int GetIndexNextPlot(void); int GetIndexNextBase(void); //--- Create a new buffer object and place it to the collection list bool CreateBuffer(ENUM_BUFFER_STATUS status); //--- Get data of the necessary timeseries and bars for working with a single buffer bar, and return the number of bars int GetBarsData(CBuffer *buffer,const int series_index,int &index_bar_period); public:
OnInit()クラスのメソッドに、このポインタの入力パラメータによって渡されるへの値設定を追加します。
//--- Constructor CBuffersCollection(); //--- Get pointers to collections of timeseries and indicators (the method is called in CollectionOnInit() method of the CEngine object) void OnInit(CTimeSeriesCollection *timeseries,CIndicatorsCollection *indicators) { this.m_timeseries=timeseries; this.m_indicators=indicators; } }; //+------------------------------------------------------------------+
また、AC指標作成メソッドでは、前の記事で作成した指標オブジェクトの作成を、指標のコレクションクラスを使用して作成および取得するように変更します。
//+------------------------------------------------------------------+ //| Create multi-symbol multi-period AC | //+------------------------------------------------------------------+ int CBuffersCollection::CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe,const int id=WRONG_VALUE) { //--- To check it, create indicator object, print its data and remove it at once //--- Parameters are not needed for AC, therefore, reset the array of indicator parameter structures ::ArrayResize(this.m_mql_param,0); //--- Create AC indicator and add it to collection this.m_indicators.CreateAC(symbol,timeframe); //--- Get from collection of AC indicator object CIndicatorDE *indicator=this.m_indicators.GetIndAC(symbol,timeframe); //--- Display all data of the created indicator in the journal, display its short description and remove indicator object indicator.Print(); indicator.PrintShort(); delete indicator; //--- Create indicator handle and set default ID
それでは、ライブラリメインオブジェクトのCEngineクラスを改善しましょう。
\MQL5\Include\DoEasy\Engine.mqhファイルで、指標コレクションファイルのインクルードをクラスコードに追加します。
//+------------------------------------------------------------------+ //| Engine.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Include files | //+------------------------------------------------------------------+ #include "Services\TimerCounter.mqh" #include "Collections\HistoryCollection.mqh" #include "Collections\MarketCollection.mqh" #include "Collections\EventsCollection.mqh" #include "Collections\AccountsCollection.mqh" #include "Collections\SymbolsCollection.mqh" #include "Collections\ResourceCollection.mqh" #include "Collections\TimeSeriesCollection.mqh" #include "Collections\BuffersCollection.mqh" #include "Collections\IndicatorsCollection.mqh" #include "TradingControl.mqh" //+------------------------------------------------------------------+
クラスのprivateセクションで指標コレクションクラスのオブジェクトを宣言します。
//+------------------------------------------------------------------+ //| Library basis class | //+------------------------------------------------------------------+ class CEngine { private: CHistoryCollection m_history; // Collection of historical orders and deals CMarketCollection m_market; // Collection of market orders and deals CEventsCollection m_events; // Event collection CAccountsCollection m_accounts; // Account collection CSymbolsCollection m_symbols; // Symbol collection CTimeSeriesCollection m_time_series; // Timeseries collection CBuffersCollection m_buffers; // Collection of indicator buffers CIndicatorsCollection m_indicators; // Indicator collection CResourceCollection m_resource; // Resource list CTradingControl m_trading; // Trading control object CPause m_pause; // Pause object CArrayObj m_list_counters; // List of timer counters int m_global_error; // Global error code bool m_first_start; // First launch flag bool m_is_hedge; // Hedge account flag bool m_is_tester; // Flag of working in the tester bool m_is_market_trade_event; // Account trading event flag bool m_is_history_trade_event; // Account history trading event flag bool m_is_account_event; // Account change event flag bool m_is_symbol_event; // Symbol change event flag ENUM_TRADE_EVENT m_last_trade_event; // Last account trading event int m_last_account_event; // Last event in the account properties int m_last_symbol_event; // Last event in the symbol properties ENUM_PROGRAM_TYPE m_program; // Program type string m_name; // Program name //--- Return the counter index by id int CounterIndex(const int id) const; //--- Return the first launch flag bool IsFirstStart(void); //--- Work with (1) order, deal and position, (2) account events void TradeEventsControl(void); void AccountEventsControl(void); //--- (1) Working with a symbol collection and (2) symbol list events in the market watch window void SymbolEventsControl(void); void MarketWatchEventsControl(void); //--- Return the last (1) market pending order, (2) market order, (3) last position, (4) position by ticket COrder *GetLastMarketPending(void); COrder *GetLastMarketOrder(void); COrder *GetLastPosition(void); COrder *GetPosition(const ulong ticket); //--- Return the last (1) removed pending order, (2) historical market order, (3) historical order (market or pending one) by its ticket COrder *GetLastHistoryPending(void); COrder *GetLastHistoryOrder(void); COrder *GetHistoryOrder(const ulong ticket); //--- Return the (1) first and the (2) last historical market orders from the list of all position orders, (3) the last deal COrder *GetFirstOrderPosition(const ulong position_id); COrder *GetLastOrderPosition(const ulong position_id); COrder *GetLastDeal(void); //--- Retrieve a necessary 'ushort' number from the packed 'long' value ushort LongToUshortFromByte(const long source_value,const uchar index) const; public:
publicセクションで、指標コレクションオブジェクトへのポインタを返すメソッドとこのコレクションの指標リストへのポインタを返すメソッドの2つを記述します。
//--- Return the bar index on the specified timeframe chart by the current chart's bar index int IndexBarPeriodByBarCurrent(const int series_index,const string symbol,const ENUM_TIMEFRAMES timeframe) { return this.m_time_series.IndexBarPeriodByBarCurrent(series_index,symbol,timeframe); } //--- Return (1) the indicator collection, (2) the indicator list from the collection CIndicatorsCollection *GetIndicatorsCollection(void) { return &this.m_indicators; } CArrayObj *GetListIndicators(void) { return this.m_indicators.GetList(); }
これらのメソッドは、プログラムから指標コレクションを呼び出すのに役立ちます。
メソッドCollectionOnInit()に、指標コレクションへのポインタをバッファのコレクションクラスおよび時系列に渡すようにします。
//--- Pass the pointers to all the necessary collections to the trading class and the indicator buffer collection class void CollectionOnInit(void) { this.m_trading.OnInit(this.GetAccountCurrent(),m_symbols.GetObject(),m_market.GetObject(),m_history.GetObject(),m_events.GetObject()); this.m_buffers.OnInit(this.m_time_series.GetObject(),this.m_indicators.GetObject()); this.m_time_series.OnInit(this.m_indicators.GetObject()); }
これで、ライブラリを初期化する場合、指標コレクションオブジェクトへのポインタが、指標コレクションへのアクセスが必要なすべてのクラスに渡されます。このコレクションで作業できるようになります。
今のところ、指標コレクションクラスを作成するために必要な改善はこれで全部です。
テスト
テストには、変更を加えない前の記事の指標が必要です。
単に新しい\MQL5\Indicators\TestDoEasy\Part54\フォルダでTestDoEasyPart54.mq5として保存します。
指標をコンパイルして、チャート上で起動します。
操作ログには作成された指標Accelerator Oscillatorのすべてのパラメータとその簡単な説明が表示されます。
Account 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10425.23 USD, 1:100, Hedge, Demo account MetaTrader 5 --- Initializing "DoEasy" library --- Working with the current symbol only. Number of used symbols: 1 "EURUSD" Working with the specified timeframe list: "H4" "H1" EURUSD symbol timeseries: - "EURUSD" H1 timeseries: Requested: 1000, Actually: 0, Created: 0, On the server: 0 - "EURUSD" H4 timeseries: Requested: 1000, Actually: 1000, Created: 1000, On the server: 6231 Time of library initializing: 00:00:00.156 ============= Beginning of the parameter list: "Standard indicator" ============= Indicator status: Standard indicator Indicator type: AC Indicator timeframe: H4 Indicator handle: 10 Indicator group: Oscillator ------ Empty value for plotting where nothing will be drawn: EMPTY_VALUE ------ Indicator symbol: EURUSD Indicator name: "Accelerator Oscillator" Indicator short name: "AC(EURUSD,H4)" ================== End of the parameter list: "Standard indicator" ================== Standard indicator Accelerator Oscillator EURUSD H4 Buffer (P0/B0/C1): Histogram from zero line EURUSD H4 Buffer [P0/B2/C2]: Calculated buffer "EURUSD" H1 timeseries created successfully: - "EURUSD" H1 timeseries: Requested: 1000, Actually: 1000, Created: 1000, On the server: 6256
次の段階
次の記事では、指標コレクションクラスの作業を続けます。
ライブラリの現在のバージョンのすべてのファイルは、MQL5のテスト指標ファイルと一緒に以下に添付されています。ダウンロードし、すべてを検証することが可能です。
指標コレクションクラスは現在開発中であるため、プログラムは絶対使用しないでください。
質問や提案は記事のコメント欄にお願いします。
シリーズのこれまでの記事:
DoEasyライブラリの時系列(第35部): バーオブジェクトと銘柄の時系列リスト
DoEasyライブラリの時系列(第36部): すべての使用銘柄期間の時系列オブジェクト
DoEasyライブラリの時系列(第37部): すべての使用銘柄期間の時系列オブジェクト
DoEasyライブラリの時系列(第38部): 時系列コレクション-リアルタイムの更新とプログラムからのデータへのアクセス
DoEasyライブラリの時系列(第39部): ライブラリに基づいた指標 - データイベントと時系列イベントの準備
DoEasyライブラリの時系列(第40部): ライブラリに基づいた指標 - 実時間でのデータ更新
DoEasyライブラリの時系列(第41部): 複数銘柄・複数期間指標の例
DoEasyライブラリの時系列(第42部): 抽象指標バッファオブジェクトクラス
DoEasyライブラリの時系列(第43部): 指標バッファオブジェクトクラス
DoEasyライブラリの時系列(第44部): 指標バッファオブジェクトのコレクションクラス
DoEasyライブラリの時系列(第45部): 複数期間指標バッファ
DoEasyライブラリの時系列(第46部): 複数銘柄・複数期間指標バッファ
DoEasyライブラリの時系列(第47部): 複数銘柄・複数期間標準指標
DoEasyライブラリの時系列(第48部): 単一サブウィンドウでの単一バッファ複数銘柄・複数期間指標
DoEasyライブラリの時系列(第49部): 複数銘柄・複数期間の複数バッファ標準指標
DoEasyライブラリの時系列(第50部): シフト付き複数銘柄・複数期間標準指標
DoEasyライブラリの時系列(第51部): 複数銘柄・複数期間の複合標準指標
DoEasyライブラリの時系列(第52部): 複数銘柄・複数期間の単一バッファ標準指標のクロスプラットフォーム化
DoEasyライブラリの時系列(第53部): 抽象基本指標クラス
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/8508




- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索