Лонгрид 11 из 13Курс
Практические рецепты надёжного клиента
Содержание
Этот раздел можно читать после базового маршрута или использовать как справочник при разработке собственного приложения.
Рецепт 1. Восстановить поток после обрыва
У WebSocket нет обещания, что клиент получит пропущенные во время обрыва события. Переподключение должно восстанавливать не только сокет, но и состояние приложения.
Пауза между попытками должна расти, например 1 → 2 → 4 → 8 → 16 → 30 секунд, и включать небольшую случайную добавку. После успешного стабильного соединения задержку можно сбросить.
Рецепт 2. Не потерять события во время первоначального снимка
Есть два рабочих подхода:
Сначала подключить поток и временно буферизовать события, затем загрузить REST-снимок и применить к нему более новые события.
Загрузить снимок, подключить поток, а после подписки повторно загрузить снимок и устранить расхождения.
Первый подход экономит один запрос, но требует корректно сравнивать время и идентификаторы. Второй проще для первого production-клиента.
Минимальная локальная запись заявки:
Поле | Зачем хранить |
|---|---|
client_order_id | Сопоставить бизнес-команду с запросом |
order_id | Обращаться к заявке в API |
status | Текущее известное состояние |
executed_quantity | Учитывать частичное исполнение |
remaining_quantity | Понимать остаток |
updated_at | Разрешать конфликты более новых и старых данных |
исходное тело команды | Проводить аудит и безопасную сверку |
Рецепт 3. Повторять только безопасные запросы
Ситуация | Автоматический повтор |
|---|---|
GET завершился сетевой ошибкой до ответа | Обычно безопасен с backoff |
GET вернул 503 или 504 | Допустим ограниченный повтор с backoff и jitter |
Получен 429 | Не повторять немедленно; снизить частоту и дождаться доступного окна |
WebSocket оборвался | Переподключиться, восстановить подписки и выполнить сверку |
POST PlaceOrder вернул явный 400 | Не повторять; исправить команду |
Ответ PlaceOrder потерян | Не повторять вслепую; сначала сверить заявки |
DELETE CancelOrder потерял ответ | Сначала запросить текущее состояние заявки |
GetUsageMetrics показывает текущее потребление квот. Этот метод полезен для наблюдения, но не заменяет ограничитель частоты на стороне клиента.
Рецепт 4. Перевести лоты в штуки
Если интерфейс пользователя принимает число лотов, тело заявки всё равно должно содержать количество в штуках:
Если trade_lot_size равен 0 или отсутствует, не угадывайте значение: остановите торговую операцию и покажите диагностическую ошибку.
Рецепт 5. Выгрузить весь каталог инструментов
Assets отдаёт доступные инструменты. Для полного каталога используется AllAssets с курсором. Следующая страница запрашивается с next_cursor; значение 0 означает конец.
Сохраняйте каталог локально и обновляйте по расписанию. Не загружайте все страницы перед каждой заявкой.
Рецепт 6. Обрабатывать только завершённые свечи
Поток BARS может несколько раз прислать свечу с одной меткой времени. Пока не появилась свеча с более поздним timestamp, предыдущая считается изменяемой.
Надёжный алгоритм:
хранить последнюю свечу как pending;
обновлять её, если пришёл тот же timestamp;
считать pending завершённой только после события с более поздним временем;
прогревать индикаторы историческими свечами без торговых команд;
генерировать один сигнал на одну завершённую свечу.
Этот паттерн используется в официальном примере стратегии SMA 9/30. Стратегический расчёт должен быть отделён от транспорта API: тогда его можно тестировать без токена и сети.
Рецепт 7. Ввести dry-run и предохранители
Минимальный набор перед включением реальных заявок:
dry-run включён по умолчанию;
явный флаг для реальной отправки;
отдельный разрешённый
account_id;максимальное количество одной заявки;
максимальная позиция по инструменту;
ограничение числа заявок за период;
проверка расписания и торговых параметров;
запрет новой команды при неизвестном результате предыдущей;
аварийный переключатель, запрещающий все новые заявки;
журнал команды, ответа и последующих событий.
Рецепт 8. Наблюдать за клиентом
Логируйте структурированно, без секретов и access_key:
Событие | Полезные поля |
|---|---|
Авторизация | время, результат, expires_at, но не токен |
Подключение | номер попытки, задержка, handshake, причина закрытия |
Подписка | тип, symbol или account_id, результат |
REST-запрос | метод, путь-шаблон, статус, длительность |
Заявка | client_order_id, order_id, symbol, quantity, status |
Сделка | trade_id, order_id, price, size, timestamp |
Сверка | количество найденных расхождений и принятые действия |
Не помещайте полный заголовок Authorization, secret_key или тело запроса авторизации в логи даже на уровне debug.
Конец лонгрида