Remind me to do this again
One tap puts two reminders in your own calendar: every three months, and 6 April, the day after the UK tax year ends on 5 April. The file is built in this page and saved by your browser. There is no mailbox behind this site, no account to make and nothing to type, so nothing about you leaves this page.
The steps
- Install the packagepip install MetaTrader5 on a Windows machine with the terminal installed. The current release is 5.0.6231, published 27 Sep 2026.Step 1bashpip install MetaTrader5 SourcePyPI: MetaTrader5 release history checked 19 Sep 2026
- Understand the one call that mattersmt5.history_deals_get(date_from, date_to) returns the filled trades between two dates as a tuple of named tuples, or None on error, in which case mt5.last_error() says why. It also accepts group="*GBP*" to filter by symbol, ticket= for a single order, or position= for every deal belonging to one position. Deals, not orders, are what a spreadsheet of your trading should be built from.Our sourced reference page for history_deals_getSourceMQL5 docs: history_deals_get (Python) checked 18 Sep 2026
- Build the dates in UTCMetaTrader 5 works in UTC. Build date_from and date_to as timezone-aware UTC datetimes, or a run from a machine set to British Summer Time will silently miss an hour at each end of the range.SourceMQL5 docs: history_deals_get (Python) checked 18 Sep 2026
- Write the CSVEach deal exposes _asdict(), so csv.DictWriter can take the field names straight from the first row. The sample below saves the last 30 days of deals to deals.csv, which any spreadsheet will open. It only reads: it never calls order_send.SourceMQL5 docs: history_deals_get (Python) checked 18 Sep 2026
- Check the totals before you rely on itThe column names come from the deal named tuple and MetaQuotes does not document this export as a tax record. Reconcile the totals against your broker's own statement before you use it for anything that matters.SourceMQL5 docs: history_deals_get (Python) checked 18 Sep 2026
- If the call returns Nonehistory_deals_get returns None rather than raising. Print mt5.last_error() and look the code up: the negative codes are IPC, version, login and timeout failures with a page of their own.Every negative code mt5.last_error() returnsSourceMQL5 docs: last_error (Python) checked 19 Sep 2026
The script
Demo account only. It stops rather than run against a live account, it reads three values from the environment so no password is ever typed into the file, and it never calls order_send. Not yet run by us, so it carries no Tested badge.
# MetaTrader 5 Python: save your deals to CSV. DEMO ACCOUNT ONLY. Not yet run by us.
# Needs Windows with the MetaTrader 5 terminal installed, and: pip install MetaTrader5
# Set MT5_LOGIN, MT5_PASSWORD and MT5_SERVER as environment variables for a demo account.
import csv
import os
from datetime import datetime, timedelta, timezone
import MetaTrader5 as mt5
if not mt5.initialize(login=int(os.environ["MT5_LOGIN"]), password=os.environ["MT5_PASSWORD"], server=os.environ["MT5_SERVER"]):
print("initialize() failed:", mt5.last_error())
raise SystemExit(1)
try:
acc = mt5.account_info()
if acc is None or acc.trade_mode != mt5.ACCOUNT_TRADE_MODE_DEMO:
raise SystemExit("Stopping: this sample runs on a demo account only.")
# MetaTrader 5 times are UTC, so build the dates in UTC
date_to = datetime.now(timezone.utc)
date_from = date_to - timedelta(days=30)
deals = mt5.history_deals_get(date_from, date_to)
if deals is None:
raise SystemExit(f"history_deals_get failed: {mt5.last_error()}")
with open("deals.csv", "w", newline="") as f:
writer = None
for deal in deals:
row = deal._asdict()
if writer is None:
writer = csv.DictWriter(f, fieldnames=list(row))
writer.writeheader()
writer.writerow(row)
print(len(deals), "deals saved to deals.csv")
finally:
mt5.shutdown()Source: MQL5 docs: history_deals_get (Python) checked 18 Sep 2026
If you would rather not write code
The desktop terminal saves the same history as an HTML or PDF report with no Python at all, and that route works on any machine the terminal runs on.
Where to go next
- Save the history from the terminal insteadHTML or PDF report, no code, from MetaQuotes' help pages
- The MetaTrader 5 Python function referenceEvery function with its signature, return value and source
- The MetaTrader 5 platform API pageWhat the Python package and MQL5 can and cannot do
- Get your data out of any brokerThe same job for IG, OANDA, Capital.com, IBKR and eToro