DoEasyライブラリの時系列(第36部): すべての使用銘柄期間の時系列オブジェクト

26 6月 2020, 09:31
Artyom Trishkin
0
754

内容


概念

前の記事では、新しい一連のDoEasyライブラリの説明を開始し、Barオブジェクトとバーオブジェクトリストの作成について検討しました。MetaTraderプラットフォームの用語を使うと、1つの時間枠で1つの銘柄の単一の時系列を作成し、この時系列の各バーのデータをその時系列に入力しました。
DoEasyライブラリの用語を使うと、1つの時間枠で1つの銘柄のバーコレクションオブジェクトを作成しました。これで、作成されたコレクション内で(指定されたコレクション履歴の深さ内で)、コレクションに存在するバーオブジェクトの任意のプロパティによる検索と並べ替えを実行できるようになりました。簡単に言うと、時系列バーのさまざまなパラメータとそれらのさまざまな組み合わせ(さまざまなバーの組み合わせは後で追加されます)を検索したり、作成されたコレクションで新しいバーを検出して現在のデータを更新したりできます。

これは良いことですが、プログラムでは複数の時間枠と銘柄を使用できるので不十分です。したがって、自由に使用できる銘柄時系列コレクションの数は、プログラムで使用するその時間枠の数と等しくなければなりません。
作成された時系列コレクションは、これを可能にします。これは、銘柄と時系列に関連して作成されます。つまり、1つの銘柄についてコレクションを必要なだけ作成できます。

1つのオブジェクト(銘柄時系列オブジェクト)に、1つの銘柄のすべてのコレクションと異なる時系列を格納できると便利です。次に、これらのオブジェクトから、さまざまな銘柄とその時間枠に共通する1つの時系列コレクションが作成されます。


銘柄時系列オブジェクト

近い将来、多くのライブラリクラスには、それらが実行されているプログラムのタイプの知識が必要となります。MQLInfoInteger()関数をMQL_PROGRAM_TYPE指定子とともに使用すると、実行中のmql5プログラムのタイプが返されます。
各クラスにプログラムタイプを格納する変数を記述しなくてよいように、変数をすべてのプログラムオブジェクトの基本クラスで宣言します。基本クラスから派生したすべてのクラスには、実行中のプログラムのタイプを格納する変数が備わります。

\MQL5\Include\DoEasy\Objects\BaseObj.mqhにあるCBaseObjクラスのprotectedセクションで、実行中のプログラムのタイプを格納するクラスメンバ変数を宣言します

