Opera MetaTrader 5 desde Python con el SDK de fxapis
pip install fxapis: conecta una cuenta de MT5, coloca órdenes que nunca se duplican y deja que el SDK reintente solo lo seguro, en Linux, macOS o Windows.
En esta página
El SDK oficial de Python de fxapis es un cliente tipado para la API REST alojada de MetaTrader 5: clientes síncrono y asíncrono sobre httpx, claves de idempotencia agregadas por ti y una clase de excepción por código de error. Necesita Python 3.10 o más reciente y es de código abierto en github.com/FXapis/fxapis-python.
A diferencia del paquete oficial MetaTrader5, no controla un terminal en tu máquina. Los terminales corren en la nube de fxapis; el SDK hace solicitudes HTTPS, así que corre en Linux, macOS, Windows, un contenedor o un trabajo programado. El paquete MetaTrader5 vs una API REST compara los dos en detalle.
Instálalo
pip install fxapis
export FXAPIS_API_KEY="fx_test_…" # create one at fxapis.com/dashboard/keys
Usa una cuenta demo de un broker mientras construyes: toda clave de fxapis, incluidas las fx_test_, llega a un broker real. No hay un mercado simulado.
De un login de MT5 a una operación cerrada
from fxapis import Fxapis
client = Fxapis() # reads FXAPIS_API_KEY
# 1. Connect the account once. The trading password, not the investor password.
account = client.accounts.connect(
login="26177561",
server="YourBroker-Demo", # exactly as MetaTrader shows it, e.g. Exness-MT5Trial8, ICMarketsSC-Demo or Pepperstone-Demo
password="your-mt5-trading-password",
mode="warm_on_demand", # online when needed, offline after 15 idle minutes
)
# 2. Bring it online and wait for `ready` — about ten seconds for a typical broker.
client.accounts.warm(account["id"])
client.accounts.wait_until_ready(account["id"])
# 3. Trade. Volumes and prices are strings: "0.01", not 0.01.
order = client.orders.market(account["id"], symbol="EURUSD", side="buy", volume="0.01")
print(order["state"], order["filledPrice"])
# 4. Read the positions, then close them.
for position in client.positions.list(account["id"]):
print(position["symbol"], position["volume"], position["profit"])
client.positions.close(account["id"], position["brokerPositionId"])
with Fxapis() as client: cierra el pool de conexiones por ti. Conectar no inicia sesión: guarda la cuenta y cifra su contraseña, y warm inicia la sesión. wait_until_ready() lanza una excepción si la cuenta necesita a una persona (una contraseña equivocada, 2FA, un certificado) en lugar de esperar para siempre.
En Linux, macOS o Google Colab
Esta es la razón habitual por la que la gente busca una «API de Python para MetaTrader 5»: el paquete oficial MetaTrader5 necesita Windows y un terminal corriendo al lado. El SDK de fxapis no necesita ninguno de los dos, porque solo hace solicitudes HTTPS:
- Linux y macOS:
pip install fxapisen cualquier entorno virtual; sin Wine, sin terminal. - Google Colab o Jupyter: ejecuta
!pip install fxapisen una celda y tomaFXAPIS_API_KEYde los secretos del notebook en lugar de pegar la clave en el notebook. - Si vienes del paquete MetaTrader5: la guía de Linux y macOS tiene una tabla que relaciona cada una de sus llamadas (
order_send,positions_get,account_info…) con su equivalente en fxapis.
Este artículo está escrito para fxapis 0.2.2 en PyPI, la versión actual al 26 de octubre de 2026.
Órdenes que nunca se duplican
client.orders.market() envía un Idempotency-Key con cada orden, generado por ti. Si la conexión se cae después de enviar la orden, el SDK la reenvía con la misma clave, y fxapis responde con el primer resultado en lugar de abrir una segunda posición. Cuando la clave debe significar algo en tu sistema (una señal y un miembro, un deal copiado), pasa la tuya:
key = f"signal_{signal_id}:member_{member_id}"
order = client.orders.market(account_id, symbol="XAUUSD", side="buy", volume="0.05", idempotency_key=key)
Un miembro que toca dos veces, o un trabajo que corre dos veces, recibe la misma orden de vuelta. Órdenes idempotentes explica por qué esto importa.
Cómo manejar cada resultado
from fxapis import OrderRejectedError, OrderUnresolvedError, SendFailedError, AccountNotReadyError
try:
order = client.orders.market(account_id, symbol="XAUUSD", side="buy", volume="0.05", idempotency_key=key)
except OrderRejectedError as err:
print("rejected:", err.message) # nothing opened; a new attempt needs a NEW key
except OrderUnresolvedError as err:
order = client.orders.wait_until_resolved(err.order_id) # never resend: wait for the answer
except (SendFailedError, AccountNotReadyError) as err:
print("not sent:", err.code) # already retried with the same key; safe to try later
El SDK reintenta solo lo que es demostrablemente seguro: los códigos que significan que no se hizo nada se reenvían con la misma clave, y los errores del servidor y las conexiones perdidas se reintentan en las lecturas y en las solicitudes que llevan una clave. ORDER_UNRESOLVED nunca se reintenta (la orden puede estar viva en el broker), y fxapis confirma una orden de apertura contra el historial de deals del propio broker.
Async, páginas y muchas cuentas
import asyncio
from fxapis import AsyncFxapis
async def main() -> None:
async with AsyncFxapis() as client:
async for order in client.orders.iter(state="unknown"):
print(order["id"], order["symbol"])
asyncio.run(main())
iter() recorre una lista paginada por ti. Para una operación en muchas cuentas (un copiador, un servicio de señales), client.multi_account_orders.create() envía una sola orden a hasta 1,000 cuentas, dentro del límite de tu plan, con un volumen por cuenta.
Adónde ir después
- fxapis-examples tiene un inicio rápido, click-to-trade y un copiador de operaciones en Python; mira el artículo de los ejemplos.
- SDKs y ejemplos en la documentación, y la guía de Python para ver cada solicitud con
requestssimple (en inglés). - Trading cubre cada resultado que puede tener una orden, y Errores, cada código.