FX・ビットコイン・オプションのシステムトレード開発と取引録

FXとビットコインのシステムトレードの開発録、オプション取引の履歴を書き連ねています。MT4, Pythonで開発しています。

MQL4ブック MT4

グローバル変数

スポンサードリンク

グローバル変数

 

複数のアプリケーションプログラムは同時にクライアント端末で動作することができる。 場合によっては、あるプログラムから別のプログラムにデータを渡す必要が生じることがあります。 特にこのMQL4には、クライアント端末のグローバル変数があります。

クライアント端末のグローバル変数は変数であり、その値はクライアント端末で開始されたすべてのアプリケーションプログラムから利用可能である(省略形:GV)。

 

クライアント端末のグローバル変数とグローバル変数は、同じ名前の異なる変数です。 グローバル変数のスコープは変数が宣言されている1つのプログラムです。 クライアント端末のグローバル変数の範囲は、クライアント端末で起動されるすべてのプログラムである。

グローバル変数のプロパティ

 

他の変数とは異なり、グローバル変数(GV)はどのプログラムからも作成できるだけでなく、削除することもできます。 GV値は、ハードディスクに保存され、クライアント端末が閉じられると保存されます。 宣言されたGVは、最後の呼び出しの瞬間から4週間、クライアント端末に存在します。 この期間にこの変数を呼び出さなかったプログラムは、クライアント端末によって削除されます。 GVはダブルタイプのものに過ぎません。

グローバル変数を扱うための関数

 

GVを扱うためのMQL4には一連の関数があります( GlobalVariablesも参照してください)。 さらなる例で使用されるものを分析してみましょう。

関数GlobalVariableSet()

この関数は、グローバル変数の新しい値を設定します。 変数が存在しない場合、システムは新しいグローバル変数を作成します。 正常に実行された場合、関数は最後のアクセスの時刻を返します。それ以外の場合は0を返します。エラー情報を取得するには、関数GetLastError()を呼び出す必要があります。

パラメーター:

name - グローバル変数の名前。

value - 新しい数値。

 

関数GlobalVariableGet()

この関数は、既存のグローバル変数の値を返します。エラーの場合は0を返します。エラー情報を取得するには、関数GetLastError()を呼び出す必要があります。

パラメーター:

name - グローバル変数の名前。

 

関数GlobalVariableDel()

この関数は、グローバル変数を削除します。 削除が成功した場合はTRUEを返し、そうでない場合はFALSEを返します。 エラー情報を取得するには、関数GetLastError()を呼び出す必要があります。

パラメーター:

name - グローバル変数の名前。

 

GlobalVariablesを使用する利便性と利点を示すために、以下の問題を解決しましょう:

問題24.複数のエキスパートアドバイザーが同時に端末で作業する。 預金は10,000ドルです。すべての未払い注文の合計金額は預金の30%を超えてはいけません。 同等の金額を各エキスパートアドバイザーに割り当てる必要があります。 取引のために割り当てられた合計を計算するEAプログラムを作成します。

取引のためにEAに割り当てられた合計の計算は難しくありません。 ただし、この計算を行うためには、プログラムで開始されたエキスパートアドバイザーの数を同時に把握する必要があります。 この質問に答えることのできるMQL4の機能はありません。 起動されるプログラムの数をカウントする唯一の可能性は、各プログラムが特定のGVの値を変更することによってそれ自体を発表する必要があることです。 さらに、この情報を必要とするすべてのプログラムは、このGVを参照して現在の状態を検出することができます。

一般的に、すべてのプログラムがこのような問題を解決するためのものではないことに注意してください。 存在を公表しないエキスパートアドバイザーが発生した場合、カウントされません。 そのため、この場合、問題定義では、GV値を変更し、さらにこの変数の値を読み取るために必要なコードを含むEAのみを使用することが前提となっています。

GlobalVariables( globalvar.mq4 )を使用しているエキスパートアドバイザーです。 問題24を解くのに使うことができます:

このEAには3つの特別な機能があります。 関数init() - EAがセキュリティウィンドウにアタッチされているときに、deinit() - EA IDがセキュリティウィンドウから切り離されたときに、start() - ティックが来ると、特別な関数がすべてクライアント端末によって開始されます。 先頭のプログラム部分には、グローバル変数の宣言が含まれます(このような変数のスコープはプログラム全体です)。

EA間の資金配分は、変更可能な1つのパラメータ、つまり同時に動作するEAの数に依存します。 そのため、EAsの量を反映するGVが唯一のものでなければならない理由は、その名前が次の行に設定されているからです。

注:GlobalVariableの名前は、実行可能プログラムで計算することができます(他の変数の名前は、プログラム作成の段階でプログラマが設定します)。

