Sorry, we don't support your browser.  Install a modern browser

Аварийное закрытие несработавшего стопа / защиты#3011

Логика аварийного закрытия при неудачной постановке стопа

Суть проблемы: трейдер зафиксировал намерение (стоп выставлен в терминале), но биржа отклонила заявку, потому что цена уже ушла за уровень (типичная ошибка на волатильности). Терминал не должен просто снимать стоп и оставлять позицию без защиты. Нужно трактовать ошибку как «стоп уже сработал по сути» и принудительно закрывать сделку.

Основной алгоритм

  1. Фиксация намерения в терминале
    При установке стопа терминал сохраняет локальную запись:

    • позиция (symbol, side, qty)
    • уровень стопа
    • тип (stop / stop-limit)
    • статус: LOCAL_ARMED
    • timestamp установки
      Это намерение считается действующим, пока позиция открыта или пользователь явно не отменит стоп.
  2. Попытка выставления на биржу
    Терминал отправляет заявку и переводит статус в PLACING.
    Ожидает ответ:

    • Accepted → статус EXCHANGE_ACTIVE, обычная работа.
    • Rejected / timeout / ошибка → переход в обработку отказа.
  3. Классификация ошибки
    При получении ошибки терминал смотрит код/текст:

    • Критические для стопа (цена уже прошла уровень, invalid price, stop price already breached, order would immediately trigger и т.п.) → считаем, что защита уже должна была сработать.
    • Транзиентные (сеть, rate limit, temporary) → ограниченное количество ретраев с небольшим backoff. Если ретраи исчерпаны — тоже переходим к аварийному закрытию.
    • Другие постоянные (нет маржи, неверный инструмент и т.д.) → уведомление + всё равно попытка закрытия, если это защитный стоп.
  4. Аварийное закрытие
    Как только ошибка классифицирована как «стоп не встал, а должен был»:

    • Статус локального стопа → MISSED_PLACEMENT_TRIGGERED.
    • Немедленно отправляется рыночная заявка на закрытие позиции (или агрессивный лимит по текущему bid/ask с небольшим оффсетом, если биржа/брокер плохо принимает market).
    • Количество — полное по позиции (или оставшееся, если частично уже закрыто).
    • Логируется событие: «Stop placement rejected (reason: …). Emergency market close sent».
    • Пользователю показывается явное уведомление (звук + попап + запись в логе), что стоп не встал и позиция закрыта принудительно.
  5. После отправки аварийного закрытия

    • Отслеживание исполнения закрывающей заявки.
    • Если закрытие частично исполнилось или отклонено — повторная попытка (с лимитом попыток) или эскалация (алерт «позиция не закрыта»).
    • Локальный стоп больше не пытается выставляться повторно автоматически.
    • В истории ордеров и в журнале сделки фиксируется цепочка: Local stop set → Exchange reject → Emergency close.

Дополнительные правила надёжности

  • Мониторинг «голых» позиций. Если позиция открыта и локальный стоп в статусе LOCAL_ARMED / MISSED_… дольше N секунд без подтверждения с биржи — принудительная проверка и закрытие.
  • Защита от гонок. Пока идёт PLACING или аварийное закрытие, повторные попытки выставить тот же стоп блокируются.
  • Приоритет защиты. Даже если пользователь в этот момент что-то меняет в терминале, аварийное закрытие не отменяется автоматически.
  • Аудит. Все переходы статусов и причины ошибок пишутся в неизменяемый лог (для разбора и для самого трейдера).

Краткий поток состояний

LOCAL_ARMED
    ↓
PLACING
    ↓
├─ Accepted → EXCHANGE_ACTIVE
└─ Rejected (price passed / critical)
       ↓
   MISSED_PLACEMENT_TRIGGERED
       ↓
   Emergency Market Close
       ↓
   Position closed / residual handling

Такая логика сохраняет намерение трейдера: если стоп был выставлен в терминале, а биржа его не приняла из-за улетевшего спреда/цены, позиция не остаётся без защиты и закрывается принудительно. Это именно то поведение, которого не хватает в описанном случае с Tiger Terminal.

5 hours ago