🐈

MT5 EAで設定ファイル(ini/txt)を使う方法

に公開

なぜ設定ファイルを使うのか

MT5のEAでは、パラメータを直接コードに書く代わりに、外部の設定ファイル(.iniや.txt)を使うことで以下のメリットがあります:

  • 再コンパイル不要: パラメータを変更してもEAの再コンパイルが不要
  • 環境別設定: 本番環境とテスト環境で異なる設定を簡単に切り替え
  • バージョン管理: Gitで設定の履歴を追跡しやすい
  • 複数通貨ペア対応: 通貨ペアごとに異なる設定ファイルを用意できる
  • 編集が簡単: メモ帳やテキストエディタで直接編集可能

設定ファイルの形式

INIファイル形式(推奨)

[General]
MagicNumber=12345
MaxTrades=5
EnableTrading=true

[RiskManagement]
RiskPercent=2.0
MaxDrawdownPercent=10.0
UseFixedLot=false

[USDJPY]
LotSize=0.1
TakeProfit=50
StopLoss=30

[EURJPY]
LotSize=0.2
TakeProfit=60
StopLoss=35

TXTファイル形式(シンプル)

# コメント: 一般設定
MagicNumber=12345
MaxTrades=5
RiskPercent=2.0

# 通貨ペア別設定
USDJPY_LotSize=0.1
USDJPY_TP=50
USDJPY_SL=30

MQL5での実装方法

1. 設定ファイルの読み込み

// 設定ファイルのパス
string ConfigFilePath = "jupiter_config.ini";

// 設定読み込み関数
bool LoadConfig() {
    string filepath = TerminalInfoString(TERMINAL_DATA_PATH) +
                     "\\MQL5\\Files\\" + ConfigFilePath;

    int filehandle = FileOpen(ConfigFilePath, FILE_READ|FILE_TXT);

    if(filehandle == INVALID_HANDLE) {
        Print("設定ファイルが開けません: ", ConfigFilePath);
        return false;
    }

    while(!FileIsEnding(filehandle)) {
        string line = FileReadString(filehandle);
        ParseConfigLine(line);
    }

    FileClose(filehandle);
    Print("設定ファイルを読み込みました");
    return true;
}

2. INI形式のパース処理

string CurrentSection = "";

void ParseConfigLine(string line) {
    // 空行とコメントをスキップ
    StringTrimLeft(line);
    StringTrimRight(line);

    if(StringLen(line) == 0 || StringSubstr(line, 0, 1) == "#" ||
       StringSubstr(line, 0, 1) == ";") {
        return;
    }

    // セクション判定 [SectionName]
    if(StringSubstr(line, 0, 1) == "[") {
        int end = StringFind(line, "]");
        if(end > 0) {
            CurrentSection = StringSubstr(line, 1, end - 1);
            return;
        }
    }

    // キー=値のパース
    int pos = StringFind(line, "=");
    if(pos > 0) {
        string key = StringSubstr(line, 0, pos);
        string value = StringSubstr(line, pos + 1);

        StringTrimLeft(key);
        StringTrimRight(key);
        StringTrimLeft(value);
        StringTrimRight(value);

        ApplyConfig(CurrentSection, key, value);
    }
}

3. 設定値の適用

// グローバル変数
int g_MagicNumber = 0;
int g_MaxTrades = 0;
double g_RiskPercent = 0.0;

void ApplyConfig(string section, string key, string value) {
    // 一般設定
    if(section == "General") {
        if(key == "MagicNumber") g_MagicNumber = (int)StringToInteger(value);
        else if(key == "MaxTrades") g_MaxTrades = (int)StringToInteger(value);
        else if(key == "EnableTrading") g_EnableTrading = (value == "true");
    }
    // リスク管理
    else if(section == "RiskManagement") {
        if(key == "RiskPercent") g_RiskPercent = StringToDouble(value);
        else if(key == "MaxDrawdownPercent") g_MaxDrawdown = StringToDouble(value);
    }
    // 通貨ペア別設定
    else if(section == _Symbol) {
        if(key == "LotSize") g_LotSize = StringToDouble(value);
        else if(key == "TakeProfit") g_TakeProfit = (int)StringToInteger(value);
        else if(key == "StopLoss") g_StopLoss = (int)StringToInteger(value);
    }
}

4. OnInit()での初期化

