Почему стоп-ордер не срабатывает в мобильном приложении
Стоп-ордер не сработал в самый неподходящий момент — позиция остаётся открытой дольше, чем планировал трейдер, и закрывается уже по другой цене. Причина обычно не в стратегии, а в цепочке «экран приложения — канал связи — торговая система»: условная заявка исполняется на стороне биржи, но её постановку инициирует телефон, и любой сбой в этой цепочке превращается в потерянную заявку.
Классический случай — потеря заявки при разрыве связи. Пользователь нажал «купить», интерфейс показал подтверждение, а запрос до торгового ядра не дошёл: при переключении между сетями ответ теряется, и приложение дорисовывает успех по локальному состоянию. Вторая частая история — ошибка размещения заявки в приложении, когда цена и объём подставляются из устаревшего снимка стакана, и стоп уходит с ценой, которой на рынке уже нет.
Несработавшая условная заявка всплывает и после перезапуска приложения. Если подтверждённый идентификатор заявки не сохранён на устройстве, после холодного старта список активных стопов пуст — трейдер ставит новый, а старый продолжает жить на стороне системы. Обратная сторона той же проблемы — дубли: повторная отправка после таймаута создаёт вторую заявку, и позиция закрывается двойным объёмом.
Для торгового счёта это оборачивается незакрытой позицией, проскальзыванием и ручными разборами вместо работы. Разбираем, как это закрывается на уровне приложения.
Что даёт корректная работа условных заявок
Корректность стоп-ордера измеряется не фактом наличия строки в списке заявок, а долей исполненных условных заявок: условие сработало — ордер ушёл на сервер и подтверждён. По журналу событий эта доля видна напрямую: считаем все срабатывания и вычитаем те, где заявка осталась локальной из-за обрыва связи или конфликта состояния.
Время от касания условия до отправки — вторая метрика. Оно зависит от того, где условие сопоставляется с потоком котировок: если ждать серверного оповещения, добавляется круг доставки, и ордер уходит с проскальзыванием. Локальное сопоставление с последующим подтверждением сокращает окно срабатывания в разы и делает его предсказуемым при перегрузке канала.
Третий срез — классы отказов заявок. Уходят потеря заявки при переключении сети и сворачивании приложения, дубли при повторной отправке, зависшие стоп-ордера после сна устройства. Локальный журнал состояний и идемпотентный ключ заявки дают повторную отправку без дублей: сервер распознаёт повтор и не создаёт вторую заявку.
Устойчивость торговой логики проверяется набором сценариев, а не одним прогоном: обрыв связи в момент срабатывания, смена сети, длительный сон, восстановление сессии. Прогоняем сборки на реальных устройствах и нестабильных сетях через TestFlight — так класс отказов ловится до релиза, а не в день волатильности.
Режимы размещения стоп-ордера: сравнение подходов
Условная заявка отличается от обычной тем, что не попадает в стакан сразу: она ждёт, пока цена дойдёт до порога, и только тогда превращается в рыночную или лимитную. Отсюда главный вопрос реализации — где живёт проверка условия и по какой цене её считать.
| Режим | Где живёт логика | Как отрабатывает условие | Ограничения |
|---|---|---|---|
| Стоп на стороне сервиса | Условная заявка хранится на сервере | Сервис следит за расчётной ценой и выставляет заявку сам | Срабатывает при закрытом приложении; нужен контроль, что стоп не потерян |
| Локальная логика в приложении | Порог хранится в приложении | Сравнивает поток цен с порогом и отправляет заявку | Только пока приложение активно и есть связь |
| Гибрид | Условие на сервисе, постановку подписывает приложение | Сервис срабатывает, приложение подтверждает исполнение | Надёжнее локального, но появляется окно до подтверждения |
| Условие по расчётной цене | Точка сравнения — расчётная цена | Порог сверяется со сглаженным значением по нескольким источникам | Меньше ложных срабатываний, но значение обновляется реже |
Сравнивать порог с последней сделкой опасно: на тонком стакане одна крупная заявка даёт выброс, стоп срабатывает, а цена тут же возвращается — клиент получает исполнение без причины. Поэтому условие привязывают к расчётной цене: срабатываний меньше, но каждое обосновано.
Выбор режима — это компромисс между надёжностью срабатывания и мгновенностью реакции, и задаёт его сам продукт. Если стоп защищает позицию, логику держат на стороне сервиса, а состояние дублируют в приложении; локальная логика уместна только как вспомогательная и с честным предупреждением о границах работы.
Как мы внедряем условные заявки: этапы работ
Условная заявка — отложенное решение с ценой срабатывания, объёмом и поведением при разрыве связи. Ошибка в любом из этих полей обходится дороже ошибки в интерфейсе, поэтому этапы внедрения торговой логики выстраиваем так, чтобы каждый опирался на зафиксированный результат предыдущего.
- Аудит сценариев заявок. Собираем перечень: стоп-лосс и тейк-профит, стоп-лимит, привязка к последней сделке или к цене маркировки, поведение при гэпе и частичном исполнении. На выходе — матрица «сценарий / условие срабатывания / ожидаемое поведение», согласованная с вашей командой.
- Проектирование схемы. Решаем, где живёт состояние заявки — на клиенте, на сервере или в торговом ядре, — и как оно сверяется после переподключения. Отдельно закрываем защиту от дублей: повторная отправка при обрыве сети не должна создавать вторую заявку.
- Реализация. Слой условных заявок пишем отдельно от интерфейса, чтобы логику срабатывания можно было менять без пересборки экранов. Обработку ценовых событий ведём одним потоком с явной очередью — это убирает гонки при резком движении рынка.
- Тестовый контур. Поднимаем окружение с потоком котировок и откликом торгового ядра, включая отказы: таймауты, отклонённые заявки, рассинхрон состояния. Каждый пункт матрицы закрываем автотестом.
- Проверка заявок на исторических данных. Проигрываем реальные торговые дни с гэпами и низкой ликвидностью: считаем, где заявка сработала по ожидаемой цене, где проскользнула, где логика разошлась с биржевой.
- Передача и регламенты. Отдаём схему состояний, описание конфигурации, порядок разбора инцидентов и метрики: доля отклонённых заявок, задержка от получения цены до отправки, число рассинхронов.
Конфигурации, схемы расчёта и регламенты передачи
После завершения работ заказчик получает не архив с исходным кодом, а комплект, по которому торговую логику можно сопровождать и развивать силами своей команды. Перечень артефактов фиксируется до старта, поэтому к сдаче не появляется «сюрпризов» — что обещали, то и на руках.
- Документация по торговой логике: жизненный цикл стоп-ордера — постановка, условия активации, срабатывание, отмена, обработка разрывов связи и повторных попыток.
- Схема расчёта цены заявки: откуда берутся рыночные данные, как цена и объём округляются под шаг и минимальный лот, как соотносятся стоп-цена и лимитная цена.
- Спецификация обмена с торговым ядром: форматы сообщений, коды ошибок и то, как каждый из них показывается пользователю.
- Набор автотестов: сценарии срабатывания, отмены и отклонения заявок, проверки граничных значений цены и объёма.
- Регламент сопровождения: порядок выпуска изменений в торговых правилах, обязательные проверки перед выкаткой, сроки реакции на инцидент.
- Схемы мониторинга: какие показатели по стоп-ордерам отслеживаются и при каких отклонениях дежурный получает сигнал.
- Журнал инженерных решений: почему правила активации и обработки сбоев выбраны именно такими.
Комплект собирается по ходу работ, а не восстанавливается в конце, поэтому передача занимает один-два разбора, а не месяц.
Кейс: как сократили число несработавших заявок
Ситуация до
Клиент — биржа цифровых активов — держал стоп-ордера на стороне приложения: цена триггера проверялась в фоне на телефоне, а заявка уходила на сервер только если процесс был жив. Свернул приложение, система выгрузила его из памяти — стоп не срабатывал. На резких движениях рынка доля несработавших стоп-заявок доходила до 6,4%, и почти каждая превращалась в обращение в поддержку с ручным разбором.
Что изменили и что получилось
Логику перенесли на серверную сторону: приложение только проверяет корректность параметров и отправляет стоп-заявку, а триггер, контроль маржи и допустимого отклонения цены живут в торговом ядре. Каждой заявке присваивается неизменяемый ключ — повторная отправка после обрыва связи не создаёт дубль. При переподключении клиент получает актуальный снимок состояния заявок, а не досчитывает его из локальной копии, поэтому расхождение «на экране ещё стоит, на бирже уже исполнен» ушло.
После доработки доля несработавших стоп-заявок — 0,7%, и это в основном выход цены за допустимое отклонение, где система честно отменяет заявку и показывает причину. Обращений в поддержку по стоп-ордерам стало в семь раз меньше, дублей заявок — ноль. В журнале по каждой заявке видно, когда сработал триггер, что ответило торговое ядро и по какой причине заявка не прошла.
Условная заявка с лимитом или по рынку: что выбрать
Стоп-ордер срабатывает по триггеру, но дальше всё зависит от типа заявки: условная заявка с лимитом и заявка по рынку отличаются тем, что именно гарантировано после касания уровня. В первом случае фиксируется цена, во втором — факт исполнения. До срабатывания обе стоят в стакане одинаково.
Условная заявка с лимитом после триггера превращается в обычную лимитную. Клиент защищён от просадки при исполнении: сделка пройдёт по указанной цене или лучше, но не хуже. Обратная сторона — гарантии исполнения нет: на резком движении цена уходит от уровня, заявка остаётся неисполненной, и позиция продолжает висеть незакрытой.
Заявка по рынку закрывает позицию по любой доступной цене в пределах глубины стакана. Здесь гарантировано исполнение, а не цена: чем тоньше стакан, тем заметнее просадка при исполнении. На ликвидном инструменте расхождение с уровнем триггера измеряется долями шага цены, на тонком — несколькими уровнями, особенно если объём сопоставим с лучшими котировками.
Отдельный риск тонкого рынка — частичное исполнение и разрывы между уровнями: крупная заявка выедает ближние уровни и добирает объём глубже. Поэтому в мобильном приложении ожидаемую просадку считают и показывают до подтверждения, а не по факту сделки.
Выбор типа срабатывания сводится к приоритету: защита цены или защита от неисполнения. Для защитного стопа по ликвидному инструменту обычно достаточно рыночной заявки — выход важнее нескольких шагов цены. Для входа на тонком рынке разумнее лимит с запасом от триггера, чтобы исполнение не сорвалось на первом же импульсе.
Технические сомнения: вопросы и ответы по заявкам
Ниже — четыре сомнения, которые чаще всего поднимают на разборе задачи. Отвечаем предметно: как ведёт себя стоп-ордер при закрытом приложении, что происходит при обрыве связи и как проверить логику, не рискуя позициями.
Сработает ли стоп-ордер, если приложение закрыто?
Да. После подтверждения условная заявка живёт на стороне торгового ядра, а телефон лишь передаёт параметры: цену активации, объём, срок действия. Срабатывание и постановку в стакан исполняет сервер, поэтому выключенный экран или пропавшая сеть условие не отменяют. Уведомление о срабатывании — следствие, а не механизм.
Что происходит при обрыве связи в момент размещения?
Запрос уходит с ключом повтора: если ответ не дошёл, приложение отправляет его снова, а ядро распознаёт дубль вместо второй заявки. После восстановления связи список сверяется с журналом заявок, а не с памятью телефона. Так на экране не появляются «фантомные» стоп-ордера и не теряются реальные.
Как проверить логику, не рискуя позициями?
Прогоняем сценарии на тестовом контуре с тем же ядром: резкий разрыв цены, частичное исполнение, отмена на границе активации, повторная постановка. Отдельно проверяем минимальный объём и шаг цены — частая причина отказа уже при подтверждении. Боевой счёт в этих прогонах не задействован.
Не потеряются ли заявки после обновления приложения?
Локальный кэш мы не считаем источником правды. При смене схемы хранения заложена миграция, а при первом запуске обновлённой версии клиент сверяет список с сервером по идентификатору — недостающие условные заявки возвращаются в интерфейс. Отдельный сценарий — откат на предыдущую версию: он не должен ломать уже размещённые стоп-ордера.
Обсудим задачу: подготовьте вводные по торговой логике
Чтобы вернуться с оценкой доработки и рабочим планом, нам нужны вводные по торговой логике — не общее описание, а то, как стоп-ордер должен вести себя именно в вашем продукте. Ниже минимум, который снимает большую часть вопросов до первого созвона.
- Типы и связки заявок: только стоп-лосс или стоп-лимит, нужны ли тейк-профит и связка, где исполнение одной заявки снимает парную.
- Триггер: по последней цене, по расчётной метке или по индексу; что считаем источником и как поступаем при расхождении между источниками.
- Режимы счёта: спот, маржинальная торговля, срочный рынок; как стоп сочетается с риск-лимитами, плечом и принудительным закрытием позиции.
- Объёмы и правила снятия: доступный и заблокированный под заявку объём, частичное исполнение, перенос стопа вслед за позицией, лимит одновременно активных заявок.
- Поведение при сбоях: обрыв связи с биржей, рестарт сервиса, повторная отправка — где хранится состояние заявки и как исключаем дубли.
- События и уведомления: что уходит в историю операций и журнал, что показываем клиенту на экране и в уведомлениях.
- Данные для проверки: доступ к тестовому контуру биржи, счета в разных режимах и список проблемных случаев из поддержки.
Если часть ответов есть в документации биржи — достаточно ссылки на нужный раздел. Опишите задачу, приложите текущие макеты и логи спорных срабатываний — обсудим задачу и вернёмся с оценкой доработки, составом этапов и планом работ.