//+------------------------------------------------------------------+
//| Base object class for all library objects                        |
//+------------------------------------------------------------------+
#define  CONTROLS_TOTAL    (10)
class CBaseObj : public CObject
  {
private:
   int               m_long_prop_total;
   int               m_double_prop_total;
   //--- Fill in the object property array
   template<typename T> bool  FillPropertySettings(const int index,T &array[][CONTROLS_TOTAL],T &array_prev[][CONTROLS_TOTAL],int &event_id);
protected:
   CArrayObj         m_list_events_base;                       // Object base event list
   CArrayObj         m_list_events;                            // Object event list
   ENUM_LOG_LEVEL    m_log_level;                              // Logging level
   ENUM_PROGRAM_TYPE m_program;                                // Program type
   MqlTick           m_tick;                                   // Tick structure for receiving quote data

クラスコンストラクタで値を設定します

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CBaseObj::CBaseObj() : m_global_error(ERR_SUCCESS),
                       m_hash_sum(0),m_hash_sum_prev(0),
                       m_is_event(false),m_event_code(WRONG_VALUE),
                       m_chart_id_main(::ChartID()),
                       m_chart_id(::ChartID()),
                       m_folder_name(DIRECTORY),
                       m_name(__FUNCTION__),
                       m_long_prop_total(0),
                       m_double_prop_total(0),
                       m_first_start(true)
  {
   ::ArrayResize(this.m_long_prop_event,0,100);
   ::ArrayResize(this.m_double_prop_event,0,100);
   ::ArrayResize(this.m_long_prop_event_prev,0,100);
   ::ArrayResize(this.m_double_prop_event_prev,0,100);
   ::ZeroMemory(this.m_tick);
   this.m_program=(ENUM_PROGRAM_TYPE)::MQLInfoInteger(MQL_PROGRAM_TYPE);
   this.m_digits_currency=(#ifdef __MQL5__ (int)::AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS) #else 2 #endif);
   this.m_list_events.Clear();
   this.m_list_events.Sort();
   this.m_list_events_base.Clear();
   this.m_list_events_base.Sort();
  }
//+------------------------------------------------------------------+

これで、すべてのライブラリオブジェクトの基本クラスから派生したすべてのオブジェクトが、実行中プログラムのタイプを「認識」します。

\MQL5\Include\DoEasy\Objects\Series\NewBarObj.mqhにあるCNewBarObjクラスで、基本オブジェクトファイルをインクルードします

//+------------------------------------------------------------------+
//|                                                    NewBarObj.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"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "..\..\Objects\BaseObj.mqh"
//+------------------------------------------------------------------+
//| "New bar" object class                                           |
//+------------------------------------------------------------------+

基本オブジェクトから「新規バー」オブジェクトを継承します

//+------------------------------------------------------------------+
//| "New bar" object class                                           |
//+------------------------------------------------------------------+
class CNewBarObj : public CBaseObj
  {
private:

プログラムタイプ変数へのすべての参照を削除します。プログラムタイプはCBaseObjで設定されるようになります。

//+------------------------------------------------------------------+
//| "New bar" object class                                           |
//+------------------------------------------------------------------+
class CNewBarObj
  {
private:
   ENUM_PROGRAM_TYPE m_program;                                   // Program type
   string            m_symbol;                                    // Symbol
   ENUM_TIMEFRAMES   m_timeframe;                                 // Timeframe
   datetime          m_new_bar_time;                              // New bar time for auto time management
   datetime          m_prev_time;                                 // Previous time for auto time management
   datetime          m_new_bar_time_manual;                       // New bar time for manual time management
   datetime          m_prev_time_manual;                          // Previous time for manual time management
//--- Return the current bar data
   datetime          GetLastBarDate(const datetime time);
public:
//--- Set (1) symbol and (2) timeframe
   void              SetSymbol(const string symbol)               { this.m_symbol=(symbol==NULL || symbol==""   ? ::Symbol() : symbol);                     }
   void              SetPeriod(const ENUM_TIMEFRAMES timeframe)   { this.m_timeframe=(timeframe==PERIOD_CURRENT ? (ENUM_TIMEFRAMES)::Period() : timeframe); }
//--- Save the new bar time during the manual time management
   void              SaveNewBarTime(const datetime time)          { this.m_prev_time_manual=this.GetLastBarDate(time);                                      }
//--- Return (1) symbol and (2) timeframe
   string            Symbol(void)                           const { return this.m_symbol;       }
   ENUM_TIMEFRAMES   Period(void)                           const { return this.m_timeframe;    }
//--- Return the (1) new bar time
   datetime          TimeNewBar(void)                       const { return this.m_new_bar_time; }
//--- Return the new bar opening flag during the time (1) auto, (2) manual management
   bool              IsNewBar(const datetime time);
   bool              IsNewBarManual(const datetime time);
//--- Constructors
                     CNewBarObj(void) : m_program((ENUM_PROGRAM_TYPE)::MQLInfoInteger(MQL_PROGRAM_TYPE)),
                                        m_symbol(::Symbol()),
                                        m_timeframe((ENUM_TIMEFRAMES)::Period()),
                                        m_prev_time(0),m_new_bar_time(0),
                                        m_prev_time_manual(0),m_new_bar_time_manual(0) {}
                     CNewBarObj(const string symbol,const ENUM_TIMEFRAMES timeframe);
  };
//+------------------------------------------------------------------+
//| Parametric constructor                                           |
//+------------------------------------------------------------------+
CNewBarObj::CNewBarObj(const string symbol,const ENUM_TIMEFRAMES timeframe) : m_symbol(symbol),m_timeframe(timeframe)
  {
   this.m_program=(ENUM_PROGRAM_TYPE)::MQLInfoInteger(MQL_PROGRAM_TYPE);
   this.m_prev_time=this.m_prev_time_manual=this.m_new_bar_time=this.m_new_bar_time_manual=0;
  }
//+------------------------------------------------------------------+

変更されたクラスの完全なコードは、本稿に添付されているファイルでご覧ください。

前の記事で作成されたCSeriesクラスを少し修正しましょう。

CObjectの代わりにCBaseObj基本オブジェクトからクラスを継承して、プログラムタイプを格納する変数を削除します。
//+------------------------------------------------------------------+
//| Timeseries class                                                 |
//+------------------------------------------------------------------+
class CSeries : public CBaseObj
  {
private:
   ENUM_PROGRAM_TYPE m_program;                                         // Program type
   ENUM_TIMEFRAMES   m_timeframe;                                       // Timeframe
   string            m_symbol;                                          // Symbol
   uint              m_amount;                                          // Amount of applied timeseries data
   uint              m_bars;                                            // Number of bars in history by symbol and timeframe
   bool              m_sync;                                            // Synchronized data flag
   CArrayObj         m_list_series;                                     // Timeseries list
   CNewBarObj        m_new_bar_obj;                                     // "New bar" object
public:

クラスのpublicセクションで、銘柄時間枠を設定するメソッドを宣言し、利用可能なデータの総量を返すメソッドの実装を完成します

//+------------------------------------------------------------------+
//| Timeseries class                                                 |
//+------------------------------------------------------------------+
class CSeries : public CBaseObj
  {
private:
   ENUM_TIMEFRAMES   m_timeframe;                                       // Timeframe
   string            m_symbol;                                          // Symbol
   uint              m_amount;                                          // Amount of applied timeseries data
   uint              m_bars;                                            // Number of bars in history by symbol and timeframe
   bool              m_sync;                                            // Synchronized data flag
   CArrayObj         m_list_series;                                     // Timeseries list
   CNewBarObj        m_new_bar_obj;                                     // "New bar" object
public:
//--- Return the timeseries list
   CArrayObj        *GetList(void)                                      { return &m_list_series;}
//--- Return the list of bars by selected (1) double, (2) integer and (3) string property fitting a compared condition
   CArrayObj        *GetList(ENUM_BAR_PROP_DOUBLE property,double value,ENUM_COMPARER_TYPE mode=EQUAL){ return CSelect::ByBarProperty(this.GetList(),property,value,mode); }
   CArrayObj        *GetList(ENUM_BAR_PROP_INTEGER property,long value,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByBarProperty(this.GetList(),property,value,mode); }
   CArrayObj        *GetList(ENUM_BAR_PROP_STRING property,string value,ENUM_COMPARER_TYPE mode=EQUAL){ return CSelect::ByBarProperty(this.GetList(),property,value,mode); }

//--- Set (1) symbol, (2) timeframe, (3) symbol and timeframe, (4) amount of applied timeseries data
   void              SetSymbol(const string symbol);
   void              SetTimeframe(const ENUM_TIMEFRAMES timeframe);
   void              SetSymbolPeriod(const string symbol,const ENUM_TIMEFRAMES timeframe);
   bool              SetAmountUsedData(const uint amount,const uint rates_total);

//--- Return (1) symbol, (2) timeframe, (3) number of applied timeseries data,
//--- (4) number of bars in the timeseries, the new bar flag with the (5) auto, (6) manual time management
   string            Symbol(void)                                          const { return this.m_symbol;                            }
   ENUM_TIMEFRAMES   Timeframe(void)                                       const { return this.m_timeframe;                         }
   uint              AmountUsedData(void)                                  const { return this.m_amount;                            }
   uint              Bars(void)                                            const { return this.m_bars;                              }
   bool              IsNewBar(const datetime time)                               { return this.m_new_bar_obj.IsNewBar(time);        }
   bool              IsNewBarManual(const datetime time)                         { return this.m_new_bar_obj.IsNewBarManual(time);  }
//--- Return the bar object by index (1) in the list and (2) in the timeseries, as well as (3) the real list size
   CBar             *GetBarByListIndex(const uint index);
   CBar             *GetBarBySeriesIndex(const uint index);
   int               DataTotal(void)                                       const { return this.m_list_series.Total();               }
//--- Return (1) Open, (2) High, (3) Low, (4) Close, (5) time, (6) tick volume, (7) real volume, (8) bar spread by index
   double            Open(const uint index,const bool from_series=true);
   double            High(const uint index,const bool from_series=true);
   double            Low(const uint index,const bool from_series=true);
   double            Close(const uint index,const bool from_series=true);
   datetime          Time(const uint index,const bool from_series=true);
   long              TickVolume(const uint index,const bool from_series=true);
   long              RealVolume(const uint index,const bool from_series=true);
   int               Spread(const uint index,const bool from_series=true);

//--- Save the new bar time during the manual time management
   void              SaveNewBarTime(const datetime time)                         { this.m_new_bar_obj.SaveNewBarTime(time);         }
//--- Synchronize symbol and timeframe data with server data
   bool              SyncData(const uint amount,const uint rates_total);
//--- (1) Create and (2) update the timeseries list
   int               Create(const uint amount=0);
   void              Refresh(const datetime time=0,
                             const double open=0,
                             const double high=0,
                             const double low=0,
                             const double close=0,
                             const long tick_volume=0,
                             const long volume=0,
                             const int spread=0);
                             
//--- Constructors
                     CSeries(void);
                     CSeries(const string symbol,const ENUM_TIMEFRAMES timeframe,const uint amount=0);
  };
//+------------------------------------------------------------------+

クラス本体の外で、銘柄と時間枠を設定するメソッドを実装します。

//+------------------------------------------------------------------+
//| Set a symbol                                                     |
//+------------------------------------------------------------------+
void CSeries::SetSymbol(const string symbol)
  {
   this.m_symbol=(symbol==NULL || symbol==""   ? ::Symbol() : symbol);
   this.m_new_bar_obj.SetSymbol(this.m_symbol);
  }
//+------------------------------------------------------------------+
//| Set a timeframe                                                  |
//+------------------------------------------------------------------+
void CSeries::SetTimeframe(const ENUM_TIMEFRAMES timeframe)
  {
   this.m_timeframe=(timeframe==PERIOD_CURRENT ? (ENUM_TIMEFRAMES)::Period() : timeframe);
   this.m_new_bar_obj.SetPeriod(this.m_timeframe);
  }
//+------------------------------------------------------------------+

メソッドに渡された値は確認され、必要に応じて調整されます。その後変数に送信されます
そして、「新規バー」クラスオブジェクトで値が設定されます

\MQL5\Include\DoEasy\Services\Select.mqhのCSelectクラスには、CBarクラスのBar.mqhファイルの代わりに、CSeriesクラスファイルがインクルードされます

//+------------------------------------------------------------------+
//|                                                       Select.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 <Arrays\ArrayObj.mqh>
#include "..\Objects\Orders\Order.mqh"
#include "..\Objects\Events\Event.mqh"
#include "..\Objects\Accounts\Account.mqh"
#include "..\Objects\Symbols\Symbol.mqh"
#include "..\Objects\PendRequest\PendRequest.mqh"
#include "..\Objects\Series\Series.mqh"
//+------------------------------------------------------------------+
//| Storage list                                                     |
//+------------------------------------------------------------------+
CArrayObj   ListStorage; // Storage object for storing sorted collection lists
//+------------------------------------------------------------------+
//| Class for sorting objects meeting the criterion                  |
//+------------------------------------------------------------------+
class CSelect
  {

これで、すべての銘柄時系列のオブジェクトのクラスを作成する準備が整いました。

銘柄時系列オブジェクトとは何でしょうか。前回の記事では、1つの銘柄に対して1つの期間の時系列オブジェクトを作成しました。これで、そのリスト内のすべてのバーオブジェクトを任意のバーオブジェクトプロパティで並び替えたり、任意のバーオブジェクトをその任意のプロパティで検出したりできます。ただし、プログラムでは多くの場合、1つ以上の銘柄の履歴の多期間分析を使用する必要があります。銘柄時系列オブジェクトには、1つの銘柄のすべての可能な時間枠の複数の時系列が含まれています。時間枠の数は、ENUM_TIMEFRAMES列挙に記述されているターミナルで使用可能なチャート期間の数と同じにすることができます。

実際、このオブジェクトはCArrayObjオブジェクトへのポインタの配列であり、ここでオブジェクトは、前の記事で作成した銘柄時系列リストです。これにはバーオブジェクトが含まれます。

本稿では、すべての銘柄時系列オブジェクトを作成して、以下を可能にします。

  • 使用の手動設定:
    • 単一銘柄の指定されたチャート期間
    • 単一銘柄のすべての可能なチャート期間
  • 作成:
    • 単一銘柄の指定された時系列オブジェクト
    • 単一銘柄のすべての可能な時系列オブジェクト
  • データのアップデート:
    • 単一銘柄の指定された時系列オブジェクト
    • 単一銘柄のすべての時系列オブジェクト

残りのオブジェクト機能は、以降の記事で使用されているすべての銘柄のすべての時系列のオブジェクトを作成するときに追加されます。

いつものように、まず新しいクラスに必要なすべてのメッセージ(メッセージインデックスと適切なテキスト)を追加します。

\MQL5\Include\DoEasy\Datas.mqhに、新しいメッセージインデックスを追加します

   MSG_LIB_TEXT_BAR_TEXT_FIRS_SET_AMOUNT_DATA,        // First, we need to set the required amount of data using SetAmountUsedData()
  
//--- CTimeSeries
   MSG_LIB_TEXT_TS_TEXT_FIRS_SET_SYMBOL,              // First, set a symbol using SetSymbol()
   MSG_LIB_TEXT_TS_TEXT_UNKNOWN_TIMEFRAME,            // Unknown timeframe
   MSG_LIB_TEXT_TS_FAILED_GET_SERIES_OBJ,             // Failed to receive the timeseries object
  };
//+------------------------------------------------------------------+

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

   {"Сначала нужно установить требуемое количество данных при помощи SetAmountUsedData()","First you need to set required amount of data using SetAmountUsedData()"},
   
   {"Сначала нужно установить символ при помощи SetSymbol()","First you need to set Symbol using SetSymbol()"},
   {"Неизвестный таймфрейм","Unknown timeframe"},
   {"Не удалось получить объект-таймсерию ","Failed to get timeseries object "},
   
  };
//+---------------------------------------------------------------------+

\MQL5\Include\DoEasy\Objects\Series\で、CTimeSeriesクラスのTimeSeries.mqhファイルを作成します。Series.mqh時系列オブジェクトファイルをインクルードして、CObject標準ライブラリベースオブジェクトから派生させます
クラス本体に必要なコンテンツを入力し、すべての変数とメソッドを個別に検討します。

//+------------------------------------------------------------------+
//|                                                   TimeSeries.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"
#property strict    // Necessary for mql4
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "Series.mqh"
//+------------------------------------------------------------------+
//| Timeseries class                                                 |
//+------------------------------------------------------------------+
class CTimeSeries : public CObject
  {
private:
   string            m_symbol;                                             // Timeseries symbol
   CArrayObj         m_list_series;                                        // List of timeseries by timeframes
//--- Return (1) the timeframe index in the list and (2) the timeframe by index
   char              IndexTimeframe(const ENUM_TIMEFRAMES timeframe) const;
   ENUM_TIMEFRAMES   TimeframeByIndex(const uchar index)             const;
public:
//--- Return (1) the full list of timeseries, (2) specified timeseries object and (3) timeseries object by index
   CArrayObj        *GetList(void)                                         { return &this.m_list_series;                                        }
   CSeries          *GetSeries(const ENUM_TIMEFRAMES timeframe)            { return this.m_list_series.At(this.IndexTimeframe(timeframe));      }
   CSeries          *GetSeriesByIndex(const uchar index)                   { return this.m_list_series.At(index);                               }
//--- Set/return timeseries symbol
   void              SetSymbol(const string symbol)                        { this.m_symbol=(symbol==NULL || symbol=="" ? ::Symbol() : symbol);  }
   string            Symbol(void)                                    const { return this.m_symbol;                                              }
//--- Set the history depth (1) of a specified timeseries and (2) of all applied symbol timeseries
   bool              SetAmountUsedData(const ENUM_TIMEFRAMES timeframe,const uint amount=0,const int rates_total=0);
   bool              SetAmountAllUsedData(const uint amount=0,const int rates_total=0);
//--- Return the flag of data synchronization with the server data of the (1) specified timeseries, (2) all timeseries
   bool              SyncData(const ENUM_TIMEFRAMES timeframe,const uint amount=0,const uint rates_total=0);
   bool              SyncAllData(const uint amount=0,const uint rates_total=0);
   
//--- Create (1) the specified timeseries list and (2) all timeseries lists
   bool              SeriesCreate(const ENUM_TIMEFRAMES timeframe,const uint amount=0);
   bool              SeriesCreateAll(const uint amount=0);
//--- Update (1) the specified timeseries list and (2) all timeseries lists
   void              Refresh(const ENUM_TIMEFRAMES timeframe,
                             const datetime time=0,
                             const double open=0,
                             const double high=0,
                             const double low=0,
                             const double close=0,
                             const long tick_volume=0,
                             const long volume=0,
                             const int spread=0);
   void              RefreshAll(const datetime time=0,
                             const double open=0,
                             const double high=0,
                             const double low=0,
                             const double close=0,
                             const long tick_volume=0,
                             const long volume=0,
                             const int spread=0);
//--- Constructor
                     CTimeSeries(void);
  };
//+------------------------------------------------------------------+

m_symbolクラスメンバ変数は銘柄名を格納します。これに対して、必要な時系列が作成されてオブジェクトに格納され、処理されます。その後、変数値を使用して、必要な銘柄の時系列を持つ必要なオブジェクトを選択します。

CObjectクラスインスタンスへのポインタの配列m_list_seriesは、前の記事で作成した時系列オブジェクトを格納するように設計されています。リスト内のオブジェクトの数は、プラットフォームで利用可能なすべての時間枠の数と同じにすることができ、 ENUM_TIMEFRAMES列挙にリストされている順にリストに配置されるので、リスト内の各時系列オブジェクトのインデックスを正確に知ることができます。時系列オブジェクトリストのインデックスを返すために2つのメソッドが作成されます。

IndexTimeframe()メソッドは、時間枠値によってリスト内の時系列オブジェクトインデックスを返します。
これは、クラス本体外で実装されています。

//+------------------------------------------------------------------+
//| Return the timeframe index in the list                           |
//+------------------------------------------------------------------+
char CTimeSeries::IndexTimeframe(ENUM_TIMEFRAMES timeframe) const
  {
   int statement=(timeframe==PERIOD_CURRENT ? ::Period() : timeframe);
   switch(statement)
     {
      case PERIOD_M1    :  return 0;
      case PERIOD_M2    :  return 1;
      case PERIOD_M3    :  return 2;
      case PERIOD_M4    :  return 3;
      case PERIOD_M5    :  return 4;
      case PERIOD_M6    :  return 5;
      case PERIOD_M10   :  return 6;
      case PERIOD_M12   :  return 7;
      case PERIOD_M15   :  return 8;
      case PERIOD_M20   :  return 9;
      case PERIOD_M30   :  return 10;
      case PERIOD_H1    :  return 11;
      case PERIOD_H2    :  return 12;
      case PERIOD_H3    :  return 13;
      case PERIOD_H4    :  return 14;
      case PERIOD_H6    :  return 15;
      case PERIOD_H8    :  return 16;
      case PERIOD_H12   :  return 17;
      case PERIOD_D1    :  return 18;
      case PERIOD_W1    :  return 19;
      case PERIOD_MN1   :  return 20;
      default           :  ::Print(DFUN,CMessage::Text(MSG_LIB_TEXT_TS_TEXT_UNKNOWN_TIMEFRAME)); return WRONG_VALUE;
     }
  }
//+------------------------------------------------------------------+

ここではすべてが非常に明確です。メソッドに渡される時間枠に応じて、ENUM_TIMEFRAMES列挙内のシリアル番号( m_list_seriesリスト内のインデックス)が返されます。  

TimeframeByIndex()メソッドは、リストの時系列オブジェクトインデックス値によって時間枠を返します。
これは、クラス本体外で実装されています。

//+------------------------------------------------------------------+
//| Return a timeframe by index                                      |
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES CTimeSeries::TimeframeByIndex(const uchar index) const
  {
   switch(index)
     {
      case 0   :  return PERIOD_M1;
      case 1   :  return PERIOD_M2;
      case 2   :  return PERIOD_M3;
      case 3   :  return PERIOD_M4;
      case 4   :  return PERIOD_M5;
      case 5   :  return PERIOD_M6;
      case 6   :  return PERIOD_M10;
      case 7   :  return PERIOD_M12;
      case 8   :  return PERIOD_M15;
      case 9   :  return PERIOD_M20;
      case 10  :  return PERIOD_M30;
      case 11  :  return PERIOD_H1;
      case 12  :  return PERIOD_H2;
      case 13  :  return PERIOD_H3;
      case 14  :  return PERIOD_H4;
      case 15  :  return PERIOD_H6;
      case 16  :  return PERIOD_H8;
      case 17  :  return PERIOD_H12;
      case 18  :  return PERIOD_D1;
      case 19  :  return PERIOD_W1;
      case 20  :  return PERIOD_MN1;
      default  :  ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_NOT_GET_DATAS),"... ",CMessage::Text(MSG_SYM_STATUS_INDEX),": ",(string)index); return WRONG_VALUE;
     }
  }
//+------------------------------------------------------------------+

このメソッドはIndexTimeframe()の反対です。メソッドに渡されたインデックスに応じて、ENUM_TIMEFRAMES列挙内の順序で適切な時間枠が返されます。

Getlist()メソッドは、すべての時系列の完全なリストを「そのまま」制御プログラムに返します。プログラムでは、取得したリストから必要な時系列を選択できます。

GetSeries()メソッドは、 ENUM_TIMEFRAMES列挙からの必要な時系列の名前で指定された時系列オブジェクトをm_list_seriesリストから返します。以前に考慮されたIndexTimeframe()メソッドを使用して、リストの時系列インデックスを取得します。

GetSeriesByIndex()メソッドは、m_list_seriesリストのインデックスによって時系列オブジェクトを返します。

指定された時系列の履歴深度を設定するメソッドを実装します。

//+------------------------------------------------------------------+
//| Set a history depth of a specified timeseries                    |
//+------------------------------------------------------------------+
bool CTimeSeries::SetAmountUsedData(const ENUM_TIMEFRAMES timeframe,const uint amount=0,const int rates_total=0)
  {
   if(this.m_symbol==NULL)
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_TEXT_TS_TEXT_FIRS_SET_SYMBOL));
      return false;
     }
   CSeries *series_obj=this.m_list_series.At(this.IndexTimeframe(timeframe));
   return series_obj.SetAmountUsedData(amount,rates_total);
  }
