English Русский 中文 Español Deutsch Português
MQL5をプログラミングの基礎: ターミナルのグローバル変数

MQL5をプログラミングの基礎: ターミナルのグローバル変数

MetaTrader 5 | 5 12月 2016, 11:46
2 443 0
Dmitry Fedoseev
Dmitry Fedoseev

コンテンツ


図1。グローバル変数のコード

他のプログラミング言語でよく知られているグローバル変数 (図2) とターミナルのグローバル変数を混同しないようにします


図2。ターミナルの移動平均 EA のコード フラグメントです。プログラムのグローバル変数は、赤で強調表示されています。

ターミナルのグローバル変数は、他のプログラミング言語の完全一致でないので、 MQL5初心者には人気がありません。どのように使用するかわからず、応用が面倒であるため、複雑に感じられるようです。: GlobalVariableSet()、GlobalVariableGet()、GlobalVariableCheck() など。

ターミナルのグローバル変数の主な関数はターミナルの終了後も、その値を保持することです。重要なデータを格納するため、非常に便利な高速な手段を提供し、オーダー間の複雑な相互作用を含む信頼性の高い EA を開発するときには、不可欠です。これをマスターしたら、グローバル変数なしでは EA開発ができなくなります。

この記事では、関数とアプリケーションのメソッドを検証し、開発を大幅に簡素化し、作業を加速するクラス グローバル変数を操作するためのすべての関数を学ぶことができる実践的な例を提供します。

ここでMQL5ドキュメントのグローバル変数を操作する関数があります。 

ターミナルでのグローバル変数の表示

ターミナルで次のコマンドを実行: メイン メニュー-ツール-グローバル変数。[グローバル変数] ウィンドウ (図3) が表示されます。

 
図3。ターミナルのグローバル変数ウィンドウ 

基本的に、グローバル変数のすべてがプログラムによって実行されますしかし、EA をテストするとき、このウィンドウが役に立つ可能性があります。すべてのターミナルのグローバル変数を表示できるだけでなく、名前と値を編集することができます。変数を変更するには、その名前または値のフィールドをクリックします。また、ウィンドウでは、新しい変数を作成することができます。これを行うには、右上の追加をクリックします。削除ボタンを使用してグローバル変数を削除します。削除する前に、ボタンアクティブに必要な変数をクリックします。グローバル変数の作成、変更および削除の練習をします。注: 既にウィンドウに変数が含まれている場合、EA はアカウントを開始した可能性があります。

グローバル変数には 3 つの属性: 名前、値および時間があります。時間フィールドは、変数が最後にアクセスしたときに表示されます。最終アクセス後、4 週間の有効期限を過ぎると、変数は自動的に削除されます。ただし、変数には、重要なデータが保存されている場合、定期的にアクセスされ、その有効期間を延長します。  

ターミナルのグローバル変数の作成

値が割り当てられたときに、変数は自動的に生成されます。指定された名前の変数が既に存在する場合は、その値が更新されます。GlobalVariableSet()関数を使用して、変数に値を代入しています。2つのパラメータが関数に渡されます: 変数名 (文字列) とその値 (ダブル型)。変数を作成してみましょう。MetaEditor を開き、スクリプトを作成し、OnStart() 関数に以下のコードを記述します。

GlobalVariableSet("test",1.23);

 スクリプトを実行し、ターミナルからグローバル変数ウィンドウを開きます。ウィンドウには、「テスト」という名前の新しい変数と 1.23 (図4) の値があるはずです。

 
図4。新しい「テスト」変数とグローバル変数ウィンドウのフラグメント

この例のコードは、sGVTestCrEAte スクリプトにあります。

グローバル変数の値を受信

前の例のスクリプトがその作業を完了しても、変数はまだ存在します。その値を見てみましょう。GlobalVariableGet()関数は、値を受け取るために使用されます。関数の呼び出しメソッドが2 つあります。最初の 1 つを適用すると、関数名のみが渡されます。この関数は、double 型の値を返します。

double val=GlobalVariableGet("test");
Alert(val);

コードを実行する、1.23 の値とウィンドウが開かれます。下記の添付 sGVTestGet1 にスクリプトの例があります。。

2 番目のメソッドを適用すると、-名前と2重変数の値 (2 番目のパラメータは、リンクによって渡される)-2 つのパラメータはtrueまたはfalseの結果に応じてを返す関数に渡されます。

double val;
bool result=GlobalVariableGet("test",val);
Alert(result," ",val);

メッセージ「true 1.23」とウィンドウが結果として開かれます。

