English Русский 中文 Español Deutsch Português
preview
MQL5の構造体とデータ表示メソッド

MQL5の構造体とデータ表示メソッド

MetaTrader 5 | 8 12月 2023, 13:53
389 0
Artyom Trishkin
Artyom Trishkin

内容


はじめに

構造体は、単一の変数から任意の定義に属する論理的に関連するデータを格納、記録、検索するための便利なツールです。

MQL5には、サービス情報の保存と送信を目的とした12の定義済み構造体があります。

MqlParamおよびMqlTradeRequest構造体は、指標を作成し、取引リクエストをサーバーに送信するための技術情報を送信します。完成した構造体のデータ送信結果に応じて、構造体の必要項目を埋めていきます。言い換えれば、これらの構造体では、プログラマーがこれらの構造体のフィールドに記入したデータを表示する必要は特にありません。
しかし、残りの構造体はクエリ結果を返し、各フィールドはターミナルサブシステムか取引サーバーによって埋められます。このような構造体からデータを取得したり、プログラムによって構造体のフィールドに入力されたデータを分析したり、あるいはログに出力して手動で分析したりすることは、プログラム上の意思決定や、論理エラーの発生箇所を把握発見するために非常に便利で必要なことです。

構造体のすべてのフィールドを表示するためには、標準的なArrayPrint()関数があります。この関数では、配列に含まれるデータを便利な表形式で、扱われる構造体の型とともに表示します。しかし、表形式で表現するよりも便利なために、構造体から別の形式でデータを表示する必要があることもあります。たとえば、構造体のすべてのフィールドを、ヘッダーと対応するデータとともに1行で表示する必要があるかもしれません。大量のデータを分析するには、こちらの方が便利かもしれません。同時に、構造体フィールドの説明や対応するデータの別の表現など、より詳細なビューが必要な場合もあります。

今回の記事では、構造体データを見るための標準的なツールを見て、操作ログで構造体データをさまざまに表示するためのカスタム関数を作成します。


MqlDateTime構造体

このデータ構造体には、int型のフィールドが8つ含まれています。

struct MqlDateTime
  {
   int year;           // year
   int mon;            // month
   int day;            // day
   int hour;           // hour
   int min;            // minutes
   int sec;            // seconds
   int day_of_week;    // day of the week (0-Sunday, 1-Monday, ... ,6-Saturday)
   int day_of_year;    // number of a day in the year (1st of January has number 0)
  };

構造体フィールドを埋めるためには、標準関数TimeCurrent()TimeGMT()TimeLocal()TimeTradeServer()TimeToStruct()が使用されます。

最初の4つの関数は、現在の日付、GMT日付、ローカルコンピュータの時刻、取引サーバーの日付を返すだけでなく、それぞれ1つのオーバーロードを持っています。関数の仮パラメータでは、参照によって日付構造体を渡すことができます。関数実行後、関数に渡された構造体フィールドは、関数が返した日付データで埋められます。

TimeToStruct()関数は、特にdatetime 値型(1970年01月01日からの秒数)からMqlDateTime構造体型変数に構造体を埋めるように設計されています。

bool  TimeToStruct(
   datetime      dt,            // date and time
   MqlDateTime&  dt_struct      // structure for accepting values 
   );

成功すればtrue、そうでなければfalseが返されます。この操作の後、日付構造体は、最初のdatetime型の変数パラメータで渡された時間データで満たされます。

日付の構造体は完成しましたが、どうやって表示するのでしょうか。標準のTimeToString()関数は、1970年1月1日からの秒単位の時刻を含む値を「yyyy.mm.dd hh:min:sec」形式の文字列に変換します。

ただし、この関数はMqlDateTime構造体では動作せず、datetime日付で動作します。では、この構造体を時間の値に戻すべきでしょうか。もちろん、そんなことはありません。各関数は、それぞれの目的に応じたものです。年、月、時間、分、曜日など、日付構造体から日付と時刻の構成要素を個別に取り出すことができますが、すべての構造体データを表示するにはどうすればいいのでしょうか。
ArrayPrint()関数は、単純な型または単純な構造体の配列をログに記録するもので、このタスクに適しています。表の形でデータを表示し、列は構造体のフィールド、行は配列のセルを表します。言い換えれば、1つの日付構造体を表示するには、1の配列が必要です。D1チャートからデータを取得する場合、1取引週の配列サイズは通常5取引日となります。


MqlDateTime, 表示メソッド

次の関数は、ArrayPrint()を使用して、操作ログの現在時刻から取得した日付構造体を表示します。

void OnStart()
  {
//--- Declare a date structure variable
   MqlDateTime  time;
//--- Get the current time and at the same time fill in the date structure
   TimeCurrent(time);
//--- Declare an array with the MqlDateTime type and write the data of the filled structure into it

   MqlDateTime array[1];
   array[0]=time;
//--- Display the header and time using the standard ArrayPrint()
   Print("Time current (ArrayPrint):");
   ArrayPrint(array);
   /* Sample output:
      Time current (ArrayPrint):
          [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year]
      [0]   2023     7    17     12     8    37             1           197
   */
  }

それぞれ、日付構造体を受け取り、それを操作ログに表示する関数は次のようになります。

//+------------------------------------------------------------------+
//| Take a date structure and display its data to the journal.       |
//| Use ArrayPrint() for display                                     |
//+------------------------------------------------------------------+
void MqlDateTimePrint(const MqlDateTime& time_struct)
  {
//--- Declare an array with the MqlDateTime type and write the data of the obtained structure into it
   MqlDateTime array[1];
   array[0]=time_struct;
//--- Print the array
   ArrayPrint(array);
   /* Sample output:
      Time current (ArrayPrint):
          [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year]
      [0]   2023     7    17     12     8    37             1           197
   */
  }

この関数は、time_struct変数に渡された日付を操作ログに表示することができます。

以下は、上で紹介した関数を使用して、1つの日付構造体をログ記録する関数です。

void OnStart()
  {
//--- Declare a date structure variable
   MqlDateTime  time;
//--- Get the current time and at the same time fill in the date structure
   TimeCurrent(time);
//--- Display the header and time using the standard ArrayPrint()
   Print("Time current (ArrayPrint):");
   MqlDateTimePrint(time);
   /* Sample output:
      Time current (ArrayPrint):
          [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year]
      [0]   2023     7    17     12     8    37             1           197
   */
  }


日付の配列を表示する必要がある場合(結局のところ、これがArrayPrint()の主な目的です)、データ配列をdatetime関数に渡し、MqlDateTime配列を埋めて表示する必要があります。

以下は、datetime配列を受け取り、MqlDateTime配列を表示する関数です。

//+------------------------------------------------------------------+
//| Accept the datetime array, convert it into MqlDateTime and       |
//| display converted data into the journal.                         |
//| Use ArrayPrint() for display                                     |
//+------------------------------------------------------------------+
void MqlDateTimePrint(const datetime& array_time[])
  {
//--- Declare a dynamic array of the MqlDateTime type
   MqlDateTime array_struct[];
//--- Get the size of the array passed to the function
   int total=(int)array_time.Size();
//--- If an empty array is passed, report on that and leave the function
   if(total==0)
     {
      PrintFormat("%s: Error. Empty array.",__FUNCTION__);
      return;
     }
//--- Change the size of the MqlDateTime array to match the size of the datetime array
   ResetLastError();
   if(ArrayResize(array_struct,total)!=total)
     {
      PrintFormat("%s: ArrayResize() failed. Error %s",__FUNCTION__,(string)GetLastError());
      return;
     }
//--- Convert dates from the datetime array into the date structure in the MqlDateTime array
   for(int i=0;i<total;i++)
     {
      ResetLastError();
      if(!TimeToStruct(array_time[i],array_struct[i]))
         PrintFormat("%s: [%s] TimeToStruct() failed. Error %s",__FUNCTION__,(string)i,(string)GetLastError());
     }
//--- Print the filled MqlDateTime array
   ArrayPrint(array_struct);
   /* Sample output:
      Time data of the last 10 bars GBPUSD H1 (ArrayPrint):
          [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year]
      [0]   2023     7    17      7     0     0             1           197
      [1]   2023     7    17      8     0     0             1           197
      [2]   2023     7    17      9     0     0             1           197
      [3]   2023     7    17     10     0     0             1           197
      [4]   2023     7    17     11     0     0             1           197
      [5]   2023     7    17     12     0     0             1           197
      [6]   2023     7    17     13     0     0             1           197
      [7]   2023     7    17     14     0     0             1           197
      [8]   2023     7    17     15     0     0             1           197
      [9]   2023     7    17     16     0     0             1           197
   */
  }


