⬡ API · WITH CODE · 14 MIN READ

MetaTrader 5 API with Python: automate Brazil's B3 exchange and Forex.

The bridge that connects Python's flexibility to the MT5 terminal. Pull data from Brazil's B3 exchange, compute signals with your favorite libraries and send orders — all in code. With complete examples.

By the RoboTraderIA Team· updated May 2026· intermediate to advanced level

MQL5 (MetaTrader's native language) is powerful, but Python has an unbeatable ecosystem: pandas, numpy, scikit-learn, ready-made indicator libraries. The official MetaTrader5 library gives you the best of both worlds — you use Python to think and MT5 to execute. And the part that matters most to you: it is the most accessible way to automate Brazil's B3 (mini index and mini dollar futures) with Python.

How the bridge works: the MetaTrader5 library is not a standalone web API. It connects your Python script to an MT5 terminal installed and open on Windows. Python sends the commands, MT5 executes them at the broker. Think of MT5 as the "engine" and Python as the "brain".

01Installation and prerequisites

You need: Windows, your broker's MT5 terminal installed and logged in, and Python 3.11+. Then:

pip install MetaTrader5 pandas

About the operating system: the library is officially Windows-only, because it depends on the MT5 terminal. You can run it through Wine on Linux or (the most common setup for a 24/5 bot) on a Windows VPS. On Mac, through a virtual machine. For serious automation, a Windows VPS is the way to go.

02Connecting to the terminal

With MT5 open and logged into your account (use a demo account!), initialize the connection:

# conectar.py
import MetaTrader5 as mt5

# initializes the connection to the open MT5 terminal
if not mt5.initialize():
    print("Falha ao conectar:", mt5.last_error())
    quit()

# account info (confirm it is a DEMO account)
conta = mt5.account_info()
print(f"Conta: {conta.login} | Saldo: {conta.balance} | Servidor: {conta.server}")

# always close the connection when you are done
# mt5.shutdown()

If you need to log in from code (instead of manually in the terminal), pass credentials to initialize:

mt5.initialize(login=12345678, password="sua_senha", server="NomeDoServidor-Demo")

03Pulling candles (including from B3)

This is the part that plugs into your indicators. Pull candles for any asset your broker offers — including WIN (mini index) and WDO (mini dollar) if it gives you access to B3:

# dados.py
import MetaTrader5 as mt5
import pandas as pd
from datetime import datetime

mt5.initialize()

# symbol: e.g. "WIN$N" (mini index), "WDO$N" (mini dollar) or "EURUSD"
# the exact symbol name varies by broker — check it in the Market Watch
simbolo = "WIN$N"
timeframe = mt5.TIMEFRAME_M5   # M1, M5, M15, H1, etc.

# fetches the last 500 candles
rates = mt5.copy_rates_from_pos(simbolo, timeframe, 0, 500)
df = pd.DataFrame(rates)
df["time"] = pd.to_datetime(df["time"], unit="s")
print(df[["time","open","high","low","close","tick_volume"]].tail())

Tip on B3 symbols: the exact name (e.g. WIN$N, WINFUT, WDO$N) varies from broker to broker. Open Market Watch in MT5, right-click → "Show All", and copy the exact name that appears. Use mt5.symbol_select(simbolo, True) to make sure it is enabled.

04Computing a signal with your indicators

This is where Python shines — use the indicator functions you already learned in our guides. The DataFrame that came from MT5 plugs straight in:

# reuse the functions from the indicator guides
from indicadores import calcular_rsi, calcular_macd   # your modules

df["rsi"] = calcular_rsi(df["close"])
macd, sinal, hist = calcular_macd(df["close"])

# example of a combined signal
u = df.iloc[-1]
sinal_compra = (u["rsi"] < 70) and (macd.iloc[-1] > sinal.iloc[-1])

It integrates with everything you have already seen: the RSI, MACD, ATR functions from our guides work directly on that DataFrame. That is the beauty of using Python: the whole ecosystem becomes available for B3.

05Sending an order

Sending an order in MT5 is more verbose than on Binance, because you build a detailed "request". Example of a market buy with stop and target:

# executar.py
def comprar(simbolo, lote, stop_pts, alvo_pts):
    info = mt5.symbol_info_tick(simbolo)
    preco = info.ask
    point = mt5.symbol_info(simbolo).point

    request = {
        "action": mt5.TRADE_ACTION_DEAL,
        "symbol": simbolo,
        "volume": lote,
        "type": mt5.ORDER_TYPE_BUY,
        "price": preco,
        "sl": preco - stop_pts * point,   # stop loss
        "tp": preco + alvo_pts * point,   # take profit
        "deviation": 20,                   # allowed slippage
        "magic": 123456,                  # your bot's id
        "type_filling": mt5.ORDER_FILLING_FOK,
    }
    resultado = mt5.order_send(request)
    if resultado.retcode != mt5.TRADE_RETCODE_DONE:
        print("Erro na ordem:", resultado.retcode, resultado.comment)
    return resultado

The detail that trips up beginners: the type_filling (the fill mode) has to match what the asset accepts — FOK, IOC or RETURN. If the order fails with a "filling" error, try the other modes. The magic number identifies your bot's orders (handy for managing only your own).

Already understand how a bot is structured?

See the full bot architecture guide — the same logic from our Binance tutorial applies to MT5.

See the architecture →

06Managing positions

For a complete bot, you need to query and close positions:

# list your bot's open positions (by magic)
posicoes = mt5.positions_get(symbol="WIN$N")
for p in posicoes:
    if p.magic == 123456:
        print(f"Posição {p.ticket}: lucro {p.profit}")

# close a position
def fechar(posicao):
    tick = mt5.symbol_info_tick(posicao.symbol)
    request = {
        "action": mt5.TRADE_ACTION_DEAL,
        "symbol": posicao.symbol,
        "volume": posicao.volume,
        "type": mt5.ORDER_TYPE_SELL if posicao.type == 0 else mt5.ORDER_TYPE_BUY,
        "position": posicao.ticket,
        "price": tick.bid if posicao.type == 0 else tick.ask,
        "deviation": 20,
        "type_filling": mt5.ORDER_FILLING_FOK,
    }
    return mt5.order_send(request)

07The bot loop

Putting it all together, the skeleton of an MT5 bot:

import time

mt5.initialize()
try:
    while True:
        df = puxar_candles("WIN$N", mt5.TIMEFRAME_M5)
        sinal = calcular_sinal(df)              # your strategy
        atr = calcular_atr(df).iloc[-1]        # dynamic stop

        if sinal == "COMPRA" and not tem_posicao():
            lote = dimensionar(atr)             # risk management
            comprar("WIN$N", lote, stop_pts=2*atr, alvo_pts=4*atr)

        time.sleep(60)                       # checks every minute
except Exception as e:
    print("Erro:", e)
finally:
    mt5.shutdown()

Before real money: run it on a demo account for weeks. Confirm that the symbols, the type_filling and the lot size calculation are right for your asset. A volume or point error can send an order of the wrong size. Test, test, test — and only then go live, with the minimum lot.

08Frequently asked questions

Can you automate B3 with Python?

Yes. The official MetaTrader5 library connects to the MT5 terminal, and if your broker offers MT5 with access to Brazil's B3 exchange (WIN, WDO), you pull data and send orders through Python. It is the most accessible way to automate the Brazilian market with Python.

Do I need MT5 installed?

Yes. The library is not a web API — it is a bridge to the MT5 terminal installed and open on Windows. Python sends the commands, MT5 executes them at the broker.

Does it work on Linux or Mac?

Officially it is Windows only. You can run it through Wine on Linux or on a Windows VPS (the most common setup for a 24/5 bot). On Mac, through a virtual machine. For serious trading, use a Windows VPS.

How is it different from using MQL5 directly?

MQL5 runs inside MT5 and is more tightly integrated for pure execution. Python through the API wins on ecosystem (pandas, ML, libraries). Many people use Python for research and signals, and MQL5 for critical execution. To get started, Python is more accessible.

The WIN symbol name does not work — why?

The exact name varies by broker (WIN$N, WINFUT, WIN$, etc.). Open Market Watch in MT5, show all symbols and copy the exact name. Use mt5.symbol_select(name, True) to enable it.

Related reading

🎁 Get the free trading bot (with the Quotex, Deriv and IQ Option APIs)

Open source bot + ready-made API code. You edit it by chatting with ChatGPT/Claude — no programming. Free, no spam.

👉 Want the ready-made bot instead? Go to botbinaryoptions.com →