【MQL4】グローバル変数関数の使い方を徹底解説!GlobalVariableSet / Get / Check / Del

【辞書】MQLリファレンス

MQL4でEA(自動売買プログラム)やインジケーターを開発していると、「MT4を再起動しても値を保持しておきたい」「複数のEA間でデータを共有したい」という場面に遭遇します。そんなときに活躍するのが、クライアントターミナルのグローバル変数(以下「ターミナルグローバル変数」)です。

この記事では、ターミナルグローバル変数を操作するための主要関数 ── GlobalVariableSetGlobalVariableGetGlobalVariableCheckGlobalVariableDel を中心に、使い方と注意点をわかりやすく解説します。

ターミナルグローバル変数とは?── 2種類の「グローバル変数」に注意

MQL4には「グローバル変数」と呼ばれるものが2種類あります。ここを混同すると大きな混乱のもとになるので、最初にしっかり区別しましょう。

① MQL4プログラム内のグローバル変数

関数の外(OnInit()OnTick()の外側)で宣言する変数のことです。プログラム全体からアクセスできますが、EAをチャートから外したりMT4を終了すると値は消えます

// プログラム内グローバル変数の例
int g_tickCount = 0;  // プログラム内のどの関数からもアクセス可能

void OnTick()
{
    g_tickCount++;
    Print("ティック回数: ", g_tickCount);
}

② クライアントターミナルのグローバル変数(本記事の主役)

MT4のメニュー「ツール → グローバル変数」(ショートカット:F3キー)で確認できる変数です。こちらはMT4を終了してもデータが保持されます。さらに、同じMT4上で動作しているすべてのEA・インジケーターからアクセス可能なので、プログラム間のデータ共有にも使えます。

ターミナルグローバル変数の特徴をまとめると、次のとおりです。

  • データ型は double 型のみ(文字列や整数を直接格納することはできません)
  • 最後のアクセスから4週間保持され、その後は自動的に削除される
  • 同一MT4上の全MQL4プログラムからアクセス可能
  • GlobalVariable系の専用関数を使って操作する

主要なグローバル変数関数一覧

以下が、ターミナルグローバル変数を操作するための主要関数です。

関数名 機能 戻り値
GlobalVariableSet() 値を設定(存在しなければ新規作成) datetime(最終アクセス時刻)/ 0(失敗)
GlobalVariableGet() 値を取得 double(格納されている値)
GlobalVariableCheck() 変数の存在を確認 true(存在する)/ false(存在しない)
GlobalVariableDel() 変数を削除 true(成功)/ false(失敗)
GlobalVariablesTotal() 変数の総数を取得 int(変数の数)
GlobalVariablesDeleteAll() 変数を一括削除 int(削除された数)
GlobalVariableName() インデックスから変数名を取得 string(変数名)

この中でも特に使用頻度の高い4つの関数を、コード例とともに詳しく見ていきましょう。

GlobalVariableSet() ── 値の設定・新規作成

ターミナルグローバル変数に値を設定する関数です。指定した名前の変数が存在しない場合は、自動的に新しい変数が作成されます。

// 構文
datetime GlobalVariableSet(
    string name,   // グローバル変数名
    double value   // 設定する値
);

戻り値は、成功した場合に最終アクセス時刻(datetime型)、失敗した場合に0が返ります。

void OnInit()
{
    // グローバル変数 "MyEA_BuyPrice" に値を設定
    datetime dt = GlobalVariableSet("MyEA_BuyPrice", 150.250);
    
    if(dt != 0)
        Print("設定成功! アクセス時刻: ", TimeToString(dt));
    else
        Print("設定失敗。エラー: ", GetLastError());
}

GlobalVariableGet() ── 値の取得

ターミナルグローバル変数から値を読み取る関数です。戻り値はdouble型です。

// 構文
double GlobalVariableGet(
    string name   // グローバル変数名
);

指定した名前の変数が存在しない場合は0が返り、エラーコードがセットされます。