//+------------------------------------------------------------------+

このメソッドは、履歴の深さを設定する必要がある時系列時間枠、必要な履歴時系列データのサイズ (履歴の深さ、0の場合は1000バーの深さを使用)、および現在の時系列バーの数(現在の時間枠で現在の銘柄の履歴深度を設定する場合の指標のみrates_totalパラメータをOnCalculate()に渡しますが、それ以外の場合はパラメータは重要ではありません)を受け取ります。

クラスオブジェクトの銘柄が設定されていない場合は、適切なメッセージを表示してfalseを返します。
リクエストされた時系列オブジェクトを時間枠名で取得したインデックスによってリストから取得し、 前の記事で検討したのと同じ名前の時系列オブジェクトクラスメソッドを使用して履歴の深さを設定した結果を返します

すべての使用された銘柄時系列の履歴深度を設定するメソッドを実装します。

//+------------------------------------------------------------------+
//| Set the history depth of all applied symbol timeseries           |
//+------------------------------------------------------------------+
bool CTimeSeries::SetAmountAllUsedData(const uint amount=0,const int rates_total=0)
  {
   if(this.m_symbol==NULL)
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_TEXT_TS_TEXT_FIRS_SET_SYMBOL));
      return false;
     }
   bool res=true;
   for(int i=0;i<21;i++)
     {
      CSeries *series_obj=this.m_list_series.At(i);
      if(series_obj==NULL)
         continue;
      res &=series_obj.SetAmountUsedData(amount,rates_total);
     }
   return res;
  }
