Интеграцию FIX API и MT4 следует проектировать как контролируемый слой преобразования и доказательств, а не как коннектор, который просто пересылает заявки. Тикет MetaTrader, FIX ClOrdID, OrderID контрагента и идентификатор исполнения не являются взаимозаменяемыми. Если считать их одним и тем же, при частичных исполнениях, цепочках cancel/replace, переподключении или end-of-day корректировках возникают неверные статусы, дубли исполнений и ошибочные балансы.

Подход POLADO: сохранять исходные события без изменения; переводить их в каноническую модель заявок и исполнений; делать каждого потребителя идемпотентным; не считать окончательными клиентский статус, баланс или операционное действие, пока внешняя истина об исполнении не подтверждена сверкой.

Эта статья намеренно уже, чем наши материалы об интеграции FIX API, управлении состояниями заявок и сверке торговых данных. Здесь рассматривается архитектура, необходимая тогда, когда тикеты, символы, группы счетов и логика исполнения MetaTrader должны работать совместно с FIX или внешними brokerage API.

Мост должен управлять двумя версиями истины, а не только отправлять заявку

В MetaTrader заявки, сделки и позиции могут быть разными объектами. В документации MetaTrader 5 указано, что заявки и сделки получают тикеты, связанные с соответствующей позицией. В FIX execution report клиентский идентификатор заявки, идентификатор заявки у площадки и идентификатор исполнения могут быть разными сущностями. В FIX цепочка cancel/replace использует ClOrdID и OrigClOrdID, а ExecID идентифицирует отдельное событие исполнения. Поэтому production-мост не может исходить из предположения «один тикет — одна сделка».

Это различие отражено в модели торговли MetaTrader 5 и в справочнике FIX Execution Report. Для MT4 на этапе discovery также нужно установить доступный broker-side интерфейс и конфигурацию сервера: официальная страница MetaTrader 4 API описывает Manager API как средство интеграции платформы и расширения её функций.

Модель POLADO: native event, canonical model, projection

Разделите мост на три слоя данных:

  1. Исходное доказательство: сохраняйте raw FIX-сообщение, broker webhook, REST-ответ или событие MT4/MT5 с источником, временем получения и хешем payload.
  2. Каноническая модель исполнения: преобразуйте источник в независимые объекты: OrderIntent, OrderRevision, Execution, CancelRequest, PositionEffect и ReconciliationBreak.
  3. Операционные проекции: стройте экран трейдера, очереди back office, exposure, историю клиента, отчётность и входы для ledger на основе канонических событий.

Такое разделение позволяет изменить правило mapping, повторно обработать позднее исполнение или расследовать спорный callback без переписывания истории. Ни один клиентский статус или финансовая проекция не должны зависеть от удалённого исходного payload.

1. Управляйте идентификаторами как графом связей, а не таблицей соответствий

Для одного торгового намерения могут потребоваться все следующие идентификаторы:

  • Canonical intent ID: неизменяемый внутренний ID моста.
  • Client request ID: ID, созданный терминалом, внутренней OMS или административным процессом.
  • Тикеты MT order, deal и position: native ID объектов платформы.
  • FIX ClOrdID и OrigClOrdID: цепочка клиентской заявки и её изменений.
  • FIX OrderID, broker order ID и venue order ID: идентификаторы внешних систем.
  • Execution/deal ID: опора для идемпотентности каждого исполнения, отмены сделки или коррекции.

Простой mapping mt_ticket → fix_order_id недостаточен. Одно намерение может иметь несколько ревизий; одна ревизия — несколько маршрутов; один маршрут — несколько исполнений; исполнение может быть позднее отменено или исправлено. Эти связи нужно хранить явно. В частности, прежняя заявка может получить исполнение до подтверждённого replace; запрос на изменение не должен автоматически закрывать старую заявку.

Практическое правило