int OnInit() {
    // 設定ファイルから読み込み
    if(!LoadConfig()) {
        Print("デフォルト設定を使用します");
        // デフォルト値を設定
        g_MagicNumber = 12345;
        g_MaxTrades = 5;
        g_RiskPercent = 2.0;
    }

    Print("MagicNumber: ", g_MagicNumber);
    Print("MaxTrades: ", g_MaxTrades);
    Print("RiskPercent: ", g_RiskPercent);

    return INIT_SUCCEEDED;
}

実践例:通貨ペア別設定

設定ファイル: jupiter_config.ini

[General]
MagicNumber=99999
MaxSpread=30
EnableNews=false

[USDJPY]
Enabled=true
LotSize=0.1
TakeProfit=50
StopLoss=30
MaxTrades=3

[EURJPY]
Enabled=true
LotSize=0.2
TakeProfit=60
StopLoss=35
MaxTrades=2

[GBPJPY]
Enabled=false
LotSize=0.05
TakeProfit=80
StopLoss=40
MaxTrades=1

通貨ペア別設定の構造体

struct SymbolConfig {
    bool Enabled;
    double LotSize;
    int TakeProfit;
    int StopLoss;
    int MaxTrades;
};

SymbolConfig g_SymbolConfig;

void ApplySymbolConfig(string key, string value) {
    if(key == "Enabled") g_SymbolConfig.Enabled = (value == "true");
    else if(key == "LotSize") g_SymbolConfig.LotSize = StringToDouble(value);
    else if(key == "TakeProfit") g_SymbolConfig.TakeProfit = (int)StringToInteger(value);
    else if(key == "StopLoss") g_SymbolConfig.StopLoss = (int)StringToInteger(value);
    else if(key == "MaxTrades") g_SymbolConfig.MaxTrades = (int)StringToInteger(value);
}

設定ファイルの配置場所

MT5では設定ファイルは以下の場所に配置します:

C:\Users\[ユーザー名]\AppData\Roaming\MetaQuotes\Terminal\[ターミナルID]\MQL5\Files\

または、コードで指定:

string filepath = TerminalInfoString(TERMINAL_DATA_PATH) + "\\MQL5\\Files\\jupiter_config.ini";

デバッグとエラー処理

ログ出力

void LoadConfig() {
    Print("=== 設定ファイル読み込み開始 ===");

    if(!FileIsExist(ConfigFilePath, FILE_COMMON)) {
        Print("警告: 設定ファイルが見つかりません: ", ConfigFilePath);
        return false;
    }

    Print("ファイルパス: ", TerminalInfoString(TERMINAL_DATA_PATH),
          "\\MQL5\\Files\\", ConfigFilePath);

    // ... 読み込み処理 ...

    Print("=== 設定ファイル読み込み完了 ===");
}

エラー処理

int filehandle = FileOpen(ConfigFilePath, FILE_READ|FILE_TXT);

if(filehandle == INVALID_HANDLE) {
    int error = GetLastError();
    Print("ファイルオープンエラー: ", error);

    switch(error) {
        case 5002: Print("ファイルが見つかりません"); break;
        case 5004: Print("ファイルが開けません"); break;
        case 5027: Print("アクセス権限がありません"); break;
        default: Print("不明なエラー"); break;
    }

    return false;
}

ベストプラクティス

1. デフォルト値を用意

void SetDefaultConfig() {
    g_MagicNumber = 12345;
    g_MaxTrades = 5;
    g_RiskPercent = 2.0;
    // ... 他のデフォルト値
}

int OnInit() {
    SetDefaultConfig();  // まずデフォルト値を設定
    LoadConfig();        // 設定ファイルで上書き
    return INIT_SUCCEEDED;
}

2. 設定の検証

bool ValidateConfig() {
    if(g_LotSize < 0.01) {
        Print("エラー: LotSizeが小さすぎます");
        return false;
    }

    if(g_TakeProfit <= 0) {
        Print("エラー: TakeProfitが不正です");
        return false;
    }

    return true;
}

3. 設定のリロード機能

// チャート上でF7キーやイベントで設定を再読み込み
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {
    if(id == CHARTEVENT_KEYDOWN && lparam == 'R') {
        Print("設定を再読み込みします...");
        LoadConfig();
        ValidateConfig();
    }
}

まとめ

設定ファイルを使うメリット:

  • 再コンパイル不要でパラメータ変更可能
  • テキストエディタで簡単に編集
  • 環境ごとに設定ファイルを分けられる
  • Gitで設定変更履歴を管理できる

実装のポイント:

  • INI形式を使うとセクション分けができて読みやすい
  • デフォルト値を必ず用意する
  • エラー処理とログ出力を充実させる
  • 設定の検証機能を実装する

この方法を使えば、EAの設定管理が格段に楽になります!

Discussion