//+------------------------------------------------------------------+

このメソッドは、履歴時系列データの必要なサイズ(履歴の深さ、0の場合は1000バーの深さを使用)、および現在の時系列バーの数(現在の時間枠で現在の銘柄の履歴深度を設定する場合の指標のみrates_totalパラメータをOnCalculate()に渡しますが、それ以外の場合はパラメータは重要ではありません)。

クラスオブジェクトの銘柄が設定されていない場合は、適切なメッセージを表示してfalseを返します。
既存のすべての時間枠の完全なリストを反復処理しリストからループインデックスによって次の時系列リストを取得し前の記事で検討したのと同じ名前の時系列オブジェクトクラスメソッドを使用して履歴深度を設定した結果をresローカル変数に書き込みます。使用可能な時系列オブジェクトの履歴の深さを設定するメソッドの少なくとも1つがfalseを返した場合、変数にfalseが設定されます。
ループの完了時に、res変数に書かれたすべての設定の結果を返します

以下は、サーバデータとの指定された時系列データ同期のフラグを返すメソッドの実装です。

//+------------------------------------------------------------------+
//| Return the flag of data synchronization                          |
//| with the server data                                             |
//+------------------------------------------------------------------+
bool CTimeSeries::SyncData(const ENUM_TIMEFRAMES timeframe,const uint amount=0,const uint rates_total=0)
  {
   if(this.m_symbol==NULL)
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_TEXT_TS_TEXT_FIRS_SET_SYMBOL));
      return false;
     }
   CSeries *series_obj=this.m_list_series.At(this.IndexTimeframe(timeframe));
   if(series_obj==NULL)
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_TEXT_TS_FAILED_GET_SERIES_OBJ),this.m_symbol," ",TimeframeDescription(timeframe));
      return false;
     }
   return series_obj.SyncData(amount,rates_total);
  }