したがって、上記の関数を使用して操作ログにdatetime配列を出力する関数は次のようになります。

void OnStart()
  {
//--- Declare a time array
   datetime array[];
//--- Copy the time of the last 10 bars to the array
   ResetLastError();
   if(CopyTime(Symbol(),Period(),0,10,array)<0)
     {
      PrintFormat("CopyTime() failed. Error %s",(string)GetLastError());
      return;
     }
//--- Display the header and the time data array of the last 10 bars using the standard ArrayPrint()
   PrintFormat("Time data of the last 10 bars %s %s (ArrayPrint):",Symbol(),StringSubstr(EnumToString(Period()),7));
   MqlDateTimePrint(array);
   /* Sample output:
      Time data of the last 10 bars GBPUSD H1 (ArrayPrint):
          [year] [mon] [day] [hour] [min] [sec] [day_of_week] [day_of_year]
      [0]   2023     7    17      7     0     0             1           197
      [1]   2023     7    17      8     0     0             1           197
      [2]   2023     7    17      9     0     0             1           197
      [3]   2023     7    17     10     0     0             1           197
      [4]   2023     7    17     11     0     0             1           197
      [5]   2023     7    17     12     0     0             1           197
      [6]   2023     7    17     13     0     0             1           197
      [7]   2023     7    17     14     0     0             1           197
      [8]   2023     7    17     15     0     0             1           197
      [9]   2023     7    17     16     0     0             1           197
   */
  }


MqlDateTime構造体データを操作するための関数

上記のテストはすべて、便利で、実用的で、簡潔です。しかし、できれば同じ簡潔な表現が望ましいが、より完全な情報が必要な場合もあります。あるいは逆に、データ提示の簡潔さやドライさを減らすことで、より詳細な説明が必要になるかもしれません。例えば、日にちだけでは混乱するかもしれませんが、「木曜日」と書かれていれば、木曜日のことだとすぐに理解できます。月番号も同様で、どの月が7番目かを思い出すより、「07(7月)」と表示された方がいい場合もあります.。もちろんこれは大げさかもしれませんが、それでもこのような小さな改善が利便性を高めている。このような小さな便利さが積み重なることで、プログラムログの大量のエントリを分析する際に、非常に具体的な時間短縮につながります。

このような便利な機能を追加するには、MqlDateTimeフォーマットで日付の説明を返す独自の関数を書く必要があります。

その関数は、次をおこないます。

  1. 短いフォーマット(曜日、月、日、年、時間)でデータを表示する
  2. 表にデータを表示する(データヘッダ値)

構造体フィールドの説明を返す関数を作り始める前に、曜日と月の名前を返す補助関数を書きます。

補助関数

曜日名を取得するために、曜日を数値形式で格納する構造体フィールドの値に応じて曜日のテキストを返す簡単な関数を書いてみましょう。

//+------------------------------------------------------------------+
//| Return the name of a week day                                    |
//+------------------------------------------------------------------+
string DayWeek(MqlDateTime &date_time)
  {
//--- Define a week day name
   string dw=EnumToString((ENUM_DAY_OF_WEEK)date_time.day_of_week);
//--- Convert all obtained symbols to lower case and replace the first letter from small to capital
   if(dw.Lower())
      dw.SetChar(0,ushort(dw.GetChar(0)-0x20));
//--- Return a resulting string
   return dw;
   /* Sample output:
      Wednesday
   */
  }

MQL5には曜日名のリストがあるので、ここでは列挙定数の文字列表現を使用します。テキストが正しく表示されるように、単語の最初の文字を除いて、行内のすべての文字を小文字に変換します。

月の名前を取得するために、数値形式で構造体フィールドに格納されている値に応じて月名のテキストを返す簡単な関数を書いてみましょう。

//+------------------------------------------------------------------+
//| Return a month name                                              |
//+------------------------------------------------------------------+
string Month(MqlDateTime &date_time)
  {
//--- Define a month name
   switch(date_time.mon)
     {
      case  1  :  return "January";
      case  2  :  return "February";
      case  3  :  return "March";
      case  4  :  return "April";
      case  5  :  return "May";
      case  6  :  return "June";
      case  7  :  return "July";
      case  8  :  return "August";
      case  9  :  return "September";
      case 10  :  return "October";
      case 11  :  return "November";
      case 12  :  return "December";
      default  :  return "Undefined";
     }
   /* Sample output:
      July
   */
  }

MQL5には月を選択する列挙型がないので、ここでは構造体フィールドに書かれたデジタル値に応じて月名のテキストを選択して返すswitch演算子を使わなければなりません。

これらの関数は、曜日や月の説明を表示するのに役立つでしょう。また、将来、私たちの次のプロジェクトに役立つかもしれません。

MqlDateTime構造体フィールドの説明を返す関数は、「StringFormat():レビューと既成の例」で採用されている書式を持ちます。関数が返す各行は、ヘッダーとデータを持ちます。ヘッダーは左端からインデントすることができ、返されたレコードの表形式のビューのための幅を与えることができます。インデントと幅の値をパラメータとして関数に渡します。これらのオプションのデフォルト値はゼロです。つまり、パディングなしで、幅はヘッダーテキストの長さ+1に等しくなります。


MqlDateTime構造体の年:

//+------------------------------------------------------------------+
//| Return the year as a string from MqlDateTime                     |
//+------------------------------------------------------------------+
string MqlDateTimeYear(MqlDateTime &date_time,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Year:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-lu",indent,"",w,header,date_time.year);
   /* Sample output:
      Year: 2023
   */
  }


MqlDateTime構造体の月:

//+------------------------------------------------------------------+
//| Return the month as a string from MqlDateTime                    |
//+------------------------------------------------------------------+
string MqlDateTimeMonth(MqlDateTime &date_time,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Month:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get a month name
   string mn=Month(date_time);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%02lu (%s)",indent,"",w,header,date_time.mon,mn);
   /* Sample output:
      Month: 07 (July)
   */
  }


MqlDateTime構造体の日:

//+------------------------------------------------------------------+
//| Return the day as a string from the MqlDateTime structure        |
//+------------------------------------------------------------------+
string MqlDateTimeDay(MqlDateTime &date_time,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Day:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%02lu",indent,"",w,header,date_time.day);
   /* Sample output:
      Day: 19
   */
  }



MqlDateTime 構造体の時間:

//+------------------------------------------------------------------+
//| Return hours as a string from the MqlDateTime structure          |
//+------------------------------------------------------------------+
string MqlDateTimeHour(MqlDateTime &date_time,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Hour:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%02lu",indent,"",w,header,date_time.hour);
   /* Sample output:
      Hour: 08
   */
  }


MqlDateTime構造体の分:

//+------------------------------------------------------------------+
//| Return minutes as a string from MqlDateTime                      |
//+------------------------------------------------------------------+
string MqlDateTimeMin(MqlDateTime &date_time,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Minutes:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%02lu",indent,"",w,header,date_time.min);
   /* Sample output:
      Minutes: 41
   */
  }


MqlDateTime構造体の秒:

//+------------------------------------------------------------------+
//| Return seconds as a string from MqlDateTime                      |
//+------------------------------------------------------------------+
string MqlDateTimeSec(MqlDateTime &date_time,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Seconds:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%02lu",indent,"",w,header,date_time.sec);
   /* Sample output:
      Seconds: 23
   */
  }


MqlDateTime構造体の曜日:

//+------------------------------------------------------------------+
//| Return a week day as a string from the MqlDateTime structure     |
//+------------------------------------------------------------------+
string MqlDateTimeDayWeek(MqlDateTime &date_time,const uint header_width=0,const uint indent=0,bool descr=true)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Day of week:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Get a week day name
   string dw=DayWeek(date_time);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-s (%-lu)",indent,"",w,header,dw,date_time.day_of_week);
   /* Sample output:
      Day of week: Wednesday (3)
   */
  }


MqlDateTime構造体の1年間の日数:

