P
PipsGrowth
Automation

MT5 Batch File Automation: Advanced Backtesting Scripts for Multiple EAs

Master MT5 batch file automation for running hundreds of backtests across multiple EAs, symbols, and timeframes. Complete scripts for parallel testing, result parsing, and CI/CD pipelines.

PG
Pips Growth Team
2026-07-10
9 min

MT5 Batch File Automation: Advanced Backtesting Scripts

Running individual backtests in MT5 Strategy Tester is fine for quick checks. But when you need to test 5 EAs across 10 symbols on 3 timeframes — that's 150 tests. Doing that manually would take days. Batch file automation turns it into a single command.

This guide builds on our MT5 CLI Optimization guide with advanced batch scripting techniques.

Prerequisites

  • MetaTrader 5 installed (terminal64.exe)
  • At least one compiled EA (.ex5 file)
  • Basic familiarity with .ini config files (see our CLI guide)

Project Structure

Organize your automation workspace:

D:\MT5_Automation\
├── Configs\           # Base .ini templates
│   ├── base_backtest.ini
│   └── base_optimize.ini
├── Scripts\           # Batch and Python scripts
│   ├── run_all.bat
│   ├── run_parallel.bat
│   └── parse_results.py
├── Reports\           # Output directory for .htm and .xml
├── Params\            # EA parameter .set files
│   ├── trend_follower.set
│   └── scalper_pro.set
└── Logs\              # Execution logs

Base Config Templates

base_backtest.ini (Single Test)

[Tester]
Expert=MyEAs\__EA_NAME__
ExpertParameters=__PARAM_FILE__
Symbol=__SYMBOL__
Period=__TIMEFRAME__
Deposit=10000
Currency=USD
Leverage=1:100
Model=4
Optimization=0
FromDate=2023.01.01
ToDate=2025.01.01
Report=D:\MT5_Automation\Reports\__REPORT_NAME__
ReplaceReport=1
ShutdownTerminal=1
UseLocal=1
Visual=0
Port=__PORT__

base_optimize.ini (Optimization)

[Tester]
Expert=MyEAs\__EA_NAME__
ExpertParameters=__PARAM_FILE__
Symbol=__SYMBOL__
Period=__TIMEFRAME__
Deposit=10000
Currency=USD
Leverage=1:100
Model=4
Optimization=2
OptimizationCriterion=5
FromDate=2023.01.01
ToDate=2025.01.01
ForwardMode=2
Report=D:\MT5_Automation\Reports\__REPORT_NAME__
ReplaceReport=1
ShutdownTerminal=1
UseLocal=1
UseCloud=0
Visual=0
Port=__PORT__

Advanced Batch Scripts

1. Sequential Multi-EA Testing

@echo off
setlocal enabledelayedexpansion

set MT5="C:\Program Files\MetaTrader 5\terminal64.exe"
set BASE_DIR=D:\MT5_Automation
set CONFIG_DIR=%BASE_DIR%\Configs
set REPORT_DIR=%BASE_DIR%\Reports
set LOG_DIR=%BASE_DIR%\Logs

:: Define test matrix
set EAS=TrendFollower GridMaster ScalperPro BreakoutHunter
set SYMBOLS=EURUSD GBPUSD USDJPY AUDUSD USDCAD
set TIMEFRAMES=M15 H1 H4

set PORT=2000
set TOTAL=0
set PASSED=0
set FAILED=0

for %%E in (%EAS%) do (
    for %%S in (%SYMBOLS%) do (
        for %%T in (%TIMEFRAMES%) do (
            set /a TOTAL+=1
            set REPORT_NAME=%%E_%%S_%%T
            set CONFIG_OUT=%CONFIG_DIR%\run_!REPORT_NAME!.ini
            
            :: Generate config from template
            powershell -Command "(Get-Content %CONFIG_DIR%\base_backtest.ini) `
                -replace '__EA_NAME__', '%%E' `
                -replace '__PARAM_FILE__', '%%E.set' `
                -replace '__SYMBOL__', '%%S' `
                -replace '__TIMEFRAME__', '%%T' `
                -replace '__REPORT_NAME__', '!REPORT_NAME!' `
                -replace '__PORT__', '!PORT!' `
                | Set-Content '!CONFIG_OUT!'"
            
            echo [!TOTAL!] Testing %%E on %%S %%T ...
            
            :: Run test with timeout (1 hour max)
            %MT5% /config:"!CONFIG_OUT!" 2>%LOG_DIR%\!REPORT_NAME!.log
            
            if exist "%REPORT_DIR%\!REPORT_NAME!.htm" (
                echo   ✓ Report generated
                set /a PASSED+=1
            ) else (
                echo   ✗ No report found
                set /a FAILED+=1
            )
            
            set /a PORT+=1
        )
    )
)