//+------------------------------------------------------------------+

このメソッドは、同期フラグを返す必要がある時系列時間枠、必要な履歴時系列データのサイズ (履歴の深さ、0の場合は1000バーの深さを使用)、および現在の時系列バーの数(現在の時間枠で現在の銘柄の履歴深度を設定する場合の指標のみrates_totalパラメータをOnCalculate()に渡しますが、それ以外の場合はパラメータは重要ではありません)。

クラスオブジェクトの銘柄が設定されていない場合は、適切なメッセージを表示してfalseを返します。
リクエストされた時系列オブジェクトを時間枠名で取得したインデックスによってリストから取得し、 前の記事で検討したのと同じ名前の時系列オブジェクトクラスメソッドを使用してデータ同期結果をチェックした結果を返します

以下は、サーバデータとのすべての時系列のデータ同期のフラグを返すメソッドの実装です。

//+------------------------------------------------------------------+
//| Return the flag of data synchronization                          |
//| of all timeseries with the server data                           |
//+------------------------------------------------------------------+
bool CTimeSeries::SyncAllData(const uint amount=0,const uint rates_total=0)
  {
   if(this.m_symbol==NULL)
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_TEXT_TS_TEXT_FIRS_SET_SYMBOL));
      return false;
     }
   bool res=true;
   for(int i=0;i<21;i++)
     {
      CSeries *series_obj=this.m_list_series.At(i);
      if(series_obj==NULL)
         continue;
      res &=series_obj.SyncData(amount,rates_total);
     }
   return res;
  }
//+------------------------------------------------------------------+

このメソッドは、履歴時系列データの必要なサイズ(履歴の深さ、0の場合は1000バーの深さを使用)、および現在の時系列バーの数(現在の時間枠で現在の銘柄の履歴深度を設定する場合の指標のみrates_totalパラメータをOnCalculate()に渡しますが、それ以外の場合はパラメータは重要ではありません)。

クラスオブジェクトの銘柄が設定されていない場合は、適切なメッセージを表示してfalseを返します。
既存のすべての時間枠の完全なリストを反復処理しリストからループインデックスによって次の時系列リストを取得し前の記事で検討したのと同じ名前の時系列オブジェクトクラスメソッドを使用してデータの同期を確認したフラグをresローカル変数に書き込みます。時系列オブジェクトの同期を確認するメソッドの少なくとも1つがfalseを返した場合、変数にfalseが設定されます。
ループの完了時に、res変数に書かれたすべての確認の結果を返します

指定された時系列リストを作成するメソッドを実装します。

//+------------------------------------------------------------------+
//| Create a specified timeseries list                               |
//+------------------------------------------------------------------+
bool CTimeSeries::Create(const ENUM_TIMEFRAMES timeframe,const uint amount=0)
  {
   CSeries *series_obj=this.m_list_series.At(this.IndexTimeframe(timeframe));
   if(series_obj==NULL)
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_TEXT_TS_FAILED_GET_SERIES_OBJ),this.m_symbol," ",TimeframeDescription(timeframe));
      return false;
     }
   if(series_obj.AmountUsedData()==0)
     {
      ::Print(DFUN,CMessage::Text(MSG_LIB_TEXT_BAR_TEXT_FIRS_SET_AMOUNT_DATA));
      return false;
     }
   return(series_obj.Create(amount)>0);
  }
//+------------------------------------------------------------------+