Зафиксируйте в data contract смысл и границу уникальности каждого ID. Например: уникален ли ExecID в пределах контрагента, счёта или торгового дня? Уникален ли MT ticket только в пределах сервера и счёта? Возможен ли повтор ClOrdID? Формулировка «мы сохраняем строку» не является стратегией идентичности, достаточной для production-сверки.

2. Нормализацию символов и contract size поместите за versioned instrument master

EURUSD, EURUSD.a и EUR/USD могут обозначать одну экономическую валютную пару, но не обязательно один и тот же торгуемый контракт. Prefix или suffix могут сопровождаться различными digits, minimum lot, lot step, contract size, валютой расчёта, margin treatment, swap rules и торговыми сессиями.

Для каждого исполнения храните не только source symbol, но и действующую версию instrument mapping:

  • canonical instrument ID и source-specific symbol;
  • asset class, base/quote и settlement currency;
  • contract size, quantity unit, lot multiplier, minimum и increment;
  • price precision, tick size и правила округления;
  • поведение hedging/netting и правило агрегации позиции;
  • время начала и окончания действия mapping.

Не делайте лоты канонической quantity. В канонической модели храните экономическое количество, а преобразование в лоты и обратно оставьте adapter-у. Иначе exposure, commission и P&L могут быть неверными, если одинаковый отображаемый размер лота представляет разные contract size в разных группах или у разных контрагентов. Это прямое продолжение задач instrument master и нормализации ценообразования.

3. Обрабатывайте исполнения и статус заявки как разные факты

Состояние заявки не равно исполнению. Заявка может быть accepted, working, partially filled, cancelled или filled и при этом получить несколько исполнений, отмену сделки либо коррекцию исполнения. В канонической модели:

  • Execution содержит execution ID, цену, количество, контекст liquidity/routing, время исполнения и source evidence.
  • Order state является проекцией, рассчитанной по валидным lifecycle- и execution-фактам.
  • Position effect рассчитывается отдельно по правилам netting или hedging данного счёта.

FIX Execution Report различает OrderID, ExecID, ExecType, OrdStatus, ClOrdID и, когда применимо, OrigClOrdID. Если сжать эти поля в один столбец статуса, исчезает доказательная база, необходимая для объяснения результата.

Правило идемпотентности

Для каждого входящего исполнения создавайте детерминированный ключ дедупликации, например counterparty + account + execution_id + execution_version/event_type. Если контрагент не даёт стабильный execution ID, формируйте резервный fingerprint из message ID, trade ID, order reference, timestamp, price и quantity, но отмечайте его как более слабое доказательство. Дубликат нельзя просто молча отбросить: сохраните native record и сделайте решение о дедупликации проверяемым.

4. Защитите гонки cancel, modify и reconnect явной state machine

Критичный сценарий выглядит так: пользователь MT4/MT5 отправляет modify или cancel, мост передаёт запрос, связь пропадает, после чего приходят и fill, и ответ на отмену. Небезопасно просто заменить локальный статус последним полученным сообщением.

State machine должна различать как минимум: request created, request transmitted, acknowledgement uncertain, pending cancel/replace, replacement accepted, replacement rejected, fill received, cancellation confirmed, external state unknown и reconciled final state. Статус «unknown» не означает провал production-системы. Он безопаснее, чем объявить заявку cancelled или filled без доказательств.

FIX session recovery необходим на транспортном уровне, но не заменяет business recovery. Хранилище сообщений, sequence numbers и логика resend/gap fill должны быть долговечными; документированные настройки QuickFIX/J включают persistence сообщений, resend-поведение и refresh при logon. После reconnect мост всё равно должен получить authoritative snapshots открытых заявок, недавних исполнений и позиций, а затем сверить локальную проекцию с source truth и воспроизведённым потоком событий.

5. Рассматривайте mapping счетов и групп как границу авторизации

MT login, MetaTrader group, CRM client, legal entity, FIX account tag и liquidity profile — разные понятия. Их сопоставление по display name может привести к маршрутизации через неверный профиль, применению чужих leverage rules или раскрытию данных другого tenant.

