#!/usr/bin/env python3 """Parse MT5 binary deal files and export to readable format""" import struct import os import glob from datetime import datetime def parse_deal_file(filepath): """Parse MT5 deals binary file""" if not os.path.exists(filepath) or os.path.getsize(filepath) < 100: return None deals = [] with open(filepath, 'rb') as f: data = f.read() # Look for profit values and timestamps for i in range(0, len(data) - 8, 8): try: val = struct.unpack('d', data[i:i+8])[0] # Look for reasonable profit values if -10000 < val < 10000 and abs(val) > 1: deals.append({ 'offset': i, 'profit': round(val, 2) }) except: pass return deals def main(): base_path = os.path.expanduser("~/mt5-docker/config/.wine/drive_c/Program Files/MetaTrader 5/Bases") print("=== MT5 Deal Parser ===\n") # Find all deal files pattern = os.path.join(base_path, "*/trades/*/deals_*.dat") deal_files = glob.glob(pattern) total_profit = 0 for filepath in deal_files: if os.path.getsize(filepath) < 100: continue filename = os.path.basename(filepath) dirname = os.path.basename(os.path.dirname(filepath)) print(f"\nAccount: {dirname}") print(f"File: {filename}") deals = parse_deal_file(filepath) if deals: profits = [d['profit'] for d in deals] total = sum(profits) total_profit += total print(f"Trades found: {len(profits)}") print(f"Total P&L: ${total:,.2f}") print(f"Wins: ${sum(p for p in profits if p > 0):,.2f}") print(f"Losses: ${sum(p for p in profits if p < 0):,.2f}") print(f"\n{'='*50}") print(f"COMBINED P&L: ${total_profit:,.2f}") print(f"{'='*50}") if __name__ == "__main__": main()