このメソッドは、時系列を作成する必要がある時間枠と、作成された時系列の履歴の深さ(デフォルト値はゼロです。SetAmountUsedData()メソッドを使用して時系列オブジェクトに以前に設定された履歴の深さで時系列を作成します。値がゼロを超えるが指定されたチャート期間の利用可能な時系列バーの値よりも小さい場合、メソッドに渡された作成された履歴深度が使用されます)を受け取ります。

時間枠名で受け取ったインデックスから必要な時系列オブジェクトを取得しますオブジェクトの取得に失敗した場合または履歴の深さがまだ設定されていない場合は、適切なメッセージを表示してfalseを返します。

前回の記事で検討したのと同じ名前の時系列オブジェクトメソッドを使用して、メソッドから時系列の作成結果を返します。前の記事で説明した時系列作成メソッドは、時系列リストに追加されたオブジェクトバーの数を返しますが、現在のメソッドはブール値を返すため、追加された要素の数を「ゼロ以上」リストと比較した結果をtrueまたはfalseとして返すだけで十分です。 これがまさにここで行うことです。

すべての時系列リストを作成するメソッドを実装します。

//+------------------------------------------------------------------+
//| Create all timeseries lists                                      |
//+------------------------------------------------------------------+
bool CTimeSeries::CreateAll(const uint amount=0)
  {
   bool res=true;
   for(int i=0;i<21;i++)
     {
      CSeries *series_obj=this.m_list_series.At(i);
      if(series_obj==NULL || series_obj.AmountUsedData()==0)
         continue;
      res &=(series_obj.Create(amount)>0);
     }
   return res;
  }
//+------------------------------------------------------------------+

このメソッドは、作成された時系列の履歴の深さを受け取ります(デフォルト値はゼロです。SetAmountUsedData()メソッドを使用して時系列オブジェクトに以前に設定された履歴の深さで時系列を作成します。値がゼロを超えるが指定されたチャート期間の利用可能な時系列バーの値よりも小さい場合、メソッドに渡された作成された履歴深度が使用されます)。

すべての時間枠のリストを反復処理し、 ループインデックスによって次の時系列オブジェクトを取得します。 オブジェクトの取得に失敗した場合または履歴の深さがまだ設定されていない場合は、次の時間枠に進みます

ローカルのres変数は、 前の記事で検討した同じ名前の時系列オブジェクトクラスメソッドを使用して時系列を作成した結果がリストに追加された要素の数を「ゼロ以上」で比較した結果として表されたものを受け取ります。 時系列オブジェクトを作成するメソッドの少なくとも1つがfalseを返した場合、変数はfalseに設定されます。
ループの完了時に、res
変数に書き込まれたすべての時系列の作成結果を返します。

指定された時系列リストを更新するメソッドを実装します。

//+------------------------------------------------------------------+
//| Update a specified timeseries list                               |
//+------------------------------------------------------------------+
void CTimeSeries::Refresh(const ENUM_TIMEFRAMES timeframe,
                          const datetime time=0,
                          const double open=0,
                          const double high=0,
                          const double low=0,
                          const double close=0,
                          const long tick_volume=0,
                          const long volume=0,
                          const int spread=0)
  {
   CSeries *series_obj=this.m_list_series.At(this.IndexTimeframe(timeframe));
   if(series_obj==NULL || series_obj.DataTotal()==0)
      return;
   series_obj.Refresh(time,open,high,low,close,tick_volume,volume,spread);
  }
//+------------------------------------------------------------------+

メソッドは、更新された時系列時間枠および現在のバー価格データを受け取ります(現在の時間枠で現在の銘柄のデータを更新するときの指標のみ、データを価格配列からOnCalculate()に渡します。その他の場合では、渡されたパラメータの値は重要ではありません)。

時間枠名で受け取ったインデックスから必要な時系列オブジェクトを取得しますオブジェクトの取得に失敗した場合または作成された時間枠履歴のサイズがゼロの場合(時間枠が使用されていないか、Create()メソッドを使用して作成されていない場合)は、メソッドを終了します。
次に、前の記事で検討したのと同じ名前の時系列オブジェクトを更新するメソッドを呼び出します

すべての時系列リストを更新するメソッドを実装します。

//+------------------------------------------------------------------+
//| Update all timeseries lists                                      |
//+------------------------------------------------------------------+
void CTimeSeries::RefreshAll(const datetime time=0,
                             const double open=0,
                             const double high=0,
                             const double low=0,
                             const double close=0,
                             const long tick_volume=0,
                             const long volume=0,
                             const int spread=0)
  {
   for(int i=0;i<21;i++)
     {
      CSeries *series_obj=this.m_list_series.At(i);
      if(series_obj==NULL || series_obj.DataTotal()==0)
         continue;
      series_obj.Refresh(time,open,high,low,close,tick_volume,volume,spread);
     }
  }
//+------------------------------------------------------------------+

メソッドは現在のバー価格データを受け取ります(現在の時間枠で現在の銘柄のデータを更新するときの指標のみ、価格配列からデータを価格配列からOnCalculate()に渡します。他の場合では、渡されたパラメータの値は重要ではありません)。

すべての時間枠のリストによるループで、次の時系列オブジェクトをループインデックスで取得します。オブジェクトの取得に失敗した場合または作成された時間枠履歴のサイズがゼロ(時間枠が使用されていないか、Create()メソッドを使用して作成されていない場合)、次の時間枠に進みます。

次に、前の記事で検討したのと同じ名前の時系列オブジェクトを更新するメソッドを呼び出します

1つの銘柄のすべての時系列のオブジェクトクラスの最初のバージョンが準備できました。現在のクラスの機能は、単一の銘柄のいくつかの時間枠での作業をテストするのに十分です。将来的には、複数の銘柄に共通の事件列コレクションクラスを作成するときに、それを改良します。

\MQL5\Include\DoEasy\Engine.mqhにあるCEngineクラスファイルで、インクルードする時系列オブジェクトクラスファイルの文字列を

//+------------------------------------------------------------------+
//| 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 "TradingControl.mqh"
#include "Objects\Series\Series.mqh"
//+------------------------------------------------------------------+

使用されているすべての銘柄期間の時系列オブジェクトのファイルで置き換えます。

//+------------------------------------------------------------------+
//| 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 "TradingControl.mqh"
#include "Objects\Series\TimeSeries.mqh"
//+------------------------------------------------------------------+

これで、新しく作成されたクラスがライブラリベースのプログラムから見えるようになりました。

テスト

異なる期間の時系列での単一銘柄の使用をテストするには、前の記事のEAを\MQL5\Experts\TestDoEasy\Part36\TestDoEasyPart36.mq5として保存します。

クラスをテストするには、条件付きコンパイルディレクティブを使用して、テストEAの2つのバージョンを作成します。

  • 最初のEAバージョンは、現在の銘柄の2つの時系列を作成します。1つ目は、2本のバーのみで構成されるM15用です。
    もう1つは10本のバーで構成され、EAが起動されている現在のチャート期間についてです。
  • 2番目のEAバージョンは、現在の銘柄のすべての時系列をデフォルト値で作成します
    (時系列ごとに1000バー、または使用可能なバーの数が1000未満の場合には可能な最大値)。