echo.
echo ==========================================
echo Results: %PASSED%/%TOTAL% passed, %FAILED% failed
echo Reports: %REPORT_DIR%
echo ==========================================

2. Parallel Optimization (4 Agents)

@echo off
set MT5="C:\Program Files\MetaTrader 5\terminal64.exe"
set CONFIG_DIR=D:\MT5_Automation\Configs

:: Launch 4 parallel optimizations
start "MT5-EURUSD" %MT5% /config:%CONFIG_DIR%\optimize_eurusd.ini /port:2000
start "MT5-GBPUSD" %MT5% /config:%CONFIG_DIR%\optimize_gbpusd.ini /port:2001
start "MT5-USDJPY" %MT5% /config:%CONFIG_DIR%\optimize_usdjpy.ini /port:2002
start "MT5-AUDUSD" %MT5% /config:%CONFIG_DIR%\optimize_audusd.ini /port:2003

echo 4 parallel optimizations launched.
echo Waiting for all to complete...

:: Wait for all MT5 instances to close
:waitloop
tasklist /fi "imagename eq terminal64.exe" | find "terminal64.exe" >nul
if %errorlevel%==0 (
    timeout /t 10 /nobreak >nul
    goto waitloop
)

echo All optimizations complete!
python D:\MT5_Automation\Scripts\parse_results.py

3. PowerShell Script (More Powerful)

# run_optimizations.ps1
$MT5 = "C:\Program Files\MetaTrader 5\terminal64.exe"
$ConfigDir = "D:\MT5_Automation\Configs"
$ReportDir = "D:\MT5_Automation\Reports"

$TestMatrix = @(
    @{ EA = "TrendFollower"; Symbol = "EURUSD"; TF = "H1"; Port = 2000 }
    @{ EA = "TrendFollower"; Symbol = "GBPUSD"; TF = "H1"; Port = 2001 }
    @{ EA = "GridMaster";    Symbol = "EURUSD"; TF = "M15"; Port = 2002 }
    @{ EA = "GridMaster";    Symbol = "USDJPY"; TF = "H4";  Port = 2003 }
)

foreach ($test in $TestMatrix) {
    $configFile = Join-Path $ConfigDir "base_optimize.ini"
    $outputConfig = Join-Path $ConfigDir "run_$($test.EA)_$($test.Symbol)_$($test.TF).ini"
    
    # Generate config
    $content = Get-Content $configFile
    $content = $content -replace '__EA_NAME__', $test.EA
    $content = $content -replace '__SYMBOL__', $test.Symbol
    $content = $content -replace '__TIMEFRAME__', $test.TF
    $content = $content -replace '__PORT__', $test.Port
    $content | Set-Content $outputConfig
    
    Write-Host "Starting $($test.EA) on $($test.Symbol) $($test.TF)..."
    
    # Run in background
    Start-Process -FilePath $MT5 -ArgumentList "/config:$outputConfig" -Wait
}

Write-Host "All optimizations complete!"

Python Results Parser

#!/usr/bin/env python3
"""Parse all MT5 backtest/optimization reports in a directory."""

import os
import glob
import xml.etree.ElementTree as ET
import pandas as pd
from datetime import datetime

def parse_backtest_htm(htm_path):
    """Parse single backtest .htm report using regex."""
    import re
    
    with open(htm_path, 'r', encoding='utf-8', errors='ignore') as f:
        content = f.read()
    
    # Extract key metrics from HTML tables
    metrics = {}
    
    patterns = {
        'total_net_profit': r'Total Net Profit[^0-9-]*([\d.,-]+)',
        'profit_factor': r'Profit Factor[^0-9.]*([\d.]+)',
        'max_drawdown': r'Equity Drawdown Max[^0-9.%]*([\d.]+)%?',
        'total_trades': r'Total Trades[^0-9]*([\d]+)',
        'sharpe_ratio': r'Sharpe Ratio[^0-9.-]*([\d.-]+)',
    }
    
    for key, pattern in patterns.items():
        match = re.search(pattern, content)
        if match:
            val = match.group(1).replace(',', '').replace(' ', '')
            try:
                metrics[key] = float(val)
            except ValueError:
                metrics[key] = val
    
    return metrics

