# MetaTrader 5 Python API quickstart: first call

Independent and unofficial. Not affiliated with or endorsed by any broker or platform named here. Educational only: nothing here is advice, and nothing here recommends a broker or a trade.

This is the markdown version of https://openbrokerapi.com/platforms/metatrader-5/quickstart, written from the same records as that page.

Risk warning: CFDs and spread bets are complex instruments and come with a high risk of losing money rapidly due to leverage. You can lose money on these products, and each provider publishes its own loss figure under FCA rules. You should consider whether you understand how they work and whether you can afford to take the high risk of losing your money. Automated and API trading can amplify losses through bugs, connectivity failures and runaway orders.

Install MetaTrader5 on Windows, connect to a running terminal, pull ticks, bars and deal history, and send a demo order. Every step sourced.

- Checked: 2026-09-25

Unverified: the code on this page was written from the documentation and has not yet been run on a demo account.

Demo accounts only. Credentials are read from environment variables on your own machine. No field on this site asks for a key, a username or a password.

## Steps

### 1. Windows and a running terminal

The Python package talks to the MetaTrader 5 terminal by interprocess communication, so the terminal must be installed, running and logged in, ideally to a demo account. Every PyPI build is Windows x86-64. No Linux build, no macOS build, no exceptions.

Status: verified. Source: [pypi.org](https://pypi.org/project/MetaTrader5/), checked 2026-09-25.

### 2. Install the package

pip install MetaTrader5. MQL5 recommends Python 3.8 or later; PyPI lists 3.6 to 3.14. The current release is 5.0.6231, published on 27 Sep 2026, and MetaQuotes ships new builds often, so upgrade regularly.

Python:

```python
pip install MetaTrader5
# Upgrade later with:
pip install -U MetaTrader5
```

JavaScript:

```javascript
// The MetaTrader5 package is Python only. It talks to the terminal on the same
// Windows machine, so there is no HTTP endpoint to call from JavaScript.
// Use the Python tab.
```

curl:

```bash
# The MetaTrader5 package is Python only. It talks to the terminal on the same
# Windows machine, so there is no HTTP endpoint for curl. Use the Python tab.
```

Status: verified. Source: [mql5.com](https://www.mql5.com/en/docs/python_metatrader5), checked 2026-09-25.

### 3. Connect with initialize()

initialize() returns True or False. On False, last_error() gives a code and description, such as -6 for failed authorisation. You only need login() to switch account: leave out password and server and it uses the ones saved in the terminal. Always finish with shutdown().

Python:

```python
import os
import MetaTrader5 as mt5

# The terminal must be installed, running and logged in to a demo account
if not mt5.initialize():
    raise SystemExit(f"initialize() failed: {mt5.last_error()}")

print(mt5.version())
print(mt5.account_info())

# Optional: switch account. Password and server fall back to those saved in the terminal.
# Values come from environment variables you set yourself, never from the code:
# mt5.login(int(os.environ["MT5_LOGIN"]), password=os.environ["MT5_PASSWORD"], server=os.environ["MT5_SERVER"])

mt5.shutdown()
```

JavaScript:

```javascript
// The MetaTrader5 package is Python only. It talks to the terminal on the same
// Windows machine, so there is no HTTP endpoint to call from JavaScript.
// Use the Python tab.
```

curl:

```bash
# The MetaTrader5 package is Python only. It talks to the terminal on the same
# Windows machine, so there is no HTTP endpoint for curl. Use the Python tab.
```

Status: verified. Source: [mql5.com](https://www.mql5.com/en/docs/python_metatrader5/mt5initialize_py), checked 2026-09-25.

### 4. First real call: prices

Select the symbol, then symbol_info_tick gives you bid, ask, last and time. copy_rates_from_pos returns a numpy array of bars with time, open, high, low, close, tick_volume, spread and real_volume. Position 0 is the current bar.

Python:

```python
import MetaTrader5 as mt5

if not mt5.initialize():
    raise SystemExit(f"initialize() failed: {mt5.last_error()}")

if not mt5.symbol_select("EURUSD", True):
    print("EURUSD not available:", mt5.last_error())
else:
    tick = mt5.symbol_info_tick("EURUSD")
    print("bid", tick.bid, "ask", tick.ask)

    # Last 10 daily bars; position 0 is the current bar
    rates = mt5.copy_rates_from_pos("EURUSD", mt5.TIMEFRAME_D1, 0, 10)
    for r in rates:
        print(r['time'], r['open'], r['high'], r['low'], r['close'])

mt5.shutdown()
```

JavaScript:

```javascript
// The MetaTrader5 package is Python only. It talks to the terminal on the same
// Windows machine, so there is no HTTP endpoint to call from JavaScript.
// Use the Python tab.
```

curl:

```bash
# The MetaTrader5 package is Python only. It talks to the terminal on the same
# Windows machine, so there is no HTTP endpoint for curl. Use the Python tab.
```

Status: verified. Source: [mql5.com](https://www.mql5.com/en/docs/python_metatrader5/mt5copyratesfrompos_py), checked 2026-09-25.

### 5. Your trade history

history_deals_get(date_from, date_to) returns deals as named tuples with ticket, symbol, type, volume, price and profit, or None on error. Filter with group=, ticket= or position= when you want less.

Python:

```python
from datetime import datetime, timedelta
import MetaTrader5 as mt5

if not mt5.initialize():
    raise SystemExit(f"initialize() failed: {mt5.last_error()}")

date_to = datetime.now()
date_from = date_to - timedelta(days=30)
deals = mt5.history_deals_get(date_from, date_to)
if deals is None:
    print("No deals, error code =", mt5.last_error())
else:
    for d in deals:
        print(d.ticket, d.symbol, d.type, d.volume, d.price, d.profit)

mt5.shutdown()
```

JavaScript:

```javascript
// The MetaTrader5 package is Python only. It talks to the terminal on the same
// Windows machine, so there is no HTTP endpoint to call from JavaScript.
// Use the Python tab.
```

curl:

```bash
# The MetaTrader5 package is Python only. It talks to the terminal on the same
# Windows machine, so there is no HTTP endpoint for curl. Use the Python tab.
```

Status: verified. Source: [mql5.com](https://www.mql5.com/en/docs/python_metatrader5/mt5historydealsget_py), checked 2026-09-25.

### 6. A demo order, if you want one

order_send takes a request dict and returns a result. Success is result.retcode equal to TRADE_RETCODE_DONE (10009). The code reads the fill policies the symbol allows from symbol_info(symbol).filling_mode and picks FOK, IOC or RETURN to match, which avoids retcode 10030, unsupported filling mode. Demo account only.

Python:

```python
import MetaTrader5 as mt5

# Demo account only
if not mt5.initialize():
    raise SystemExit(f"initialize() failed: {mt5.last_error()}")

symbol = "EURUSD"
mt5.symbol_select(symbol, True)
price = mt5.symbol_info_tick(symbol).ask

info = mt5.account_info()
if info is None or info.trade_mode != mt5.ACCOUNT_TRADE_MODE_DEMO:
    raise SystemExit("Not a demo account. Stopping before any order is sent.")

# Pick a filling mode the symbol allows. filling_mode is a bit mask:
# 1 = fill or kill (SYMBOL_FILLING_FOK), 2 = immediate or cancel (SYMBOL_FILLING_IOC).
# A hardcoded ORDER_FILLING_RETURN fails with retcode 10030 on market execution symbols.
modes = mt5.symbol_info(symbol).filling_mode
if modes & 1:
    filling = mt5.ORDER_FILLING_FOK
elif modes & 2:
    filling = mt5.ORDER_FILLING_IOC
else:
    # allowed in every execution mode except market execution
    filling = mt5.ORDER_FILLING_RETURN

request = {
    "action": mt5.TRADE_ACTION_DEAL,
    "symbol": symbol,
    "volume": 0.01,
    "type": mt5.ORDER_TYPE_BUY,
    "price": price,
    "deviation": 20,
    "magic": 234000,
    "comment": "quickstart",
    "type_time": mt5.ORDER_TIME_GTC,
    "type_filling": filling,
}
result = mt5.order_send(request)
if result.retcode != mt5.TRADE_RETCODE_DONE:
    print("order_send failed, retcode =", result.retcode)  # 10030: unsupported filling mode
else:
    print("Filled, order", result.order)

mt5.shutdown()
```

JavaScript:

```javascript
// The MetaTrader5 package is Python only. It talks to the terminal on the same
// Windows machine, so there is no HTTP endpoint to call from JavaScript.
// Use the Python tab.
```

curl:

```bash
# The MetaTrader5 package is Python only. It talks to the terminal on the same
# Windows machine, so there is no HTTP endpoint for curl. Use the Python tab.
```

Status: unverified. Source: [mql5.com](https://www.mql5.com/en/docs/python_metatrader5/mt5ordersend_py), no checked date recorded.

## Sources

- Status: verified. Source: [MQL5 docs: Python integration](https://www.mql5.com/en/docs/python_metatrader5), checked 2026-09-25.
- Status: verified. Source: [PyPI: MetaTrader5](https://pypi.org/project/MetaTrader5/), checked 2026-09-25.
- Status: verified. Source: [MQL5 docs: initialize](https://www.mql5.com/en/docs/python_metatrader5/mt5initialize_py), checked 2026-09-25.
- Status: verified. Source: [MQL5 docs: login](https://www.mql5.com/en/docs/python_metatrader5/mt5login_py), checked 2026-09-25.
- Status: verified. Source: [MQL5 docs: last_error](https://www.mql5.com/en/docs/python_metatrader5/mt5lasterror_py), checked 2026-09-25.
- Status: verified. Source: [MQL5 docs: symbol_info_tick](https://www.mql5.com/en/docs/python_metatrader5/mt5symbolinfotick_py), checked 2026-09-25.
- Status: verified. Source: [MQL5 docs: copy_rates_from_pos](https://www.mql5.com/en/docs/python_metatrader5/mt5copyratesfrompos_py), checked 2026-09-25.
- Status: verified. Source: [MQL5 docs: history_deals_get](https://www.mql5.com/en/docs/python_metatrader5/mt5historydealsget_py), checked 2026-09-25.
- Status: verified. Source: [MQL5 docs: order_send](https://www.mql5.com/en/docs/python_metatrader5/mt5ordersend_py), checked 2026-09-25.

## Next on the MetaTrader 5 API

- [MetaTrader 5 API error codes](https://openbrokerapi.com/errors/mt5): 311 decoded, each with what it means, and the fix where the source gives one.
- [MetaTrader 5 functions](https://openbrokerapi.com/platforms/metatrader-5/functions): 78 documented, each with its signature, arguments, return value and source.
- [MetaTrader 5 API page](https://openbrokerapi.com/platforms/metatrader-5): The full record: access, authentication, limits and the source for each.
- [Claude with MetaTrader 5: a safe, read-first setup](https://openbrokerapi.com/guides/claude-mt5): Guide
- [MetaTrader 5 for Python: which platforms does it run on?](https://openbrokerapi.com/guides/metatrader-5-python-platforms): Guide
- [MT5 trade history to a spreadsheet with Python](https://openbrokerapi.com/guides/mt5-trade-history-to-a-spreadsheet): Guide

## Licence and how to cite

The records behind this page are all rights reserved. This file is the page itself, at its own address, in another format. It is not part of the CC BY 4.0 downloads listed at https://openbrokerapi.com/data. Quote from it with a link to the page.

Cite as: MetaTrader 5 Python API quickstart: first call. Broker API Hub, https://openbrokerapi.com/platforms/metatrader-5/quickstart, newest check 2026-09-25.

Where you rely on a single figure, cite the source and the checked date printed beside it as well. Where this page and a broker's own documentation differ, the documentation wins.