EAグローバル変数のブロックに、時系列クラスの単一のオブジェクトを残します。CSeriesクラスオブジェクトはCTimeSeriesクラスオブジェクトの一部になっているため、CSeriesクラスの代わりにCTimeSeriesクラス変数を定義します。
CSeriesオブジェクトを削除します

//--- global variables
CEngine        engine;
CSeries        series;
CSeries        series_m1;
SDataButt      butt_data[TOTAL_BUTT];

また、2番目のオブジェクトの名前を変更し、その型をCTimeSeriesとして定義します

//--- global variables
CEngine        engine;
CTimeSeries    timeseries;
SDataButt      butt_data[TOTAL_BUTT];

EAのOnInit()ハンドラの最後に、指定されたTIMESERIES_ALL IDの有無に応じて時系列を作成するためのコードブロックを記述します。

//--- Check playing a standard sound by macro substitution and a custom sound by description
   engine.PlaySoundByDescription(SND_OK);
   Sleep(600);
   engine.PlaySoundByDescription(TextByLanguage("Звук упавшей монетки 2","Falling coin 2"));

//--- Set a symbol for created timeseries
   timeseries.SetSymbol(Symbol());
//#define TIMESERIES_ALL
//--- Create two timeseries
   #ifndef TIMESERIES_ALL
      timeseries.SyncData(PERIOD_CURRENT,10);
      timeseries.Create(PERIOD_CURRENT);
      timeseries.SyncData(PERIOD_M15,2);
      timeseries.Create(PERIOD_M15);
//--- Create all timeseries
   #else 
      timeseries.SyncAllData();
      timeseries.CreateAll();
   #endif 
//--- Check created timeseries
   CArrayObj *list=timeseries.GetList();
   Print(TextByLanguage("Данные созданных таймсерий:","Data of created timeseries:"));
   for(int i=0;i<list.Total();i++)
     {
      CSeries *series_obj=timeseries.GetSeriesByIndex((uchar)i);
      if(series_obj==NULL || series_obj.AmountUsedData()==0 || series_obj.DataTotal()==0)
         continue;
      Print(
            DFUN,i,": ",series_obj.Symbol()," ",TimeframeDescription(series_obj.Timeframe()),
            ": AmountUsedData=",series_obj.AmountUsedData(),", DataTotal=",series_obj.DataTotal(),", Bars=",series_obj.Bars()
           );
     }
   Print("");
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+

まず、銘柄時系列クラスの銘柄名を必ず設定してください。次に、マクロ置換として定義され、コメントアウトされたID があります。その存在/不在は、コンパイルするコードのバージョンを定義します。2つの時系列を作成するためのバージョン( IDがない場合)またはすべての時系列を作成するためのバージョン( IDがある場合)です。

一般に、またすべての銘柄時系列のオブジェクトクラスの現在のバージョンでは、時系列を作成するには次のものが必要です。

  1. すべての時系列オブジェクトの銘柄を設定する
  2. 時系列履歴の深さを設定し、サーバとの時系列データの同期をチェックするメソッドを呼び出す
  3. 指定した履歴の深さに基づいて時系列を作成する

通常、履歴の深さを設定し、サーバの同期を確認するメソッドは、結果が返されるかどうかを確認する必要があります。履歴の深さを設定できなかった場合、またはデータがサーバとまだ同期していない場合、このメソッドはfalseを返すことがあります。
ただし、このチェックをスキップして現在の銘柄でテストを実行することはできます。ほとんどの場合、データ全体が利用可能になります。データが利用できない場合でも、時系列は作成されません。履歴データのロードを開始する機能への最初のアクセスが読み込みを開始し、データが最初のEAの起動中に同期化されるため、EAを再起動するだけで済みます。

必要な時系列が作成されたら、作成された時系列の完全なリストを操作ログに表示して、作成が成功したかどうかを確認します。
これを行うには、すべての時系列の完全なリストを受け取ります。ループで、リストから次の時系列オブジェクトを受け取ります。時系列が作成された場合(履歴の深さがあり、データが入力されている場合)、データを操作ログに表示します。

OnTick()ハンドラの最後に、コードブロックを挿入して、作成されたすべての銘柄時系列のデータを更新します

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- If working in the tester
   if(MQLInfoInteger(MQL_TESTER))
     {
      engine.OnTimer();       // Working in the timer
      PressButtonsControl();  // Button pressing control
      EventsHandling();       // Working with events
     }
//--- If the trailing flag is set
   if(trailing_on)
     {
      TrailingPositions();    // Trailing positions
      TrailingOrders();       // Trailing of pending orders
     }
//--- Update created timeseries
   CArrayObj *list=timeseries.GetList();
   for(int i=0;i<list.Total();i++)
     {
      CSeries *series_obj=timeseries.GetSeriesByIndex((uchar)i);
      if(series_obj==NULL || series_obj.DataTotal()==0)
         continue;
      series_obj.Refresh();
      if(series_obj.IsNewBar(0))
        {
         Print(TextByLanguage("Новый бар на ","New bar on "),series_obj.Symbol()," ",TimeframeDescription(series_obj.Timeframe())," ",TimeToString(series_obj.Time(0)));
         if(series_obj.Timeframe()==Period())
            engine.PlaySoundByDescription(SND_NEWS);
        }
     }
  }
//+------------------------------------------------------------------+

ここでは、すべての銘柄時系列のオブジェクトから時系列のリストを取得します時系列のリストによるループでは、ループインデックスによって次の時系列オブジェクトを取得します時系列を受け取れなかった場合、またはデータ(バー)がない場合、次の時間枠の次の時系列に進みます。時系列オブジェクトを受け取ったら、更新します。時系列に新しいバーフラグが設定されている場合、適切なメッセージを表示します(現在の時系列のnews.wavサウンドも再生します)。