def parse_optimization_xml(xml_path):
    """Parse optimization .xml report into DataFrame."""
    tree = ET.parse(xml_path)
    root = tree.getroot()
    
    results = []
    for item in root.findall('.//Item'):
        row = {
            'pass': int(item.get('Pass', 0)),
            'profit': float(item.findtext('Profit', 0)),
            'profit_factor': float(item.findtext('ProfitFactor', 0)),
            'drawdown_pct': float(item.findtext('EquityDrawdown', 0)),
            'sharpe': float(item.findtext('SharpeRatio', 0)),
            'sortino': float(item.findtext('SortinoRatio', 0)),
            'trades': int(item.findtext('TotalTrades', 0)),
            'win_rate': float(item.findtext('WinRate', 0)),
            'expected_payoff': float(item.findtext('ExpectedPayoff', 0)),
        }
        for inp in item.findall('.//Input'):
            row[f'inp_{inp.get("Name")}'] = float(inp.text)
        results.append(row)
    
    return pd.DataFrame(results)

def analyze_all_reports(report_dir):
    """Parse all XML reports and combine into summary."""
    all_dfs = []
    
    for xml_file in glob.glob(os.path.join(report_dir, '*.xml')):
        try:
            df = parse_optimization_xml(xml_file)
            df['source'] = os.path.basename(xml_file)
            all_dfs.append(df)
        except Exception as e:
            print(f"Error parsing {xml_file}: {e}")
    
    if not all_dfs:
        print("No XML reports found!")
        return None
    
    combined = pd.concat(all_dfs, ignore_index=True)
    
    # Quality filters
    filtered = combined[
        (combined['profit'] > 0) &
        (combined['trades'] >= 50) &
        (combined['drawdown_pct'] < 25) &
        (combined['profit_factor'] > 1.2) &
        (combined['sharpe'] > 0.5)
    ].sort_values('sharpe', ascending=False)
    
    print(f"\n{'='*60}")
    print(f"Total optimization passes: {len(combined)}")
    print(f"Passing quality filters:   {len(filtered)}")
    print(f"{'='*60}\n")
    
    if len(filtered) > 0:
        print("Top 10 by Sharpe Ratio:")
        print(filtered.head(10)[['source', 'profit', 'sharpe', 'drawdown_pct', 'trades', 'profit_factor']].to_string())
        
        # Save to CSV
        output_path = os.path.join(report_dir, f'analysis_{datetime.now().strftime("%Y%m%d_%H%M%S")}.csv')
        filtered.to_csv(output_path, index=False)
        print(f"\nFull results saved to: {output_path}")
    
    return filtered

if __name__ == '__main__':
    report_dir = r'D:\MT5_Automation\Reports'
    analyze_all_reports(report_dir)

CI/CD Integration

GitHub Actions Example

name: EA Optimization CI
on:
  push:
    paths:
      - 'eas/**'
      - 'configs/**'
  schedule:
    - cron: '0 2 * * 0'  # Weekly Sunday 2AM

jobs:
  optimize:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install MT5
        run: |
          choco install metatrader5 -y
      
      - name: Run Optimizations
        run: |
          ./scripts/run_all.bat
      
      - name: Parse Results
        run: python ./scripts/parse_results.py
      
      - name: Upload Reports
        uses: actions/upload-artifact@v4
        with:
          name: optimization-reports
          path: ./Reports/

IDE Integration for Batch Workflows

When running batch optimizations, you can integrate the workflow into your IDE:

VS Code: Run Batch Optimization as a Task

Add to .vscode/tasks.json:

{
  "label": "Batch Optimize All EAs",
  "type": "shell",
  "command": "D:\\MT5_Automation\\Scripts\\run_all.bat",
  "group": {"kind": "build", "isDefault": true},
  "problemMatcher": []
}

Windsurf / Cursor: AI-Driven Batch Optimization

In AI-powered IDEs, you can ask the AI to manage the entire batch workflow:

"Read all .mq5 files in my EAs folder, compile each one with MetaEditor, then run optimization for each across EURUSD, GBPUSD, and USDJPY on H1 and H4. Parse all XML results and create a summary table showing the best parameters for each EA."

The AI will:

  1. List all .mq5 files in your Experts folder
  2. Call metaeditor64.exe /compile for each
  3. Generate .ini configs for each EA/symbol/timeframe combination
  4. Run terminal64.exe /config: sequentially or in parallel
  5. Parse all .xml reports with Python
  6. Present a summary table with the best parameters

Git-Based EA Version Control

Store your EAs and configs in a Git repository for reproducibility:

my-ea-project/
├── EAs/
│   ├── TrendFollower.mq5
│   ├── GridMaster.mq5
│   └── ScalperPro.mq5
├── Configs/
│   ├── base_optimize.ini
│   └── base_backtest.ini
├── Params/
│   ├── trend_follower.set
│   └── grid_master.set
├── Scripts/
│   ├── run_all.bat
│   ├── run_parallel.bat
│   └── parse_results.py
└── Reports/          # .gitignore this folder

