Comprehensive Guide to Accessing Price and Tick Data in MetaTrader 5 Using Python
Watch on YouTube: Price & Tick Data in MT5 Using Python (Part 1 / Part 2)
MetaTrader 5 (MT5) offers robust functionality for retrieving market data, enabling traders to analyze prices and ticks with precision. In this post, we’ll explore key functions—copy_rates_from, copy_rates_from_pos, copy_rates_range, copy_ticks_from, and copy_ticks_range—that are essential for working with candlestick (OHLC) and tick data in Python. Each function caters to specific use cases, making data handling in MT5 efficient and flexible.
1. Understanding copy_rates_from
The copy_rates_from function retrieves historical OHLC data, tick volume, spread and real volume, starting from a specific date and time. It’s ideal when you know the starting point of your data query. The function takes four arguments: the trading symbol (symbol), the timeframe (timeframe), the starting date for the bar open time (date_from), and the number of bars to retrieve (count).
When creating a datetime object in Python, it defaults to using the local time zone, whereas MetaTrader 5 stores tick and bar open times in the UTC time zone (without any offset). To ensure accurate results, datetime objects used in functions that rely on time must be created in UTC. We’ll use the pytz library to handle timezone differences effectively. This ensures that all datetime objects are properly localized to UTC when interacting with MetaTrader 5, and can be easily converted to other time zones for display or analysis.
Example:
import MetaTrader5 as mt5
import pandas as pd
import pytz
from datetime import datetime
# Initialize connection to MT5 (use your demo account credentials)
if not mt5.initialize(login=52021XXX, server="XXX-Demo", password="G3wt9SY&4XXXX"):
print("Failed to connect to MetaTrader 5, error code:", mt5.last_error())
quit()
# Define symbol and timeframe
symbol = "EURUSD"
timeframe = mt5.TIMEFRAME_H1
# Define the number of bars to retrieve
num_bars = 10
# Define a datetime object in UTC using pytz
timezone = pytz.timezone("Etc/UTC")
utc_from = datetime(2025, 1, 10, tzinfo=timezone)
# Fetch rates using copy_rates_from
rates_utc = mt5.copy_rates_from(symbol, timeframe, utc_from, num_bars)
# Convert rates to a DataFrame
df_utc = pd.DataFrame(rates_utc)
df_utc['time'] = pd.to_datetime(df_utc['time'], unit='s', utc=True)
# mt5.shutdown()
Explanation:
- Symbol and Timeframe Setup:
- Specifies the trading symbol (EURUSD) and the timeframe (H1, hourly bars) for data retrieval.
- Define UTC Datetime:
- Creates a datetime object for the starting time in UTC using the pytz library to ensure compatibility with MT5’s UTC-based time storage.
- Fetch Trading Data:
- Retrieves 10 historical bars for the specified symbol and timeframe using the copy_rates_from function, starting from the UTC-defined datetime.
- Create and Process DataFrame:
- Converts the retrieved data into a pandas.DataFrame.
- Ensures the time column is properly converted to UTC using pd.to_datetime with the utc=True parameter.
For the following examples, we assume that the mt5 package has been imported and the connection has been successfully established.
2. Working with copy_rates_from_pos
The copy_rates_from_pos function retrieves data starting from a specific index in the series, rather than a specific time. The bars are numbered from the present to the past, with the zero bar representing the current bar.
Example:
import pandas as pd
# Fetch 10 hourly candles for EURUSD starting from position 0
rates = mt5.copy_rates_from_pos("EURUSD", mt5.TIMEFRAME_H1, 0, 10)
# Convert to DataFrame
rates_df = pd.DataFrame(rates)
rates_df['time'] = pd.to_datetime(rates_df['time'], unit='s')
rates_df.set_index('time', inplace=True)
print(rates_df.head())
Use Case: This is useful for sequential data analysis when you want data from a particular position in the historical series.
3. Retrieving Data Using copy_rates_range
The copy_rates_range function allows you to fetch historical data within a specific date range. This method is ideal for backtesting or analyzing a specific time window. Similarly to copy_rates_from, we’ll use the pytz library to handle timezone adjustments effectively.
Example:
import pandas as pd
import pytz
# Define the date range in UTC using pytz
timezone = pytz.timezone("Etc/UTC")
start_date = pd.Timestamp("2025-01-09", tz=timezone)
end_date = pd.Timestamp("2025-01-10", tz=timezone)
# Fetch EURUSD hourly data between two UTC dates
rates = mt5.copy_rates_range("EURUSD", mt5.TIMEFRAME_H1, start_date, end_date)
# Convert the retrieved data to a DataFrame
rates_df = pd.DataFrame(rates)
rates_df['time'] = pd.to_datetime(rates_df['time'], unit='s', utc=True) # Explicitly handle UTC
rates_df.set_index('time', inplace=True)
# Display the first few rows of the DataFrame
print(rates_df.head())
4. Using copy_ticks_from for Tick Data
The copy_ticks_from function retrieves raw tick data starting from a specified time. The function takes four arguments: the trading symbol (symbol), the starting date and time for the tick data (date_from), the number of ticks to retrieve (count), and the type of tick data to fetch, specified by flags such as COPY_TICKS_ALL, COPY_TICKS_INFO, or COPY_TICKS_TRADE.
Example:
import pandas as pd
import pytz
# Define the timestamp in UTC using pytz
timezone = pytz.timezone("Etc/UTC")
start_time = pd.Timestamp("2025-01-01", tz=timezone)
# Fetch 1000 ticks for EURUSD starting from the specific UTC time
ticks = mt5.copy_ticks_from("EURUSD", start_time, 1000, mt5.COPY_TICKS_ALL)
# Convert ticks to a DataFrame
ticks_df = pd.DataFrame(ticks)
# Convert the 'time' column to UTC
ticks_df['time'] = pd.to_datetime(ticks_df['time'], unit='s', utc=True)
# Display the first few rows of the DataFrame
print(ticks_df.head())5. Fetching Tick Data with copy_ticks_range
Like copy_rates_range, this function retrieves tick data within a specific time range, making it essential for detailed tick-by-tick analysis or high-frequency trading.
Example:
import pandas as pd
# Fetch tick data for EURUSD between two dates
ticks = mt5.copy_ticks_range("EURUSD", pd.Timestamp("2025-01-01"), pd.Timestamp("2025-02-01"), mt5.COPY_TICKS_ALL)
# Convert to DataFrame
ticks_df = pd.DataFrame(ticks)
ticks_df['time'] = pd.to_datetime(ticks_df['time'], unit='s')
print(ticks_df.head())
Conclusion
Mastering these data retrieval functions is essential for successful algorithmic trading in MT5. Whether you’re utilizing candlestick data for backtesting or tick data for high-frequency trading, the “copy” functions discussed above provide both flexibility and precision.
In the next post, we’ll dive into working with orders. Stay tuned to learn more about optimizing your trading strategies using Python and MetaTrader 5!
