記事"MQL5 クックブック:MetaTrader 5 ストラレジーテスタでの position プロパティ分析"についてのディスカッション

 

新しい記事 MQL5 クックブック:MetaTrader 5 ストラレジーテスタでの position プロパティ分析 はパブリッシュされました:

先行記事 "MQL5 Cookbook: Position Properties on the Custom Info Panel"の Expert Advisor の変更バージョンを提供します。お伝えする問題の中にはバーからのデータ取得、現シンボルにおける新規バーイベント確認、ファイルに標準ライブラリのトレードクラスのインクルード、トレード処理実行用トレードシグナルおよび関数検索のための関数作成、OnTrade() 関数におけるトレードイベント決定などがあります。

MQL5 Cookbook: Analyzing Position Properties in the MetaTrader 5 Strategy Tester

作者: Anatoli Kazharski

 

CheckNewBar関数の中で、静的変数 new_barは最初の行でゼロにされ、関数のロジックはそれがゼロに等しいかどうかに基づいています。どこがわからないか教えていただけませんか?

bool CheckNewBar()
  {
//--- 現在のバーのオープン時間を表す変数
   static datetime new_bar=NULL;
//--- 現在のバーのオープン時間を取得するための配列
   static datetime time_last_bar[1]={0};
//--- 現在のバーの開始時刻を取得する。
// 受信中にエラーが発生した場合は、それを報告します。
   if(CopyTime(_Symbol,Period(),0,1,time_last_bar)==-1)
     { Print(__FUNCTION__,": バーの開店時間のコピーエラー: "+IntegerToString(GetLastError())+""); }
//--- これが最初の関数呼び出しの場合
   if(new_bar==NULL)
     {
      // 時間を設定する
      new_bar=time_last_bar[0];
      Print(__FUNCTION__,": 初期化 ["+_Symbol+"][TF: "+TimeframeToString(Period())+"]["
            +TimeToString(time_last_bar[0],TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"]");
      return(false); // 偽を返して終了 
     }
//--- 時刻が異なる場合
   if(new_bar!=time_last_bar[0])
     {
      new_bar=time_last_bar[0]; // 時間を設定して終了 
      return(true); // 時間を記憶し、trueを返す
     }
//--- ここまで来たのだから、バーは新しいものではない。
   return(false);
  }
 
Sergey Voytsekhovsky:

CheckNewBar関数の中で、静的変数 new_barは最初の行でゼロにされ、関数のロジックはそれがゼロに等しいかどうかに基づいています。どこがわからないか教えていただけませんか?

ヘルプにはこうあります:

staticというキーワードで宣言されたローカル変数は、関数が存在する 間ずっとその値を保持します。そのようなローカル変数は、次に関数を呼び出すたびに、前回の呼び出し時の値を保持します。

つまり、CheckNewBar()関数の新しい呼び出しでは、new_bar変数は前の呼び出しで受け取った値を保持しますが、最初の行では新しい値NULLが代入されます。私の混乱を払拭してください、おそらく私はどこか愚かなのでしょうが、WHERE?

 
Sergey Voytsekhovsky:

CheckNewBar関数の中で、静的変数 new_barは最初の行でゼロにされ、関数のロジックはそれがゼロに等しいかどうかに基づいています。どこがわからないか教えていただけませんか?

ヘルプを正しく理解していれば、static datetimenew_bar=NULL; という行で、「初期値が指定されていない場合、スタティック・メモリ・クラスの変数はゼロの初期値を取る」となっています。ということは、nullで初期化すべきではなく、ロジックは完璧なはずです。それとも違うのか?

 
Sergey Voytsekhovsky:

ヘルプを正しく理解していれば、static datetimenew_bar=NULL; という行は、"初期値が指定されていない場合、スタティック・メモリ・クラス変数はゼロの初期値を取る "ということです。ということは、nullで初期化すべきではなく、そうすればロジックは完璧になるはずだ。それとも違うのか?

変数は必ず初期化しなければならない。これは不文律だ。これを守らない人は、遅かれ早かれ、非常に見つけにくいエラーを犯すことになる)


静的変数の仕組み

//+------------------------------------------------------------------+
//|テストEA。mq5
//|Copyright © 2018, Vladimir Karputov |
//|http://wmua.ru/slesar/|( 英語
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
//+------------------------------------------------------------------+
//| エキスパート初期化関数|
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
|エキスパート初期化関数|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| エキスパートティック機能|
//+------------------------------------------------------------------+
void OnTick()
  {
//--- 新しいバーが誕生した時だけ働く。
   static datetime PrevBars=0;
   Print("PrevBars ",PrevBars);
   datetime time_0=iTime(Symbol(),Period(),0);
   if(time_0==PrevBars)
      return;
   PrevBars=time_0;
   Print("New bar. PrevBars ",PrevBars);
  }
//+------------------------------------------------------------------+


エキスパート・タブにプリントする。OnTick()への最初の入力は、静的変数 である新しいバーの 初期化 です。

2018.01.08 00:00:00   PrevBars 1970.01.01 00:00:00
2018.01.08 00:00:00   New bar. PrevBars 2018.01.08 00:00:00
2018.01.08 00:00:30   PrevBars 2018.01.08 00:00:00
2018.01.08 00:00:59   PrevBars 2018.01.08 00:00:00
2018.01.08 00:01:00   PrevBars 2018.01.08 00:00:00
2018.01.08 00:01:00   New bar. PrevBars 2018.01.08 00:01:00
2018.01.08 00:01:30   PrevBars 2018.01.08 00:01:00
2018.01.08 00:02:00   PrevBars 2018.01.08 00:01:00
ファイル:
Test_EA.mq5  4 kb
 
Vladimir Karputov:

変数は常に初期化しなければならない。これは不文律である。これを守らない人は、遅かれ早かれ、非常に見つけにくいエラーを犯すことになる)


静的変数の仕組み


エキスパート・タブへのプリントアウト。OnTick()への最初の入力は、静的変数 である新しいバーの 初期化 です。

簡潔でわかりやすい回答をありがとうございました。