English Русский 中文 Español Deutsch Português
preview
PrintFormat()を調べてすぐ使える例を適用する

PrintFormat()を調べてすぐ使える例を適用する

MetaTrader 5 | 7 12月 2023, 14:40
444 0
Artyom Trishkin
Artyom Trishkin

ログやモニター画面に値を表示するのは、「Hello, world」よりも複雑なものを表示しなくていい限り、シンプルで馴染みのある操作です。しかし、遅かれ早かれ、あまり需要のない値やプロパティをフォーマットして出力する必要がある状況が発生します。もちろん、MQL5のヘルプで調べることもできます。

しかし、場合によっては、MetaTrader 5ターミナルによって提供されるあらゆる種類の情報を表示するための、既製のレシピのコレクションがほしいことがあるでしょう。この記事では、PrintFormat関数の呼び出しの複雑さを理解し、コードに挿入するだけですぐに使えるようになるテンプレートを書いてみます。


内容


はじめに

ターミナルで動作するアプリケーションは、その状態や環境の状態をユーザーに知らせることができなければなりません。このようなデータは、取引ターミナルの[エキスパート]タブにあるプログラムログに常に出力されます。その後、プログラムログを解析して分析する場合、すべてのエントリが読みやすい形式であることが重要です。情報の読み取りと検索のしやすさはこれに依存するためです。

MQL5言語には、行または行に変換されたデータをログに出力するPrint()関数があります。短いログならこれで十分です。しかし、大量のデータをログに送るのであれば、データが理解しやすい形でフォーマットされていることが望ましくなります。

データヘッダー(説明)とそれに対応する値がフォーマットされずに1行に書かれている場合、短いリストではデータを読むことは困難ではありませんが、データがたくさんあり、それらがすべてつながり、記述の長さや意味が異なれば、これらはすべて単なる長い情報の流れになってしまいます。このようなデータは、すべてのヘッダーが同じ幅を持ち(ヘッダー列)、ヘッダーに対応するデータがヘッダーから同じ距離に位置する(データ列)、単一の表形式にフォーマットされることが望ましくなります。PrintFormat()はまさにそれを達成します。指定されたフォーマットに従って、文字と値のセットをフォーマットし、EA操作ログに表示することができます。


PrintFormat()のしくみ

PrintFormat()関数は、入力として、データが表示されるべき形式を記述するフォーマット文字列と、ログに表示される方法に従って結果の文字列に配置されるフォーマット文字列に対応するデータのセットを受け取ります。各値の出力形式は自由に設定できます。簡単に言うと、こんな感じです。

("%Value1 is to be displayed like this%Value2 is to be displayed like this%Value3 is to be displayed like this ... ... %ValueN is to be displayed like this some text", Value1, Value2, Value3, ... ..., ValueN)

ご覧のように、特定のデータをテキストで表示する必要がある場所には、出力データの値を表示する方法を記述したフォーマット行が必要です。各フォーマット文字列の前には%が付いており、その後に続くのが出力フォーマットの説明であることを知らせます。フォーマット記述の間に任意のテキストを書くことができます(上の例では末尾の「some text」)。フォーマット文字とテキストで行の入力を終えたら、フォーマット行に記述された出力フォーマットの順番で、データをカンマで区切ります。上の例では、各フォーマットの説明と対応する値が同じ色でマークされています。

まず、ログに表示するテキストを書きます。次に、テキスト内にデータ出力フォーマットの記号を入力します。

例:("%This text will be located in the 50 character wide column%these double data will be in the next column and left aligned", string_variable_with_text_of_the_first_column, double data_of_the_second_column);

もちろん、特殊なフォーマット文字があるため、これらすべてを文章で説明する必要はありません。これらは厳密に指定された順序で並べられるべきですが、フォーマット行にすべてが存在してはなりません。

フォーマット文字列は左から右へと読み込まれます。最初のフォーマット指定(もしあれば)に遭遇すると、フォーマット文字列の後の最初のパラメータの値が、指定された指定に従って変換されて表示されます。2つ目のフォーマット指定は、2つ目のパラメータを変換して表示させます。これが、フォーマット文字列の終わりまで続きます。

フォーマットは以下の形式で指定されます。

         %[flags][width][.precision][{h | l | ll | I32 | I64}]type

フォーマット文字列の各項目についてヘルプに書かれていることを見て、さらに詳しく説明します。

パーセント記号(%):新しいフォーマット文字列を開始します。この記号の後に、少なくとも1つの指定子を指定しなければなりません。そして、型指定子(type)が、フォーマットされた出力のための唯一の必須フィールドであることを理解することが重要です。つまり、ある行に「%」が入力されている場合、「%」の後にはこの場所に表示されるデータの種類を示さなければなりません(または、テキスト中に「%」記号を書くためは、あと1つのパーセント記号を書きます。つまり、これが新しいフォーマット行の始まりではなく、単にテキスト中のパーセント記号であることを示すには、「%%」という組み合わせを書く必要があります)。