void OnTick()
{
    double buyPrice = GlobalVariableGet("MyEA_BuyPrice");
    
    if(GetLastError() == 0)
        Print("保存されていた買値: ", buyPrice);
    else
        Print("グローバル変数が見つかりません");
}

💡 ポイント:戻り値が0なのか、それとも「本当に0が格納されている」のか区別がつかない場合があります。確実に存在を確認したい場合は、次に紹介する GlobalVariableCheck() と組み合わせましょう。

GlobalVariableCheck() ── 存在の確認

指定した名前のターミナルグローバル変数が存在するかどうかを確認する関数です。

// 構文
bool GlobalVariableCheck(
    string name   // グローバル変数名
);

変数が存在する場合は true、存在しない場合は false を返します。

void OnInit()
{
    string gvName = "MyEA_BuyPrice";
    
    // 変数が存在するか先に確認してから値を取得する
    if(GlobalVariableCheck(gvName))
    {
        double val = GlobalVariableGet(gvName);
        Print(gvName, " の値: ", val);
    }
    else
    {
        Print(gvName, " は存在しません。初期値を設定します。");
        GlobalVariableSet(gvName, 0.0);
    }
}

このように、GlobalVariableCheck()GlobalVariableGet() の順で呼び出すのが安全なパターンです。

GlobalVariableDel() ── 変数の削除

不要になったターミナルグローバル変数を削除する関数です。

// 構文
bool GlobalVariableDel(
    string name   // グローバル変数名
);

削除に成功した場合は true、失敗した場合は false を返します。

void OnDeinit(const int reason)
{
    // EA終了時にグローバル変数をクリーンアップ
    if(GlobalVariableDel("MyEA_BuyPrice"))
        Print("グローバル変数を削除しました");
    else
        Print("削除失敗。エラー: ", GetLastError());
}

実践例:EA再起動後もポジション情報を保持する

ここまでの関数を組み合わせた実践的なサンプルを見てみましょう。EAがポジションを持ったときにチケット番号をターミナルグローバル変数に保存し、MT4再起動後でも管理を継続できるようにします。

#property strict

// EA固有のプレフィックスをつけて名前衝突を防ぐ
string gvPrefix = "SampleEA_";

//+------------------------------------------------------------------+
//| 初期化処理                                                        |
//+------------------------------------------------------------------+
void OnInit()
{
    string gvTicket = gvPrefix + Symbol() + "_Ticket";
    
    // 前回保存したチケット番号があるか確認
    if(GlobalVariableCheck(gvTicket))
    {
        int ticket = (int)GlobalVariableGet(gvTicket);
        if(ticket > 0)
        {
            Print("前回のチケット番号を復元: ", ticket);
            // 必要に応じてポジション情報を再取得する処理を追加
        }
    }
    else
    {
        Print("保存済みチケットなし。新規稼働を開始します。");
    }
}

//+------------------------------------------------------------------+
//| ティック処理                                                      |
//+------------------------------------------------------------------+
void OnTick()
{
    string gvTicket = gvPrefix + Symbol() + "_Ticket";
    
    // 新規注文を出す処理(簡略化)
    int ticket = OrderSend(Symbol(), OP_BUY, 0.01, Ask, 3, 0, 0, "SampleEA", 12345, 0, clrBlue);
    
    if(ticket > 0)
    {
        // チケット番号をグローバル変数に保存
        GlobalVariableSet(gvTicket, (double)ticket);
        Print("チケット ", ticket, " をグローバル変数に保存しました");
    }
}

//+------------------------------------------------------------------+
//| 終了処理                                                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // パラメータ変更やチャート切替時はデータを保持
    // 手動削除(REASON_REMOVE)の場合のみクリーンアップ
    if(reason == REASON_REMOVE)
    {
        string gvTicket = gvPrefix + Symbol() + "_Ticket";
        GlobalVariableDel(gvTicket);
        Print("EA削除のため、グローバル変数をクリーンアップしました");
    }
}

