Как подключить ИИ-агентов к MetaTrader 5 через MCP
Введение
В начале 2026 года мир ИИ-агентов пережил бурный рост. Такие инструменты, как OpenClaw — персональный ИИ-ассистент с открытым исходным кодом, набравший более 250 000 звёзд на GitHub менее чем за 60 дней, — показали, что ИИ способен на гораздо большее, чем просто общение в чате. Эти агенты просматривают веб-страницы, управляют календарями, отправляют электронные письма, выполняют код, а теперь, благодаря растущей экосистеме интеграций, могут даже самостоятельно торговать криптовалютами. Такие проекты, как BankrBot, предлагают полную автоматизацию торговли криптовалютами через OpenClaw, а боты на рынке прогнозов Polymarket, как сообщается, принесли сотни тысяч долларов прибыли.
Однако здесь есть явный пробел. Если вы трейдер Forex или CFD и используете MetaTrader 5, ни одной такой интеграции для вас не существует. В криптовалютном сегменте есть десятки навыков, MCP-серверов и инструментов автоматизации. На стороне MetaTrader по сути нет ничего. В запросе на добавление функции в репозитории OpenClaw на GitHub прямо говорится о необходимости встроенной возможности исполнения торговых операций в MetaTrader 5, а темы на форуме Forex Factory показывают, что трейдеры активно ищут решения. Спрос действительно существует, но до сих пор его никто не удовлетворил — до этого момента.
В этой статье мы создадим сервер MCP. Это стандартизированный мост, позволяющий любому ИИ-агенту напрямую взаимодействовать с MetaTrader 5. По завершении вы сможете писать своему ИИ-ассистенту в Telegram, Claude Desktop или любом клиенте, совместимом с MCP. ИИ будет получать данные в реальном времени из вашего терминала и совершать реальные сделки от вашего имени. Мы рассмотрим следующие темы:
- Что такое MCP? Универсальный протокол для ИИ-инструментов
- Обзор архитектуры
- Настройка проекта и зависимости
- Создание клиентской обёртки MetaTrader 5
- Реализация инструментов MCP
- Точка входа сервера MCP
- Тестирование с помощью MCP Inspector
- Подключение к ИИ-агентам
- Заключение
Полный исходный код приведен в конце этой статьи. Всё написано на Python с использованием официальной библиотеки MetaTrader 5 от MetaQuotes, поэтому, если вы уже работали с интеграцией MetaTrader 5 с Python, вам будет очень легко освоиться. Если нет, не беспокойтесь — мы рассмотрим всё по порядку.
1. Что такое MCP? Универсальный протокол для ИИ-инструментов
Прежде чем приступить к написанию кода, нам необходимо понять, что такое MCP и почему он важен. MCP — это аббревиатура от Model Context Protocol (протокол контекста модели), который был создан компанией Anthropic (разработчиком Claude) как открытый стандарт для подключения ИИ-моделей к внешним инструментам и источникам данных. Считайте MCP универсальным адаптером: вместо того чтобы каждое ИИ-приложение создавало собственную интеграцию для каждого сервиса, MCP предоставляет единый стандартизированный протокол, по которому любой ИИ-клиент может взаимодействовать с любым сервером инструментов.
Аналогия для сообщества MQL5 вполне понятна. Пакет Python для MetaTrader 5 от MetaQuotes представляет собой мост между Python и вашим терминалом MetaTrader 5 — он предоставляет скриптам на Python стандартизированный способ вызова функций MetaTrader 5. MCP делает то же самое, но на уровень выше: он предоставляет ИИ-агентам стандартизированный способ обнаруживать и вызывать инструменты, которые предоставляют скрипты Python (или любые другие программы). Без MCP каждому ИИ-приложению (OpenClaw, Claude Desktop, Cursor, VS Code Copilot) потребовался бы собственный формат плагинов. С MCP вы создаёте один сервер, и любой совместимый клиент может сразу же начать им пользоваться.
Как работает MCP
Сервер MCP — это программа, которая предоставляет инструменты — функции, которые может вызывать ИИ-агент. Каждый инструмент имеет название, описание (чтобы ИИ знал, когда его использовать), набор типизированных параметров и возвращаемое значение. При подключении сервера MCP к ИИ-клиенту клиент автоматически обнаруживает все доступные инструменты и их схемы. Затем ИИ-модель на основе запроса пользователя решает, какие инструменты вызвать, формирует корректные параметры, вызывает инструмент и интерпретирует результат.
Например, наш сервер MCP для MetaTrader 5 будет предоставлять инструмент get_rates с параметрами symbol, timeframe и count. Когда пользователь обращается к своему ИИ-ассистенту с запросом «Покажи мне последние 10 часовых свечей по паре EURUSD», ИИ понимает, что для этого требуются рыночные данные, вызывает get_rates с параметрами symbol="EURUSD", timeframe="H1" и count=10, получает данные OHLCV и представляет их в удобочитаемом формате. Пользователю не нужно знать о том, что был вызван инструмент MCP, — он просто ведёт диалог со своим помощником.
Транспорт MCP: stdio
MCP поддерживает несколько транспортных механизмов. Для локальных серверов в качестве стандарта используется stdio (стандартный ввод/вывод). Для этого не требуется ни HTTP-сервер, ни настройка портов, ни открытие доступа по сети. Сервер запускается по требованию клиента и осуществляет обмен данными через каналы ввода-вывода (pipes). Это самый простой и безопасный транспорт для инструмента, управляющего торговым терминалом на вашем локальном компьютере.