フラグ(flags):

  • - (マイナス記号):行テキストは指定された幅内で左揃えになります。幅は、フラグに続くwidth指定子で指定します。「%-10」は、テキストがフィールドの左端に整列され、幅が10文字であることを意味します。この行の次のテキストは、10文字の同じフィールドの右端から始まります。この10文字フィールド内に表示されるテキストが10文字より長い場合、次のテキストはフィールドではなくテキストの最後に配置されます。言い換えれば、フィールドの幅は、そこに配置されたテキストのサイズに合わせて拡大されます。テキストがフィールドの幅に沿って切り捨てられることはありません。逆に、フィールドがテキストの長さに沿って拡大するのです。
    void OnStart()
      {
    //--- Declare the variables to be printed
       string   header="";  // Data header
       double   value1=0;   // First value
       double   value2=0;   // Second value
       
    //--- First line with a header of less than 10 characters and data in 20-character fields
    //--- The header and data are pressed to the left edge of their field
       header="10characters";
       value1=10000000;
       value2=20000000;
       PrintFormat("%-10s%-20ld%-20lld",header,(int)value1,(long)value2);
       
    //--- Second line with a header of more than 10 characters and data in 20-character fields
    //--- The header and data are pressed to the left edge of their field
       header="Over10characters";
       value1=10000000;
       value2=20000000;
       PrintFormat("%-10s%-20ld%-20lld",header,(int)value1,(long)value2);
    
       /* Sample output:
          10characters10000000            20000000            
          Over10characters10000000            20000000            
       */
      }
    
    


  • +(プラス記号):符号付き型の場合、出力データの値に応じて+または-の符号が常に表示されます(例:+222、-12.35)。2行のフォーマットされたテキストが連続し、同じデータ列の一番上の行では出力データの値が正で、一番下の行では負である場合、視覚的に値が1文字分(「-」の分)相対的にずれます。以下では、この視覚的な不便さを解消するフラグについて考えてみます。
    void OnStart()
      {
    //--- Declare the variables to be printed
       string   header="";  // Data header
       double   value1=0;   // First value
       double   value2=0;   // Second value
       
    //--- The first line with a header in a 16-character field and data in 20-character fields
    //--- The header and data are pressed to the left edge.
    //--- Data values of the second field are displayed with +/- signs
       header="Header1";
       value1=-10000000;
       value2=20000000;
       PrintFormat("%-16s%-+20ld%-20lld",header,(int)value1,(long)value2);
       
    //--- The second line with a header in a 16-character field and data in 20-character fields
    //--- The header and data are pressed to the left edge.
    //--- Data values of the second field are displayed with +/- signs
       header="Header2";
       value1=10000000;
       value2=-20000000;
       PrintFormat("%-16s%-+20ld%-20lld",header,(int)value1,(long)value2);
       
       /* Sample output:
          Header1      -10000000           20000000            
          Header2      +10000000           -20000000           
       */
      }
    
    


  • 0(ゼロ):指定されたフィールド幅内の出力値の前にゼロが加えられます。フラグ0が整数フォーマット(i, u, x, o, d)で指定され、精度指定(例:%04.d)が設定されている場合、0は無視されます。言い換えれば、精度フォーマット(最小出力文字数)が与えられている整数型では、このフォーマット(フォーマット0)の先頭のゼロは優先されません。フィールド全体を埋めるため、精度の形式と矛盾するからです。
    void OnStart()
      {
    //--- Declare the variables to be printed
       string   header="";  // Data header
       double   value1=0;   // First value
       double   value2=0;   // Second value
       
    //--- The first line with a header in a 16-character field and data in 20-character fields
    //--- The header and data are pressed to the left edge.
    //--- Data values of the second field are displayed with +/- signs
    //--- The data values of the third field are pressed to the right edge with leading zeros added.
       header="Header1";
       value1=-10000000;
       value2=20000000;
       PrintFormat("%-16s%-+20ld%020lld",header,(int)value1,(long)value2);
       
    //--- The second line with a header in a 16-character field and data in 20-character fields
    //--- The header and data of the second field are pressed to the left edge.
    //--- Data values of the second field are displayed with +/- signs
    //--- The data values of the third field are pressed to the right edge with leading zeros added.
       header="Header2";
       value1=10000000;
       value2=-20000000;
       PrintFormat("%-16s%-+20ld%020lld",header,(int)value1,(long)value2);
       
       /* Sample output:
          Header1      -10000000           00000000000020000000
          Header2      +10000000           -0000000000020000000
       */
      }
    
    


  • (スペース):出力値の前にスペースが入るのは、値が符号付きで正の場合です。このフラグを持つフィールドの正のデータ値は、それぞれ1文字ずつ右にシフトされます。これにより、同じ列の異なる行に正の値と負の値がある場合、視覚的に値を揃えることができます。負のデータの「-」の代わりにスペースが入ります。
    void OnStart()
      {
    //--- Declare the variables to be printed
       string   header="";  // Data header
       double   value1=0;   // First value
       double   value2=0;   // Second value
       
    //--- The first line with a header in a 16-character field and data in 20-character fields
    //--- The header and data of the second field are pressed to the left edge.
    //--- Data values of the third field are pressed to the right edge
    //--- For the second and third fields from the left, a space is added for positive values.
       header="Header1";
       value1=-10000000;
       value2=20000000;
       PrintFormat("%-16s%- 20ld% 20lld",header,(int)value1,(long)value2);
       
    //--- The second line with a header in a 16-character field and data in 20-character fields
    //--- The header and data of the second field are pressed to the left edge.
    //--- Data values of the third field are pressed to the right edge
    //--- For the second and third fields from the left, a space is added for positive values.
       header="Header2";
       value1=10000000;
       value2=-20000000;
       PrintFormat("%-16s%- 20ld% 20lld",header,(int)value1,(long)value2);
       
       /* Sample output:
          Header1      -10000000                       20000000
          Header2       10000000                      -20000000
       */
      }
    
    


  • #記号

    1.o、x、Xフォーマットと併用すると、それぞれ0、0x、0Xが出力値の前に追加されます。
    void OnStart()
      {
    //--- Declare the variables to be printed
       string   header="";  // Data header
       double   value1=0;   // First value
       double   value2=0;   // Second value
       
    //--- First line with a header and data in 16-character fields
    //--- The header and data of all fields are pressed to the left edge.
    //--- Data values of the second field are displayed in decimal format
    //--- Data values of the third field are displayed in octal format with 0 added before the value
       header="Header1";
       value1=10000;
       value2=10000;
       PrintFormat("%-16s(DEC) %-16ld(OCT) %-#16lo",header,(uint)value1,(uint)value2);
       
    //--- Second line with header and data in 16-character fields
    //--- The header and data of all fields are pressed to the left edge.
    //--- Data values of the second field are displayed in hexadecimal format with 0x added before the value
    //--- Data values of the third field are displayed in hexadecimal format with 0X added before the value
       header="Header2";
       value1=10000;
       value2=10000;
       PrintFormat("%-16s(hex) %-#16lx(HEX) %-#16lX",header,(uint)value1,(uint)value2);
       
       /* Sample output:
          Header1      (DEC) 10000           (OCT) 023420          
          Header2      (hex) 0x2710          (HEX) 0X2710          
       */
      }
    
    


    2.e、E、a、Aフォーマットと併用すると、値は常に小数点付きで出力されます。

    void OnStart()
      {
    //--- Declare the variables to be printed
       string   header="";  // Data header
       double   value1=0;   // First value
       double   value2=0;   // Second value
       
    //--- The first line with a header in a 16-character field and data in 22-character fields
    //--- The header and data of all fields are pressed to the left edge.
    //--- Data values of the second field are displayed together with the 'e' format
    //--- Data values of the third field are displayed together with the 'E' format
       header="Header1";
       value1=255;
       value2=1024;
       PrintFormat("%-16s(e) %-22e(E) %-#22E",header,(double)value1,(double)value2);
       
    //--- The second line with a header in a 16-character field and data in 22-character fields
    //--- The header and data of all fields are pressed to the left edge.
    //--- Data values of the second field are displayed together with the 'a' format
    //--- Data values of the third field are displayed together with the 'A' format
       header="Header2";
       value1=255;
       value2=1024;
       PrintFormat("%-16s(a) %-#22a(A) %-#22A",header,(double)value1,(double)value2);
       
       /* Sample output:
          Header1      (e) 2.550000e+02          (E) 1.024000E+03          
          Header2      (a) 0x1.fe00000000000p+7  (A) 0X1.0000000000000P+10 
       */
      }
    
    


    3.gまたはGフォーマットとともに使用すると、このフラグは出力値に小数点があるかどうかを判断し、先頭のゼロがカットされるのを防ぎます。gフォーマットは、またはeの最もコンパクトな表示タイプを選択し、 選択したフォーマットでエントリーを表示します。Gフォーマットは、gフォーマットと同じですが、fまたはEフォーマットのどちらかを選択します。

    void OnStart()
      {
    //--- Declare the variables to be printed
       string   header="";  // Data header
       double   value1=0;   // First value
       double   value2=0;   // Second value
       
    //--- The first line with a header in a 16-character field and data in 22-character fields
    //--- The header and data of all fields are pressed to the left edge.
    //--- Data values of the second field are displayed together with the 'f' format with default precision
    //--- Data values of the third field are displayed together with the 'g' format
       header="Header1";
       value1=Point();
       value2=DBL_MAX;
       PrintFormat("%-16s(f) %-22f(g) %-#22g",header,(double)value1,(double)value2);
       
    //--- The second line with a header in a 16-character field and data in 22-character fields
    //--- The header and data of all fields are pressed to the left edge.
    //--- Data values of the second field are displayed together with the 'f' format with 5-character precision
    //--- Data values of the third field are displayed together with the 'G' format
       header="Header2";
       value1=Point();
       value2=EMPTY_VALUE;
       PrintFormat("%-16s(f) %-#22.5f(G) %-#22G",header,(double)value1,(double)value2);
       
       /* Sample output:
          Header1      (f) 0.000010              (g) 1.79769e+308          
          Header2      (f) 0.00001               (G) 1.79769E+308          
       */
      }
    
    

    #flagは、cdiusの各フォーマットと併用すると無視されます。


    幅指定子(width):表示するフォーマット値の最小文字数。指定子の役割については、上記のフラグとともに議論しました。ひとつ面白いニュアンスがあります。幅の値にアスタリスク(*)を指定した場合、データとともにリストで指定された値がアスタリスクに置き換わります。

    void OnStart()
      {
    //--- Declare the variables to be printed
       string   header="";  // Data header
       double   value1=0;   // First value
       double   value2=0;   // Second value
       
    //--- The first line with a header in a *-character field (16) and data in *-character fields (22)
    //--- The header and data of all fields are pressed to the left edge.
    //--- Data values of the second field are displayed together with the 'f' format with default precision
    //--- Data values of the third field are displayed together with the 'g' format
       header="Header1";
       value1=Point();
       value2=DBL_MAX;
       PrintFormat("%-*s(f) %-*f(g) %-#*g",16,header,22,(double)value1,22,(double)value2);
       
    //--- The second line with a header in a *-character field (16) and data in *-character fields (22)
    //--- The header and data of all fields are pressed to the left edge.
    //--- Data values of the second field are displayed together with the 'f' format with 5-character precision
    //--- Data values of the third field are displayed together with the 'G' format
       header="Header2";
       value1=Point();
       value2=EMPTY_VALUE;
       PrintFormat("%-*s(f) %-#*.5f(G) %-#*G",16,header,22,(double)value1,22,(double)value2);
       
       /* Sample output:
          Header1      (f) 0.000010              (g) 1.79769e+308          
          Header2      (f) 0.00001               (G) 1.79769E+308          
       */
      }
    
    

    この例では、出力は前のものと変わりませんが、ここでは各フィールドの幅を値のリストの数値パラメータとして指定しています。これは、表が関数内に表示され、その関数に表の各列の幅の値を渡すことができる場合に便利です。これらはフォーマット文字列のアスタリスクに置き換えられます。


    精度指定子(.precision):小数点以下の桁数。精度指定は、四捨五入の有無にかかわらず、端数値の一部を切り捨てることができます。

    異なるフォーマットタイプ(type)では、精度指定は異なる方法で適用されます。

    • a、A:  小数点以下の桁数を指定します。
      void OnStart()
        {
      //--- Declare the variables to be printed
         string   header="";  // Data header
         double   value1=0;   // First value
         double   value2=0;   // Second value
         
      //--- The first line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'a' format with default precision
      //--- Data values of the third field are displayed together with the 'A' format with default precision
         header="Header1";
         value1=Point();
         value2=DBL_MAX;
         PrintFormat("%-16s(a) %-22a(A) %-#22A",header,(double)value1,(double)value2);
         
      //--- The second line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'a' format with 5-character precision
      //--- Data values of the third field are displayed together with the 'A' format with 7-character precision
         header="Header2";
         value1=Point();
         value2=EMPTY_VALUE;
         PrintFormat("%-16s(a) %-#22.5a(A) %-#22.7A",header,(double)value1,(double)value2);
         
         /* Sample output:
            Header1      (a) 0x1.4f8b588e368f1p-17 (A ) 0X1.FFFFFFFFFFFFFP+1023
            Header2      (a) 0x1.4f8b6p-17         (A) 0X2.0000000P+1023     
         */
        }
      
      


    • d、i、u、o、x、X:最小表示桁数を指定します。対応するパラメータの桁数が指定された精度より少ない場合、出力の左側をゼロ埋めします。出力桁数が指定精度より多い場合、表示値は切り捨てられません。
      void OnStart()
        {
      //--- Declare the variables to be printed
         string   header="";  // Data header
         double   value1=0;   // First value
         double   value2=0;   // Second value
         
      //--- The first line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'd' format with 4-character precision
      //--- Data values of the third field are displayed together with the 'i' format with 11-character precision
         header="Header1";
         value1=INT_MAX;
         value2=INT_MAX;
         PrintFormat("%-16s(d) %-22.4d(i) %-#22.11i",header,(int)value1,(int)value2);
         
      //--- The second line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'u' format with 4-character precision
      //--- Data values of the third field are displayed together with the 'o' format with 11-character precision
         header="Header2";
         value1=INT_MAX;
         value2=INT_MAX;
         PrintFormat("%-16s(u) %-#22.4u(o) %-#22.11o",header,(double)value1,(double)value2);
         
      //--- The third line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'x' format with 4-character precision
      //--- Data values of the third field are displayed together with the 'X' format with 11-character precision
         header="Header3";
         value1=INT_MAX;
         value2=INT_MAX;
         PrintFormat("%-16s(x) %-#22.4x(X) %-#22.11X",header,(double)value1,(double)value2);
         
         /* Sample output:
            Header1      (d) 2147483647            (i) 02147483647           
            Header2      (u) 4290772992            (o) 037760000000          
            Header3      (x) 0xffc00000            (X) 0X000FFC00000         
         */
        }
      
      


    • e、E、f:小数点以下の表示桁数を指定します。表示される最後の桁は四捨五入されます。
      void OnStart()
        {
      //--- Declare the variables to be printed
         string   header="";  // Data header
         double   value1=0;   // First value
         double   value2=0;   // Second value
         
      //--- The first line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'e' format with 4-character precision
      //--- Data values of the third field are displayed together with the 'E' format with 11-character precision
         header="Header1";
         value1=DBL_MAX;
         value2=DBL_MAX;
         PrintFormat("%-16s(e) %-22.4e(E) %-#22.11E",header,(double)value1,(double)value2);
         
      //--- The second line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'f' format with 4-character precision
      //--- Data values of the third field are displayed together with the 'f' format with 11-character precision
         header="Header2";
         value1=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
         value2=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
         PrintFormat("%-16s(f) %-#22.4f(f) %-#22.11f",header,(double)value1,(double)value2);
         
         /* Sample output:
            Header1      (e) 1.7977e+308           (E) 1.79769313486E+308    
            Header2      (f) 1.2729                (f) 1.27286000000         
         */
        }
      
      

    • g、G:最大有効桁数を指定します。
      void OnStart()
        {
      //--- Declare the variables to be printed
         string   header="";  // Data header
         double   value1=0;   // First value
         double   value2=0;   // Second value
         
      //--- The first line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'g' format with 4-character precision
      //--- Data values of the third field are displayed together with the 'G' format with 11-character precision
         header="Header1";
         value1=DBL_MAX;
         value2=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
         PrintFormat("%-16s(g) %-22.4g(G) %-#22.11G",header,(double)value1,(double)value2);
         
      //--- The second line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'g' format with 4-character precision
      //--- Data values of the third field are displayed together with the 'G' format with 11-character precision
         header="Header2";
         value1=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
         value2=DBL_MAX;
         PrintFormat("%-16s(g) %-#22.4g(G) %-#22.11G",header,(double)value1,(double)value2);
         
         /* Sample output:
            Header1      (g) 1.798e+308            (G) 1.2731600000          
            Header2      (g) 1.273                 (G) 1.7976931349E+308     
      
         */
        }
      
      
      最大有効桁数は小数点以下の桁数を意味しないことに留意してください。ここでは数字の全桁が考慮されます。指定されたビット深度が4桁でDigits()の値が5の場合、価格値の小数点以下4桁は表示されません。この例では、数字の4桁目が小数点以下のであるため、小数点以下3桁(1.273)しか表示されません。


    • s:表示される行の文字数。行の長さが精度値を超えた場合、出力中に行が切り捨てられます。
      void OnStart()
        {
      //---
      
      //--- Declare the variables to be printed
         string   header="";  // Data header
         double   value1=0;   // First value
         double   value2=0;   // Second value
         
      //--- The first line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'g' format with 4-character precision
      //--- Data values of the third field are displayed together with the 's' format with 11-character precision
         header="Header1";
         value1=DBL_MAX;
         value2=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
         PrintFormat("%-16s(g) %-22.4g(s) %-#22.11s",header,(double)value1,(string)value2);
         
      //--- The second line with a header in a 16-character field and data in 22-character fields
      //--- The header and data of all fields are pressed to the left edge.
      //--- Data values of the second field are displayed together with the 'g' format with 5-character precision
      //--- Data values of the third field are displayed together with the 's' format with 4-character precision
         header="Header2";
         value1=DBL_MAX;
         value2=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
         PrintFormat("%-16s(g) %-#22.5g(s) %-#22.4s",header,(double)value1,(string)value2);
         
         /* Sample output:
            Header1      (g) 1.798e+308            (s) 1.2872                
            Header2      (g) 1.7977e+308           (s) 1.28                  
      
         */
        }
      
      

        データサイズ指定子(h | l | ll | I32 | I64):パラメータとして渡される整数データのサイズを指定します。このデータのサイズ(int、uint、short、ushort、long、ulong)は、パラメータとして整数を渡すことで指定できます。以下は、サイズ指定子とデータ型の互換性の表です。

        データサイズ
        サイズ指定子
         型指定子
          short   h
          d, i, o, x, X
          ushort   h
          u, o, x, X
          int
          l(小文字のL)、I32
          d, i, o, x, X
          uint
          l(小文字のL)、I32
          u, o, x, X
          long
          ll(小文字のLが2つ)、I64
          d, i, o, x, X
          ulong
          I64
          u, o, x, X


        データ型指定子(type):フォーマットされた出力のための唯一の必須フィールド。 

        記号
         種類 フォーマット
        c
        int
        short型の記号
        C
        int
        char型の記号(ANSI)
        d
        int
        符号付き10進整数
        i
        int
        符号付き10進整数
        o
        int
        符号なし8進整数
        u
        int
        符号なし10進整数
        x
        int
        符号なし16進整数(abcdefを使用)
        X
        int
        符号なし16進整数(ABCDEFを使用)
        e
        double
        「[ – ]d.dddd e [sign]ddd」のフォーマットを持つ実数値。ここで、dは小数点以下1桁、ddddは小数点以下1桁以上、dddは指数の大きさを定義する3桁の数字、「sign」はプラスまたはマイナスの符号。
        E
        double
        指数記号が大文字(eの代わりにE)である点を除き、eフォーマットと同じ。
        f
        double
        「 [ – ]dddd.dddd」フォーマットを持つ実数値。ここで、ddddは1桁以上の10進数。小数点の前に表示される桁数は、数値の値によって異なる。小数点以下の桁数は、要求される精度によって決まる。
        g
        double
        fまたはeフォーマットで出力される実数値で、どちらの出力がよりコンパクトかによって異なる。
        G
        double
        fまたはEフォーマットで出力される実数値で、どちらの出力がよりコンパクトかによって異なる。
        a
        double
        「[−]0xh.hhhh p±dd」フォーマットを持つ実数値。ここで、h.hhhhはabcdefを用いた16進数による仮数、ddは1桁以上の指数。小数点以下の桁数は精度指定によって決定される。
        A
        double
        「[−]0xh.hhhh P±dd」フォーマットを持つ実数値。ここで、h.hhhhはABCDEFを使用した16進数による仮数、ddは1桁以上の指数。小数点以下の桁数は精度指定によって決定される。
        s
        string
        ライン出力


        データ型は、どのような形でターミナルログのエントリを受け取りたいかを指定することができます。例えば、cまたはC型を使用する場合、出力は1文字です。パラメータで渡される値は、その文字のUnicodeまたはANSIテーブルコードを指定します。一方、他の型指定子で同じ値を使用すると、パラメータ値自体は選択されたフォーマットで表示されますが、文字は表示されません:

        void OnStart()
          {
        //--- Declare the variables to be printed
           string   header="";  // Data header
           char     value1=0;   // First value
           char     value2=0;   // Second value
           
        //--- The first line with a header in a 16-character field and data in 10-character fields
        //--- The header and data of all fields are pressed to the left edge.
        //--- Data values of the second field are displayed together with the 'c' format
        //--- Data values of the third field are displayed together with the 'C' format
           header="Header1";
           value1=65;
           value2=66;
           PrintFormat("%-16s(c) %-10c(C) %-10C",header,(char)value1,(char)value2);
           
        //--- The second line with a header in a 16-character field and data in 10-character fields
        //--- The header and data of all fields are pressed to the left edge.
        //--- Data values of the second field are displayed together with the 'c' format
        //--- Data values of the third field are displayed together with the 'C' format
           header="Header2";
           value1=67;
           value2=68;
           PrintFormat("%-16s(c) %-10c(C) %-10C",header,(char)value1,(char)value2);
           
        //--- The third line with a header in a 16-character field and data in 10-character fields
        //--- The header and data of all fields are pressed to the left edge.
        //--- Data values of the second field are displayed together with the 'd' format
        //--- Data values of the third field are displayed together with the 'i' format
           header="Header3";
           value1=65;
           value2=66;
           PrintFormat("%-16s(d) %-10d(i) %-10i",header,(int)value1,(int)value2);
           
           /* Sample output:
              Header1      (c) A         (C) B         
              Header2      (c) C         (C) D         
              Header3      (d) 65        (i) 66        
           */
          }
        
        

        ログに表示されるテキストのすべてのフォーマット指定子を簡単に見てみました。取引口座のプロパティを表示する具体例を使って、これがどのように見えるかを見てみましょう。


        口座プロパティのフォーマットされた表示

        整数、実数、文字列プロパティは、それぞれAccountInfoInteger()AccountInfoDouble()AccountInfoString()関数を使用して取得できます。

        すべてのプロパティの完全なリストを表示する必要は必ずしもありません。したがって、各プロパティについて、このプロパティの説明をログに出力する関数を作成します。その後、必要なプロパティ(すべて、または選択されたもの)をログに送信する関数を、既製の関数から組み立てることが可能になります。

        ヘッダーフィールドの幅と左端からのヘッダーフィールドのインデントという2つのパラメータを関数に渡します。整数プロパティ、実数プロパティ、文字列プロパティの順に説明します。


        口座の整数プロパティを表示する関数

        口座番号

        //+------------------------------------------------------------------+
        //| Print a description of the account number into the journal       |
        //+------------------------------------------------------------------+
        void AccountLoginPrint(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="Login:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s%-s",indent,"",w,header,(string)AccountInfoInteger(ACCOUNT_LOGIN));
           /* Sample output:
              Login: 68008618
           */
          }
        
        

        フォーマット文字列では、まず左端からの行インデントの大きさをアスタリスクで示します。行のパラメータには、インデントフィールドのサイズ(アスタリスクの代わり)文字列値(s文字の代わりに空文字列)を渡します。
        %*sフォーマットは、パラメータに渡された空文字列を、文字列パラメータに渡されたインデント値に従って空白埋めします。従って、空欄は必要な大きさの行のスペース文字から作るのが便利です。次に、フォーマット行で、ヘッダーフィールドのサイズをアスタリスクで示し、その場所にw変数の値を渡し、header変数にヘッダー行を渡します。最後のパラメータは、AccountInfoInteger()の行としての口座インデックス値です。


        取引口座の種類:

        //+------------------------------------------------------------------+
        //| Print a trading account type into the journal                    |
        //+------------------------------------------------------------------+
        void AccountTradeModePrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the value of the trading account type
           ENUM_ACCOUNT_TRADE_MODE trade_mode=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE);
        //--- "Cut out" the name of the trading account type from the line obtained from enum
           string mode=StringSubstr(EnumToString(trade_mode),19);
        //--- Convert the characters of the resulting line to lower case and replace the first letter from small to capital
           if(mode.Lower())
              mode.SetChar(0,ushort(mode.GetChar(0)-0x20));
        //--- 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="Trade mode:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s%-s",indent,"",w,header,mode);
           /* Sample output:
              Trade mode: Demo
           */
          }
        
        


        レバレッジサイズ

        //+------------------------------------------------------------------+
        //| Print a description of the provided leverage size in the journal |
        //+------------------------------------------------------------------+
        void AccountLeveragePrint(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="Leverage:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s1:%-s",indent,"",w,header,(string)AccountInfoInteger(ACCOUNT_LEVERAGE));
           /* Sample output:
              Leverage: 1:100
           */
          }
        
        


        最大注文数

        //+------------------------------------------------------------------+
        //| Print a description of the maximum allowed                       |
        //| number of active pending orders                                  |
        //+------------------------------------------------------------------+
        void AccountLimitOrdersPrint(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="Limit orders:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s%-s",indent,"",w,header,(string)AccountInfoInteger(ACCOUNT_LIMIT_ORDERS));
           /* Sample output:
              Limit orders: 200
           */
          }
        
        


        最低担保モード

        //+------------------------------------------------------------------+
        //| Print a description of the mode for setting a minimal            |
        //| accepted level of collateral in the journal                      |
        //+------------------------------------------------------------------+
        void AccountMarginSOModePrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the value of the mode for setting the minimum available collateral
           ENUM_ACCOUNT_STOPOUT_MODE so_mode=(ENUM_ACCOUNT_STOPOUT_MODE)AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE);
        //--- "Cut out" the mode name from the line obtained from enum 
           string mode=StringSubstr(EnumToString(so_mode),21);
        //--- Convert the characters of the resulting line to lower case and replace the first letter from small to capital
           if(mode.Lower())
              mode.SetChar(0,ushort(mode.GetChar(0)-0x20));
        //--- 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="StopOut mode:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s%-s",indent,"",w,header,mode);
           /* Sample output:
              StopOut mode: Percent
           */
          }
        
        


        口座取引の許可

        //+------------------------------------------------------------------+
        //| Print a description                                              |
        //| of allowing trading for the current account in the journal       |
        //+------------------------------------------------------------------+
        void AccountTradeAllowedPrint(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="Trade allowed:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- Depending on the bool value of the property, pass the "Yes" or "No" line as a parameter
           PrintFormat("%*s%-*s%-s",indent,"",w,header,((bool)AccountInfoInteger(ACCOUNT_TRADE_ALLOWED) ? "Yes" : "No"));
           /* Sample output:
              Trade allowed: Yes
           */
          }
        
        


        EAの取引許可

        //+------------------------------------------------------------------+
        //| Print a description                                              |
        //| allowing trading for an EA                                       |
        //+------------------------------------------------------------------+
        void AccountTradeExpertPrint(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="Trade expert:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- Depending on the bool value of the property, pass the "Yes" or "No" line as a parameter
           PrintFormat("%*s%-*s%-s",indent,"",w,header,((bool)AccountInfoInteger(ACCOUNT_TRADE_EXPERT) ? "Yes" : "No"));
           /* Sample output:
              Trade expert: Yes
           */
          }
        
        


        証拠金計算モード

        //+------------------------------------------------------------------+
        //| Print a description of the margin calculation mode in the journal|
        //+------------------------------------------------------------------+
        void AccountMarginModePrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the value of the margin calculation mode
           ENUM_ACCOUNT_MARGIN_MODE  margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE);
        //--- "Cut out" the mode name from the line obtained from enum 
           string mode=StringSubstr(EnumToString(margin_mode),20);
        //--- Convert the characters of the resulting line to lower case and replace the first letter from small to capital
           if(mode.Lower())
              mode.SetChar(0,ushort(mode.GetChar(0)-0x20));
        //--- Replace all underscore characters with space in the resulting line
           StringReplace(mode,"_"," ");
        //--- 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="Margin mode:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s%-s",indent,"",w,header,mode);
           /* Sample output:
              Margin mode: Retail hedging
           */
          }
        
        


        口座通貨の小数点以下の桁数

        //+------------------------------------------------------------------+
        //| Print a description of the number of                             |
        //| decimal places for an account currency                           |
        //+------------------------------------------------------------------+
        void AccountCurrencyDigitsPrint(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="Currency digits:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s%-s",indent,"",w,header,(string)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS));
           /* Sample output:
              Currency digits: 2
           */
          }
        
        


        FIFOルールによるポジション決済のフラグ

        //+------------------------------------------------------------------+
        //| Print a description of the flag indicating                       |
        //| that positions can only be closed using the FIFO rule            |
        //+------------------------------------------------------------------+
        void AccountFIFOClosePrint(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="FIFO close:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- Depending on the bool value of the property, pass the "Yes" or "No" line as a parameter
           PrintFormat("%*s%-*s%-s",indent,"",w,header,((bool)AccountInfoInteger(ACCOUNT_FIFO_CLOSE) ? "Yes" : "No"));
           /* Sample output:
              FIFO close: No
           */
          }
        
        


        1つの銘柄での両方向のポジションの許可

        //+------------------------------------------------------------------+
        //| Print a description of the flag indicating                       |
        //| opposite positions are allowed on a single symbol                |
        //+------------------------------------------------------------------+
        void AccountHedgeAllowedPrint(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="Hedge allowed:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- Depending on the bool value of the property, pass the "Yes" or "No" line as a parameter
           PrintFormat("%*s%-*s%-s",indent,"",w,header,((bool)AccountInfoInteger(ACCOUNT_HEDGE_ALLOWED) ? "Yes" : "No"));
           /* Sample output:
              Hedge allowed: Yes
           */
          }
        
        


        口座の実数プロパティを表示するための関数

        口座残高

        //+------------------------------------------------------------------------------------+
        //| Print a description of the account balance in the deposit currency in the journal  |
        //+------------------------------------------------------------------------------------+
        void AccountBalancePrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the balance, the number of decimal places for the symbol and its name
           double ballance=AccountInfoDouble(ACCOUNT_BALANCE);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Balance:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,ballance,currency);
           /* Sample output:
              Balance: 10015.00 USD
           */
          }
        
        


        口座クレジット

        //+------------------------------------------------------------------+
        //| Print a description of account credit size                       |
        //| in a deposit currency                                            |
        //+------------------------------------------------------------------+
        void AccountCreditPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the credit, the number of decimal places for the symbol and its name
           double credit=AccountInfoDouble(ACCOUNT_CREDIT);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Credit:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,credit,currency);
           /* Sample output:
              Credit: 0.00 USD
           */
          }
        
        


        当期利益

        //+------------------------------------------------------------------+
        //| Print a description                                              |
        //| of the current profit in the deposit currency                    |
        //+------------------------------------------------------------------+
        void AccountProfitPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the current profit, the number of decimal places for the symbol and its name
           double profit=AccountInfoDouble(ACCOUNT_PROFIT);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Profit:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,profit,currency);
           /* Sample output:
              Profit: 0.00 USD
           */
          }
        
        


        口座エクイティ

        //+------------------------------------------------------------------+
        //| Print a description of the value of                              |
        //| equity on an account in a deposit currency                       |
        //+------------------------------------------------------------------+
        void AccountEquityPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the equity, the number of decimal places for the symbol and its name
           double equity=AccountInfoDouble(ACCOUNT_EQUITY);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Equity:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,equity,currency);
           /* Sample output:
              Equity: 10015.00 USD
           */
          }
        
        


        予約担保

        //+------------------------------------------------------------------+
        //| Print a description of                                           |
        //| reserved collateral funds on the account in a deposit currency   |
        //+------------------------------------------------------------------+
        void AccountMarginPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the reserved collateral, the number of decimal places for the symbol and its name
           double margin=AccountInfoDouble(ACCOUNT_MARGIN);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Margin:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,margin,currency);
           /* Sample output:
              Margin: 0.00 USD
           */
          }
        
        


        ポジションを持つための資金

        //+--------------------------------------------------------------------------------------+
        //| Print a description of the free funds,                                               |
        //| available for opening a position on an account in a deposit currency, in the journal |
        //+--------------------------------------------------------------------------------------+
        void AccountMarginFreePrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the reserved collateral, the number of decimal places for the symbol and its name
           double margin_free=AccountInfoDouble(ACCOUNT_MARGIN_FREE);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Margin free:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,margin_free,currency);
           /* Sample output:
              Margin free: 10015.00 USD
           */
          }
        
        


        口座の担保レベル

        //+------------------------------------------------------------------+
        //| Print a description                                              |
        //| of the collateral level on an account in %                       |
        //+------------------------------------------------------------------+
        void AccountMarginLevelPrint(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="Margin level:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- The value is set with 'digits' equal to 2 and the fact that the property is displayed in % is specified
           PrintFormat("%*s%-*s%-.2f %%",indent,"",w,header,AccountInfoDouble(ACCOUNT_MARGIN_LEVEL));
           /* Sample output:
              Margin level: 0.00 %
           */
          }
        
        


        マージンコール担保レベル

        //+----------------------------------------------------------------------------+
        //| Print a description of the collateral level,                               |
        //| at which a deposit to an account is required (Margin Call), in the journal |
        //+----------------------------------------------------------------------------+
        void AccountMarginSOCallPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the MarginCall level values, the number of decimal places for the symbol and its name
           double margin_so_call=AccountInfoDouble(ACCOUNT_MARGIN_SO_CALL);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- If the level of collateral for MarginCall is calculated as %,
        //--- specify 'currency' in % rather than in account currency, while 'digits' will be equal to 2
           if(AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE)==ACCOUNT_STOPOUT_MODE_PERCENT)
             {
              currency="%";
              digits=2;
             }
        //--- 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="Margin Call:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value obtained above
           PrintFormat("%*s%-*s%-.*f %s",indent,"",w,header,digits,margin_so_call,currency);
           /* Sample output:
              Margin Call: 50.00 %
           */
          }
        
        


        証拠金ストップアウレベル

        //+------------------------------------------------------------------+
        //| Print a description of the collateral level,                     |
        //| upon reaching which                                              |
        //| the most loss-making position is forcefully closed (Stop Out)    |
        //+------------------------------------------------------------------+
        void AccountMarginStopOutPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the StopOut level values, the number of decimal places for the symbol and its name
           double margin_so_so=AccountInfoDouble(ACCOUNT_MARGIN_SO_SO);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- If the level of collateral for StopOut is calculated as %,
        //--- specify 'currency' in % rather than in account currency, while 'digits' will be equal to 2
           if(AccountInfoInteger(ACCOUNT_MARGIN_SO_MODE)==ACCOUNT_STOPOUT_MODE_PERCENT)
             {
              currency="%";
              digits=2;
             }
        //--- 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="Margin Stop Out:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value obtained above
           PrintFormat("%*s%-*s%-.*f %s",indent,"",w,header,digits,margin_so_so,currency);
           /* Sample output:
              Margin Stop Out: 30.00 %
           */
          }
        
        


        未決注文の証拠金をカバーするために口座に留保されている金額

        //+------------------------------------------------------------------+
        //| Print a description of the funds                                 |
        //| reserved on the account for security                             |
        //| of a guarantee amount for all pending orders                     |
        //+------------------------------------------------------------------+
        void AccountMarginInitialPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the amount of the reserved funds, the number of decimal places for the symbol and its name
           double margin_initial=AccountInfoDouble(ACCOUNT_MARGIN_INITIAL);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Margin initial:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,margin_initial,currency);
           /* Sample output:
              Margin initial: 0.00 USD
           */
          }
        
        


        未決ポジションをカバーするために口座に留保されている最低資本額

        //+------------------------------------------------------------------+
        //| Print a description of the funds                                 |
        //| reserved on the account for security                             |
        //| of the min amount of all open positions                          |
        //+------------------------------------------------------------------+
        void AccountMarginMaintenancePrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the amount of the reserved funds, the number of decimal places for the symbol and its name
           double margin_maintenance=AccountInfoDouble(ACCOUNT_MARGIN_MAINTENANCE);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Margin maintenance:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,margin_maintenance,currency);
           /* Sample output:
              Margin maintenance: 0.00 USD
           */
          }
        
        


        資産規模

        //+----------------------------------------------------------------------------+
        //| Print a description of the current asset size on the account in the journal|
        //+----------------------------------------------------------------------------+
        void AccountAssetsPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the current asset size on the account, the number of decimal places for the symbol and its name
           double assets=AccountInfoDouble(ACCOUNT_ASSETS);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Assets:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,assets,currency);
           /* Sample output:
              Assets: 0.00 USD
           */
          }
        
        


        負債額

        //+------------------------------------------------------------------+
        //| Print a description                                              |
        //| of the current liabilities on the account                        |
        //+------------------------------------------------------------------+
        void AccountLiabilitiesPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the current liabilities on the account, the number of decimal places for the symbol and its name
           double liabilities=AccountInfoDouble(ACCOUNT_LIABILITIES);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Liabilities:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,liabilities,currency);
           /* Sample output:
              Liabilities: 0.00 USD
           */
          }
        
        


        コミッションのブロック

        //+------------------------------------------------------------------+
        //| Print a description                                              |
        //| of the current sum of blocked commissions on an account          |
        //+------------------------------------------------------------------+
        void AccountComissionBlockedPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Get the current blocked commissions on the account, the number of decimal places for the symbol and its name
           double commission_blocked=AccountInfoDouble(ACCOUNT_COMMISSION_BLOCKED);
           int digits=(int)AccountInfoInteger(ACCOUNT_CURRENCY_DIGITS);
           string currency=AccountInfoString(ACCOUNT_CURRENCY);
        //--- 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="Comission blocked:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
        //--- To display the value correctly, replace the asterisk in the format line with the digits value for the symbol
           PrintFormat("%*s%-*s%-.*f %-s",indent,"",w,header,digits,commission_blocked,currency);
           /* Sample output:
              Comission blocked: 0.00 USD
           */
          }
        
        


        口座の文字列プロパティを表示するための関数

        クライアント名

        //+------------------------------------------------------------------+
        //| Print a description of the client name into the journal          |
        //+------------------------------------------------------------------+
        void AccountNamePrint(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="Name:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s%-s",indent,"",w,header,AccountInfoString(ACCOUNT_NAME));
           /* Sample output:
              Name: Artem
           */
          }
        
        


        取引サーバー名

        //+------------------------------------------------------------------+
        //| Print a description of the trade server name into the journal    |
        //+------------------------------------------------------------------+
        void AccountServerPrint(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="Server:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s%-s",indent,"",w,header,AccountInfoString(ACCOUNT_SERVER));
           /* Sample output:
              Server: MetaQuotes-Demo
           */
          }
        //+------------------------------------------------------------------+
        
        


        預金通貨名

        //+------------------------------------------------------------------+
        //| Print a description of a deposit currency name                   |
        //+------------------------------------------------------------------+
        void AccountCurrencyPrint(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="Currency:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s%-s",indent,"",w,header,AccountInfoString(ACCOUNT_CURRENCY));
           /* Sample output:
              Currency: USD
           */
          }
        
        


        口座開設会社名

        //+------------------------------------------------------------------+
        //| Print a description of the company name,                         |
        //| serving an account, into the journal                             |
        //+------------------------------------------------------------------+
        void AccountCompanyPrint(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="Company:";
           uint w=(header_width==0 ? header.Length()+1 : header_width);
        //--- Print the property value in the log with a header with the required width and indentation
           PrintFormat("%*s%-*s%-s",indent,"",w,header,AccountInfoString(ACCOUNT_COMPANY));
           /* Sample output:
              Company: MetaQuotes Software Corp.
           */
          }
        
        

        上記で紹介した関数はすべてほとんど同じです。それぞれで、左端からの行のインデントとヘッダーフィールドの幅を設定できます。関数に渡されるゼロのデフォルト値は、インデントがなく、証拠金幅がヘッダー行のサイズ+1文字に等しいことを意味します。したがって、これらの関数をそのまま使用して、必要な口座プロパティを表示することができます。ただし、プロパティのグループを表示する関数を作成する必要がある場合は、操作ログ内の値をすっきり見やすく出力するために、ヘッダーフィールドのインデントと幅が必要になります。

        このような、操作ログ内のすべての口座プロパティを表示する関数の例を作ってみましょう。

        すべての口座データを操作ログに表示する関数:

        //+------------------------------------------------------------------+
        //| Print account data into the journal                              |
        //+------------------------------------------------------------------+
        void AccountInfoPrint(const uint header_width=0,const uint indent=0)
          {
        //--- Display descriptions of integer properties according to their location in ENUM_ACCOUNT_INFO_INTEGER
           Print("AccountInfoInteger properties:");
           AccountLoginPrint(header_width,indent);
           AccountTradeModePrint(header_width,indent);
           AccountLeveragePrint(header_width,indent);
           AccountLimitOrdersPrint(header_width,indent);
           AccountMarginSOModePrint(header_width,indent);
           AccountTradeAllowedPrint(header_width,indent);
           AccountTradeExpertPrint(header_width,indent);
           AccountMarginModePrint(header_width,indent);
           AccountCurrencyDigitsPrint(header_width,indent);
           AccountFIFOClosePrint(header_width,indent);
           AccountHedgeAllowedPrint(header_width,indent);
        //--- Display descriptions of real properties according to their location in ENUM_ACCOUNT_INFO_DOUBLE
           Print("AccountInfoDouble properties:");
           AccountBalancePrint(header_width,indent);
           AccountCreditPrint(header_width,indent);
           AccountProfitPrint(header_width,indent);
           AccountEquityPrint(header_width,indent);
           AccountMarginPrint(header_width,indent);
           AccountMarginFreePrint(header_width,indent);
           AccountMarginLevelPrint(header_width,indent);
           AccountMarginSOCallPrint(header_width,indent);
           AccountMarginStopOutPrint(header_width,indent);
           AccountMarginInitialPrint(header_width,indent);
           AccountMarginMaintenancePrint(header_width,indent);
           AccountAssetsPrint(header_width,indent);
           AccountLiabilitiesPrint(header_width,indent);
           AccountComissionBlockedPrint(header_width,indent);
        //--- Display descriptions of string properties according to their location in ENUM_ACCOUNT_INFO_STRING
           Print("AccountInfoString properties:");
           AccountNamePrint(header_width,indent);
           AccountServerPrint(header_width,indent);
           AccountCurrencyPrint(header_width,indent);
           AccountCompanyPrint(header_width,indent);
          }
        
        

        この関数は、ENUM_ACCOUNT_INFO_INTEGERENUM_ACCOUNT_INFO_DOUBLEENUM_ACCOUNT_INFO_STRING列挙型にこれらのプロパティが現れる順に、口座プロパティデータを表示するすべての関数を連続して呼び出します。

        以下は、ヘッダーフィールドの幅を20文字、インデントを2文字にしてスクリプトから関数を呼び出した結果です。

        void OnStart()
          {
        //--- Print trading account properties in the journal
           AccountInfoPrint(20,2);
           /* Sample output:
              AccountInfoInteger properties:
                Login:              68008618
                Trade mode:         Demo
                Leverage:           1:100
                Limit orders:       200
                StopOut mode:       Percent
                Trade allowed:      Yes
                Trade expert:       Yes
                Margin mode:        Retail hedging
                Currency digits:    2
                FIFO close:         No
                Hedge allowed:      Yes
              AccountInfoDouble properties:
                Balance:            10015.00 USD
                Credit:             0.00 USD
                Profit:             2.11 USD
                Equity:             10017.11 USD
                Margin:             25.61 USD
                Margin free:        9991.50 USD
                Margin level:       39114.06 %
                Margin Call:        50.00 %
                Margin Stop Out:    30.00 %
                Margin initial:     0.00 USD
                Margin maintenance: 0.00 USD
                Assets:             0.00 USD
                Liabilities:        0.00 USD
                Comission blocked:  0.00 USD
              AccountInfoString properties:
                Name:               Artem
                Server:             MetaQuotes-Demo
                Currency:           USD
                Company:            MetaQuotes Software Corp.
           */
          }
        
        


        ティックプロパティからのミリ秒単位の時間

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

        MqlTick型の変数を使用すると、SymbolInfoTick()関数を1回呼び出すだけで、Ask、Bid、Last、Volumeの値を取得できます。さらに、この構造体にはミリ秒単位のティックタイムが含まれます。時間値はlong型の変数で与えられます。言い換えれば、このデータをログに出力する場合、単純に1970年01月01日から経過したミリ秒数を示す数字を取得することになります。このデータを人間が読みやすい時間形式で表示するには、数値を日付に変換し、結果の日付にミリ秒を加えます。

        秒付きの日付を得るには、ミリ秒数を1000で割り、ミリ秒の時間を得るには、日付のミリ秒数を1000で割った余りを取る必要があります。

        一般的には次のようになります。

        void OnStart()
          {
        //---
           MqlTick tick;
           if(SymbolInfoTick(Symbol(),tick))
             {
              string time_str=string((datetime)tick.time_msc / 1000)+"."+string(tick.time_msc % 1000);
              Print("time_str=",time_str);
             }
           /* Sample output:
              time_str=2023.07.10 18:49:36.463
           */
          }  
        
        


        ミリ秒単位で時刻を受け取り、Date Time.Mscフォーマットで時刻を表示する関数を書いてみましょう。

        //+------------------------------------------------------------------+
        //| Print the time in the Date Time.Msc format in the journal        |
        //+------------------------------------------------------------------+
        void TimeMSCPrint(const long time_msc,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);
        //--- Print the date and time in the journal with a header with the required width and indentation, milliseconds with 3 digit precision 
           PrintFormat("%*s%-*s%-s.%.3lu",indent,"",w,header,string((datetime)time_msc / 1000),time_msc % 1000);
           /* Sample output:
              Time msc: 2023.07.10 19:49:05.233
           */
          }
        
        


        日付と時刻をミリ秒単位で直接取得し、操作ログに表示するには、以下の関数を使用します。

        //+------------------------------------------------------------------+
        //| Print the time in the Date Time.Msc format for a symbol          |
        //+------------------------------------------------------------------+
        void TimeMSCPrint(const string symbol,const uint header_width=0,const uint indent=0)
          {
        //--- Get time from the tick
           MqlTick tick;
           if(!SymbolInfoTick(symbol,tick))
             {
              Print(__FUNCTION__,": SymbolInfoTick error: ",(string)GetLastError());
              return;
             }
        //--- Print the time in milliseconds using the first version of the function
           TimeMSCPrint(tick.time_msc,header_width,indent);
           /* Sample output:
              Time msc: 2023.07.10 20:07:08.202
           */
          }
        
        


        結論

        この記事では、フォーマットされた行を表示するPrintFormat()関数について調べ、プログラムで「そのまま」使用できる口座プロパティを表示するサンプル関数を作成しました。ただし、フォーマットされた出力を作成するもう1つの方法があります。StringFormat()関数です。必要な形式の行を操作ログに出力するPrintFormat()とは異なり、指定された形式でフォーマットされた行を返します。フォーマット行から目的の行を作成するので、フォーマットされたテキストを表示するのに便利だと思います。この行は、操作ログに出力するだけでなく、プログラム中のさまざまな場所で使用することができます。次回は、StringFormat()について考え、その特徴を見ていきます。


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

        StringFormat():レビューと既成の例 StringFormat():レビューと既成の例
        この記事では、PrintFormat()関数のレビューを続けます。StringFormat()を使った文字列の書式設定と、そのプログラムでのさらなる使用法について簡単に説明します。また、ターミナル操作ログに銘柄データを表示するためのテンプレートも作成します。この記事は、初心者にも経験豊富な開発者にも役立つでしょう。
        ニューラルネットワークが簡単に(第48回):Q関数値の過大評価を減らす方法 ニューラルネットワークが簡単に(第48回):Q関数値の過大評価を減らす方法
        前回は、連続的な行動空間でモデルを学習できるDDPG法を紹介しました。しかし、他のQ学習法と同様、DDPGはQ関数値を過大評価しやすくなります。この問題によって、しばしば最適でない戦略でエージェントを訓練することになります。この記事では、前述の問題を克服するためのいくつかのアプローチを見ていきます。
        MQL5の構造体とデータ表示メソッド MQL5の構造体とデータ表示メソッド
        この記事では、MqlDateTime、MqlTick、MqlRates、MqlBookInfoの各構造体と、それらからデータを表示するメソッドについて見ていきます。構造体のすべてのフィールドを表示するためには、標準的なArrayPrint()関数があります。この関数では、配列に含まれるデータを便利な表形式で、扱われる構造体の型とともに表示します。
        ニューラルネットワークが簡単に(第47回):連続行動空間 ニューラルネットワークが簡単に(第47回):連続行動空間
        この記事では、エージェントのタスクの範囲を拡大します。訓練の過程には、どのような取引戦略にも不可欠な資金管理とリスク管理の側面も含まれます。