//+------------------------------------------------------------------+
//|Return a number of a day in a year from MqlDateTime               |
//+------------------------------------------------------------------+
string MqlDateTimeDayYear(MqlDateTime &date_time,const uint header_width=0,const uint indent=0)
  {
//--- Define the header text and the width of the header field
//--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
   string header="Day of year:";
   uint w=(header_width==0 ? header.Length()+1 : header_width);
//--- Return the property value with a header having the required width and indentation
   return StringFormat("%*s%-*s%-lu",indent,"",w,header,date_time.day_of_year);
   /* Sample output:
      Day of year: 199
   */
  }


使用例:

MqlDateTime構造体から日付時刻の短いレコードを表示するために、「DW, Month DD, YYYY, HH:MM:SS」フォーマットで日付を返す関数を書きます。

//+------------------------------------------------------------------+
//| Return the date as a string from the MqlDateTime structure       |
//| in the DW, Month DD, YYYY, HH:MM:SS format                       |
//+------------------------------------------------------------------+
string DateTime(MqlDateTime &date_time)
  {
//--- Get the month and the first three characters of a week day
   string mn=Month(date_time);
   string dw=StringSubstr(DayWeek(date_time),0,3);
//--- Return a string in the DW, Month DD, YYYY, HH:MM:SS format
   return StringFormat("%s, %s %02lu, %lu, %02lu:%02lu:%02lu",dw,mn,date_time.day,date_time.year,date_time.hour,date_time.min,date_time.sec);
   /* Sample output:
      Wed, July 19, 2023, 08:41:23
   */
  }

これは、年の日数以外のすべての構造体データを1行でまとめたものです。この関数は、操作ログに一定数のバーを表示する場合などに便利です。

void OnStart()
  {
   datetime array[];
   MqlDateTime adt[];
   if(CopyTime(Symbol(),PERIOD_CURRENT,0,10,array)==10)
     {
      int total=(int)array.Size();
      if(ArrayResize(adt,total)==total)
        {
         for(int i=0;i<total;i++)
           {
            ResetLastError();
            if(!TimeToStruct(array[i],adt[i]))
               Print("TimeToStruct failed. Error: ",GetLastError());
            PrintFormat("%s %s [%02u] %s",Symbol(),StringSubstr(EnumToString(Period()),7),i,DateTime(adt[i]));
           }
        }
     }
   /* Sample output:
      GBPUSD H1 [00] Wed, July 19, 2023, 02:00:00
      GBPUSD H1 [01] Wed, July 19, 2023, 03:00:00
      GBPUSD H1 [02] Wed, July 19, 2023, 04:00:00
      GBPUSD H1 [03] Wed, July 19, 2023, 05:00:00
      GBPUSD H1 [04] Wed, July 19, 2023, 06:00:00
      GBPUSD H1 [05] Wed, July 19, 2023, 07:00:00
      GBPUSD H1 [06] Wed, July 19, 2023, 08:00:00
      GBPUSD H1 [07] Wed, July 19, 2023, 09:00:00
      GBPUSD H1 [08] Wed, July 19, 2023, 10:00:00
      GBPUSD H1 [09] Wed, July 19, 2023, 11:00:00
   */
  }


次の関数を実装して、構造体のすべてのフィールドを短い表形式で記録してみましょう。

//+------------------------------------------------------------------+
//| Logs descriptions of all fields of the MqlDateTime structure     |
//+------------------------------------------------------------------+
void MqlDateTimePrint(MqlDateTime &date_time,const bool short_entry=true,const uint header_width=0,const uint indent=0)
  {
//--- If it is a short entry, log the date and time in the DW, Month DD, YYYY, HH:MM:SS format
   if(short_entry)
      Print(DateTime(date_time));
   /* Sample output:
      Wed, July 19, 2023, 08:41:23
   */
//--- Otherwise
   else
     {
      //--- create a string describing all the data of the structure with indents and a given width of the header field 
      string res=StringFormat("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s",
                              MqlDateTimeYear(date_time,header_width,indent),
                              MqlDateTimeMonth(date_time,header_width,indent),
                              MqlDateTimeDay(date_time,header_width,indent),
                              MqlDateTimeHour(date_time,header_width,indent),
                              MqlDateTimeMin(date_time,header_width,indent),
                              MqlDateTimeSec(date_time,header_width,indent),
                              MqlDateTimeDayWeek(date_time,header_width,indent),
                              MqlDateTimeDayYear(date_time,header_width,indent)
                             );
      //--- Display the obtained string in the journal
      Print(res);
     }
   /* Sample output:
      Year: 2023
      Month: 07 (July)
      Day: 19
      Hour: 09
      Minutes: 32
      Seconds: 25
      Day of week: Wednesday (3)
      Day of year: 199
   */
  }

次は、関数の処理例を示す関数です。まず、操作ログに短いエントリを表示し、その後に、フィールドヘッダーを字下げし、フィールド幅をそれぞれ2文字と14文字とした表形式を表示します。

void OnStart()
  {
   MqlDateTime dt;
   TimeCurrent(dt);
   MqlDateTimePrint(dt,true);
   MqlDateTimePrint(dt,false,14,2);
   /* Sample output:
      Wed, July 19, 2023, 09:33:56
        Year:         2023
        Month:        07 (July)
        Day:          19
        Hour:         09
        Minutes:      33
        Seconds:      56
        Day of week:  Wednesday (3)
        Day of year:  199
   */
  }

上記で紹介したMqlDateTime構造体のフィールドや補助的なフィールドを操作するための関数はすべて、ご自分のプログラムで「そのまま」使用することも、ビジョンやニーズに応じて変更することもできます。


MqlTick構造体

最終価格を銘柄ごとに格納するための構造体は、現在の価格に関する最も必要なデータをタイムリーに取得するように設計されています。

struct MqlTick
  {
   datetime     time;          // Last price update time
   double       bid;           // Current Bid price
   double       ask;           // Current Ask price
   double       last;          // Current price of the last trade (Last)
   ulong        volume;        // Volume for the current Last price
   long         time_msc;      // Last price update time in milliseconds
   uint         flags;         // Tick flags
   double       volume_real;   // Volume for the current Last price
  };

MqlTick型の変数を使用すると、SymbolInfoTick()関数を1回呼び出すだけで、Ask、Bid、Last、Volumeの値とミリ秒単位の時間を取得できます。

各ティックのパラメータは、前のティックと比べて変化があるかどうかに関係なく記入されます。そのため、ティック履歴で過去の値を検索することなく、過去のどの時点の正しい価格も知ることができます。たとえば、1ティック到着中に買値だけが変化しても、その構造体には、直前の売値や出来高など、他のパラメータも含まれています。