プログラムの実行時に変数Quantityの値がどのように変更されて処理されるかを詳細に分析しましょう。 まず、セキュリティウインドウに接続されているEAは、端末内で作業している他のEAがそのことを知ることができるように、その存在をアナウンスする必要があります。 これはおそらく早い段階で行う必要があります(おそらくEAをセキュリティウィンドウに接続する瞬間に近い)。 そのための最適な場所は、特殊関数init()です。 このファンクションの最初の行で、EAは変数Quantityの現在の値を要求します。 関数GlobalVariableGet()は、この目的に使用されます。

現在、GV Quantityの値は、EAの添付ファイルの瞬間に関係なく、1つ増やさなければなりません。つまり、接続されているEAが端末で同時に動作するEAの数を1増加させることを意味します。

利便性のために、プログラムではグローバル変数エキスパートが使用されています。 その値は他のEAでは利用できません。 GV数量の値を変更するには、新しいGV値を設定する関数GlobalVariableSet()を使用します。

エキスパートの新しい価値がGV数量に割り当てられていることを意味します。 現在、この新しいGV値は端末で動作しているすべてのプログラムで使用可能です。 その後、ちょうど添付されたEAへの取引のために割り当てられた所望の合計が計算され、警告が生成される(ここでは、EAイベントが発生する時期と時期を示すためにアラートが必要である。

私たちのEAは、添付されたEA(それ自体もカウントされています)に基づいてのみ、希望の合計を計算したことに注意してください。 init()の実行が終了すると、制御がクライアント端末に渡され、EAは新しいチックを待つようになります。 新しいチックが来たら、ターミナルは特別な機能start()を起動します。

今私たちの問題の中で、EAの目的は、現在の量の添付されたEAをトレースしています - エキスパートアドバイザーは、取り付けと取り外しが可能です。 その結果、同時に動作するEAの量が変化する可能性があります。 これに応じて、EAは問題の設定に従って割り当てられた合計を再計算する必要があります。 だから、新しいティックごとにEAが最初に行ったことは、GV Quantityの新しい価値を要求していることです。

この新しい値New_Expertsが最後に既知のエキスパートと異なる場合、新しい値が現在のものとみなされ、取引のためにEAに割り当てられたMoneyが再計算され、対応するアラートが作成されます。

変数New_ExpertsとExpertが同じ場合、計算は行われず、さらにEAコード(関数start()では)で計算された変数Moneyの値が使用されます。 したがって、各ティックの状況に応じて、新しいMoney値が計算されるか、または前の値が使用されます。

離脱の段階で、問題24の計算に含まれる各エキスパートアドバイザーは、他のエキスパートアドバイザーにそれが切り離されたこと、すなわち同時に働くエキスパートアドバイザーの数が減少したことを知らせなければならない。 さらに、このEAが最後のものであれば、GVを削除する必要があります。 deini()を実行すると、EAの分離が識別されるため、対応するコードはこの関数内に正確に配置する必要があります。

deinit()のすべての計算は、あるオペレータ内で実行されます。 EAsの数が1に等しい場合、すなわちこのEAが最後のものである場合、GVは関数ClobalVariableDel()を使用して削除され、他の場合には(すなわち、EAsの数が1より大きい場合) GlobalVariableSet()関数を使用して変数Qualityに割り当てられます。 セキュリティウィンドウに接続されたままのEAは、start()の実行開始時に新しいQuality値を検出し、Moneyの希望値を再計算します。

GlobalVariablesの値は、対応する関数を使用して実行中のEAから読み取るか、または変更することができます。 GV値による直接計算はできません。 通常の式でGV値を使用するには、この値を他の変数に代入してこの変数を計算に使用する必要があります。 この目的のために、次の2つの変数が使用されています - エキスパートとNew_Experts

異なる証券の複数のウィンドウでglobalvar.mq4をコンパイルして起動することをお勧めします。 イベントシーケンスに応じて、対応するイベントがアラート機能のウィンドウに表示されます。 例えば:

イチジク。 55.連続した着脱の結果としての警告機能のウィンドウ内の警告
3つの異なる証券の窓口でEA globalvar.mq4の

クライアント端末にはツールバー「グローバル変数」を開くオプションがあり、リアルタイムモードでは現在開いているすべてのGlobalVariablesとその値を見ることができます。 このツールバーは、クライアント端末メニューのService >> Global Variables(F3キー)で利用できます。

イチジク。 同時にGlobalVariablesのツールバーは同時に
3つのEA globalvar.mq4が実行されます。

すべてのEAがデタッチされた後、このツールバーには、クライアント端末のオープンしているグローバル変数に関するレコードは含まれません。

GlobalVariablesを使用する際のエラー

 

異なる証券のウィンドウでEA globalvar.mq4を起動し、すべてのイベントを逐次追跡すると、コードが正常に動作することがわかります。 しかし、イベント間の休止がかなり大きい場合にのみそうです。 deinit()の演算子 'if'に注意してください:

この場合、グローバル変数Expertsの値が分析されます。 それはGV値を反映していますが、古くなります(すべてのプログラムがリアルタイムモードで動作することを覚えておく必要があります)。 その理由を理解するために、以下の図を見てみましょう:

 

イチジク。 57.第3ティック前のEUR / USD窓からのEAの分離。

図57は、GVの価値に関する事象の発生を示している。 何が起きているかによってこの値がどのように変化するかを見てみましょう。 EAの実行が時点t 0で開始されたと仮定しよう。この時点でGV量はまだ存在しない。 期間t 0〜t 1では、EAの特殊関数init()が実行され、結果としてGV Quantityが作成され、瞬時t 1の値は1になります。次にEUR / USDのティックで特殊関数start() 。 しかし、期間t 0〜t 6では、クライアント端末内にEAが1つしかないので、GV数量の値は変化しない。

現時点では、第2のEAがGBP / USDチャートに添付されている。 そのGV数量のinit()実行値の結果として、瞬間t 7は2に等しい。その後、瞬間t 8において、第3のEAが瞬間tの結果としてUSD / CHFチャートに添付される9 GV数量は3です。

瞬間t 10で、トレーダーはEUR / USDウィンドウからEAを取り除くことを決定する。 最後に、このウィンドウで動作するEAの変数エキスパートが、第2のティックで開始されたstart()の実行中に、すなわち期間t 4〜t 5で変更されたことに注意してください。 EUR / USDウィンドウで動作しているEAは1と同じです。そのため、このEAのdeinit()が実行されると、次の行が実行された結果、GV Quantityが削除されます。

したがって、まだ2つのEAが接続されていますが、GlobalVariableは削除されます。 このことが、接続されたEAの計算にどのような影響を及ぼすかは、理解するのが難しくありません。 start()の実行時に、これらのEAはNew_Expertsの現在の値がゼロに等しいことを検出します。そのため、Expertsの新しい値もゼロになります。 その結果、計算に使用される式では、エキスパートが分母にあるため、Moneyの値を計算することはできません。 したがって、EAにおけるさらなる計算は誤りである。

さらに、EAsのdeinit()関数(GBP / USDとUSD / CHFから切り離す)を実行すると、GVが再度開かれますが、その一方がデタッチされた後は-1になり、最後のものは切り離されます。 このすべてがMoneyの負の値になります。 重要なのは、すべてのEAがデタッチされた後、GV Quantityはクライアント端末で開いたままであり、さらにその値を使用するすべてのEAの動作に影響を与えます。

別の可能性もあります。 ギグ。 図58は、EAが取り外される前にもう1つのティックが来る場合、GV値がどのように変化するかを示す。

イチジク。 58. 3回目のチック後にEUR / USDウィンドウからEAを分離する。

 

Fig。 期間t 0〜t 9における図58に示すイベントは、図7に示すイベントと完全に一致する。 この図によれば、時刻t12において、3番目のダニがEUR / USDのために来る。 その結果、エキスパートの値は変更され、3になります。これは、deinit()の実行結果としてEUR / USDチャートからEAを削除した後、エキスパートの値が2に設定されることを意味しますすなわち、動作している残りのEAの数を正確に反映する。

この推論に基づいて、EA globalvar.mq4が正しく作成されていないと結論付けることができます。 この場合のアルゴリズムエラーは、状況を分析するために、すべてのケースで同時に動作するEAの実際の量を反映しないExpert変数の値が関数deinit()で使用されるという事実にあります。 図58で説明したケースでは、エキスパートの値は真であり、 57 - そうではありません。 したがって、EAの操作の一般的な結果は、偶発的なイベント、つまりEAが動作する証券のダニを受け取る順序に依存します。

この場合、エラーは簡単に修正できます。 解析の前​​に(オペレータの実行前に)エキスパートの値を単純に更新する必要があります:

このようなアルゴリズムエラーは、常に明白ではなく、検出が困難であるため危険です。 しかし、これはユーザーがGlobalVariablesの使用を拒否すべきではありません。 ただし、プログラムのパフォーマンスに影響を与える可能性のあるすべてのイベントを考慮して、プログラムのコードを正しく構築する必要があることを意味します。

実際の作業でグローバル変数を使用すると、他のセキュリティ上の重大なイベント(特定の価格レベルに達する、中断するなど)、別のエキスパートアドバイザーの添付についての通知(たとえば、共有権限)、同時に複数の証券に同期取引を行う。 重要なイベントを計算するインジケータからクライアント端末のグローバル変数を作成することもできます。そのような変数の値は、動作中のExpert Advisorまたはスクリプトによって使用されます。

スポンサードリンク
スポンサードリンク

-MQL4ブック, MT4
-,