Нужен отдельный versioned entitlement mapping, который определяет:

  • какой внутренний account связан с каким MT login и FIX/broker account;
  • какие инструменты, типы заявок, максимальный объём и routing profile разрешены;
  • с какой даты действует group assignment;
  • кто создал, утвердил и отозвал mapping.

Привилегированные изменения mapping требуют maker-checker approval, audit log и возможности rollback. Мост должен соответствовать общей модели контроля account management, а не становиться неконтролируемым обходным маршрутом.

6. End-of-day reconciliation — не дополнительная функция моста

Intraday processing нужен для скорости; end-of-day reconciliation замыкает контур доказательств. Для каждого торгового дня сравнивайте:

  • source orders и canonical orders;
  • source fills/deals и canonical executions по количеству, объёму, цене и комиссии;
  • open orders и pending requests;
  • объём позиции и среднюю цену;
  • cash, commission, swap и прочие финансовые эффекты;
  • использованные версии instrument mapping и account/group mapping.

Расхождение не должно автоматически создавать коррекцию баланса. Оно должно попасть в назначенную очередь с severity, source evidence, вероятной причиной и утверждённым путём исправления. Пока внешняя истина об исполнении не согласована, клиентские statements и ledger postings нельзя представлять как окончательные.

Последовательность реализации production-моста

  1. Discovery и inventory контрактов: для каждого MT server, broker API и FIX counterparty задокументируйте order types, identifiers, rate limits, recovery methods, snapshot endpoints и trading-day cut-offs.
  2. Canonical schema: версионируйте contracts для orders, revisions, executions, position effects, instruments, account mappings и reconciliation breaks.
  3. Onboarding инструментов и прав: не включайте live routing, пока symbol/contract mappings и account/group permissions не прошли review и approval.
  4. Adapters с durable inbox/outbox: отделите приём source-сообщений от business processing, чтобы retry были безопасными, трассируемыми и повторно воспроизводимыми.
  5. Lifecycle simulation: автоматизируйте partial fill, reject, cancel/replace race, duplicate callback, out-of-order event, disconnect и restart.
  6. Shadow mode: сравнивайте результаты моста с действующим операционным процессом до включения клиентских проекций или live routing.
  7. Runbooks и day-two controls: заранее утвердите действия операторов для sequence gaps, unknown external state, mapping changes, reconciliation breaks и outages контрагентов.

Чек-лист перед релизом

  • Может ли команда объяснить связь между каждым client request, MT ticket, broker/FIX order ID и execution ID?
  • Версионированы ли symbol mappings с contract size, conversion quantity и effective dates?
  • Можно ли безопасно принять duplicate и out-of-order executions, не изменив проекцию дважды?
  • Допускает ли модель исполнение предыдущей заявки до фактического подтверждения cancel/replace?
  • Сочетает ли reconnect recovery session replay, authoritative snapshots и reconciliation?
  • Виден ли оператору unknown external state вместо преобразования в неподтверждённый terminal state?
  • Утверждаются, аудируются и обратимы ли изменения account/group mapping?
  • Исключены ли end-of-day breaks из балансов, пока владелец не проверит evidence и не утвердит remediation?

Когда оправдан заказной мост MetaTrader–FIX

Крупный мост не всегда нужен процессу, который можно безопасно вести через один-два проверяемых экспорта. Но при нескольких MT servers, liquidity providers или broker API, разных account groups, риске partial fills, клиентских статусах, внутренних risk controls и требованиях к reconciliation простой forwarding script становится операционным риском.

Ценность моста не в способности отправить заявку. Она в контролируемой границе, которая сохраняет native evidence, преобразует его по управляемым mappings, безопасно восстанавливается и делает внешнюю истину об исполнении проверяемой до того, как она повлияет на клиента или финансовую операцию. POLADO проектирует FinTech и trading-интеграции именно вокруг этой границы — без попытки заменить MT4/MT5 абстрактным middleware.