This way, every optimization run is reproducible from the repo. You can tag releases (e.g., v1.2-best-sharpe) and track which parameters produced the best results.

Windows Task Scheduler

Run optimizations automatically on a schedule:

Using Task Scheduler GUI

  1. Open Task Scheduler → Create Task
  2. Triggers → New → Weekly → Sunday 2:00 AM
  3. Actions → New → Start a program → D:\MT5_Automation\Scripts\run_all.bat
  4. Conditions → Start only if computer is idle for 10 minutes
  5. Settings → Run task as soon as possible after a scheduled start is missed

Using PowerShell (Command Line)

# Create a scheduled task for weekly optimization
$action = New-ScheduledTaskAction -Execute "D:\MT5_Automation\Scripts\run_all.bat"
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At 2am
$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopIfGoingOnBatteries

Register-ScheduledTask -TaskName "MT5_Weekly_Optimization" `
    -Action $action -Trigger $trigger -Settings $settings `
    -Description "Weekly MT5 EA optimization across all symbols and timeframes"

Using schtasks (Command Line)

schtasks /create /tn "MT5_Weekly_Optimization" `
    /tr "D:\MT5_Automation\Scripts\run_all.bat" `
    /sc weekly /d SUN /st 02:00 /f

Common Issues & Solutions

Problem Solution
MT5 closes immediately Check config file encoding (must be ANSI/UTF-8 without BOM)
No report generated Ensure Report= path has write permissions
Agent port conflict Use unique Port= values for parallel runs
Optimization too slow Switch from Optimization=1 to Optimization=2 (genetic)
EA not found Check Expert= path is relative to MQL5\Experts
Login fails Remove Login= line or use valid credentials
.set file not found Check ExpertParameters= path is in MQL5\\Profiles\\Tester\\
Compilation produces no .ex5 Check .log file for MQL5 syntax errors
Optimization results empty Ensure .set file has Y flags on parameters to optimize

FAQ

How many parallel optimizations can I run?

It depends on your CPU cores. Each MT5 agent uses one core. If you have an 8-core CPU, you can run 4-6 parallel optimizations (leave 2 cores for the OS). Use different Port= values for each instance.

Can I run batch automation on a VPS?

Yes. A Windows VPS is ideal for batch optimization — it runs 24/7, doesn't interrupt your work, and can be configured with Task Scheduler. Choose a VPS with at least 4 CPU cores and 8GB RAM.

How do I handle different EA versions?

Use Git for version control. Tag each release (e.g., v1.0-stable, v1.1-better-risk). Store .set files and .ini configs alongside the EA source. This makes every optimization run reproducible.

What if my optimization produces thousands of results?

Use the Python parser with quality filters: profit > 0, trades >= 50, drawdown < 25%, sharpe > 0.5. This typically narrows thousands of passes down to 10-50 viable parameter sets. Then manually review the top 10.

Can I automate the entire pipeline (compile → optimize → deploy)?

Yes. Create a master script that: (1) compiles the EA, (2) runs optimization, (3) parses results, (4) selects best parameters, (5) copies the best .set file to the live EA folder. See our CLI Optimization guide for the Python MT5Optimizer class that handles steps 1-3.

Related Guides

Affiliate Disclosure: This page contains affiliate links. We may earn a commission when you click on certain links or sign up with brokers featured on this site, at no additional cost to you. Our reviews and recommendations are based on thorough research and remain unbiased.Learn more

Risk Warning: Trading forex and CFDs involves significant risk of loss. Past performance is not indicative of future results. CFDs are complex instruments and come with a high risk of losing money rapidly due to leverage. Ensure you understand the risks before trading. This content is for educational purposes only and does not constitute financial advice.

Written by

Pips Growth Team

Trading Education & Research Team

The Pips Growth Team is a group of experienced traders, financial analysts, and trading educators dedicated to providing accurate, actionable forex education. Our team combines decades of hands-on market experience with deep technical knowledge to create comprehensive guides, honest broker reviews, and proven trading strategies. Every article is thoroughly researched, fact-checked, and reviewed by multiple team members to ensure the highest quality and accuracy.

15+ Years Experience81+ Articles Published
Forex & CFD TradingTechnical AnalysisRisk ManagementBroker Reviews & Evaluation
View Full Profile
Share

Get Trading Tips

MT5 Batch File Automation: Advanced Backtesting Scripts for Multiple EAs | PipsGrowth