Files
mt_mt5_backertest/optimizer_main.py
T
2026-07-06 03:32:12 +08:00

149 lines
4.8 KiB
Python

#!/usr/bin/env python3
import os
import sys
import argparse
import logging
from datetime import datetime
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
OPTIMIZER_DIR = os.path.join(os.path.dirname(__file__), 'scripts', 'optimizer')
sys.path.insert(0, OPTIMIZER_DIR)
from ea_config_parser import load_all_ea_configs, load_ea_config
from smart_search import SmartSearch
from parameter_constraint import create_constraint_engine
from analyze_results import ResultAnalyzer
from ea_batch_optimizer import EABatchOptimizer
def setup_directories(base_dir):
dirs = ['configs', 'set_files', 'reports', 'results', 'scripts', 'logs']
for d in dirs:
os.makedirs(os.path.join(base_dir, d), exist_ok=True)
def cmd_generate(args):
optimizer = EABatchOptimizer(args.base_dir)
configs = load_all_ea_configs(os.path.join(args.base_dir, 'configs'))
if not configs:
logger.error('No EA configs found in ' + os.path.join(args.base_dir, 'configs'))
return
for ea_name, config in configs.items():
if args.ea and ea_name not in args.ea:
continue
logger.info('Processing: ' + ea_name)
optimizer.generate_set_files(config, max_samples=args.max_samples)
optimizer.generate_ini_for_ea(config, [])
logger.info('Generation completed!')
def cmd_run(args):
optimizer = EABatchOptimizer(args.base_dir)
if not args.ps_script:
logger.error('PowerShell script path required. Generate SET files first.')
return
logger.info('Running PowerShell script: ' + args.ps_script)
try:
result = subprocess.run(['powershell', '-ExecutionPolicy', 'Bypass', '-File', args.ps_script],
capture_output=True, text=True)
logger.info(result.stdout)
if result.stderr:
logger.error(result.stderr)
except Exception as e:
logger.error('Error running script: ' + str(e))
def cmd_analyze(args):
optimizer = EABatchOptimizer(args.base_dir)
analyzer = ResultAnalyzer(os.path.join(args.base_dir, 'reports'))
results = analyzer.parse_all_reports()
if not results:
logger.warning('No results found')
return
logger.info('Total results: ' + str(len(results)))
criterion = args.sort or 'profit_factor'
best = analyzer.find_optimal_params(results, criterion=criterion)
output_path = os.path.join(args.base_dir, 'results', 'optimization_report.txt')
analyzer.generate_report(best, output_path)
logger.info('Report saved: ' + output_path)
if args.csv:
analyzer.save_to_csv(best, args.csv)
logger.info('CSV saved: ' + args.csv)
def cmd_list(args):
configs_dir = os.path.join(args.base_dir, 'configs')
configs = load_all_ea_configs(configs_dir)
print()
print('=' * 60)
print('EA Configurations')
print('=' * 60)
for ea_name, config in configs.items():
print()
print('Name: ' + ea_name)
print('Path: ' + config.ea_path)
print('Parameters: ' + str(len(config.parameters)))
print('Combinations: ' + str(config.get_total_combinations()))
print('Strategy: ' + config.search_strategy)
print('Estimate time: ' + config.estimate_search_time())
def main():
parser = argparse.ArgumentParser(description='MT5 EA Optimizer')
parser.add_argument('--base-dir', '-d', default='optimizer',
help='Base directory for optimizer')
parser.add_argument('--ea', '-e', nargs='+',
help='EA names to process')
parser.add_argument('--max-samples', '-m', type=int, default=2000,
help='Maximum samples to generate')
parser.add_argument('--sort', '-s', default='profit_factor',
choices=['profit_factor', 'net_profit', 'win_rate', 'sharpe_ratio'],
help='Sort criterion')
parser.add_argument('--csv', '-c', help='Export results to CSV')
parser.add_argument('--ps-script', '-p', help='PowerShell script to run')
subparsers = parser.add_subparsers(dest='command', help='Commands')
subparsers.add_parser('generate', help='Generate SET files and INI')
subparsers.add_parser('run', parents=[parser], help='Run MT5 tests')
subparsers.add_parser('analyze', parents=[parser], help='Analyze results')
subparsers.add_parser('list', help='List EA configurations')
args = parser.parse_args()
setup_directories(args.base_dir)
if args.command == 'generate':
cmd_generate(args)
elif args.command == 'run':
cmd_run(args)
elif args.command == 'analyze':
cmd_analyze(args)
elif args.command == 'list':
cmd_list(args)
else:
cmd_generate(args)
if __name__ == '__main__':
main()