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.
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.