存在しない変数の値を表示しようとすると、関数はfalseと 0 を返します。少し前のコード サンプルを変更してみましょう: 1.0 の割り当てる 'val' 変数と"test2"変数の値。

double val=1.0;
bool result=GlobalVariableGet("test2",val);
Alert(result," ",val);

メッセージ「false 0.0」とウィンドウが結果として開かれます。下記の添付 sGVTestGet2 2 スクリプトの例があります。

最初のメソッドを使用して関数を呼び出すと、 存在しない変数の場合 0.0 が得られます。ただし、エラーをも受信します。最初の関数呼び出しを使用して、メソッド、エラー チェック、2 つ目の関数法のアナログを得る可能性があります。

ResetLastError();
double val=GlobalVariableGet("test2");
int err=GetLastError();
Alert(val," ",err);

コードの操作の結果としてメッセージ「0.0 4501」が開かれます。(例は sGVTestGet1-2 スクリプトにあります。)0.0 の値、4501 は、エラー コード-で"クライアント ターミナルのグローバル変数が見つかりません"。重大なエラーというほどではありません。アルゴリズムが可能にする場合、存在しない変数を参照します。たとえば、最大資産を追跡するとします。

GlobalVariableSet("max_equity",MathMax(GlobalVariableGet("max_equity",AccountInfoDouble(ACCOUNT_EQUITY)));

"Max_equity"変数が存在しない場合でも、コードは正しく動作します。最初に、MathMax() 関数は、"max_equity"変数に保存されている実際の資産と最大の値を選択します。変数が存在しないので、実際の資産価値を出します。

グローバル変数名

グローバル変数名は、文字列です。シンボル名の文字とそのオーダーに制限はありません。キーボードでエントリーできる文字は、ファイル名にスペースとが禁止されている文字を含む名前で使用できます。ただし、文字、数字、アンダー スコアの一般的な変数に似ているシンプルな名前を選択します。

グローバル変数の名前を選択するときに、1つ重要な制限があります。-名前の長さ: 63 文字以内。

変数の確認

GlobalVariableCheck()関数は、変数が存在するかどうかを確認する際に使用されます。1つのパラメータが関数に渡されます-変数名。変数が存在する場合、関数はtrue、それ以外の場合、 falseを返します。"test"と"test2"変数が存在するかどうかをチェックしてみましょう。

bool check1=GlobalVariableCheck("test");
bool check2=GlobalVariableCheck("test2");
Alert(check1," ",check2);

次の例は、下記の添付 sGVTestCheck スクリプトにあります。"true false"メッセージがスクリプト操作の結果としてあり、-一方"test2"はそうではありません。

変数の存在の確認が必要な場合、たとえば、最小を追跡する場合です。上記の例では最大の資産の追跡に関連する MathMin() と MathMax() 関数を置き換え、常に 0 が格納されます。

この例では、変数の存在の確認ができます。

if(GlobalVariableCheck("min_equity")){
   GlobalVariableSet("min_equity",MathMin(GlobalVariableGet("min_equity"),AccountInfoDouble(ACCOUNT_EQUITY)));
}
else{
   GlobalVariableSet("min_equity",AccountInfoDouble(ACCOUNT_EQUITY));

変数が存在する場合は、MathMin() 関数を使用して、最小値を選択します。そうでなければ、すぐに資産額を割り当てます。

グローバル変数の時間

図3で見たグローバル変数には、 GlobalVariableTime()関数を使用して取得できます。1つのパラメータが関数に渡されます-変数名。この関数は、datetime 型の値を返します。

datetime result=GlobalVariableTime("test");
Alert(result);

このコードは、下記の添付 sGVTestTime スクリプトにあります。可変時間属性値を変更すると、アクセスするときにのみ、すなわち他関数は GlobalVariableSet() と GlobalVariableGet() 関数を使用して変数の時間値を変更できます。グローバル変数ウィンドウで変数を手動で変更した場合、時間は関係なく、値または名前が変更されます。

すでに述べたように、変数にアクセスして4 週間経つと、その後ターミナルによって自動的に削除されます。 

すべてのグローバル変数を表示

ときとして、正確な名前がわからないグローバル変数が必要です。たとえば、始まりだけ思い出すかもしれません: gvar1、gvar2、等。このような変数を見つけるためには、ターミナルのすべてのグローバル変数を反復処理し、名前を確認する必要があります。これを行うには、GlobalVariablesTotal() GlobalVariableName()関数を使う必要があります。GlobalVariablesTotsl() 関数は、グローバル変数の合計数を返します。GlobalVariableName() 1 つは、インデックスを使用して変数名を返します。一つの int 型パラメータが、関数に渡されます。まず、すべての変数の名前と値をメッセージ ボックスに表示します。

   Alert("=== Start ===");
   int total=GlobalVariablesTotal();
   for(int i=0;i<total;i++){
      Alert(GlobalVariableName(i)," = ",GlobalVariableGet(GlobalVariableName(i)));
   }

その結果 (図5) に、すべての変数の名前と値を持つウィンドウが開かれます。コードは、下記の添付 sGVTestAllNames スクリプトで見つけることができます。

 
図5。ターミナルのすべてのグローバル変数が含まれているメッセージ ウィンドウ

名前で特定の属性を持つ変数を表示するために新しいチェックを追加してみましょう。次の例では、変数名の先頭"gvar"をチェック (sGVTestAllNames2 スクリプトでこの例を見つけることができます):

   Alert("=== Start ===");
   int total=GlobalVariablesTotal();
   for(int i=0;i<total;i++){
      if(StringFind(GlobalVariableName(i),"gvar",0)==0){
         Alert(GlobalVariableName(i)," = ",GlobalVariableGet(GlobalVariableName(i)));
      }
   }

StringFind()関数を使用してチェックされます。文字列関数のスキルを向上したい場合は、MQL5をプログラミングの基礎: 文字列をご覧ください。

グローバル変数の削除

1 つのグローバル変数を削除し、GlobalVariableDel()関数は単一のパラメータを受け取ります: 以前に作成した「テスト」変数 (sGVTestDelete スクリプト下に添付) を削除します。

GlobalVariableDel("test");

操作の結果を確認するために sGVTestGet2 1 または sGVTestGet2 2 スクリプトを使用または、グローバル変数ウィンドウを開く可能性があります。

単一の変数の除去は、簡単ですが、ほとんどの場合 1 つ以上の変数を削除します。GlobalVariablesDeletEAll()関数を使用。2 つの省略可能なパラメータが、関数に渡されます。パラメータを指定しないで関数を呼び出すと、すべてのグローバル変数は削除されます。通常、同じプレフィックス (名前の先頭) を持つ変数のグループのみを削除する必要があります。最初の関数パラメータを使用して、プレフィックスを指定します。この関数を使って実験してみましょう。まず、別のプレフィックスの変数を作成する必要があります。

   GlobalVariableSet("gr1_var1",1.2);
   GlobalVariableSet("gr1_var2",3.4);   
   GlobalVariableSet("gr2_var1",5.6);
   GlobalVariableSet("gr2_var2",7.8);  

このコードは、4 つの変数を作成します: gr1_ を持つ 2 つのものは、_gr2 プレフィックスを持つ別の 2 つのものだけでなく、プレフィックスします。このコードは、下記の添付 sGVTestCrEAte4 スクリプトで見つけることができます。SGVTestAllNames スクリプト (図6) を起動してスクリプト操作の結果を確認します。

 
図6。GVTestCrEAte4スクリプトによって作成された変数

gr1_ で始まる変数を削除 (下記 sGVTestDeleteGroup スクリプト)。

GlobalVariablesDeletEAll("gr1_");

コードを実行した後に、もう一度 sGVTestAllNames スクリプト (図7) を使用してすべての変数を表示します。gr1_ で始まる 2 つのものを除いてすべての変数のリストをもう一度表示されます。

 
図7。gr1_ で始まる変数が削除されています。

GlobalVariableDeletEAll() 関数の 2 番目のパラメータは、古い変数のみを削除する場合に使用されます。日付は、このパラメータで指定されます。変数への最後のアクセスの日付が小さい場合は指定された 1 つ以上の変数が削除されます。同等または以下の時間で、少ない時間を含む変数のみが削除されることに注意してください。こkの変数は、接頭辞によってさらに選択できます。プレフィックスによって選択が必要ない場合は、既定の NULL 値が最初のパラメータとして設定されます。

GlobalVariablesDeletEAll(NULL,StringToTime("2016.10.01 12:37"));

現実には、時間による変数の削除のみは非常に稀で、珍しいタスクを解決するために必要です。したがってそのトピックにあまりこだわる必要はありません。

GlobalVariablesFlush 関数

ターミナルを閉じるとき、グローバル変数は、その起動時にターミナルで再度ダウンロードするファイルに自動的に保存されます。プロセスのすべての機微を知る必要はありません (ファイル名、データ ストレージ形式、等)グローバル変数を使用するときは特にそうです

ターミナルが急にシャット ダウン場合、グローバル変数が失われることがあります。GlobalVariableFlush()関数は、この問題を回避するのに役立ちます。この関数は、グローバル変数を強制的に保存します。GlobalVariableSet() 関数によって値が設定されて、変数が削除されます。後は、GlobalVariableFlush() 関数を呼び出すだけです。パラメータを指定せずに関数を呼び出す: 

   GlobalVariableSet("gr1_var1",1.2);
   GlobalVariableSet("gr1_var2",3.4);   
   GlobalVariableSet("gr2_var1",5.6);
   GlobalVariableSet("gr2_var2",7.8);   
   
   GlobalVariablesFlush();

このコードは、付属の sGVTestFlush ファイルで見つけることができます。 

GlobalVariableFlush() は、関数の処理を説明するために良いでしょうが、残念ながら、ターミナルの緊急シャット ダウンの間に消えるグローバル変数を作り損いました。タスク マネージャーの [プロセス] タブを介してターミナル操作が中断されました。グローバル変数は、PC のシャットダウンで消えることがあります。大多数のユーザーPC は通常、無停電電源装置を備えいるノート パソコンを持っているので、予期しない PC 停電は今日ではほとんど行われません。専用のサーバーで動作する場合、電源障害に対する保護はさらに重要ですしたがって、グローバル変数は、GlobalVariableFlush() 関数がなくてもデータを保存するためのかなり信頼できる手段です。    

一時変数、GlobalVariableTemp 関数

GlobalVariableTemp() 関数は、(つまり、ターミナルのストップまでに存在する) 一時的なグローバル変数を作成します。MQL5上で EA を開発して数年、そのような変数の必要性を直面しています。また、一時的なグローバル変数の概念が応用の基本原理と矛盾する — 長期的なデータ ストレージ ターミナル立ち上げによる影響を受けません。しかし、 注意が必要な場合が必要があります。

1 つのパラメータの関数を呼び出すとき、変数名-渡されます。このような名前の変数が存在しない場合は、0 の値を一時変数が作成されます。その後に、GlobalVariableSet() 関数を使用して値を割り当てるので、いつものように使用することができます。変数が既に存在する (以前 GlobalVariableSet() 関数によって作成された) 場合、一時的なものには変換されません。

   GlobalVariableSet("test",1.2); //変数が存在するかどうかを確認する値の変数を設定
   GlobalVariableTemp("temp"); //一時変数を作成
   Alert("temp variable value right after crEAtion - ",GlobalVariableGet("temp"));
   GlobalVariableSet("temp",3.4); //一時変数の値を設定
   GlobalVariableTemp("test"); //「テスト」変数を一時的なものに変換

次の使用例は、下記の添付 sGVTestTemp ファイルで見つけることができます。スクリプトを開始した後に、グローバル変数ウィンドウを開きます。3.4 の値を持つ"temp"変数と"test"1.2 の値を含める必要があります。グローバル変数ウィンドウを閉じます。その後、ターミナルを再起動し、再度ウィンドウを表示します。以上で"temp"、「テスト」の変数が保存されます。

GlobalVariableSetOnCondition 関数によって変数を変更

最終的に考慮するのは、最も興味深い関数: GlobalVariableSetOnCondition()です。3つのパラメータが、関数に渡されます: 名前、新しい値、テスト値です。変数の値は 1 つのテストに等しい、新しい値を受け取り、関数がtrueを返します。同じ変数が存在しない場合、falseを返します。

動作原理で、この関数は、次のコードに似ています。

   double check_value=1;
   double value=2;

   if(GlobalVariableGet("test")==check_value){
      GlobalVariableSet("test",value);
      return(true);
   }
   else {
      return(false);
   }

「テスト」のグローバル変数が check_value に等しい場合、値が割り当てられると、 trueが返され、それ以外の場合、 falseになります。Check_value 変数は、 falseが返され、「テスト」グローバル変数が存在しない場合は、1 にあります。

GlobalVariableSetOnCondition() 関数の主な目的は、 EAに一貫性のある実行をさせることです。以来、現代のオペレーティング システム、マルチ タスク プログラムは、全ての EA がすべてのタスクを実行できるようになることを誰も保証することができません。

MT4 の操作で経験があれば、トレードの流れに覚えがあるでしょう。EAが同時にリクエストサーバーに送信する可能性があり、特定のタイミングでリクエストを送信することができます。ターミナルにいくつかのEA があった場合、激しいトレードフロー エラーが発生し、頻繁に実行します。EA がポジションを開いたり閉じたり、試行を繰り返すので、エラーは想像以上のようでした。その上、異なる EA が同じポイントでポジションをクローズするのは、非常にまれな機会でした。しかし、トレーリング ストップ (EA ではなく、ターミナルに組み込まれている) 関数が EA でアクティブ化された場合、 ティックあたりのストップロスを変更される可能性がありました。にもかかわらず、ありえないような問題現在、まだE Aの実行にあります。 

述べられたグローバル変数は、EAグループの一貫した作業を確保するため使用されます。OnTick() 関数の実行の開始時、他の EA は、待っているサイクルをエントリーを確認できるように値を変数に代入します。EAは、すべての必要な操作を完了すると、 変数に check_value を割り当て、他の EA はその OnTick() 関数などを実行することができます。

上に表示されるコードは、タスクを解決するため、 確認するをことはできません。

if(GlobalVariableGet("test")==check_value){

文字列によって続いて実行されます。 

GlobalVariableSet("test",value);

他の EA が間に割り込み、check_value を検出した後に作業を開始します。部分的にそのタスクを実行した後、最初の EA は、その操作を続行する可能性があります。したがって、2 つの EA が同時に動作する可能性があります。GlobalVariableSetOnCondition() 関数は、この問題を解決します。前述のマニュアルは、、「グローバル変数のアトミック ・ アクセスを提供します」。原子が「不可分」ということです。したがって、新しい値を割り当てると変数の値の検証中に他のプログラムを割り込むことはありません。

この関数の唯一の欠点は、後者がない場合変数を作成しないことです。つまり、(EA の初期化中に) 追加のチェックを実施し、変数を生成する必要があります。 

実験を実行するために 2 つの EA を書いてみましょう。両方の EA は完全に同じです。3 秒間の一時ストップ (Sleep() 関数) に続いて OnTick() 関数の開始時にメッセージ ウィンドウが表示されます。"EA1 エンド"のメッセージが最後に表示されます。

void OnTick(){
   Alert("EA1 start");   
   Sleep(3000);   
   Alert("EA1 end");
}

メッセージは異なりますが、2 番目の EA は同様です。:「EA2 を開始」と「EA1を終了」。添付の EA は eGVTestEA1 と eGVTestEA2 という名前です。ターミナルで 2 つの同一のチャートを開き、EAを付けます。EA が起動し、同時に仕事を終了、メッセージ ウィンドウが表示されます (図8)。


図8。EAメッセージ OnTick() 関数の実行開始と終了について

一貫性のある EA 操作を提供するために GlobalVariableSetOnCondition() 関数を適用してみましょう。挿入の変更は両方の EAで同一です。コードを書いてみましょう。このファイルは、GVTestMutex.mqh (下記) と呼びます。

GVTestMutex.mqh ファイルの関数を見てみましょう。EA の初期化中にグローバル変数が存在するかを確認し、必要に応じてを作成します (Mutex_Init() 関数)。単一のパラメータ、変数名、関数に渡されます。

void Init(string name){
   if(!GlobalVariableCheck(name)){
      GlobalVariableSet(name,0);
   }
}

2 番目の関数 (Mutex_Check())が、検証に使用されます。関数のグローバル変数のリリースを待っているサイクルが実行されます。変数がエントリーされると、関数はtrueを返し、OnTick() 関数を実行します。変数が指定された時間内で解除されていない場合、関数はfalseを返します。OnTick() 関数の実行はその場合は中断する必要があります。

bool Mutex_Check(string name,int timeout){   
   datetime end_time=TimeLocal()+timeout; //終了時刻を待機
   while(TimeLocal()<end_time){ //指定した時間内のサイクル
      if(IsStopped()){
         return(false); //EA をチャートから削除する場合
      }
      if(GlobalVariableSetOnCondition(name,1,0)){ 
         return(true);
      }
      Sleep(1); //一時ストップ
   }   
   return(false); //リリースの待機に失敗
}

グローバル変数名と秒の待機時間は、関数に渡されます。

3番目の関数は、Mutex_RelEAse() です。他の EA が自分のタスクを開始することができるようにグローバル変数 (リリース) の場合は 0 の値を設定します。

void Mutex_Release(string name){
   GlobalVariableSet(name,0);
}

EA は 1 つのコピーを作成、ファイル、関数の呼び出しを追加します。変数名は、"mutex_test"です。30 秒のタイムアウトで Mutex_Check() 関数をコールします。下における EA のコードが表示されます。

#include<GVTestMutex.mqh>

intOnInit(){
   Mutex_Init("mutex_test");
   return(INIT_SUCCEEDED);
}

void OnTick(){

   if(!Mutex_Check("mutex_test",30)){
      return;
   }

   Alert("EA1 start");
   Sleep(3000);
   Alert("EA1 end");

   Mutex_RelEAse("mutex_test");

}

EA のコピーを作成し、表示されるメッセージのテキストを変更してみましょう。EGVTestEA1-2、eGVTestEA2-2 と呼びます。図9で動作確認するための 2 つの同様のチャートに EA を起動します。

 
図9。EAが交代で作業しています。

タイムアウト パラメータに注意してください: グループ内全ての EA の動作時間を超える時間を設定します。OnTick() 関数実行中に EA がグラフから削除されますが、Mutex_RelEAse() 関数が実行されないことがあります。この場合、1 つの EA ではないがその順番を待つことになります。したがって、タイムアウト有効期限の場合、グローバル変数を 0 に設定または追跡する他のメソッドを見つける必要があります。特定のタスクに依存します。時々、EA 操作は許容範囲内、ターンで実行する必要があります。

グローバル変数の簡単な作業のクラス

グローバル変数をより便利に扱うために下記の点に注意してください。

  1. ユニーク変数名は各 EA のコピーで必要です。
  2. テスターで使用する変数の名前は、アカウントに使用されるものとは異なるはずです。
  3. EAは、テスターで動作する場合、各々の単一テストの実行の完了時にテスト中に作成したすべての変数を削除してください。
  4. 関数名を短くするグローバル変数を操作するための関数のより便利な呼び出しを提供します。
大体2つのタイプに分けることが可能で、EAでグローバル変数を使用する場合: オーダーにバインドされているものと共通のものがあります。EA操作に関連する一般的なものはデータの格納に使用されます: 例えば、ポジションのグループの最大の利益、イベントの時など。オーダーにバインドされた変数に単一のオーダー (またはポジション) に関連する追加データが含まれている: 例えば、多くの進行のシリーズでは、オープン価格のオーダーのインデックスなど。すべてのオーダーは、独自の一意なインデックス-チケットです。したがって、 変数 (「インデックス」、「価格」など) に保存されているデータの名前を定義する部分から名を形成する必要があります。オーダーチケットは、最大の長さが 63 文字を 43 文字があることを意味し、 20文字の最大長を持つ ulong 型の変数です。

一般的な変数名を形成するとき、状況はもう少し複雑です。可変長の大まかな試算を作ってみましょう。別のEAは、EA名の変数に使用できる最初の属性は、20 の文字です。同じEAが異なるシンボルで動作する可能性があります。2番目のユニークな関数が (4 文字) のシンボルであることを意味します。EAは、単一のシンボルに取り組んである、異なるオーダー Id-ulong 型のマジック ナンバー (最大長-20 文字)です。1つのターミナルからアカウントを切り替えることが可能です。口座番号は long 型変数 (最大長-19 文字)。許可された可変長で構成された 63 文字を受信し、プレフィックスの長さだけを迎えています!

つまり何かを犠牲にしています。ルール: 1 つのターミナルで 1 つのアカウントのみ動作します。複数のアカウントがある場合は、各ターミナルのインスタンスを設定します。最大プレフィックス サイズ 43 文字に減らすことと 20 文字をエントリーと口座番号を取り除くことができます。別のルールを追加する可能性があります: 長いマジック番号を使用しないでください。最後に、短い名前を与えて EA 名に注意を払うことは妥当でしょう。グローバル変数名は、EA の名から形成される、シンボル、マジック ナンバー考えられます。多分、より便利なメソッドを思い付くが、記事でこのメソッドに固執してみましょう。

クラスの作成から始めましょう。このクラスは CGlobalVariables という名前で、ファイル自体は CGlobalVariables.mqh と呼ばれます。以下に添付します。'Private' セクションにプレフィックスの 2 つの変数を宣言: 最初の 1 つ-共通変数、2 つ目のオーダーにバインドされているもの。

class CGlobalVariables{
   private:
      string m_common_prefix; //一般的な変数のプレフィックス
      string m_order_prefix; //オーダー変数のプレフィックス
   public:
      //コンス トラクター
      void CGlobalVariables(){}
      //デストラクター
      void ~CGlobalVariables(){}
}

Public' セクションで Init() メソッドを作成してみましょう。メソッドは、EA の初期化中に呼び出されることです。2 つのパラメータ-シンボルとマジック ナンバーが渡されます。プレフィックスは、このメソッドで形成されます。オーダー変数のプレフィックスは、EA 変数テスターで EA からアカウントで作業を分離するだけで、簡単です。したがって、アカウントのオーダー変数は、「order_」の中から開始し-"tester_order_"までです。テスターの一般的な変数のプレフィックスに"t _"を追加できます。 古いグローバル変数は、テスターの初期化中にも削除する必要があります。もちろん、同様に、処理中に削除する必要がありますが、 変数が残ることがあるテストの結果を確認できません。今のところは、DeletEAll() メソッドを作成し、呼び出します。'private' セクションにメソッドを配置することをお勧めします。このコードは、後で追加されます。Init() メソッドのコードは、下に表示されます。

void Init(string symbol,int magic){
   m_order_prefix="order_";
   m_common_prefix=MQLInfoString(MQL_PROGRAM_NAME)+"_"+symbol+"_"+IntegerToString(magic)+"_";
   if(MQLInfoInteger(MQL_TESTER)){
      m_order_prefix="tester_"+m_order_prefix;
      m_common_prefix="t_"+m_common_prefix;
      DeletEAll();
   }         
}

グローバル変数を含む特別なタスクに有用なように、一般的な変数のプレフィックスを返すメソッドを追加しましょう。

string Prefix(){
   return(m_common_prefix);
} 

基本的なメソッドを追加: チェック、設定、値を受信および削除する別の変数。2つのプレフィックスを持っているので、各関数 (異なるパラメータ セットが同じ名前を持つ 2 つの関数) のオーバー ロードを持つ 2 つのメソッドが必要です。1つだけのパラメータ-変数名、メソッドの 1 つのグループに渡されます。一般的な変数のメソッドです。チケットは、変数名は、関数の別のグループに渡されます。オーダー変数のメソッドは次のとおりです。

//共通の変数について
bool Check(string name){
   return(GlobalVariableCheck(m_common_prefix+name));
}
void Set(string name,double value){
   GlobalVariableSet(m_common_prefix+name,value);      
}      
double Get(string name){
   return(GlobalVariableGet(m_common_prefix+name));
} 
void Delete(string name){
   GlobalVariableDel(m_common_prefix+name); 
}
//オーダー変数
bool Check(ulong ticket,string name){
   return(GlobalVariableCheck(m_order_prefix+IntegerToString(ticket)+"_"+name));
}
void Set(ulong ticket,string name,double value){
   GlobalVariableSet(m_order_prefix+IntegerToString(ticket)+"_"+name,value);      
}      
double Get(ulong ticket,string name){
   return(GlobalVariableGet(m_order_prefix+IntegerToString(ticket)+"_"+name));
} 
void Delete(ulong ticket,string name){
   GlobalVariableDel(m_order_prefix+IntegerToString(ticket)+"_"+name); 
} 

DeletEAll() メソッドに戻り、プレフィックスの変数を削除するためのコードを記述します。

GlobalVariablesDeletEAll(m_common_prefix);
GlobalVariablesDeletEAll(m_order_prefix);  

削除は、テスターでは EA処理中に呼び出される Deinit() メソッドを追加をテストした後実行できます。

 void Deinit(){
    if(MQLInfoInteger(MQL_TESTER)){
        DeleteByPrefix();
    }
 }

グローバル変数の信頼性を改善するために GlobalVariablesFlush() 関数を使用する必要があります。関数を別のメソッドに追加してみましょう。(ポイント 4 に記載されている要件を満たす) 長い名前の関数を書くのではなく、クラスのメソッドを呼び出すのは簡単です。

void Flush(){
   GlobalVariablesFlush();
}

場合によっては、追加のプレフィックスを追加して、グループで共通の変数を組み合わせ、EA操作中にグループを削除する必要があります。もう一つ DeletByPrefix() メソッドを追加しましょう。

void DeleteByPrefix(string prefix){
   GlobalVariablesDeletEAll(m_common_prefix+prefix);
}

この結果、グローバル変数を操作するときに、タスクの 95% を解決できるように十分なクラスを取得しています。

クラスを使用するために EA に次のファイルが含まれます。

#include<CGlobalVariables.mqh>

オブジェクトを作成します。

CGlobalVariables gv;

シンボルとマジック ナンバーを渡すことによって、EA は初期化中に Init() メソッドを呼び出します。

gv.Init(Symbol(),123);

テスターから変数を削除するのには処理中 Deinit() メソッドを呼び出します。

gv.Deinit();

その後、EA を開発するときに、たとえば変数名だけのユニークな部分を渡して Delete()、Get() Set() メソッドを使用します。

   gv.Set("name1",123.456);
   double val=gv.Get("name1");

EA操作の結果として eGVTestClass_GBPJPY_123_name1 をという名前の変数は、グローバル変数 (図10) の一覧に表示されます。

 
図10。CGlobalVariables クラスを使用して作成された変数とグローバル変数ウィンドウのフラグメント

可変長の変数名を選択する際に比較的自由である29 の文字です。オーダー変数が常に完全な名前を形成し、行、チケットに変換する IntegerToSTring() 関数を呼び出す必要はないと、グローバル変数が大きく簡素化します。クラスの例は 下記 eGVTestClass で利用可能です。

また、さらに簡素化するクラスを変更することが可能です。クラスのコンス トラクターとデストラクターの改良です。Init()メソッドの呼び出し、適切なパラメータを持つコンス トラクターとデストラクターに Deinit() メソッド呼び出しを追加してみましょう。

void CGlobalVariables(string symbol="",int magic=0){
   Init(symbol,magic);
}
//デストラクター
void ~CGlobalVariables(){
   Deinit();
}

その後、Init() と Deinit() メソッドを呼び出す必要はありません。代わりに、クラスのインスタンスを作成するとき、シンボルとマジックナンバーを指定するだけです。

CGlobalVariables gv(Symbol(),123);

結論

この記事では、GlobalVariableSetOnCondition() 関数を含むターミナルのグローバル変数を操作するためのすべての関数を行いました。また、EAを作成するとき、グローバル変数の使用を大幅に効率化するクラスを作成しました。もちろん、このクラスではグローバル変数を使用するすべての関数は含まれませんが、最も必要があり、頻繁に使用されるものです。常に改善し、必要に応じて独自のものを開発できます。 

添付

  • sGVTestCrEAte、変数を作成します。
  • sGVTestGet1 — 値を受信する最初のメソッド。
  • sGVTestGet2-2番目の値を受け取るメソッド。
  • sGVTestGet1-2-存在しない変数の値を受信の最初のメソッド。
  • sGVTestGet2-2 2番目の存在しない変数の値を受け取るメソッド。
  • sGVTestCheck-変数の存在をチェックします。
  • sGVTestTime-可変時間を受信します。
  • sGVTestAllNames-すべての変数の名前の一覧を受信します。
  • sGVTestAllNames2 — 指定したプレフィックスで名前の一覧を受信します。
  • sGVTestDelete - 変数を削除します。
  • sGVTestCrEAte4-(2 つの変数と 2 つのグループ) の 4 つの変数を作成します。
  • sGVTestDeleteGroup - 変数の 1 つのグループを削除します。
  • sGVTestFlush - 変数を強制的に保存
  • sGVTestTemp-一時的な変数を作成します。
  • eGVTestEA1、eGVTestEA2-同時に複数のEAを操作
  • GVTestMutex.mqh-ミュー テックスの開発のための関数。
  • eGVTestEA1-2、eGVTestEA1-2、EAのターンでの作業を示します。
  • CGlobalVariables.mqh-グローバル変数を操作するための CGlobalVariables クラスです。
  • eGVTestClass-EA CGlobalVariables クラスを使用するメソッドをデモンストレーションします。



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

添付されたファイル |
files.zip (10.44 KB)
「タートルスープ」トレードシステムと ' タートル スープ プラス一 ' 「タートルスープ」トレードシステムと ' タートル スープ プラス一 '
この記事では、2つのトレードシステム「タートルスープ」と「タートル スープ プラスワン'のルールについて扱います。リンダ ・ ブラッドフォード ・ ラシュキ と ローレンス a. コナーズによる 高確率短期のトレード戦略です。この戦略は、かなり人気があります。15~20年間の相場の動きに基づいてを開発したものです。
グラフィカルインタフェースX: 標準チャートコントロール(ビルド4) グラフィカルインタフェースX: 標準チャートコントロール(ビルド4)
今回は、標準のチャートコントロールについて考えていきます。これによって水平スクロールを同期させる機能を持つサブチャートの配列の作成が可能になります。また、引き続き、ライブラリのコードを最適化してCPU負荷を軽減します。
80-20 トレード戦略 80-20 トレード戦略
この記事では、80-20 トレード戦略を分析するためツール (インジケーターおよびEA) の開発について説明します。トレードルールは"ストリートスマート"より引用します。リンダラッシュクとローレンス · コナーズによる"短期的なトレード戦略”です。mql5を使用して、戦略ルールを定式化し、最近の相場のヒストリーベースで、インディケータとEAをテストします。
MQL5 プログラミングの基礎: ファイル MQL5 プログラミングの基礎: ファイル
この実践向きの記事は、MQL5 内のファイルの操作に焦点を当てています。基本を把握し、スキルを磨くことができるシンプルなタスクを提供しています。