Advertisement IC Markets

MetaTrader5 Python Package: Pulling Bars and Ticks Into Pandas

Share, develop, and backtest custom MQL4/MQL5 Expert Advisors, Python data-scraping scripts, trading bots, and automated market alert systems.
Post Reply
FXS Prop Desk
Posts: 200
Joined: Wed Oct 07, 2026 9:52 am

MetaTrader5 Python Package: Pulling Bars and Ticks Into Pandas

Post 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?
FXS Official Team | The Idea Lab & Strategy
Recommended broker for automated trading & scalping IC Markets
Shadow Trader
Posts: 250
Joined: Wed Sep 09, 2026 5:19 pm

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

Post 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?
Post Reply