EAをコンパイルします( #define TIMESERIES_ALLマクロ置換定義を含む文字列176はコメントアウトします)。2つの時系列を作成するEAバージョンがコンパイルされます。
M30チャートのターミナルで起動します。作成された2つの時系列のパラメータに関するエントリが操作ログに表示されます。しばらくすると、 M15およびM30チャートで新しいバーを開くことに関するエントリが表示されます。

Account 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10425.23 USD, 1:100, Hedge, Demo account MetaTrader 5
Work only with the current symbol. The number of symbols used: 1
Data of created timeseries:
OnInit: 8: EURUSD M15: AmountUsedData=2, DataTotal=2, Bars=5000
OnInit: 10: EURUSD M30: AmountUsedData=10, DataTotal=10, Bars=5030
 
New bar on EURUSD M15 2020.02.20 20:45
New bar on EURUSD M15 2020.02.20 21:00
New bar on EURUSD M30 2020.02.20 21:00
New bar on EURUSD M15 2020.02.20 21:15
New bar on EURUSD M15 2020.02.20 21:30
New bar on EURUSD M30 2020.02.20 21:30

次に、 #define TIMESERIES_ALL マクロ置換を定義する文字列176のコメントを外して、EAをコンパイルすると、デフォルト値ですべての時系列を作成するEAバージョンが生成されます。

銘柄チャートで起動します。作成されたすべての時系列のパラメータに関するエントリが操作ログに表示されます。しばらくすると作成された時系列チャート期間に新しいバーを開くことに関するエントリが表示されます。

Account 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10425.23 USD, 1:100, Hedge, Demo account MetaTrader 5
Work only with the current symbol. The number of symbols used: 1
Data of created 時系列:
OnInit: 0: EURUSD M1: AmountUsedData=1000, DataTotal=1000, Bars=5140
OnInit: 1: EURUSD M2: AmountUsedData=1000, DataTotal=1000, Bars=4010
OnInit: 2: EURUSD M3: AmountUsedData=1000, DataTotal=1000, Bars=3633
OnInit: 3: EURUSD M4: AmountUsedData=1000, DataTotal=1000, Bars=3445
OnInit: 4: EURUSD M5: AmountUsedData=1000, DataTotal=1000, Bars=3332
OnInit: 5: EURUSD M6: AmountUsedData=1000, DataTotal=1000, Bars=3256
OnInit: 6: EURUSD M10: AmountUsedData=1000, DataTotal=1000, Bars=3106
OnInit: 7: EURUSD M12: AmountUsedData=1000, DataTotal=1000, Bars=3068
OnInit: 8: EURUSD M15: AmountUsedData=1000, DataTotal=1000, Bars=5004
OnInit: 9: EURUSD M20: AmountUsedData=1000, DataTotal=1000, Bars=2993
OnInit: 10: EURUSD M30: AmountUsedData=1000, DataTotal=1000, Bars=5032
OnInit: 11: EURUSD H1: AmountUsedData=1000, DataTotal=1000, Bars=5352
OnInit: 12: EURUSD H2: AmountUsedData=1000, DataTotal=1000, Bars=6225
OnInit: 13: EURUSD H3: AmountUsedData=1000, DataTotal=1000, Bars=6212
OnInit: 14: EURUSD H4: AmountUsedData=1000, DataTotal=1000, Bars=5292
OnInit: 15: EURUSD H6: AmountUsedData=1000, DataTotal=1000, Bars=5182
OnInit: 16: EURUSD H8: AmountUsedData=1000, DataTotal=1000, Bars=5443
OnInit: 17: EURUSD H12: AmountUsedData=1000, DataTotal=1000, Bars=5192
OnInit: 18: EURUSD D1: AmountUsedData=1000, DataTotal=1000, Bars=5080
OnInit: 19: EURUSD W1: AmountUsedData=1000, DataTotal=1000, Bars=2562
OnInit: 20: EURUSD MN1: AmountUsedData=589, DataTotal=589, Bars=589

New bar on EURUSD M1 2020.02.20 21:41
New bar on EURUSD M1 2020.02.20 21:42
New bar on EURUSD M2 2020.02.20 21:42
New bar on EURUSD M3 2020.02.20 21:42
New bar on EURUSD M6 2020.02.20 21:42
New bar on EURUSD M1 2020.02.20 21:43
New bar on EURUSD M1 2020.02.20 21:44
New bar on EURUSD M2 2020.02.20 21:44
New bar on EURUSD M4 2020.02.20 21:44
New bar on EURUSD M1 2020.02.20 21:45
New bar on EURUSD M3 2020.02.20 21:45
New bar on EURUSD M5 2020.02.20 21:45
New bar on EURUSD M15 2020.02.20 21:45

M5テスターのビジュアルモードでEAを起動します。


まず、テスターがすべての時間枠の履歴データをダウンロードし、次にEAが作成された時系列のデータを表示します。その後、メッセージが操作ログに送信され、テスト中に作成された時系列の新しいバーを開くことを通知します。

単一の銘柄時系列を操作する機能を作成するこの段階では、すべてが意図したとおりに機能します。

次の段階

次の記事では、さまざまな銘柄とその時間枠に必要な量のデータを格納する共通の時系列コレクションクラスを作成します。

現在のバージョンのライブラリのすべてのファイルは、テスト用EAファイルと一緒に以下に添付されているので、テストするにはダウンロードしてください。
質問や提案はコメント欄にお願いします。

目次に戻る

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

DoEasyライブラリの時系列(第35部): バーオブジェクトと銘柄の時系列リスト


MetaQuotes Software Corp.によりロシア語から翻訳された
元の記事: https://www.mql5.com/ru/articles/7627

添付されたファイル |
MQL5.zip (3686.04 KB)
MQL4.zip (3686.04 KB)
連続ウォークフォワード最適化(パート5):自動オプティマイザプロジェクトの概要とGUIの作成 連続ウォークフォワード最適化(パート5):自動オプティマイザプロジェクトの概要とGUIの作成

この記事では、MetaTrader5 ターミナルでのウォークフォワード最適化の詳細を説明します。 以前の記事では、最適化レポートを生成およびフィルタリングする方法を検討し、最適化プロセスを担当するアプリケーションの内部構造の分析を開始しました。 自動オプティマイザは C# アプリケーションとして実装され、独自のグラフィカル インターフェイスを備えています。 5番目となるこの記事では、このグラフィカルインタフェースの作成に専念します。

時系列の予測(第1部):経験的分解モード(EMD)法 時系列の予測(第1部):経験的分解モード(EMD)法

この記事では、経験的分解モードに基づいて時系列を予測するアルゴリズムの理論と実際の使用法について説明します。また、このメソッドのMQL実装を提案し、テスト指標とエキスパートアドバイザーを提示します。

トレーディングにおけるOLAPの適用(その4)。テスターレポートの定量的・視覚的分析 トレーディングにおけるOLAPの適用(その4)。テスターレポートの定量的・視覚的分析

この記事では、シングルパスや最適化結果に関連するテスターレポートのOLAP分析のための基本的なツールを提供しています。 このツールは標準フォーマットのファイル(tstとopt)を扱うことができ、グラフィカルなインターフェイスも提供します。 最後にMQLのソースコードを添付します。

新しいMetaTrader 5 とMQL5の登場 新しいMetaTrader 5 とMQL5の登場

これはMetaTrader5のただの簡単なレビューです。このような短い時間でシステムのすべての特徴を述べることはできません。2009年9月9日に試用を開始しました。これはシンボル的な日付でラッキーナンバーになると信じています。ベータ版のMetaTrader5とMQL5を手に入れて数日が経ちました。まだ全ての特徴を使ってはいませんが、すでに関心させられました。