Рис. 1. MCP-мост от ИИ-агента к терминалу MetaTrader 5
Из схемы видно, что сервер MCP располагается между ИИ-агентом и терминалом MetaTrader 5. Пользователь общается с ИИ-агентом на естественном языке, агент преобразует запрос в вызов инструмента MCP, наш сервер на Python обрабатывает этот вызов с помощью библиотеки MetaTrader 5, а результат возвращается пользователю. Весь цикл занимает считанные миллисекунды.
2. Обзор архитектуры
Наш сервер MCP состоит из четырёх уровней, каждый из которых выполняет чётко определённую функцию. Понимание этих уровней значительно облегчит разбор кода в следующих разделах.
Уровень 1 — константы (constants.py)
API MetaTrader 5 для Python использует числовые константы для таких параметров, как таймфреймы (TIMEFRAME_H1 = 16385), типы ордеров (ORDER_TYPE_BUY = 0), режимы исполнения и режимы срока действия ордера. Люди и ИИ-агенты работают со строками вроде «H1», «BUY», «IOC» и «GTC». Уровень констант предоставляет словари сопоставлений, которые преобразуют значения между этими двумя мирами. Это небольшой, но критически важный файл: без него каждому обработчику потребовалась бы собственная логика преобразования.
Уровень 2 — клиентская обёртка MetaTrader 5 (mt5client.py)
Этот уровень отвечает за подключение к MetaTrader 5 и предоставляет служебные функции, используемые всеми обработчиками. Её основные задачи: инициализация соединения с MetaTrader 5 (с защитой от тайм-аута), проверка перед каждой операцией, что терминал подключён и выполнен вход в учётную запись, преобразование именованных кортежей MetaTrader 5 в обычные словари Python, а также формирование правильно оформленных торговых запросов на основе понятных человеку параметров.
Уровень 3 — обработчики (handlers/*.py)
Пять модулей-обработчиков содержат собственно бизнес-логику: запросы данных по счёту, получение данных по символам и рыночных данных, управление позициями, управление ордерами и историю сделок. Каждая функция-обработчик принимает обычные параметры Python, вызывает соответствующие функции API MetaTrader 5 и возвращает словарь. Никаких зависимостей от фреймворков, никаких понятий HTTP — только чистая бизнес-логика.
Уровень 4 — сервер MCP (server.py)
Верхний уровень регистрирует 14 инструментов MCP с использованием фреймворка FastMCP. Каждый инструмент — это тонкая обёртка, которая проверяет соединение с MetaTrader 5 и передаёт управление соответствующему обработчику. Описания инструментов (строки документации, docstrings) подсказывают ИИ-агенту, когда и как использовать тот или иной инструмент. На практике они выполняют функции инжиниринга промптов для уровня инструментов.

Рис. 2. Многоуровневая архитектура проекта сервера MCP для MetaTrader 5
Полная структура проекта выглядит следующим образом:
mt5-mcp-server/ ├── server.py # MCP server entry point + 14 tool registrations ├── mt5client.py # MT5 connection wrapper + utilities ├── constants.py # String-to-MT5-constant mapping tables ├── handlers/ │ ├── account.py # Account info (1 function) │ ├── symbols.py # Market data (5 functions) │ ├── positions.py # Position management (3 functions) │ ├── orders.py # Order management (4 functions) │ └── history.py # Trade history (1 function) ├── config.json # MT5 path and optional credentials └── requirements.txt # MetaTrader5 + fastmcp
Весь проект состоит из 676 строк кода на языке Python. Здесь нет ни Flask, ни HTTP-сервера, ни Docker, ни сложного развёртывания. Он запускается непосредственно на том же компьютере с Windows, на котором установлен ваш терминал MetaTrader 5.
3. Настройка проекта и зависимости
Прежде чем приступить к разработке, давайте настроим проект. Вам понадобятся три вещи: Python 3.10 или более поздней версии, установленный на вашем компьютере с Windows; терминал MetaTrader 5, установленный и подключённый к брокерскому счёту (для тестирования мы настоятельно рекомендуем использовать демо-счёт); а также два пакета Python.
Скачайте и распакуйте архив, а затем установите необходимые зависимости:
pip install -r requirements.txt
Пакет MetaTrader5 — это официальный пакет Python-интеграции от компании MetaQuotes. Он взаимодействует с терминалом MetaTrader 5 через COM-интерфейс и предоставляет функции для любых операций — от получения данных свечей до размещения ордеров. Пакет fastmcp — это Python-фреймворк для создания серверов MCP: он обрабатывает протокол JSON-RPC, регистрацию инструментов, генерацию схем параметров на основе аннотаций типов и транспорт stdio. С этими двумя пакетами у нас есть всё необходимое.
Файл конфигурации
{
"mt5_path": "C:\\Program Files\\MetaTrader 5\\terminal64.exe",
"login": 12345678,
"password": "your_password",
"server": "YourBroker-Server",
"timeout": 60
} Все поля необязательны. Если для параметра mt5_path установлено значение null, библиотека MetaTrader 5 автоматически найдёт ваш терминал (это работает, если у вас установлена только одна копия MetaTrader 5). Если login, password и server равны null, сервер считает, что ваш терминал уже авторизован, — как обычно и бывает, если MetaTrader 5 открыт на вашем компьютере. Значение таймаута (в секундах) определяет, как долго мы ждём выполнения операций в MetaTrader 5, прежде чем прекратить попытки. Для большинства пользователей настройки по умолчанию работают без каких-либо изменений.
4. Создание клиентской обёртки для MetaTrader 5
Клиентская обёртка — это основа, от которой зависит работа каждого обработчика. Она обеспечивает управление соединением, преобразование данных и формирование торговых запросов. Давайте рассмотрим каждую часть по очереди.
Загрузка конфигурации и инициализация
Начнём с функции, которая загружает файл конфигурации и инициализирует соединение с MetaTrader 5:
import json import logging import os import threading import MetaTrader5 as mt5 log = logging.getLogger("mt5mcp") INIT_TIMEOUT = 60 _CONFIG_PATH = os.path.join( os.path.dirname(os.path.abspath(__file__)), "config.json" ) def load_config(): if not os.path.exists(_CONFIG_PATH): return {} with open(_CONFIG_PATH, "r") as f: return json.load(f)
Путь к файлу конфигурации определяется относительно местоположения самого скрипта с помощью os.path.dirname(os.path.abspath(__file__)). Это гарантирует, что независимо от того, из какого рабочего каталога запускается сервер MCP, он всегда найдёт свой файл config.json. Если файл не существует, мы возвращаем пустой словарь — сервер всё равно будет работать, используя поведение MetaTrader 5 по умолчанию.
Защита от превышения времени ожидания
Библиотека MetaTrader 5 для Python иногда может зависать, особенно во время инициализации или когда терминал не отвечает. Мы оборачиваем каждый вызов MetaTrader 5 механизмом тайм-аута:
def _run_with_timeout(fn, timeout=INIT_TIMEOUT): """Run fn() in a thread with a timeout. Returns None if timed out.""" result = [None] def _worker(): result[0] = fn() t = threading.Thread(target=_worker, daemon=True) t.start() t.join(timeout=timeout) if t.is_alive(): log.warning("MT5 call timed out after %ds", timeout) return None return result[0]
Эта функция запускает указанный вызываемый объект в потоке-демоне и ожидает его завершения в пределах заданного тайм-аута. Если вызов длится дольше 60 секунд (значение по умолчанию), мы возвращаем `None`, а не зависаем на неопределённое время. Этот подход используется для каждой операции MetaTrader 5 — инициализации, проверки информации о терминале и попыток входа. Это простая, но крайне важная подстраховка, когда ваш торговый терминал выступает в роли бэкенда.
Управление подключением: ensure_initialized()
Самая важная функция в клиентской обёртке — ensure_initialized(), которая вызывается перед каждым вызовом инструмента MCP. В ней реализована проверка, состоящая из трёх этапов:
def ensure_initialized(): info = _run_with_timeout(mt5.terminal_info, timeout=15) if info is None: log.warning("Terminal not responding, attempting full init...") return init_mt5() acc = _run_with_timeout(mt5.account_info, timeout=15) if acc is not None and acc.login != 0: return True log.warning("Not logged in, attempting login...") config = load_config() if not config.get("login"): return True return _run_with_timeout( lambda: mt5.login( login=int(config["login"]), password=config["password"], server=config["server"], ), timeout=INIT_TIMEOUT, )
Сначала мы проверяем, отвечает ли терминал вообще, вызывая terminal_info() с коротким тайм-аутом в 15 секунд. Если возвращается `None`, это означает, что терминал не запущен или не подключён — в таком случае мы пытаемся выполнить полную инициализацию. Во-вторых, если терминал работает, мы проверяем, действительно ли мы авторизованы, вызывая account_info() и убеждаясь, что значение login не равно нулю. В-третьих, если мы не авторизованы, а учётные данные доступны в config.json, мы пытаемся войти с помощью mt5.login(). Если учётные данные не настроены, мы всё равно возвращаем True — предполагая, что пользователь уже вошёл вручную.
Преобразование данных и формирование ордеров
Две служебные функции дополняют клиентскую обёртку. Функция to_dict() преобразует именованные кортежи MetaTrader 5 в обычные словари:
def to_dict(named_tuple): if named_tuple is None: return None return named_tuple._asdict()
Функция build_order_request() принимает словарь с удобочитаемыми параметрами (например, type="BUY_LIMIT", type_filling="IOC") и преобразует их в числовой формат, который ожидает mt5.order_send(). Она проверяет каждое поле, сопоставляет строки с константами MetaTrader 5 с помощью словарей сопоставления из constants.py и возвращает либо корректный словарь торгового запроса, либо сообщение об ошибке. Мы увидим эту функцию в действии, когда будем создавать обработчик ордеров.
5. Реализация инструментов MCP
После того как клиентская обёртка готова, мы можем создать функции обработчиков, которые будет вызывать каждый инструмент MCP. Мы сгруппировали их в пять модулей по предметной области: счёт, рыночные данные, позиции, ордера и история. Давайте рассмотрим самые важные из них.
Константы: слой преобразования
Прежде чем рассматривать какой-либо обработчик, нам нужны таблицы сопоставления, которые преобразуют понятные человеку строки в константы MetaTrader 5. Вот полный текст файла constants.py:
import MetaTrader5 as mt5 TIMEFRAME_MAP = { "M1": mt5.TIMEFRAME_M1, "M5": mt5.TIMEFRAME_M5, "M15": mt5.TIMEFRAME_M15, "M30": mt5.TIMEFRAME_M30, "H1": mt5.TIMEFRAME_H1, "H4": mt5.TIMEFRAME_H4, "D1": mt5.TIMEFRAME_D1, "W1": mt5.TIMEFRAME_W1, "MN1": mt5.TIMEFRAME_MN1, # ... plus M2, M3, M4, M6, M10, M12, M20, H2, H3, H6, H8, H12 } ORDER_TYPE_MAP = { "BUY": mt5.ORDER_TYPE_BUY, "SELL": mt5.ORDER_TYPE_SELL, "BUY_LIMIT": mt5.ORDER_TYPE_BUY_LIMIT, "SELL_LIMIT": mt5.ORDER_TYPE_SELL_LIMIT, "BUY_STOP": mt5.ORDER_TYPE_BUY_STOP, "SELL_STOP": mt5.ORDER_TYPE_SELL_STOP, "BUY_STOP_LIMIT": mt5.ORDER_TYPE_BUY_STOP_LIMIT, "SELL_STOP_LIMIT": mt5.ORDER_TYPE_SELL_STOP_LIMIT, } FILLING_MAP = { "FOK": mt5.ORDER_FILLING_FOK, "IOC": mt5.ORDER_FILLING_IOC, "RETURN": mt5.ORDER_FILLING_RETURN, } TIME_MAP = { "GTC": mt5.ORDER_TIME_GTC, "DAY": mt5.ORDER_TIME_DAY, "SPECIFIED": mt5.ORDER_TIME_SPECIFIED, "SPECIFIED_DAY": mt5.ORDER_TIME_SPECIFIED_DAY, }
Эти четыре словаря образуют весь слой преобразования между понятными человеку строками и числовыми константами, которые ожидает API MetaTrader 5. TIMEFRAME_MAP охватывает все 21 доступный таймфрейм — от 1-минутного до месячного. ORDER_TYPE_MAP охватывает все 8 типов ордеров, включая менее распространённые стоп-лимитные ордера. FILLING_MAP и TIME_MAP охватывают соответственно режимы исполнения и режимы срока действия ордера. Когда ИИ-агент говорит: «Разместить ордер BUY_LIMIT со сроком действия GTC», эти словари напрямую преобразуют эту фразу в числовые значения, необходимые для mt5.order_send().
Рыночные данные: получение свечей OHLCV
Обработчик рыночных данных — это то, с чего начинается большинство взаимодействий с ИИ: пользователь спрашивает о ситуации по тому или иному символу, и агенту нужны ценовые данные. Вот функция get_rates:
from constants import TIMEFRAME_MAP from mt5client import to_dict def get_rates(symbol, timeframe="M1", count=100): tf_str = timeframe.upper() tf = TIMEFRAME_MAP.get(tf_str) if tf is None: return {"error": f"Invalid timeframe: {tf_str}"} count = max(1, min(count, 10000)) rates = mt5.copy_rates_from_pos(symbol, tf, 0, count) if rates is None or len(rates) == 0: return [] return [{ "time": int(r[0]), "open": float(r[1]), "high": float(r[2]), "low": float(r[3]), "close": float(r[4]), "tick_volume": int(r[5]), "spread": int(r[6]), "real_volume": int(r[7]), } for r in rates]
Эта функция проверяет таймфрейм по нашему TIMEFRAME_MAP, ограничивает количество свечей безопасным диапазоном от 1 до 10 000 и вызывает copy_rates_from_pos(), чтобы получить данные OHLCV, начиная с самого последнего бара. Одна важная деталь: copy_rates_from_pos возвращает структурированные массивы NumPy, а не именованные кортежи, поэтому мы не можем использовать здесь нашу утилиту to_dict(). Вместо этого мы вручную создаём словари, индексируя каждую строку. Поле time представляет собой время открытия свечи в виде временной метки Unix.
Управление позициями: закрытие сделок
Управление позициями — вот где всё становится интересным. Функция `close_position` должна автоматически определять правильное направление закрытия и цену:
def close_position(ticket, volume=None, deviation=20): positions = mt5.positions_get(ticket=ticket) if not positions: return {"error": f"Position {ticket} not found"} pos = positions[0] close_volume = float(volume) if volume is not None else pos.volume close_type = mt5.ORDER_TYPE_SELL \ if pos.type == mt5.ORDER_TYPE_BUY else mt5.ORDER_TYPE_BUY tick = mt5.symbol_info_tick(pos.symbol) if tick is None: return {"error": f"Cannot get price for {pos.symbol}"} price = tick.bid if close_type == mt5.ORDER_TYPE_SELL \ else tick.ask req = { "action": mt5.TRADE_ACTION_DEAL, "position": ticket, "symbol": pos.symbol, "volume": close_volume, "type": close_type, "price": price, "type_filling": mt5.ORDER_FILLING_IOC, "deviation": int(deviation), } result = mt5.order_send(req) if result is None or result.retcode != mt5.TRADE_RETCODE_DONE: err = result.comment if result else str(mt5.last_error()) return {"error": f"Failed to close position: {err}"} return to_dict(result)
Чтобы закрыть позицию, необходимо совершить сделку в противоположном направлении. Если это позиция BUY, мы закрываем её ордером SELL по цене Bid. Если это позиция SELL, мы закрываем её ордером BUY по цене Ask. Сначала функция находит позицию по номеру тикета с помощью функции positions_get(), определяет противоположное направление и правильную цену, вызывая symbol_info_tick(), а затем отправляет закрывающий ордер через order_send(). Параметр `volume` необязателен — если он не указан, закрывается вся позиция. Если этот параметр указан, происходит частичное закрытие позиции, что удобно для постепенного выхода из позиций.
Размещение ордера: ключевая торговая функция
Функция create_order в файле orders.py — самый сложный обработчик. Она должна обрабатывать как рыночные ордера (немедленное исполнение), так и отложенные ордера (лимитные и стоп-ордера), с автоматической подстановкой цены для рыночных ордеров:
def create_order(symbol, type, volume, price=None, sl=None, tp=None, deviation=20, magic=0, comment="", type_filling="IOC", type_time="GTC"): order_type = type.upper() if order_type not in ORDER_TYPE_MAP: return {"error": f"Invalid type: {order_type}"} is_market = order_type in ("BUY", "SELL") if is_market and price is None: tick = mt5.symbol_info_tick(symbol) if tick is None: return {"error": f"Cannot get price for {symbol}"} price = tick.ask if order_type == "BUY" else tick.bid body = { "action": "DEAL" if is_market else "PENDING", "symbol": symbol, "type": order_type, "volume": volume, "price": price, "deviation": deviation, "magic": magic, "comment": comment, "type_filling": type_filling, "type_time": type_time, } if sl is not None: body["sl"] = sl if tp is not None: body["tp"] = tp req, err = build_order_request(body) if err: return {"error": err} result = mt5.order_send(req) if result is None: return {"error": f"order_send failed: {mt5.last_error()}"} return to_dict(result)
Ключевое архитектурное решение здесь — автоматическая подстановка цены для рыночных ордеров. Когда ИИ-агент говорит «купить 0,01 лота EURUSD», ему не нужно указывать цену — функция определяет, что это рыночный ордер (BUY или SELL), получает текущую цену Ask для ордеров BUY или цену Bid для ордеров SELL и автоматически подставляет её. Для отложенных ордеров (BUY_LIMIT, SELL_LIMIT, BUY_STOP, SELL_STOP) параметр `price` обязателен, поскольку пользователь должен указать уровень, на котором ордер должен сработать. Для рыночных ордеров (немедленное исполнение) параметр `action` задаётся как `DEAL`, а для лимитных/стоп-ордеров — как `PENDING`. Наконец, словарь передаётся в функцию `build_order_request()`, чтобы преобразовать все строковые значения в константы MetaTrader 5 перед вызовом `order_send()`.
6. Точка входа сервера MCP
Когда все обработчики готовы, точка входа сервера связывает все компоненты воедино. Именно здесь мы регистрируем наши 14 инструментов MCP с использованием фреймворка FastMCP. Давайте рассмотрим ключевые паттерны.
Настройка сервера и общие инструкции
from fastmcp import FastMCP from mt5client import ensure_initialized from handlers import account, symbols, positions, orders, history mcp = FastMCP( "MT5 Trading Server", instructions=( "Always call get_account before placing trades to verify margin. " "Always call get_symbol_info before placing orders to get volume " "constraints (volume_min, volume_max, volume_step, trade_stops_level). " "Use get_positions to find ticket numbers before modifying or closing." ), )
Параметр «instructions» представляет собой глобальный промпт, который ИИ-агент получает при обнаружении сервера. Это позволяет задать правила поведения: всегда проверять маржу на счёте перед торговлей, всегда проверять ограничения символа перед размещением ордеров и всегда узнавать номера тикетов перед изменением позиций. Эти инструкции служат своего рода страховкой: даже если общее обучение ИИ не охватывает принятые правила торговли в MetaTrader 5, эти правила гарантируют, что он будет следовать разумному рабочему процессу. Вы можете изменить эти инструкции или задать собственные, чтобы изменить поведение ИИ.
Шаблон регистрации инструмента
Каждый инструмент построен по одной и той же схеме: тонкая обёртка проверяет соединение и передаёт управление обработчику. Вот как выглядят инструменты только для чтения:
def _ensure(): """Check MT5 connection, return error dict if not connected.""" if not ensure_initialized(): return {"error": "MT5 terminal not connected"} return None @mcp.tool(annotations={"readOnlyHint": True}) def get_account() -> dict: """Get current trading account information including balance, equity, margin, free margin, leverage, and whether trading is allowed. Call this before placing trades to verify account state.""" err = _ensure() if err: return err return account.get_account()
Декоратор @mcp.tool() регистрирует функцию как инструмент MCP. FastMCP автоматически выводит JSON-схему инструмента на основе аннотаций типов функции и использует строку документации как описание инструмента. Параметр annotations указывает ИИ-клиенту, является ли инструмент доступным только для чтения (его безопасно вызывать без подтверждения пользователя) или деструктивным (перед выполнением нужно запросить подтверждение). Вспомогательная функция _ensure() позволяет избежать дублирования проверки подключения в каждом инструменте.
А вот как выглядят инструменты изменения — обратите внимание на аннотацию destructiveHint у close_position:
@mcp.tool(annotations={"destructiveHint": True})
def close_position(ticket: int, volume: float | None = None,
deviation: int = 20) -> dict:
"""Close an open position entirely or partially. Use get_positions
first to get the ticket number. For partial close, specify the volume
to close. retcode 10009 = success."""
err = _ensure()
if err:
return err
return positions.close_position(ticket, volume, deviation) Аннотация destructiveHint:True сообщает ИИ-клиенту, что этот инструмент имеет необратимые последствия. Корректно реализованный ИИ-клиент запросит у пользователя подтверждение перед его вызовом. Это важный механизм безопасности, когда на кону стоят реальные деньги.
Сервер запускается одной строкой в конце файла:
if __name__ == "__main__": mcp.run()
Вызов mcp.run() запускает транспорт stdio: сервер считывает сообщения JSON-RPC из stdin и записывает ответы в stdout. Здесь нет HTTP-сервера, нет порта, который нужно настраивать, и нет открытия доступа по сети. ИИ-клиент запускает сервер как подпроцесс и обменивается с ним данными через каналы.
7. Тестирование с помощью MCP Inspector
Прежде чем подключаться к какому-либо ИИ-агенту, необходимо убедиться, что все инструменты работают правильно. Экосистема MCP предоставляет интерактивный инструмент тестирования под названием MCP Inspector, который позволяет вручную запускать инструменты и анализировать их ответы.
Убедитесь, что терминал MetaTrader 5 открыт и вы вошли в систему, а затем запустите:
npx @modelcontextprotocol/inspector
При этом откроется интерфейс в браузере. Настройте соединение следующим образом: Transport = stdio, Command = python, Args = server.py. После подключения на панели Tools отобразятся все 14 инструментов.

Рис. 3. MCP Inspector с перечнем набора инструментов MetaTrader 5
Начните с того, что выберите get_account и выполните его без параметров. Вы должны увидеть баланс счёта, средства / equity, кредитное плечо и другие данные, возвращённые в формате JSON. Это подтверждает, что подключение к MetaTrader 5 работает.

Рис. 4. MCP Inspector возвращает актуальные данные счёта из MetaTrader 5
Теперь, когда мы убедились, что инструменты работают, мы проведём тестирование на демо-счёте с помощью Claude Desktop, который будет вызывать инструменты get_symbol_info и get_rates для рыночного анализа в реальном времени.
Важно: всегда сначала тестируйте на демо-счёте. Сервер MCP выполняет реальные сделки на том счёте, под которым выполнен вход в терминале MetaTrader 5. Проверьте поведение каждого инструмента, прежде чем подключать его к ИИ-агенту, который может вызывать инструменты автономно.
8. Подключение к ИИ-агентам
Теперь, когда сервер протестирован, мы можем подключить его к реальным ИИ-агентам. Мы рассмотрим два способа интеграции: Claude Desktop для прямого использования и OpenClaw для доступа через Telegram.
Интеграция с Claude Desktop
Claude Desktop изначально поддерживает серверы MCP. Чтобы добавить наш сервер MetaTrader 5, отредактируйте файл конфигурации Claude Desktop, расположенный по адресу %APPDATA%\Claude\claude_desktop_config.json:
{
"mcpServers": {
"mt5": {
"command": "C:\\Path\\To\\python.exe",
"args": ["C:\\Path\\To\\mt5-mcp-server\\server.py"]
}
}
} Замените пути на фактическое расположение вашего интерпретатора Python и файла server.py. Используйте ту установку Python, в которой установлены пакеты MetaTrader 5 и fastmcp. Перезапустите Claude Desktop, и вы увидите инструменты MetaTrader 5, доступные в меню инструментов.
Теперь вы можете вести естественные беседы с Claude о своём торговом счёте. Спросите: «Каков текущий баланс моего счёта?», и Claude вызовет get_account. Спросите: «Покажи мне ситуацию по EURUSD на таймфрейме H4», и Claude вызовет get_symbol_info и get_rates, а затем предоставит анализ на основе данных в реальном времени. Скажите: «Размести ордер на покупку 0,01 лота EURUSD со стоп-лоссом на уровне 1,1500», и Claude проверит вашу маржу, удостоверится в соответствии ограничениям символа и выполнит сделку — запросив ваше подтверждение перед любым деструктивным действием.

Рис. 5. Claude Desktop использует сервер MCP MetaTrader 5 для анализа рынка в реальном времени
На приведённой выше GIF-анимации видно, как Claude получает актуальные рыночные данные из MetaTrader 5 и проводит анализ — и всё это в формате естественного разговора. Пользователю не нужно разбираться в инструментах MCP, схемах JSON или API на Python. Пользователь просто задаёт вопрос и получает ответ, подкреплённый данными в режиме реального времени из своего торгового терминала.
Интеграция OpenClaw с Telegram
Для трейдеров, которые хотят взаимодействовать с MetaTrader 5 со своего телефона, OpenClaw предоставляет такую возможность. OpenClaw — это ИИ-агент с открытым исходным кодом, который подключается к мессенджерам, таким как Telegram, WhatsApp и Discord. Создав навык OpenClaw — Markdown-файл, который объясняет агенту, как использовать наши инструменты MCP, — мы можем включить торговлю через Telegram.
Файл навыка (SKILL.md) указывает OpenClaw, когда вызывать наши инструменты MetaTrader 5 и каким правилам следовать:
--- name: mt5-trading description: Trade forex/CFDs via MetaTrader 5. Use when the user asks about account balance, symbol prices, open positions, or wants to place/modify/close trades. metadata: openclaw: requires: env: - MT5_MCP_PATH --- # MT5 Trading Skill Use the MT5 MCP server tools for all trading operations. ## Rules - Always call get_account before placing any trade - Always call get_symbol_info to check volume_min and trade_stops_level - Never place trades without user confirmation - Report retcode from order results (10009 = success)
После установки навыка и настройки MCP-сервера в OpenClaw вы можете отправить своему боту в Telegram сообщение: «Какие у меня открытые позиции?» или «Закрой позицию по EURUSD», и ИИ-агент выполнит соответствующие инструменты. Работа с ним аналогична Claude Desktop, но доступна с любого устройства, на котором установлен Telegram.
Заключение
В этой статье мы создали полнофункциональный сервер MCP, который связывает MetaTrader 5 с миром ИИ-агентов. Сервер предоставляет 14 инструментов, охватывающих информацию о счёте, рыночные данные, управление позициями, размещение ордеров и историю торговли — всё, что нужно ИИ-ассистенту, чтобы выступать в роли полноценного торгового помощника.
- Универсальная совместимость. Сервер MCP работает с любыми клиентами, совместимыми с MCP, — Claude Desktop, OpenClaw, Cursor, VS Code, а также с любыми будущими клиентами, поддерживающими этот протокол. Создайте один раз — используйте везде.
- Торговля с использованием естественного языка. Пользователи взаимодействуют посредством диалога, а не с помощью синтаксиса команд. Спросите: «Каков спред по паре EURUSD в данный момент?», вместо того чтобы писать код для вызова функции symbol_info_tick.
- Безопасность, заложенная в архитектуру. Сервер включает проверки соединения при каждом вызове инструмента, защиту по таймауту от зависаний MetaTrader 5, аннотации деструктивных действий для исполнения сделок, а также глобальные инструкции, обеспечивающие проверки перед торговлей.
- Минимальный размер. Весь проект состоит из 676 строк кода на языке Python и имеет всего две зависимости (MetaTrader 5 и fastmcp). Ни Docker, ни виртуальных машин, ни веб-серверов.
- Расширяемая основа. Архитектура на основе обработчиков упрощает добавление новых инструментов — например, инструмента, рассчитывающего размер позиции на основе процента риска, или инструмента, отслеживающего позиции и отправляющего оповещения при срабатывании стоп-лоссов.
Существует ряд ограничений. Библиотека Python для MetaTrader 5 предназначена только для Windows, поэтому сервер должен работать на том же компьютере, что и терминал. API Python для MetaTrader 5 является однопоточным, поэтому одновременные вызовы могут привести к проблемам. Перед использованием реальных средств необходимо провести тщательное тестирование на демо-счёте.
Что касается дальнейшего развития, то здесь можно выделить несколько перспективных направлений. Разбор сигналов из каналов Telegram — использование существующей интеграции OpenClaw с Telegram для считывания торговых сигналов и их автоматического исполнения с помощью наших инструментов MCP. Поддержка нескольких терминалов — расширение конфигурации для одновременного управления подключениями к нескольким брокерам. А также аналитические инструменты — объединение возможностей работы с рыночными данными с библиотеками технического анализа, чтобы дать ИИ-агенту более глубокое понимание рынка.
Разрыв между ИИ-агентами и MetaTrader 5 больше не существует. Код приведён ниже — установите его, подключите и начните торговать с помощью своего ИИ-ассистента.
Отказ от ответственности: эта статья предназначена исключительно для образовательных целей. Автоматическая торговля сопряжена со значительным риском. Всегда тщательно тестируйте на демо-счетах, прежде чем использовать реальные средства. Автор не несёт ответственности за какие-либо финансовые убытки, возникшие в результате использования данного программного обеспечения.
| Имя файла | Описание |
|---|---|
| mt5-mcp-server.zip | Полный проект сервера MCP — server.py, mt5client.py, constants.py, все обработчики, config.json и README |
| SKILL.md | Определение навыка OpenClaw для торговой интеграции с MetaTrader 5 (входит в ZIP-архив) |
Перевод с английского произведен MetaQuotes Ltd.
Оригинальная статья: https://www.mql5.com/en/articles/21905
Предупреждение: все права на данные материалы принадлежат MetaQuotes Ltd. Полная или частичная перепечатка запрещена.
Данная статья написана пользователем сайта и отражает его личную точку зрения. Компания MetaQuotes Ltd не несет ответственности за достоверность представленной информации, а также за возможные последствия использования описанных решений, стратегий или рекомендаций.
Рыночная микроструктура в MQL5 (Часть 3): Оценка параметра d модели ARFIMA методом GPH
Нейросети в трейдинге: Управление риском через распределение результатов (Окончание)
За пределами GARCH (Часть IV): Реализация анализа разбиений в MQL5
От начального к среднему уровню: Подокна (I)
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Хороший обзор… Четырёхслойная архитектура (константы/сопоставления, оболочка клиента MT5, обработчики доменов, точка входа MCP) — идеальный подход для этой задачи, и мне нравится, что вы явно указали на механизмы защиты соединений и аннотации деструктивных действий, а не оставили вопрос безопасности на второй план.
Стоит добавить для тех, кто планирует расширить это до реального исполнения: по нашему опыту, самой сложной частью была не сама инфраструктура MCP, а обеспечение достаточной надёжности инструментов обратного считывания (позиции/баланс/прибыль и убыток), чтобы представление агента о состоянии счёта не расходилось с фактическим состоянием терминала (особенно при повторных подключениях). Защита от таймаутов помогает, но не решает проблему устаревания данных полностью. Мы столкнулись с аналогичной проблемой при создании нашего уровня выполнения MCP для MT4/MT5 и в итоге решили рассматривать «синхронизацию состояния» как отдельную подсистему, а не привязывать её к обработчикам управления сделками.
Интересно, планируете ли вы продолжение работы в области интеграции с клиентскими приложениями (Claude Desktop / OpenClaw) — именно там пользовательский опыт обычно становится особенно интересным.
Интересно, планируете ли вы продолжение работы в области интеграции с клиентскими приложениями (Claude Desktop / OpenClaw) — именно там пользовательский опыт обычно становится особенно интересным.
Это было очень полезно.