
MQL5 プログラミングの基礎:ターミナルのグローバル変数
はじめに
MQL4/5 環境では、興味深いインスツルメント-クライアントターミナルのグローバル変数 、があります。それによりターミナルの全プログラムについて共有データストレージ領域を作成することができます。その上、この領域のライフタイムはテーミナルのクローズを停止させることはありません。本稿ではオブジェクト指向プログラミングツールによってターミナルのグローバル変数とは何であるのか明確な考えを得ます。
本稿では以降、特に指定のない限り、クライアントターミナルのグローバル変数を『グローバル変数』と呼びます。
1. グローバル変数、関数
プログラマーとしての視点からは、グローバル変数はトレーディングターミナルの動作中プログラムすべてにとって使用可能な名前付メモリ領域を言います。初心者のプログラマーは同時に動作している複数ターミナルがある場合、それらはすべてクローバル関数のために独自の独立したメモリスペースを有します。それらは重なることはありません。
言語開発者はドキュメンテーションで、グローバル変数を処理するためには11個の関数が使用される、と特定します。
理論は MQL4 教本の『グローバル変数』 セクションにあります。
次のセクションで私は、セットのタスクを実装するためにオブジェクト指向プログラミングインスツルメントを使用します。
2. クラス CGlobalVar
オブジェクト指向プログラミングの考え方に導かれ、クラス CGlobalVarを作成します。これは直接グローバル変数のオブジェクトに関わるものです。
//+------------------------------------------------------------------+ //| Class CGlobalVar | //+------------------------------------------------------------------+ class CGlobalVar : public CObject { //--- === Data members === --- private: string m_name; double m_value; //--- datetime m_create_time; datetime m_last_time; //--- flag for temporary var bool m_is_temp; //--- === Methods === --- public: //--- constructor/destructor void CGlobalVar(void); void CGlobalVar(const string _var_name,const double _var_val, const datetime _create_time); void ~CGlobalVar(void){}; //--- create/delete bool Create(const string _var_name,const double _var_val=0.0, const bool _is_temp=false); bool Delete(void); //--- exist bool IsGlobalVar(const string _var_name,bool _to_print=false); //--- set methods bool Value(const double _var_val); bool ValueOnCondition(const double _var_new_val,const double _var_check_val); //--- get methods string Name(void) const; datetime CreateTime(void) const; datetime LastTime(void); template<typename T> T GetValue(T _type) const; bool IsTemporary(void) const; //--- private: string FormName(const string _base_name,const bool _is_temp=false); };
クラスは何をインクルードしなければならないのでしょうか?最小限の属性リストとして、私は以下のプロパティを選択します。
- 変数名
- 変数値
- 作成時刻
- 最終呼び出し時刻
- 一時変数の特徴
メソッドについては以下です。
- 作成
- 削除
- 存在確認
- 新しい値の設定
- 条件付新しい値の設定
- 名前の受け取り
- 値の受け取り
- 一時変数フラグの受け取り
CGlobalVar::GetValue メソッドについては別にお話します。それはテンプレートメソッドです。それはユーザーが引数として設定する変数値に対するデータタイを返します。
ここでの問題は MQL では関数はパラメータによってのみ分類されることです。そのためフェイクのパラメータを追加する必要があります。
テストスクリプトGlobals_test1.mq5 を作成します。ここで CGlobalVar タイプのオブジェクトを処理します。
#include "CGlobalVar.mqh" //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { CGlobalVar gVar1; //--- create a temporary global var if(gVar1.Create("Gvar1",3.123456789101235,true)) { Print("\n---=== A new global var ===---"); PrintFormat("Name: \"%s\"",gVar1.Name()); PrintFormat("Is temporary: %d",gVar1.IsTemporary()); //--- Get the value //--- double type double d=0.0; double dRes=gVar1.GetValue(d); PrintFormat("Double value: %0.15f",dRes); //--- float type float f=0.0; float fRes=gVar1.GetValue(f); PrintFormat("Float value: %0.7f",fRes); //--- string type string s=NULL; string sRes=gVar1.GetValue(s); PrintFormat("String value: %s",sRes); //--- Set a new value double new_val=3.191; if(gVar1.Value(new_val)) PrintFormat("New value is set: %f",new_val); //--- Set a new value on condition new_val=3.18; if(gVar1.ValueOnCondition(3.18,3.191)) PrintFormat("New value on conditionis set: %f",new_val); } }
グローバル変数は以下のように作成されます。
gVar1.Create("Gvar1",3.123456789101235,true)
最初の引数は後の変数名("Gvar1")の基本的なコンポーネントで、2番目の引数は(3.123456789101235)の値で、3番目の引数は変数が一時的(真)なものであることを示す特徴です。
変数名は名前とプログラムタイプを基本のコンポーネントに追加することで作成されます。
私の場合それは以下です。
- Gvar1 -基本コンポーネント
- prog_Globals_test1 -変数が作成されたプログラム(その名前はGlobals_test1です)
- プログラムタイプは- scr (スクリプト)です。
F3 を押すと、次のエントリが MetaTrader 5 ウィンドウのグローバル変数リストに表示されます。
図1 Test_temp_var1_prog_Globals_test1_scr 変数の値は 3.18
起動時、また正常に実装されたとき、『エキスパート』ジャーナルに以下のエントリーが表示されます。
KP 0 10:20:20.736 Globals_test1 (AUDUSD.e,H1) ---=== A new global var ===--- EH 0 10:20:21.095 Globals_test1 (AUDUSD.e,H1) Name: "Gvar1_temp_prog_Globals_test1_scr" LF 0 10:20:21.876 Globals_test1 (AUDUSD.e,H1) Is temporary: 1 MO 0 10:20:31.470 Globals_test1 (AUDUSD.e,H1) Double value: 3.123456789101235 KG 0 10:20:31.470 Globals_test1 (AUDUSD.e,H1) Float value: 3.1234567 OP 0 10:20:31.470 Globals_test1 (AUDUSD.e,H1) String value: 3.123456789101235 RH 0 10:20:31.470 Globals_test1 (AUDUSD.e,H1) New value is set: 3.191000 DJ 0 10:20:31.470 Globals_test1 (AUDUSD.e,H1) New value on conditionis set: 3.180000
変数値の異なるデータタイプはジャーナルに表示されます。
MetaTrader 5 ターミナルが再起動されると、Gvar1_temp_prog_Globals_test1_scr 変数はグローバル変数リストから消えます。それが起こるのは変数が一時的なものでそれはターミナルが開いているあいだ存続するためです。
MQL4/5 ではグローバル変数にデータを受け取る際、変数が一時的なものかどうか見つける方法はありません。おそらくもっとも簡単な特定方法は一時変数が変数名にキーを追加することです。たとえば、それは変数名の中にある接尾辞 "temp" の可能性があります。ただし、グローバル変数名作成を管理する必要があるのは、この方法の明確な欠点です。特にそのような変数が別のプログラムで作成されクラスを使用していないときには、顕著です。
ある時点で、私はグローバル変数がいくつ作成され、どれくらい速く作成されるのか知りたいと思いました。
わずかに前のスクリプトを変更し、それにGlobals_test2.mq5と名づけました。それは異なる実行回数で起動しました。変数を削除するため毎回実行後ターミナルの再起動を行いました。
#property script_show_inputs //--- #include "CGlobalVar.mqh" input uint InpCnt=10000; // Number of variables //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- start value uint start=GetTickCount(); //--- for(uint idx=0;idx<InpCnt;idx++) { CGlobalVar gVar; //--- Create a temporary global var if(!gVar.Create("Test_var"+IntegerToString(idx+1),idx+0.15,true)) Alert("Error creating a global variable!"); } //--- finish value uint time=GetTickCount()-start; //--- to print PrintFormat("Creation of %d global variables took %d ms",InpCnt,time); }
以下がその結果です(図2)。
図2 一時変数作成に要した時間
すべてのグローバル変数に対して行った同様のテストは図3に表示しています。その作成には長くかかることはありません。
その背後にある理由は、これら変数が Profiles フォルダ内のgvariables.dat ファイルにあるディスクに保存されるというものです。
図3 全グローバル変数作成に要した時間
それほどまで多くのグローバル変数を作成する必要はないと思います。私が行ったのは単に好奇心からです。
次の節ではグローバル変数のセットで作業しようと思います。
3. CGlobalVarList クラス
グローバル変数を使った作業を管理するには、 CGlobalVarListタイプのグローバル変数のクラスリストを作成します。このリストタイプは標準リストクラスCListの継承クラスです。
クラス宣言は以下のように記述します。
//+------------------------------------------------------------------+ //| Class CGlobalVarList | //+------------------------------------------------------------------+ class CGlobalVarList : public CList { //--- === Data members === --- private: ENUM_GVARS_TYPE m_gvars_type; //--- === Methods === --- public: //--- constructor/destructor void CGlobalVarList(void); void ~CGlobalVarList(void){}; //--- load/unload bool LoadCurrentGlobals(void); bool KillCurrentGlobals(void); //--- working with files virtual bool Save(const int _file_ha); virtual bool Load(const int _file_ha); //--- service void Print(const int _digs); void SetGvarType(const ENUM_GVARS_TYPE _gvar_type); //--- private: bool CheckGlobalVar(const string _var_name); };
現グローバル変数に接続しているオブジェクトは CGlobalVarListタイプのリストにインクルードされ、それからCGlobalVarList::LoadCurrentGlobals メソッドが使われます。
//+------------------------------------------------------------------+ //| Load current global vars | //+------------------------------------------------------------------+ bool CGlobalVarList::LoadCurrentGlobals(void) { ENUM_GVARS_TYPE curr_gvar_type=this.m_gvars_type; int gvars_cnt=GlobalVariablesTotal(); //--- for(int idx=0;idx<gvars_cnt;idx++) { string gvar_name=GlobalVariableName(idx); if(this.CheckGlobalVar(gvar_name)) continue; //--- gvar properties double gvar_val=GlobalVariableGet(gvar_name); datetime gvar_time=GlobalVariableTime(gvar_name); CGlobalVar *ptr_gvar=new CGlobalVar(gvar_name,gvar_val,gvar_time); //--- control gvar type if(CheckPointer(ptr_gvar)==POINTER_DYNAMIC) { if(curr_gvar_type>GVARS_TYPE_ALL) { bool is_temp=ptr_gvar.IsTemporary(); //--- only full-fledged if(curr_gvar_type==GVARS_TYPE_FULL) {if(is_temp)continue;} //--- only temporary else if(curr_gvar_type==GVARS_TYPE_TEMP) {if(!is_temp)continue;} } //--- try to add if(this.Add(ptr_gvar)>-1) continue; } //--- return false; } //--- return true; }
このメソッドは存在するグローバル変数をすべて読み、それをリストにインクルードします。
m_gvars_type 属性はインクルードされたグローバル変数タイプを管理します。それはENUM_GVARS_TYPE タイプの列挙です。
//+------------------------------------------------------------------+ //| Enumeration for gvars type | //+------------------------------------------------------------------+ enum ENUM_GVARS_TYPE { GVARS_TYPE_ALL=-1, // all global GVARS_TYPE_FULL=0, // only full GVARS_TYPE_TEMP=1, // only temporary };
CGlobalVarList リストの初期化前に、図4 にあるグローバル変数セットがあったとします。
図4 グローバル変数のおおよそのセット
このセットがリストによって正しく処理されるか確認していきます。その確認を実行するには Globals_test3.mq5 テストスクリプトを作成します。
#include "CGlobalVarList.mqh" //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { CGlobalVarList gvarList; gvarList.LoadCurrentGlobals(); PrintFormat("Number of variables in the set: %d",gvarList.Total()); }
スクリプトが開始されたのち新しいグローバル変数(黄色で強調されています)が出現しました。それは起こるはずではありませんでした。(図5)。
図5 新規グローバル変数セット
文字列は次のように表示されます。
2014.10.21 11:35:00.839 Globals_test3 (AUDUSD.e,H1) Number of variables in the list: 10
それが起こったのは、CGlobalVarList::LoadCurrentGlobals メソッドの宣言で、CGlobalVar::Createメソッドへの参照があったためです。
それは新規グローバル変数が文字列内で作成されることを意味します。
if(ptr_gvar.Create(gvar_name,gvar_val))
また、グローバル変数のインデックスは新しい変数が出現すると変わります。それが混乱の源です。
私はCGlobalVar::Create メソッドをもっとアクティブでないものと置き換えることをお薦めします。リスト内で変数が配慮されるようCGlobalVar クラスにはパラメータを持つコンストラクタを追加する必要があります。
変更後、CGlobalVarList::LoadCurrentGlobalsメソッドは以下のように記述されます。
//+------------------------------------------------------------------+ //| Load current global vars | //+------------------------------------------------------------------+ bool CGlobalVarList::LoadCurrentGlobals(void) { int gvars_cnt=GlobalVariablesTotal(); //--- for(int idx=0;idx<gvars_cnt;idx++) { string gvar_name=GlobalVariableName(idx); double gvar_val=GlobalVariableGet(gvar_name); datetime gvar_time=GlobalVariableTime(gvar_name); CGlobalVar *ptr_gvar=new CGlobalVar(gvar_name,gvar_val,gvar_time); if(CheckPointer(ptr_gvar)==POINTER_DYNAMIC) if(this.Add(ptr_gvar)>-1) continue; //--- return false; } //--- return true; }
メソッド変更後、スクリプトは正しく動作しています。そして以下のレコードが表示されます。
2014.10.21 11:38:04.424 Globals_test3 (AUDUSD.e,H1) Number of variables in the list: 6
それから、リストを削除、表示できる機能を追加しようとしています。
以下が Globals_test3.mq5 スクリプトです。
//--- #include "CGlobalVarList.mqh" //--- input ENUM_GVARS_TYPE InpGvarType=GVARS_TYPE_FULL; // Set gvar type //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { CGlobalVarList gvarList; //--- delete gvars gvarList.SetGvarType(InpGvarType); //--- load current gvars gvarList.LoadCurrentGlobals(); Print("Print the list before deletion."); gvarList.Print(10); //--- delete gvars if(gvarList.KillCurrentGlobals()) { Print("Print the screen after deletion."); gvarList.Print(10); } }
異なるグローバル変数を10個作成してタスクを複雑にしようと思います(図6)。
図6 多様なグローバル変数
われわれのリスト gvarList には完全な変数のみインクルードします。それらは削除されます。
『エキスパート』のジャーナルには以下が入っています。
MG 0 11:05:01.113 Globals_test3 (AUDUSD.e,H1) Print the list before deletion. KL 0 11:05:01.613 Globals_test3 (AUDUSD.e,H1) OI 0 11:05:01.613 Globals_test3 (AUDUSD.e,H1) ---===Local list===--- QS 0 11:05:01.613 Globals_test3 (AUDUSD.e,H1) Global variable type: GVARS_TYPE_FULL RI 0 11:05:01.613 Globals_test3 (AUDUSD.e,H1) Total number of global variables: 10 EG 0 11:05:01.613 Globals_test3 (AUDUSD.e,H1) Number of global variables in current list: 5 RN 0 11:05:01.613 Globals_test3 (AUDUSD.e,H1) Gvar #1, name - gVar10_prog_test1_scr, value - 16.6400000000 KP 0 11:05:01.613 Globals_test3 (AUDUSD.e,H1) Gvar #2, name - gVar2_prog_test1_scr, value - 4.6400000000 GR 0 11:05:01.613 Globals_test3 (AUDUSD.e,H1) Gvar #3, name - gVar4_prog_test1_scr, value - 7.6400000000 RD 0 11:05:01.613 Globals_test3 (AUDUSD.e,H1) Gvar #4, name - gVar6_prog_test1_scr, value - 10.6400000000 LJ 0 11:05:01.613 Globals_test3 (AUDUSD.e,H1) Gvar #5, name - gVar8_prog_test1_scr, value - 13.6400000000 EH 0 11:06:18.675 Globals_test3 (AUDUSD.e,H1) Print the list after deletion. FS 0 11:06:19.003 Globals_test3 (AUDUSD.e,H1) JJ 0 11:06:19.003 Globals_test3 (AUDUSD.e,H1) ---===Local list===--- HN 0 11:06:19.003 Globals_test3 (AUDUSD.e,H1) Global variable type: GVARS_TYPE_FULL KH 0 11:06:19.003 Globals_test3 (AUDUSD.e,H1) Total number of global variables: 5 QP 0 11:06:19.003 Globals_test3 (AUDUSD.e,H1) Number of global variables in the current list: 0
完全なグローバル変数だけをインクルードするリストは正しく作成されました。
それはクリアされ、ターミナルには一時変数5個だけが残っていました(図7)。
図7 一時グローバル変数
意図したタスクは達成されました。
CGlobalVarList クラスには、ファイルにデータを保存するメソッドとファイルからデータをダウンロードするメソッドも実装されました。
4. 実用的アプリケーション
周知のようにMQL4/5 iは特殊化されたプログラム言語です。それはトレーディング戦略をプログラムするために作成されました。特定のトレーディングアイデアを公式化するための方法として言語ツールがすべて考慮されるのはそのためです。
Expert Advisorを MQL5 プラットフォームのグローバル変数にリンクする例は十分あります。今日私が提案するのは、プログラム実装の管理が必要な状況を詳しく調べることです。
モジュールアプローチに基づく売買ロボット"Globals_test_EA"のコードがあるとします。
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Comment(""); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { Main(); }
ここでメインモジュールは次のように記述されます。
//+------------------------------------------------------------------+ //| Main module | //+------------------------------------------------------------------+ void Main(void) { //--- set flags for all modules for(int idx=0;idx<GVARS_LIST_SIZE;idx++) SetFlag(idx,false); //--- Check the trade possibility and connectivity //--- permission to trade if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) //--- connection to the trading server if(TerminalInfoInteger(TERMINAL_CONNECTED)) //--- permission to trade for the launched EA if(MQLInfoInteger(MQL_TRADE_ALLOWED)) { //--- 1) opening module Open(); //--- 2) closing module Close(); //--- 3) Trailing Stop module Trail(); } }
それは成分が3つあるメインモジュールです。
- オープンモジュール
- クローズモジュール
- トレーリングストップモジュール
ここでプログラム実行段階を制御するグローバル変数を作成する必要があります。
モジュールの形式には3段階あります。各段階では、2つのコントロールポイントが使用されます。第1のコントロールポイントはモジュール動作の初めを管理するもので、第2のコントロールポイントはモジュール動作の終わりを管理するものです。
コントロールポイントはグローバル変数の形式で実装されます。
よって、次の名前のグローバル変数が6個必要です。
//--- global variables: names string gVar_names[6]= { "gvarOpen_start","gvarOpen_finish", "gvarClose_start","gvarClose_finish", "gvarTrail_start","gvarTrail_finish" };
モジュールすべてに対してのフラグは Main() 関数の最初に設定され、個別のモジュールすべてでクリアされます。『独自』フラグについてのみ述べているのは言うまでもありません。たとえば、Open() モジュールを参照します。
//+------------------------------------------------------------------+ //| Open module | //+------------------------------------------------------------------+ void Open(void) { Comment(curr_module+__FUNCTION__); //--- if(!IsStopped()) { //--- clear the module start flag SetFlag(0,true); //--- assume that the module operates for approximately 1.25 s { Sleep(1250); } //--- clear the module finish flag SetFlag(1,true); } }
モジュール実行時には、プログラムが Open()ブロックで動作しているというコメントがチャートウィンドウに表示さます。
プログラムが強制終了されなければ、コントロールは対応フラグを設定/クリアする関数に渡されます。任意のコントロールポイントでフラグがクリアに失敗すると、モジュールは作業が終了していないとみなします。
グローバル変数によるモジュール動作の追跡段階のパターンは図8に表示されています。
図8 フラグシーケンス処理パターン
たとえば"Globals_test_EA" Expert Advisor はチャートにアタッチされ、正常に処理をしています。
チャートから Expert Advisor を削除したとき、ジャーナルに次のようなエントリが表示されました。
2014.10.22 20:14:29.575 Globals_test_EA (EURUSD.e,H1) Program forced to terminate before execution: <<Open_finish>>
そのためOpen(). モジュール内で終了が起こりました。
F3 を押してグローバル変数リストを開きます(図9)。
図9 "Globals_test_EA" Expert Advisor のグローバル変数
リストを見ると Open() モジュール動作の開始に関わるフラグだけがゼロ設定となっていました。
ポジションのオープン、クローズ、管理と連結するコマンド実行失敗時に潜在的に誤りが検出されているように見えます。
同じチャート上でロボットを再起動したあと、以下の情報がジャーナルに表示されます。
RQ 0 20:28:25.135 Globals_test_EA (EURUSD.e,H1) Non-zero value for: <<Open_finish>> CL 0 20:28:25.135 Globals_test_EA (EURUSD.e,H1) Non-zero value for: <<Close_start>> DH 0 20:28:25.135 Globals_test_EA (EURUSD.e,H1) Non-zero value for: <<Close_finish>> ES 0 20:28:25.135 Globals_test_EA (EURUSD.e,H1) Non-zero value for: <<Trail_start>> RS 0 20:28:25.135 Globals_test_EA (EURUSD.e,H1) Non-zero value for: <<Trail_finish>>
このように、プログラム段階の失敗については警告を受け取ります。それはもうひとつ別の疑問に導きます。これら段階が失敗した場合、何を行うことができるのでしょうか?それはまたの機会に。
おわりに
本稿はターミナルのグローバル変数の処理を助けるオブジェクト作成のための MQL5 言語の オブジェクト指向機能を明らかにしました。
プログラム段階の実装のためのコントロールポイントとしてグローバル変数が使用される場合が例としての役割をしました。
いつものように、コメント、提案、建設的批判をお待ちしています。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1210
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
機能について 理解を深めようと、この記事を読みました。グローバル変数の作成や変更は取引環境にどのような影響を与えるのでしょうか?
グローバル変数の数値が何を表しているのか説明できますか?
しばらく前からターミナルのグローバル変数について調べ、理解しようとしていますが、まだその使い方や効果を理解していません。可能であれば、グローバル変数の作成が私の取引口座の残高にどのようにプラスの結果をもたらすか、簡単な例を教えていただけませんか?
ありがとうございました。
よろしくお願いします、
デール
MQL5プログラミングの基礎 - グローバルターミナル変数:
著者:Dennis Kirichenko
課題
MetaQuotes 社が提供する為替取引ツールである MT4 / MT5 において、外部 txt ファイルのグローバル変数(通称グローバル変数)を読み書きしたい。
状態:
状態:下記参考ページに記載されているCGlobalVar.mqhクラスとCGlobalVarList.mqhクラスを使って実装したい。
(具体的には、CGLobalVarListクラスのSave()/Load()メソッドを使ってグローバル変数の書き込み/読み込みを行います)
基本的にWindows API(HANDLE CeateFile W ()など)は使用しない。Д.).
操作ファイルの格納位置:
操作先ファイルのデフォルト位置は、このクラスの指定に従う。
/ ファイル
または
FileOpen()の引数にFILE_COMMONを指定した場合に格納される。
C:\ を指定した場合に格納されます。
のいずれか。
作成したファイル:
実験用サンプルとして、簡単なスクリプトファイルを2つ作成。
WriteGlobalParameters.mq4。
и
ReadGlobalParameters.mq4。
によって作成された。
備考
グローバル変数を他の端末と共有することだけが目的であれば、共有メモリを使う方法などを考えることができます。ただし、今回は外部 txt ファイルを使用する方法のみを考えてください。
② エクスポート側のファイル(WriteGlobalParamaeters.mq 4)は、MQLの組み込み関数GlobalVariablesTotal()、GlobalVariableName()、GlobalVariableGet()、GlobalVariableTime()を使い、Save(HANDLE)は使わず WriteFile()関数を使って書きます(↓)。
For (int i = GlobalVariablesTotal () - 1; i> = 0; i -){
string gName = GlobalVariableName (i);
if (this.CheckGlobalVar (gName)) continue;
double gValue = GlobalVariableGet (gName);
datetime gTime = GlobalVariableTime (gName);
WriteFile (hFile, gName, gValue, gTime);
}, 変数のリストを指定されたディレクトリのtxtファイルに書き込むことは可能でした。
しかし、上記のGlobalVariable関数群の場合、書き出すことはできても、グローバルリード変数やターミナル変数のリストに追加することができないため、そのままになっています。
#### エラーメッセージ
WriteGlobalParameters.mq 4 Side:
2018.05.26 22:34:45.283 WriteGlobalParameters EURUSD、M1:uninit理由0
2018.05.26 22: 34: 45.283 WriteGlobalParameters EURUSD, M1: ファイル保存エラー
2018.05.26 22: 34: 45.282 WriteGlobalParameters EURUSD, M1: ポインタ作成エラー
ReadGlobalParameters.mq 4 Side:
2018.05.26 22: 43: 08.397 ReadGlobalParameters EURUSD, M1: 不明確な理由 0
2018.05.26 22:43:08.397 ReadGlobalParameters EURUSD、M1:ポインタ作成エラー
* 上記のエラーメッセージから
ポインタの仕様の不備とファイル操作の不備により、意図した操作が失敗していることは明らかです、
以下のコードのどこに問題があるのか不明なので、この点について(不明瞭な理由0も含めて)お話ししたいと思います。
MQL4/MQL5.
WriteGlobalParameters.mq4>。
//+------------------------------------------------------------------+
//| WriteGlobalParameters.mq4 |.
//| Copyright 2018, MetaQuotes Software Corp.
//|https://www.mql5.com|
//+------------------------------------------------------------------+
#プロパティ copyright "Copyright 2018, MetaQuotes Software Corp."
#property link"https://www.mql5.com"
#property バージョン "1.00"
#include <ArraysList.mqh>
<CGlobalVar.mqh> をインクルードする。
<CGlobalVarList.mqh> をインクルードする。
//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数
//+------------------------------------------------------------------+
void OnStart(){
//ファイル名
string FileName="Write";
string FileType="txt";
string file=FileName+". "+FileType;
//ポインタ
CGlobalVarList *list = new CGlobalVarList;
if(list!=NULL){
Print("ポインタ作成エラー");
}
//ハンドル
int hFile;
hFile=FileOpen(file,FILE_WRITE|FILE_COMMON); //FILE_CSV|FILE_UNICODE
if(hFile>=0){
if(!list.Save(hFile)){
Print("ファイル保存エラー");
リストを削除します;
FileClose(hFile);
}
//閉じる
FileClose(hFile);
}
//ポインタを解放する
リストを削除します;
}
==========================================================================
ReadGlobalParameters.mq4> を参照してください。
//+------------------------------------------------------------------+
//| ReadGlobalParameters.mq4 |.
//| Copyright 2018, MetaQuotes Software Corp.
//|https://www.mql5.com|
//+------------------------------------------------------------------+
#プロパティ copyright "Copyright 2018, MetaQuotes Software Corp."
#property link"https://www.mql5.com"
#property バージョン "1.00"
#include <ArraysList.mqh>
<CGlobalVar.mqh> をインクルードする。
<CGlobalVarList.mqh> をインクルードする。
//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数
//+------------------------------------------------------------------+
void OnStart(){
//ファイル名
string FileName="Read";
string FileType="txt";
string file=FileName+". "+FileType;
//ポインタ
CGlobalVarList *list = new CGlobalVarList;
if(list!=NULL){
Print("ポインタ作成エラー");
}
//ハンドル
int hFile;
hFile=FileOpen(file,FILE_READ|FILE_COMMON); //FILE_CSV|FILE_UNICODE
if(hFile>=0){
if(!list.Load(hFile)){
Print("ファイル・ロード・エラー");
リストを削除します;
FileClose(hFile);
}
//閉じる
FileClose(hFile);
}
//ポインタを解放する
リストを削除します;
}
### 試してみた
MT4を起動し、端末のグローバル変数リストに任意の名前と数値(ココでは簡単に0.0か1.0)を登録する。
(時間は登録時に自動で設定されるので設定しない)。
================================================== ===============
まず、Write GlobalParameters.mq4 側から---。
⓪ の設定で WriteGlobalParameters.mq4 をチャートに適用します。
→ 正常に動作すれば、上記で指定したディレクトリにファイルが作成され、グローバル変数情報を入力する必要があります。
ディレクトリ(C: ㊤User ㊤ Name ㊤ AppData ㊤ Roaming ㊤ MetaQuotes ㊤ Terminal ㊤ Common ㊤ Files ㊤)を確認、
指定した「Write.txt」が作成されましたが、ファイルサイズは0キロバイトです。
→ 開くと、当然、グローバル変数の名前も値も入力されていない。
================================================== ================
次はReadGlobalParameters.mq 4側 ---。
2.と同じディレクトリに任意の名前と数値のグローバル変数を読み込む "Read.txt "ファイルを作成しました。
(名前・数値・タイムスタンプを分割(不特定)と分割タブ(FileOpen()で"◆t "を指定)の2種類を作成しテストした))
④ ①と同様、ReadGlobalParameters.mq4をチャートに適用しても、上記エラーメッセージとターミナル上のグローバル変数リストのオープンも空でした。
================================================== ================
備考
念のため、FileOpen()関数にデフォルトで設定されているFILE_CSV、FILE_UNICODE、FILE_BIN、FILE_ANSIでも同様の実験を行いましたが、結果は変わりませんでした。
現在、 グローバル変数はダブルのみです。
key:valueのペアのような要素を持つCMapオブジェクトを使いたい。
あるいは、配列やリストを使うこともできます。 あるいは、配列やリストをグローバル変数として使う。
あるいは、メモリへのポインタを グローバル変数として 使う 。