Page 1 of 1

MetaTrader5 Python Package: Pulling Bars and Ticks Into Pandas

Posted: Thu Oct 08, 2026 1:36 pm
by FXS Prop Desk
The MetaTrader5 Python package connects to a running MT5 terminal and gives access to price data and trading functions.

Basic example:

Code: Select all

import MetaTrader5 as mt5
import pandas as pd
mt5.initialize()
rates = mt5.copy_rates_from_pos("EURUSD", mt5.TIMEFRAME_M5, 0, 5000)
df = pd.DataFrame(rates)
df['time'] = pd.to_datetime(df['time'], unit='s')
ticks = mt5.copy_ticks_range("EURUSD", start, end, mt5.COPY_TICKS_ALL)
mt5.shutdown()
Notes:
  • Times are in server time, returned as UTC seconds.
  • The terminal must be running and logged in.
  • Windows only, unless using workarounds.
  • Tick history depends on what the broker provides.
Uses: spread analysis, session statistics, custom backtests.

A practical tip: store the downloaded data locally after the first pull. Repeated requests for long histories are slow and may hit limits in the terminal, while local files make analysis much faster.

Do you use the MT5 Python package, and what for?

Re: MetaTrader5 Python Package: Pulling Bars and Ticks Into Pandas

Posted: Mon Oct 12, 2026 5:11 pm
by Shadow Trader
One thing that bit me early: the time column isn't really UTC. The terminal hands back epoch seconds stamped in server time, so pd.to_datetime with unit s gives you broker time labelled as UTC.

A typical New York close server sits two hours ahead of London, so the London open shows up as 10:00 in the dataframe. The exception is the week or two when UK and US clocks change on different dates, which matters now, with the UK falling back on 25 October and the US a week after. I subtract the offset straight after the pull and keep a proper UTC column next to the raw one.

For spread work I pull ticks with COPY_TICKS_INFO rather than ALL, since I only need bid and ask changes. The spread field in the bar data is one number per bar, so it hides exactly the spikes I'm measuring.

Agree on storing locally. I loop one day at a time and write each day to its own parquet file, so a failed request costs me a day instead of a month.

Small one: initialize returns False rather than raising when the terminal isn't logged in, so I check it and print last_error first. Have you found a reliable way to run it headless on a VPS?