ティックフラグを分析し、どのデータが変更されたかを調べます。

  • TICK_FLAG_BID - ティックが買値を変更
  • TICK_FLAG_ASK - ティックが売値を変更
  • TICK_FLAG_LAST:ティックが最後の取引価格を変更
  • TICK_FLAG_VOLUME - ティックがボリュームを変更
  • TICK_FLAG_BUY - ティックは買い取引の結果
  • TICK_FLAG_SELL - ティックは売り取引の結果

    MqlTick、表示メソッド

    ArrayPrint()関数は、MqlDateTimeと同じように操作ログに構造体を表示するのに適しています。

    void OnStart()
      {
    //--- Declare a variable with the MqlTick type
       MqlTick  tick;
    //--- If failed to get the last tick, display the error message and exit the method
       if(!SymbolInfoTick(Symbol(),tick))
         {
          Print("SymbolInfoTick failed, error: ",(string)GetLastError());
          return;
         }
    //--- Display the tick using standard ArrayPrint()
    //--- To do this, declare an array of dimension 1 with type MqlTick,
    //--- enter the value of the 'tick' variable into it and print it
       MqlTick array[1];
       array[0]=tick;
       Print("Last tick (ArrayPrint):");
       ArrayPrint(array);
       /* Sample output:
          Last tick (ArrayPrint):
                           [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
          [0] 2023.07.19 17:02:49 1.28992 1.28996 0.0000        0 1689786169589       6       0.00000
       */
      }
    
    

    配列を表示するには、その配列にティックの範囲を記入すればよいのです。

    void OnStart()
      {
    //--- Declare a dynamic array of the MqlTick type
       MqlTick  array[];
    //--- If failed to get the last 10 ticks, display the error message and exit the method
       if(CopyTicks(Symbol(),array,COPY_TICKS_ALL,0,10)!=10)
         {
          Print("CopyTicks failed, error: ",(string)GetLastError());
          return;
         }
       Print("Last 10 tick (ArrayPrint):");
       ArrayPrint(array);
       /* Sample output:
          Last 10 tick (ArrayPrint):
                           [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
          [0] 2023.07.19 17:24:38 1.28804 1.28808 0.0000        0 1689787478461       6       0.00000
          [1] 2023.07.19 17:24:38 1.28806 1.28810 0.0000        0 1689787478602       6       0.00000
          [2] 2023.07.19 17:24:38 1.28804 1.28808 0.0000        0 1689787478932       6       0.00000
          [3] 2023.07.19 17:24:39 1.28806 1.28810 0.0000        0 1689787479210       6       0.00000
          [4] 2023.07.19 17:24:39 1.28807 1.28811 0.0000        0 1689787479765       6       0.00000
          [5] 2023.07.19 17:24:39 1.28808 1.28812 0.0000        0 1689787479801       6       0.00000
          [6] 2023.07.19 17:24:40 1.28809 1.28813 0.0000        0 1689787480240       6       0.00000
          [7] 2023.07.19 17:24:40 1.28807 1.28811 0.0000        0 1689787480288       6       0.00000
          [8] 2023.07.19 17:24:40 1.28809 1.28813 0.0000        0 1689787480369       6       0.00000
          [9] 2023.07.19 17:24:40 1.28810 1.28814 0.0000        0 1689787480399       6       0.00000
       */
      }
    
    

    繰り返しになりますが、もっと意味のある値の表示が必要です。例えば、ミリ秒単位の時間やフラグなどです。時刻は時刻形式で、フラグは列挙定数形式など、普通のやり方で表示するのが便利でしょう。


    MqlTick構造体データを操作するための関数

    MqlTick構造体データを操作するための関数を実装してみましょう。MqlDateTime構造体を操作するために既に作成されたすべての関数と同様に、MqlTickを操作するための関数は、フォーマットされた文字列を返します。行のフォーマットには、テキストの左証拠金とヘッダーフィールドの幅が含まれます。デフォルトでは、パディングと証拠金幅の値はゼロになります。つまり、パディングはなく、証拠金幅はヘッダーテキストの長さ+1に等しくなります。


    補助関数

    ミリ秒単位の時間を文字列として返す関数はすでに書きました。ここでは、ティック時間をミリ秒単位で返すのに便利です。応用してみましょう。

    //+------------------------------------------------------------------+
    //| Accept a date in ms, return time in Date Time.Msc format         |
    //+------------------------------------------------------------------+
    string TimeMSC(const long time_msc)
      {
       return StringFormat("%s.%.3hu",string((datetime)time_msc / 1000),time_msc % 1000);
       /* Sample output:
          2023.07.13 09:31:58.177
       */
      }
    
    


    MqlTick構造体の時間:

    //+------------------------------------------------------------------+
    //| Return the time of the last price update as a string             |
    //+------------------------------------------------------------------+
    string MqlTickTime(const MqlTick &tick,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Time:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-s",indent,"",w,header,(string)tick.time);
       /* Sample output:
          Time: 2023.07.19 20:58:00
       */
      }
    
    


    MqlTick構造体の買値:

    //+------------------------------------------------------------------+
    //| Return the Bid price as a string                                 |
    //+------------------------------------------------------------------+
    string MqlTickBid(const string symbol,const MqlTick &tick,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Bid:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Get the number of decimal places
       int dg=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,tick.bid);
       /* Sample output:
          Bid: 1.29237
       */
      }
    
    


    MqlTick構造体の売値:

    //+------------------------------------------------------------------+
    //| Return the Ask price as a string                                 |
    //+------------------------------------------------------------------+
    string MqlTickAsk(const string symbol,const MqlTick &tick,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Ask:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Get the number of decimal places
       int dg=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,tick.ask);
       /* Sample output:
          Ask: 1.29231
       */
      }
    
    


    MqlTick構造体の最後の取引価格:

    //+------------------------------------------------------------------+
    //| Return the Last price as a string                                |
    //+------------------------------------------------------------------+
    string MqlTickLast(const string symbol,const MqlTick &tick,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Last:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Get the number of decimal places
       int dg=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,tick.last);
       /* Sample output:
          Last: 0.00000
       */
      }
    
    


    MqlTick構造体の最終価格ボリューム:

    //+------------------------------------------------------------------+
    //| Return the volume for the Last price as a string                 |
    //+------------------------------------------------------------------+
    string MqlTickVolume(const MqlTick &tick,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Volume:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-I64u",indent,"",w,header,tick.volume);
       /* Sample output:
          Volume: 0
       */
      }
    
    


    MqlTick構造体のミリ秒単位の時間:

    //+------------------------------------------------------------------+
    //| Return the time in milliseconds as a string                      |
    //+------------------------------------------------------------------+
    string MqlTickTimeMSC(const MqlTick &tick,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Time msc:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-s",indent,"",w,header,TimeMSC(tick.time_msc));
       /* Sample output:
          Time msc: 2023.07.19 21:21:09.732
       */
      }
    
    


    MqlTick構造体のティックフラグ:

    //+------------------------------------------------------------------+
    //| Return tick flags as a string                                    |
    //+------------------------------------------------------------------+
    string MqlTickFlags(const MqlTick &tick,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Flags:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Define a variable to describe tick flags
       string flags="";
    //--- Parse tick flags into components
       if((tick.flags & TICK_FLAG_BID)==TICK_FLAG_BID)
          flags+=(flags.Length()>0 ? "|" : "")+"BID";
       if((tick.flags & TICK_FLAG_ASK)==TICK_FLAG_ASK)
          flags+=(flags.Length()>0 ? "|" : "")+"ASK";
       if((tick.flags & TICK_FLAG_LAST)==TICK_FLAG_LAST)
          flags+=(flags.Length()>0 ? "|" : "")+"LAST";
       if((tick.flags & TICK_FLAG_VOLUME)==TICK_FLAG_VOLUME)
          flags+=(flags.Length()>0 ? "|" : "")+"VOLUME";
       if((tick.flags & TICK_FLAG_BUY)==TICK_FLAG_BUY)
          flags+=(flags.Length()>0 ? "|" : "")+"BUY";
       if((tick.flags & TICK_FLAG_SELL)==TICK_FLAG_SELL)
          flags+=(flags.Length()>0 ? "|" : "")+"SELL";
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-s",indent,"",w,header,flags);
       /* Sample output:
          Flags: BID|ASK
       */
      }
    
    


    MqlTick構造体の精度を高めた最終価格ボリューム:

    //+------------------------------------------------------------------+
    //| Return the volume for the Last price as a string                 |
    //+------------------------------------------------------------------+
    string MqlTickVolumeReal(const MqlTick &tick,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Volume Real:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-.2f",indent,"",w,header,tick.volume_real);
       /* Sample output:
          Volume Real: 0.00
       */
      }
    
    


    使用例

    ティックデータを操作ログに表示する関数を書きます。操作ログに表示される価格の精度を知るために、銘柄名を関数に渡します。VolumeフィールドとVolume Realフィールドには、最終価格ボリュームが含まれているため、Lastがゼロ(翻訳されていない)であれば、ボリュームを表示する意味はありません。ティックの配列からティックのインデックスを指定して表示できるようにするために、関数の入力パラメータにこのインデックスを渡します。デフォルトは-1であり、この値ではインデックスは表示されません。

    //+------------------------------------------------------------------+
    //| Logs descriptions of all fields of the MqlTick structure         |
    //| If Last==0, Last, Volume and Volume Real fields are not displayed|
    //+------------------------------------------------------------------+
    void MqlTickPrint(const string symbol,const MqlTick &tick,const bool short_entry=true,const uint header_width=0,const uint indent=0,int index=WRONG_VALUE)
      {
    //--- Declare the variable for storing the result
       string res="";
    //--- Get the number of decimal places
       int dg=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
       string num=(index==WRONG_VALUE ? "" : StringFormat("[%ld] ",index));
    //--- If it is a short entry, log the tick data in the Symbol TimeMSC, Bid, Ask, Last, Vol/VolR, Flags format
       if(short_entry)
         {
          //--- If Last is not zero, display Last, Volume and Volume Real, otherwise they are all zero and there is no point in displaying them
          string last=(tick.last!=0 ? StringFormat(", Last: %.*f, Vol: %I64u/%.2f",dg,tick.last,tick.volume,tick.volume_real) : "");
          res=StringFormat("%sTick %s Time: %s, Bid: %.*f, Ask: %.*f%s, %s",num,symbol,TimeMSC(tick.time_msc),dg,tick.bid,dg,tick.ask,last,MqlTickFlags(tick));
          Print(res);
         }
       /* Sample output (if Last is not zero):
          Tick GBPUSD Time: 2023.07.20 13:57:31.376, Bid: 1.28947, Ask: 1.28951, Last: 1.28947, Vol: 33/33.45, Flags: BID|ASK
          Sample output (if Last is zero):
          Tick GBPUSD Time: 2023.07.20 13:59:33.274, Bid: 1.28956, Ask: 1.28960, Flags: BID|ASK
       */
    //--- Otherwise
       else
         {
          //--- create a string describing all the data of the structure with indents and a given width of the header field 
          res=StringFormat("%s\n%s\n%s%s%s\n%s\n%s%s",
                           MqlTickTime(tick,header_width,indent),
                           MqlTickBid(symbol,tick,header_width,indent),
                           MqlTickAsk(symbol,tick,header_width,indent),
                           (tick.last!=0 ? "\n"+MqlTickLast(symbol,tick,header_width,indent) : ""),
                           (tick.last!=0 ? "\n"+MqlTickVolume(tick,header_width,indent) : ""),
                           MqlTickTimeMSC(tick,header_width,indent),
                           MqlTickFlags(tick,header_width,indent),
                           (tick.last!=0 ? "\n"+MqlTickVolumeReal(tick,header_width,indent) : "")
                          );
          //--- Display the obtained string in the journal
          Print(res);
         }
       /* Sample output (if Last is not zero):
          Time:         2023.07.20 14:42:33
          Bid:          1.28958
          Ask:          1.28962
          Last:         1.28947
          Volume:       33
          Time msc:     2023.07.20 14:42:33.401
          Flags:        BID|ASK
          Volume Real:  33.45
          
          Sample output (if Last is zero):
          Time:         2023.07.20 14:42:33
          Bid:          1.28958
          Ask:          1.28962
          Time msc:     2023.07.20 14:42:33.401
          Flags:        BID|ASK
       */
      }
    
    

    次は、直近の10ティックを、配列からのティックインデックスを示す短い形式で操作ログに出力する関数です。

    void OnStart()
      {
    //--- Declare a dynamic array of the MqlTick type
       MqlTick  array[];
    //--- If failed to get the last 10 ticks, display the error message and exit the method
       if(CopyTicks(Symbol(),array,COPY_TICKS_ALL,0,10)!=10)
         {
          Print("CopyTicks failed, error: ",(string)GetLastError());
          return;
         }
       Print("Last 10 tick (MqlTickPrint):");
       for(int i=0;i<(int)array.Size();i++)
          MqlTickPrint(Symbol(),array[i],true,0,0,i);
    
       /* Sample output:
          Last 10 tick (MqlTickPrint):
          [0] Tick GBPUSD Time: 2023.07.20 15:36:29.941, Bid: 1.28686, Ask: 1.28690, Flags: BID|ASK
          [1] Tick GBPUSD Time: 2023.07.20 15:36:29.970, Bid: 1.28688, Ask: 1.28692, Flags: BID|ASK
          [2] Tick GBPUSD Time: 2023.07.20 15:36:30.061, Bid: 1.28689, Ask: 1.28693, Flags: BID|ASK
          [3] Tick GBPUSD Time: 2023.07.20 15:36:30.212, Bid: 1.28688, Ask: 1.28692, Flags: BID|ASK
          [4] Tick GBPUSD Time: 2023.07.20 15:36:30.259, Bid: 1.28689, Ask: 1.28693, Flags: BID|ASK
          [5] Tick GBPUSD Time: 2023.07.20 15:36:30.467, Bid: 1.28682, Ask: 1.28686, Flags: BID|ASK
          [6] Tick GBPUSD Time: 2023.07.20 15:36:30.522, Bid: 1.28681, Ask: 1.28685, Flags: BID|ASK
          [7] Tick GBPUSD Time: 2023.07.20 15:36:30.572, Bid: 1.28673, Ask: 1.28677, Flags: BID|ASK
          [8] Tick GBPUSD Time: 2023.07.20 15:36:30.574, Bid: 1.28672, Ask: 1.28676, Flags: BID|ASK
          [9] Tick GBPUSD Time: 2023.07.20 15:36:30.669, Bid: 1.28674, Ask: 1.28678, Flags: BID|ASK
       */
      }
    
    

    次は、左インデント2文字、ヘッダーフィールド幅14文字で、配列の最後の4ティックをログに表示する関数です。

    void OnStart()
      {
    //--- Declare a dynamic array of the MqlTick type
       MqlTick  array[];
    //--- If the last 4 ticks are not received in the array, display an error message and leave
       if(CopyTicks(Symbol(),array,COPY_TICKS_ALL,0,4)!=4)
         {
          Print("CopyTicks failed, error: ",(string)GetLastError());
          return;
         }
       Print("Last 4 tick (MqlTickPrint):");
       for(int i=0;i<(int)array.Size();i++)
         {
          PrintFormat("Tick[%lu] %s:",i,Symbol());
          MqlTickPrint(Symbol(),array[i],false,14,2);
         }
    
       /* Sample output:
          Last 4 tick (MqlTickPrint):
          Tick[0] GBPUSD:
            Time:         2023.07.20 17:04:51
            Bid:          1.28776
            Ask:          1.28780
            Time msc:     2023.07.20 17:04:51.203
            Flags:        BID|ASK
          Tick[1] GBPUSD:
            Time:         2023.07.20 17:04:51
            Bid:          1.28772
            Ask:          1.28776
            Time msc:     2023.07.20 17:04:51.331
            Flags:        BID|ASK
          Tick[2] GBPUSD:
            Time:         2023.07.20 17:04:51
            Bid:          1.28771
            Ask:          1.28775
            Time msc:     2023.07.20 17:04:51.378
            Flags:        BID|ASK
          Tick[3] GBPUSD:
            Time:         2023.07.20 17:04:51
            Bid:          1.28772
            Ask:          1.28776
            Time msc:     2023.07.20 17:04:51.680
            Flags:        BID|ASK
       */
      }
    
    


    MqlRates構造体

    以下は価格、数量、スプレッドの情報を格納するための構造体です。

    struct MqlRates
      {
       datetime time;         // period start time
       double   open;         // open price
       double   high;         // high price for the period
       double   low;          // low price for the period
       double   close;        // close price
       long     tick_volume;  // tick volume
       int      spread;       // spread
       long     real_volume;  // exchange volume
      };
    

    MqlRates、表示メソッド

    MqlRatesは、過去のデータの単一バーのデータを保存するための構造体です。この構造体は、CopyRates()関数を使って埋めることができます。現在のバーのデータを取得するには、インデックスを0、コピーしたバーの数を1として、関数呼び出しの最初のフォームを使用することができます。いずれにせよ、この関数はMqlRates型で配列を埋めます。これは、ArrayPrint()を使ってこの配列を操作ログに表示するのが便利だという結論につながります。

    void OnStart()
      {
    //---
       MqlRates array[];
       if(CopyRates(Symbol(),PERIOD_CURRENT,0,1,array)!=1)
         {
          Print("CopyRates failed, error: ",(string)GetLastError());
          return;
         }
       Print("Current bar ",Symbol()," ",StringSubstr(EnumToString(Period()),7)," (ArrayPrint):");
       ArrayPrint(array);
       /* Sample output:
          Current bar GBPUSD H1 (ArrayPrint):
                           [time]  [open]  [high]   [low] [close] [tick_volume] [spread] [real_volume]
          [0] 2023.07.21 04:00:00 1.28763 1.28765 1.28663 1.28748          2083        7             0
       */
      }
    
    

    したがって、直近の10本のバーをコピーするには、コピーするデータ数を10に等しく指定するだけでよくなります。

    void OnStart()
      {
    //---
       MqlRates array[];
       if(CopyRates(Symbol(),PERIOD_CURRENT,0,10,array)!=10)
         {
          Print("CopyRates failed, error: ",(string)GetLastError());
          return;
         }
       Print("Data of the last 10 bars: ",Symbol()," ",StringSubstr(EnumToString(Period()),7)," (ArrayPrint):");
       ArrayPrint(array);
       /* Sample output:
          Data of the last 10 bars: GBPUSD H1 (ArrayPrint):
                           [time]  [open]  [high]   [low] [close] [tick_volume] [spread] [real_volume]
          [0] 2023.07.20 20:00:00 1.28530 1.28676 1.28512 1.28641          2699        4             0
          [1] 2023.07.20 21:00:00 1.28641 1.28652 1.28557 1.28587          1726        3             0
          [2] 2023.07.20 22:00:00 1.28587 1.28681 1.28572 1.28648          2432        3             0
          [3] 2023.07.20 23:00:00 1.28648 1.28683 1.28632 1.28665           768        4             0
          [4] 2023.07.21 00:00:00 1.28663 1.28685 1.28613 1.28682           396        1             0
          [5] 2023.07.21 01:00:00 1.28684 1.28732 1.28680 1.28714           543        8             0
          [6] 2023.07.21 02:00:00 1.28714 1.28740 1.28690 1.28721           814        2             0
          [7] 2023.07.21 03:00:00 1.28721 1.28774 1.28685 1.28761          2058        5             0
          [8] 2023.07.21 04:00:00 1.28763 1.28791 1.28663 1.28774          3480        7             0
          [9] 2023.07.21 05:00:00 1.28774 1.28776 1.28769 1.28774            18        7             0
       */
      }
    
    

    すべてが同じです。操作ログには長いデータのリストがあります。テーブルのヘッダーが操作ログウィンドウの上端に隠れてしまうと、表示されている数字が何を指しているのかわからなくなってしまいます。

    構造体フィールドの説明を返して、このデータをターミナル操作ログに表示する独自の関数を書いてみましょう。


    MqlRates構造体データを操作するための関数

    私たちのカスタム関数は、構造体の各フィールドのテキスト説明を返します。各記述にはヘッダーと実際のデータがあります。関数から返された文字列に対して、左端からのインデントとヘッダーフィールドの幅を設定することができます。


    Time

    Timeは、期間の開始時間です。言い換えれば、構造体に書き込まれたデータが要求された銘柄とチャート期間のバーの開始時間です。

    //+------------------------------------------------------------------+
    //| Return the bar opening time as a string                          |
    //+------------------------------------------------------------------+
    string MqlRatesTime(const MqlRates &rates,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Time:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-s",indent,"",w,header,(string)rates.time);
       /* Sample output:
          Time: 2023.07.21 06:00:00
       */
      }
    
    


    Open

    構造体に書き込まれたデータが要求された銘柄とチャート期間のバー始値です。

    //+------------------------------------------------------------------+
    //| Return the bar open price as a string                            |
    //+------------------------------------------------------------------+
    string MqlRatesOpen(const string symbol,const MqlRates &rates,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Open:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Get the number of decimal places
       int dg=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,rates.open);
       /* Sample output:
          Open: 1.28812
       */
      }
    
    


    High

    高値 - 構造体に書き込まれたデータが要求された、銘柄とチャート期間のバーの最高値です。

    //+------------------------------------------------------------------+
    //| Return the High bar price as a string                            |
    //+------------------------------------------------------------------+
    string MqlRatesHigh(const string symbol,const MqlRates &rates,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="High:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Get the number of decimal places
       int dg=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,rates.high);
       /* Sample output:
          High: 1.28859
       */
      }
    
    


    Low

    安値 - 構造体に書き込まれたデータが要求された銘柄とチャート期間のバーの最安値です。

    //+------------------------------------------------------------------+
    //| Return the bar Low price as a string                             |
    //+------------------------------------------------------------------+
    string MqlRatesLow(const string symbol,const MqlRates &rates,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Low:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Get the number of decimal places
       int dg=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,rates.low);
       /* Sample output:
          Low: 1.28757
       */
      }
    
    


    Close

    終値 - 構造体に書き込まれたデータが要求された銘柄とチャート期間のバーの終値です。
    現在のバーの終値は、チャートがどの価格に基づいているかに応じて、現在の買値または最終価格と等しくなります。

    //+------------------------------------------------------------------+
    //| Return the bar close price as a string                           |
    //+------------------------------------------------------------------+
    string MqlRatesClose(const string symbol,const MqlRates &rates,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Close:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Get the number of decimal places
       int dg=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,rates.close);
       /* Sample output:
          Close: 1.28770
       */
      }
    
    


    TickVolume

    バーのティックボリュームです。

    //+------------------------------------------------------------------+
    //| Return the tick volume of a bar as a string                      |
    //+------------------------------------------------------------------+
    string MqlRatesTickVolume(const MqlRates &rates,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Tick Volume:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-lld",indent,"",w,header,rates.tick_volume);
       /* Sample output:
          Tick Volume: 963
       */
      }
    
    


    Spread

    バーのスプレッドです。

    //+------------------------------------------------------------------+
    //| Return the bar spread as a string                                |
    //+------------------------------------------------------------------+
    string MqlRatesSpread(const MqlRates &rates,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Spread:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-ld",indent,"",w,header,rates.spread);
       /* Sample output:
          Spread: 4
       */
      }
    
    


    RealVolume

    バーの取引量です。

    //+------------------------------------------------------------------+
    //| Return the bar exchange volume as a string                       |
    //+------------------------------------------------------------------+
    string MqlRatesRealVolume(const MqlRates &rates,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Real Volume:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-lld",indent,"",w,header,rates.real_volume);
       /* Sample output:
          Real Volume: 0
       */
      }
    
    


    使用例

    操作ログに過去10本のバーのデータを表示する関数を書いてみましょう。

    void OnStart()
      {
    //--- Copy the last 10 data bars to the MqlRates array
       MqlRates array[];
       if(CopyRates(Symbol(),PERIOD_CURRENT,0,10,array)!=10)
         {
          Print("CopyRates failed, error: ",(string)GetLastError());
          return;
         }
    
    //--- Set the indexing of the array like a timeseries
       ArraySetAsSeries(array,true);
    //--- Print short entries in the journal in a loop through the array with the received bar data
       for(int i=0;i<(int)array.Size();i++)
          MqlRatesPrint(Symbol(),PERIOD_CURRENT,array[i],true,0,0,i);
       
       /* Sample output:
          GBPUSD H1[0]: 2023.07.21 14:00:00, O: 1.28451, H: 1.28541, L: 1.28451, C: 1.28501, S:  4, V:   821, RV: 0
          GBPUSD H1[1]: 2023.07.21 13:00:00, O: 1.28678, H: 1.28685, L: 1.28418, C: 1.28452, S:  1, V:  3602, RV: 0
          GBPUSD H1[2]: 2023.07.21 12:00:00, O: 1.28581, H: 1.28696, L: 1.28557, C: 1.28678, S:  1, V:  4807, RV: 0
          GBPUSD H1[3]: 2023.07.21 11:00:00, O: 1.28695, H: 1.28745, L: 1.28401, C: 1.28581, S:  1, V:  7440, RV: 0
          GBPUSD H1[4]: 2023.07.21 10:00:00, O: 1.28933, H: 1.28960, L: 1.28651, C: 1.28696, S:  1, V:  8883, RV: 0
          GBPUSD H1[5]: 2023.07.21 09:00:00, O: 1.28788, H: 1.29040, L: 1.28753, C: 1.28934, S:  1, V:  5474, RV: 0
          GBPUSD H1[6]: 2023.07.21 08:00:00, O: 1.28794, H: 1.28848, L: 1.28713, C: 1.28787, S:  1, V:  1885, RV: 0
          GBPUSD H1[7]: 2023.07.21 07:00:00, O: 1.28762, H: 1.28808, L: 1.28744, C: 1.28794, S:  4, V:   878, RV: 0
          GBPUSD H1[8]: 2023.07.21 06:00:00, O: 1.28812, H: 1.28859, L: 1.28743, C: 1.28760, S:  3, V:  1112, RV: 0
          GBPUSD H1[9]: 2023.07.21 05:00:00, O: 1.28774, H: 1.28820, L: 1.28747, C: 1.28812, S:  7, V:  1671, RV: 0
       */
      }
    
    

    必要な量のデータを配列にコピーした後、それを時系列のようにインデックス付けして、データがターミナルでチャートの棒グラフと同じように表示されるようにします。インデックスがゼロのデータは現在のバーに対応します。

    この関数は、操作ログの最後の4バーを、ヘッダーフィールドを2文字左にインデントし、タイトルフィールドの幅を14文字にして、表形式で表示します。

    void OnStart()
      {
    //--- Copy the last 4 data bars to the MqlRates array
       MqlRates array[];
       if(CopyRates(Symbol(),PERIOD_CURRENT,0,4,array)!=4)
         {
          Print("CopyRates failed, error: ",(string)GetLastError());
          return;
         }
    
    //--- Set the indexing of the array like a timeseries
       ArraySetAsSeries(array,true);
    //--- Print short entries in the journal in a loop through the array with the received bar data
       for(int i=0;i<(int)array.Size();i++)
          MqlRatesPrint(Symbol(),PERIOD_CURRENT,array[i],false,14,2,i);
       
       /* Sample output:
          GBPUSD H1[0]:
            Time:         2023.07.21 14:00:00
            Open:         1.28451
            High:         1.28541
            Low:          1.28451
            Close:        1.28491
            Tick Volume:  1098
            Spread:       4
            Real Volume:  0
          GBPUSD H1[1]:
            Time:         2023.07.21 13:00:00
            Open:         1.28678
            High:         1.28685
            Low:          1.28418
            Close:        1.28452
            Tick Volume:  3602
            Spread:       1
            Real Volume:  0
          GBPUSD H1[2]:
            Time:         2023.07.21 12:00:00
            Open:         1.28581
            High:         1.28696
            Low:          1.28557
            Close:        1.28678
            Tick Volume:  4807
            Spread:       1
            Real Volume:  0
          GBPUSD H1[3]:
            Time:         2023.07.21 11:00:00
            Open:         1.28695
            High:         1.28745
            Low:          1.28401
            Close:        1.28581
            Tick Volume:  7440
            Spread:       1
            Real Volume:  0
       */
      }
    
    


    MqlBookInfo構造体

    市場深度データを提供する構造体です。

    struct MqlBookInfo
      {
       ENUM_BOOK_TYPE   type;            // order type from ENUM_BOOK_TYPE enumeration
       double           price;           // price
       long             volume;          // volume
       double           volume_real;     // volume with increased accuracy
      };
    

    この構造体を使うには、この型の変数を宣言するだけで済みます。市場深度はすべての金融商品について利用できるわけではありません。市場深度のデータを受信する前に、MarketBookAdd() を使用して購読する必要があります。完了したら、MarketBookRelease()を使用して、購読を解除します。EAプログラムには、受信された通知を処理するOnBookEvent() void関数を含める必要があります。


    MqlBookInfo、表示メソッド

    市場深度の各受信には、その中の注文リストの受信が含まれます。これはデータ配列です。したがって、ArrayPrint() を使用して、市場深度のスナップショットを表示できます。

    void OnStart()
      {
    //--- Declare an array to store a snapshot of the market depth
       MqlBookInfo array[];
    //--- If unable to open the market depth and subscribe to its events, inform of that and leave
       if(!MarketBookAdd(Symbol()))
         {
          Print("MarketBookAdd failed, error: ",(string)GetLastError());
          return;
         }
    //--- If unable to obtain the market depth entries, inform of that and leave
       if(!MarketBookGet(Symbol(),array))
         {
          Print("MarketBookGet failed, error: ",(string)GetLastError());
          return;
         }
    //--- Print the header in the journal and the market depth snapshot from the array below
       Print("MarketBookInfo by ",Symbol(),":");
       ArrayPrint(array);
    //--- If unable to unsubscribe from the market depth, send an error message to the journal
       if(!MarketBookRelease(Symbol()))
          Print("MarketBookRelease failed, error: ",(string)GetLastError());
       /* Sample output:
          MarketBookInfo by GBPUSD:
              [type] [price] [volume] [volume_real]
          [0]      1 1.28280      100     100.00000
          [1]      1 1.28276       50      50.00000
          [2]      1 1.28275       20      20.00000
          [3]      1 1.28273       10      10.00000
          [4]      2 1.28268       10      10.00000
          [5]      2 1.28266       20      20.00000
          [6]      2 1.28265       50      50.00000
          [7]      2 1.28260      100     100.00000
       */
      }
    
    

    おわかりのように、ここでのリクエストの種類は数値で表されており、これは知覚するのに不便です。市場深度フィールドに関する記述を返す関数を、前述した他の構造体ですでに受け入れられているスタイルで書いてみましょう。


    MqlBookInfo構造体データを操作するための関数

    MqlBookInfo構造体のフィールドの文字列表現を返すすべての関数は、対応する構造体のフィールドを記述するために上で説明した関数と同じスタイルになります。これらのメソッドについて考えてみましょう。


    MqlBookInfo市場深度構造体の注文タイプ:

    //+------------------------------------------------------------------+
    //| Return the order type in the market depth as a string            |
    //+------------------------------------------------------------------+
    string MqlBookInfoType(const MqlBookInfo &book,const uint header_width=0,const uint indent=0)
      {
    //--- Get the value of the order type
       ENUM_BOOK_TYPE book_type=book.type;
    //--- "Cut out" the type from the string obtained from enum
       string type=StringSubstr(EnumToString(book_type),10);
    //--- Convert all obtained symbols to lower case and replace the first letter from small to capital
       if(type.Lower())
          type.SetChar(0,ushort(type.GetChar(0)-0x20));
    //--- Replace all underscore characters with space in the resulting line
       StringReplace(type,"_"," ");
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Type:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-s",indent,"",w,header,type);
       /* Sample output:
          Type: Sell
       */
      }
    
    


    MqlBookInfo市場深度構造体の注文価格:

    //+------------------------------------------------------------------+
    //| Return the order price in the market depth as a string           |
    //+------------------------------------------------------------------+
    string MqlBookInfoPrice(const string symbol,const MqlBookInfo &book,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Price:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Get the number of decimal places
       int dg=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-.*f",indent,"",w,header,dg,book.price);
       /* Sample output:
          Price: 1.28498
       */
      }
    
    


    MqlBookInfo市場深度構造体の注文量:

    //+------------------------------------------------------------------+
    //| Return the order volume in the market depth as a string          |
    //+------------------------------------------------------------------+
    string MqlBookInfoVolume(const MqlBookInfo &book,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Volume:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-lld",indent,"",w,header,book.volume);
       /* Sample output:
          Volume: 100
       */
      }
    
    


    正確さを増したボリューム:

    //+------------------------------------------------------------------+
    //| Return the order volume with increased accuracy as a string      |
    //+------------------------------------------------------------------+
    string MqlBookInfoVolumeReal(const MqlBookInfo &book,const uint header_width=0,const uint indent=0)
      {
    //--- Define the header text and the width of the header field
    //--- If the header width is passed to the function equal to zero, then the width will be the size of the header line + 1
       string header="Volume Real:";
       uint w=(header_width==0 ? header.Length()+1 : header_width);
    //--- Return the property value with a header having the required width and indentation
       return StringFormat("%*s%-*s%-.2f",indent,"",w,header,book.volume_real);
       /* Sample output:
          Volume Real: 100.00
       */
      }
    
    


    使用例:

    では、MqlBookInfo構造体のすべてのデータを操作ログに出力する関数を書いてみましょう。一行形式と表形式の2種類の表示が可能です。

    //+------------------------------------------------------------------+
    //| Logs a description of all fields of the MqlRates structure       |
    //+------------------------------------------------------------------+
    void MqlBookInfoPrint(const string symbol,const MqlBookInfo &book,
                          const bool short_entry=true,const uint header_width=0,const uint indent=0,int index=WRONG_VALUE)
      {
    //--- Declare the variable for storing the result
       string res="";
    //--- Get the number of decimal places and the string index value
       int dg=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
       string num=(index==WRONG_VALUE ? "" : StringFormat("[%02ld]",index));
       
    //--- "Cut out" the type from the order type name string obtained from enum
       string type=StringSubstr(EnumToString(book.type),10);
    //--- Convert all obtained symbols to lower case and replace the first letter from small to capital
       if(type.Lower())
          type.SetChar(0,ushort(type.GetChar(0)-0x20));
    //--- Replace all underscore characters with space in the resulting line
       StringReplace(type,"_"," ");
       
    //--- If it is a short entry, log the market depth data in the [index] Type Price V VR format
       if(short_entry)
         {
          res=StringFormat("%-8s%-11s%- *.*f Volume%- 5lld Real%- 8.2f",
                           num,type,dg+4,dg,book.price,book.volume,book.volume_real);
          Print(res);
         }
       /* Sample output:
          [00]    Sell        1.28598  Volume 100  Real 100.00 
       */
    //--- Otherwise
       else
         {
          //--- create a string describing all the data of the structure with indents and a given width of the header field 
          res=StringFormat("Market Book by %s %s:\n%s\n%s\n%s\n%s",symbol,num,
                           MqlBookInfoType(book,header_width,indent),
                           MqlBookInfoPrice(symbol,book,header_width,indent),
                           MqlBookInfoVolume(book,header_width,indent),
                           MqlBookInfoVolumeReal(book,header_width,indent)
                          );
          //--- Display the obtained string in the journal
          Print(res);
         }
       /* Sample output
          BoolInfo by GBPUSD [00]:
            Type:         Sell
            Price:        1.28588
            Volume:       100
            Volume Real:  100.00
       */
      }
    
    

    市場深度は単一の注文ではなく、これらの注文のリストを配列で受け取るため、ここでのメインモードは、操作ログへの出力を1行にまとめることです。従って、この配列を操作ログに表示するには、以下の関数を使います。

    //+----------------------------------------------------------------------+
    //| Display the market depth entries in the journal in the short format  |
    //+----------------------------------------------------------------------+
    void MqlBookInfoPrintShort(const string symbol,const MqlBookInfo &book_array[])
      {
       PrintFormat("Market Book by %s:",symbol);
       for(int i=0;i<(int)book_array.Size();i++)
          MqlBookInfoPrint(symbol,book_array[i],true,0,0,i);
      }
    
    

    この関数は、市場深度の注文の配列を受け取り、その配列をループして、短い出力を使用して、すべての市場深度データを操作ログに表示します。

    次は、この関数の使い方と結果を示す関数です。

    void OnStart()
      {
    //--- Declare an array to store a snapshot of the market depth
       MqlBookInfo array[];
    //--- If unable to open the market depth and subscribe to its events, inform of that and leave
       if(!MarketBookAdd(Symbol()))
         {
          Print("MarketBookAdd failed, error: ",(string)GetLastError());
          return;
         }
    //--- If unable to obtain the market depth entries, inform of that and leave
       if(!MarketBookGet(Symbol(),array))
         {
          Print("MarketBookGet failed, error: ",(string)GetLastError());
          return;
         }
    //--- Print in the journal a snapshot of the market depth from the array in the form of strings
       MqlBookInfoPrintShort(Symbol(),array);
    
    //--- If unable to unsubscribe from the market depth, send an error message to the journal
       if(!MarketBookRelease(Symbol()))
          Print("MarketBookRelease failed, error: ",(string)GetLastError());
       
       /* Sample output:
          Market Book by GBPUSD:
          [00]    Sell        1.28674  Volume 100  Real 100.00 
          [01]    Sell        1.28668  Volume 50   Real 50.00  
          [02]    Sell        1.28666  Volume 20   Real 20.00  
          [03]    Sell        1.28664  Volume 10   Real 10.00  
          [04]    Buy         1.28657  Volume 10   Real 10.00  
          [05]    Buy         1.28654  Volume 20   Real 20.00  
          [06]    Buy         1.28653  Volume 50   Real 50.00  
          [07]    Buy         1.28646  Volume 100  Real 100.00 
       */
      }
    
    

    しかし、同じデータを表形式で表示する必要がある場合もあります。そのためには、次の関数を使うことができます。

    //+------------------------------------------------------------------------+
    //| Display the market depth entries in the journal in the tabular format  |
    //+------------------------------------------------------------------------+
    void MqlBookInfoPrintTable(const string symbol,const MqlBookInfo &book_array[],const uint header_width=0,const uint indent=0)
      {
       for(int i=0;i<(int)book_array.Size();i++)
          MqlBookInfoPrint(symbol,book_array[i],false,header_width,indent,i);
      }
    
    

    次は、この関数の使い方と結果を示す関数です。

    void OnStart()
      {
    //--- Declare an array to store a snapshot of the market depth
       MqlBookInfo array[];
    //--- If unable to open the market depth and subscribe to its events, inform of that and leave
       if(!MarketBookAdd(Symbol()))
         {
          Print("MarketBookAdd failed, error: ",(string)GetLastError());
          return;
         }
    //--- If unable to obtain the market depth entries, inform of that and leave
       if(!MarketBookGet(Symbol(),array))
         {
          Print("MarketBookGet failed, error: ",(string)GetLastError());
          return;
         }
    //--- Print in the journal a snapshot of the market depth from the array in the form of strings
       MqlBookInfoPrintTable(Symbol(),array,14,2);
    
    //--- If unable to unsubscribe from the market depth, send an error message to the journal
       if(!MarketBookRelease(Symbol()))
          Print("MarketBookRelease failed, error: ",(string)GetLastError());
       
       /* Sample output:
          Market Book by GBPUSD [00]:
            Type:         Sell
            Price:        1.28627
            Volume:       100
            Volume Real:  100.00
          Market Book by GBPUSD [01]:
            Type:         Sell
            Price:        1.28620
            Volume:       50
            Volume Real:  50.00
          Market Book by GBPUSD [02]:
            Type:         Sell
            Price:        1.28618
            Volume:       20
            Volume Real:  20.00
          Market Book by GBPUSD [03]:
            Type:         Sell
            Price:        1.28615
            Volume:       10
            Volume Real:  10.00
          Market Book by GBPUSD [04]:
            Type:         Buy
            Price:        1.28610
            Volume:       10
            Volume Real:  10.00
          Market Book by GBPUSD [05]:
            Type:         Buy
            Price:        1.28606
            Volume:       20
            Volume Real:  20.00
          Market Book by GBPUSD [06]:
            Type:         Buy
            Price:        1.28605
            Volume:       50
            Volume Real:  50.00
          Market Book by GBPUSD [07]:
            Type:         Buy
            Price:        1.28599
            Volume:       100
            Volume Real:  100.00
       */
      }
    
    


    結論

    今回は、MqlDateTimeMqlTickMqlRatesMqlBookInfoの4つの構造体のフィールドの表示について考えました。作成された関数は、各構造体のフィールドの説明をHeader-Data形式の文字列として返し、表示したり別の関数内で使用したりできます。すべての関数は自立しており、カスタムプログラムですぐに「そのまま」使用できます。次のステップは、取引構造体の説明と表示です。


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

    離散ハートレー変換 離散ハートレー変換
    この記事では、スペクトル分析と信号処理の方法の1つである離散ハートレー変換について説明します。信号のフィルタリング、スペクトルの分析などが可能になります。DHTの能力は離散フーリエ変換の能力に劣りません。ただし、DFTとは異なり、DHTは実数のみを使用するため、実際の実装がより便利であり、その適用結果はより視覚的です。
    StringFormat():レビューと既成の例 StringFormat():レビューと既成の例
    この記事では、PrintFormat()関数のレビューを続けます。StringFormat()を使った文字列の書式設定と、そのプログラムでのさらなる使用法について簡単に説明します。また、ターミナル操作ログに銘柄データを表示するためのテンプレートも作成します。この記事は、初心者にも経験豊富な開発者にも役立つでしょう。
    ニューラルネットワークが簡単に(第49回):Soft Actor-Critic ニューラルネットワークが簡単に(第49回):Soft Actor-Critic
    連続行動空間の問題を解決するための強化学習アルゴリズムについての議論を続けます。この記事では、Soft Actor-Critic (SAC)アルゴリズムについて説明します。SACの主な利点は、期待される報酬を最大化するだけでなく、行動のエントロピー(多様性)を最大化する最適な方策を見つけられることです。
    PrintFormat()を調べてすぐ使える例を適用する PrintFormat()を調べてすぐ使える例を適用する
    この記事は、初心者にも経験豊富な開発者にも役立つでしょう。PrintFormat()関数について調べ、文字列フォーマットの例を分析し、ターミナルのログに様々な情報を表示するためのテンプレートを書きます。