グローバル変数を使うときの注意点

1. 名前の衝突に注意 ── プレフィックスをつけよう

ターミナルグローバル変数は同じMT4上の全プログラムで共有されます。異なるEAが同じ名前の変数を使うと、互いに値を上書きしてしまい不具合の原因になります。上のサンプルのように、EA名+通貨ペア名をプレフィックスとしてつけるのがベストプラクティスです。

2. 格納できるのは double 型のみ

ターミナルグローバル変数に格納できるのはdouble型の値だけです。整数(int)を保存したい場合はキャストが必要です。また、long型の大きな値(例:チャートIDなど)を格納すると、doubleの精度の問題で値が正確に復元できないことがあるので注意が必要です。

3. 4週間でデータが消える

クライアントターミナルのグローバル変数は、最後のアクセスから4週間クライアントターミナルに保持され、その後自動的に削除されます。長期間EAを停止する場合は、この点を意識しておきましょう。定期的にアクセス(読み書き)すればタイマーはリセットされます。

4. 不要な変数は削除する

使わなくなったグローバル変数を放置すると、F3キーで確認したときに一覧が煩雑になります。EA終了時に適切に GlobalVariableDel() で削除するか、GlobalVariablesDeleteAll() でプレフィックス指定の一括削除を行いましょう。

// プレフィックスを指定して一括削除
int deleted = GlobalVariablesDeleteAll("SampleEA_");
Print(deleted, " 個のグローバル変数を削除しました");

補足:その他の便利な関数

主要4関数以外にも、覚えておくと便利な関数を紹介します。

  • GlobalVariablesTotal() ── 現在のターミナルグローバル変数の総数を取得
  • GlobalVariableName(index) ── インデックス番号から変数名を取得(ループで全変数を列挙する際に便利)
  • GlobalVariableSetOnCondition() ── 現在値が指定値と一致する場合のみ更新する(排他制御に利用可能)
  • GlobalVariableTemp() ── MT4終了時に自動削除される一時的なグローバル変数を作成
  • GlobalVariablesFlush() ── メモリ上のグローバル変数をディスクに強制保存

まとめ

ターミナルグローバル変数は、MQL4プログラミングにおいてデータの永続化やプログラム間のデータ共有を実現するための重要な仕組みです。今回紹介した4つの基本関数を押さえておけば、多くの場面で活用できます。

  • GlobalVariableSet() で値を保存
  • GlobalVariableGet() で値を取得
  • GlobalVariableCheck() で存在を確認
  • GlobalVariableDel() で不要な変数を削除

名前の衝突を避けるためにプレフィックスをつけること、double型しか格納できないこと、4週間の有効期限があることを忘れずに、安全で堅牢なEA開発に役立ててください!

**記事のポイント:**

| 項目 | 内容 |

|—|—|

| **タイトル** | 【MQL4】グローバル変数関数の使い方を徹底解説!GlobalVariableSet / Get / Check / Del |

| **タグ** | MQL4, グローバル変数, GlobalVariableSet, EA開発, MetaTrader4 |

| **文字数** | 約8,900文字(HTML含む) / 本文テキスト約3,000文字相当 |

| **構成** | 導入 → 2種類のグローバル変数の区別 → 関数一覧表 → 4関数の詳細解説(構文+コード例) → 実践サンプル → 注意点4つ → 補足関数 → まとめ |

記事の特徴:

– **初心者が最も混同しやすい「2種類のグローバル変数」の違い**を冒頭で明確に解説

– 各関数に**構文・戻り値・実用コードサンプル**を掲載

– **実践例**として「EA再起動後もチケット番号を保持する」リアルなユースケースを提示

– **注意点**では名前衝突・double型制限・4週間有効期限・long型精度問題など、実開発で陥りやすい落とし穴をカバー

– 補足として `GlobalVariableSetOnCondition` や `GlobalVariableTemp` など発展的な関数も紹介