Перейти к основному содержимому

Управление подписками

При работе с торговой системой важно иметь доступ к актуальным биржевым данным без необходимости запрашивать их вручную. Для этих целей WebSocket API предлагает механизм подписки на интересующие данные.

В рамках подписки система будет возвращать в ответ на одиночный запрос сообщения, содержащие изменения данных для отслеживаемого инструмента и выбранного типа данных. Подписка будет действовать до тех пор, пока активно WebSocket-соединение, что даёт возможность получать актуальные данные в течение всей торговой сессии, лишь единожды выполнив запрос на их получение.

Ниже описаны основные особенности управления WebSocket-подписками.


Интерфейсы

Для управления подписками и передачи биржевых данных от торговой системы АЛОР Брокер используется WebSocket-интерфейс /ws. В зависимости от используемого контура системы, полный путь к интерфейсу будет различаться:

АдресКонтур
wss://api.alor.ru/wsБоевой контур системы. Для использования требуется действующий торговый аккаунт
wss://apidev.alor.ru/wsТестовый контур системы. Для использования требуется тестовый торговый аккаунт
Обратите внимание!

Для обеспечения безопасности передаваемых данных сервер принимает запросы только по протоколу WebSocket Secure (wss). Попытка подключения по незащищённому протоколу WebSocket (ws) будет отклонена сервером с ответом 406 Not Acceptable.


Формирование запроса

Независимо от того, подписка какого типа создаётся, отправляемый запрос всегда должен соответствовать следующим характеристикам:

  1. Выполняется авторизованным пользователем
  2. Указывает на определённый тип операции
  3. Имеет уникальный идентификатор для отделения от других запросов

Для соблюдения этих требований тело сообщения для каждого поддерживаемого запроса должно содержать заполненные обязательные параметры token, opcode и guid.

Ниже описаны детали применения этих параметров.

Авторизация

Все операции, выполняемые с помощью WebSocket API, требуют авторизацию для подтверждения личности пользователя API и наличия у него прав на выполнение запрашиваемых действий. В качестве подтверждения используется Access Токен пользователя API, передаваемый серверу в качестве значения параметра token.

В отличии от запросов для управления заявками, при взаимодействии с интерфейсом управления подписками /ws Access Токен необходимо указывать в каждом запросе, будь то создание новой подписки или её отмена.

Для авторизации отправляемых запросов укажите Access Токен в качестве значения параметра token в теле сообщения.

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

Тело запроса (Подписка на биржевой стакан)
{
"opcode": "OrderBookGetAndSubscribe",
"code": "SBER",
"depth": 10,
"exchange": "MOEX",
"format": "Simple",
"frequency": 0,
"guid": "c328fcf1-e495-408a-a0ed-e20f95d6b813",
"token": "eyJhbGciOiJ..."
}

Где:

  • token — Access Токен для авторизации запроса

При успешной авторизации в ответ сервер однократно передаст сообщение с кодом 200, подтверждающее создание подписки.

Пример тела ответа, подтверждающего создание подписки

200. Запрос успешно обработан
{
"message": "Handled successfully",
"httpCode": 200,
"requestGuid": "c328fcf1-e495-408a-a0ed-e20f95d6b813"
}

После чего в WebSocket-соединение, в которое был отправлен запрос на создание подписки, начнут поступать сообщения с кодом ответа 100, содержащие запрошенную информацию.

Пример тела информационного сообщения

100. Информационные сообщения канала
{
"data": {
"snapshot": true,
"bids": [
{
"price": 257.70,
"volume": 157
}
],
"asks": [
{
"price": 257.71,
"volume": 288
}
],
"timestamp": 1702631123,
"ms_timestamp": 1702631123780,
"existing": true
},
"guid": "c328fcf1-e495-408a-a0ed-e20f95d6b813"
}

В случае неудачной попытки авторизации (Например, из-за указания недействительного Access Токена) в WebSocket-соединение будет возвращён ответ с кодом 401, после чего соединение будет разорвано сервером.

Пример тела сообщения, содержащего отказ в создании подписки

401. Не удалось авторизовать запрос
{
"requestGuid": "c328fcf1-e495-408a-a0ed-e20f95d6b813",
"httpCode": 401,
"message": "Invalid JWT token!"
}
Резюме
  • Для выполнения запросов требуется авторизация
  • Каждый запрос авторизуется отдельно
  • Авторизация запросов выполняется параметром token
  • В качестве значения должен использоваться Access Токен, действительный как для выбранного контура системы, так и для времени выполнения запроса
  • Неудачная попытка авторизации разрывает установленное WebSocket-соединение

Идентификация

Каждое WebSocket-соединение даёт пользователю API возможность создать множество одновременно активных подписок, в рамках которых сервер будет возвращать запрошенную информацию. Для идентификации отправляемых и получаемых сообщений как составляющих одной подписки используется параметр guid, передаваемый серверу в теле запроса и возвращаемый во всех ответах в рамках созданной подписки.

подсказка

Параметр guid присваивается подписке пользователем API, а не сервером. Предусмотрите механизм генерации значений для данного параметра в используемом ПО.

В качестве значения параметра guid сервер принимает любое произвольное строковое значение, уникальное для установленного WebSocket-соединения. С равным успехом значением данного параметра могут быть следующие комбинации символов:

  • 123456
  • abcdefABCDEF
  • !@№;%:?*()-_=+/|"'
  • c328fcf1-e495-408a-a0ed-e20f95d6b813
  • Client-31075-Subscription-51-SBER-Quotes

Таким образом, в зависимости от задачи, guid запроса может содержать как случайно сгенерированное, так и персонализированное значение. При этом для значения действует ограничение по длине — не более 50 символов.

Экранирование спецсимволов

При использовании спецсимволов в составе идентификатора убедитесь в сохранении целостности отправляемого JSON объекта. Символы, нарушающие синтаксис, должны быть исключены из комбинации или экранированы с помощью символа \. При этом экранирующий символ не учитывается как часть идентификатора, в связи с чем, например, значение /|\" будет интерпретировано системой как /|".

Каждое WebSocket-соединение изолировано от остальных, в связи с чем одно и то же значение параметра guid может использоваться в нескольких запросах, если они созданы в разных соединениях.

В отличии от запросов на управление заявками, при создании подписок сервер сохранит активным WebSocket-соединение при использовании неуникального значения guid. Вместо этого новая подписка заменит прежнюю, созданную с тем же значением параметра.

Резюме
  • Одно WebSocket-соединение поддерживает возможность создания множества одновременно активных подписок
  • Каждый запрос должен содержать заполненный параметр guid
  • Ответные сообщения от сервера содержат то же значение guid, которое было передано пользователем в запросе
  • Параметр guid заполняется пользователем API
  • Значение параметра может быть произвольным, но не длиннее 50 символов
  • Спецсимволы, нарушающие целостность JSON объекта, должны быть экранированы или исключены
  • Значение параметра должно быть уникальным для используемого WebSocket-соединения. Уникальным считается значение, не использовавшееся в запросах с момента установления соединения
  • Одинаковое значение параметра guid может применяться без последствий в разных WebSocket-соединениях
  • Использование неуникального значения при создании новой подписки заменяет созданную ранее

Выбор операции

При работе с HTTP API все действия пользователя определяются заданным в качестве пути URL ресурса и HTTP-глаголом, указывающим на метод взаимодействия (GET, PUT, POST, DELETE). В случае с WebSocket API метод взаимодействия определяется кодом операции, передаваемым в рамках WebSocket-соединения клиентском сообщении.

Как и в случае с HTTP-глаголами, коды операции строго определены и не допускают изменений в формулировке или написании. Разница заключается в том, что HTTP-глаголы определены общепринятым стандартом RFC 9110, тогда как для WebSocket API коды операций определяются выбранным создателями системы способом реализации метода.

Точное значение кода для каждой из операций представлено на странице описания соответствующего запроса.

Пример

Для создания подписки на котировки по выбранному финансовому инструменту используется код операции QuotesSubscribe. Для успешного выполнения запроса данный код должен передаваться системе в неизменном виде.

Такие варианты, как quotessubscribe, QuoteSubscribe, SubscribeQuotes или Quotes:Subscribe, будут отклонены системой как неизвестные операции.


Создание подписки

Подписка на информационный канал производится отправкой в установленное WebSocket-соединение сообщения, содержащего в теле актуальный токен доступа (token), код исполняемой операции (opcode), уникальный идентификатор (guid) и дополнительные параметры, определяющие детали подписки.

Пример тела запроса на создание подписки на биржевой стакан:

{
"opcode": "OrderBookGetAndSubscribe",
"code": "SBER",
"depth": 10,
"exchange": "MOEX",
"format": "Simple",
"frequency": 0,
"guid": "c328fcf1-e495-408a-a0ed-e20f95d6b813",
"token": "eyJhbGciOiJ..."
}

Где:

  • opcode — Код выполняемой операции
  • code — Код финансового инструмента (Тикер)
  • depth — Глубина стакана
  • exchange — Биржа
  • format — Формат представления возвращаемых данных
  • frequency — Максимальная частота отдачи данных сервером в миллисекундах
  • guid — Уникальный идентификатор сообщений создаваемой подписки. Все входящие сообщения, соответствующие этой подписке, будут иметь такое значение поля guid
  • token — Access Токен для авторизации запроса
примечание

Значение для поля guid указывается пользователем. Предусмотрите в используемом ПО механизм генерации уникальных идентификаторов для отправляемых сообщений.


Отмена подписки

Отмена подписки на информационный канал выполняется аналогичным подписке способом — отправкой сообщения с кодом операции unsubscribe и значением guid отменяемой подписки.

Пример тела запроса на отмену подписки (Отмена ранее созданной подписки на биржевой стакан):

{
"opcode": "unsubscribe",
"token": "eyJhbGciOiJ...",
"guid": "c328fcf1-e495-408a-a0ed-e20f95d6b813"
}
примечание

WebSocket-соединения изолированы друг от друга, в связи с чем подписка должна отменяться в рамках того же соединения, в котором была установлена.


Ограничения и рекомендации

При работе с WebSocket API необходимо учитывать ряд ограничений и условий использования информационных каналов, налагаемых системой.

Ограничение

Рекомендация

По ряду причин сервер может разорвать установленное WebSocket-соединение без инициативы на его восстановление со своей стороны

Предусмотрите в используемом ПО механизм автоматического переподключения при разрыве соединения

Для каждого пользователя API со стороны сервера установлено ограничение на количество активных подписок в размере нескольких сотен тысяч. При превышении установленного лимита пользователю будет временно (на несколько минут) ограничена возможность создания новых подписок. Ранее созданные подписки продолжат действовать.

Предусмотрите в используемом ПО механизм автоматической отмены подписок без прерывания WebSocket-соединения

Для каждого WebSocket-соединения со стороны сервера установлено ограничение на количество необработанных сообщений в буфере сервера в размере 5000 записей.

При превышении установленного лимита пользователю будет временно (от нескольких минут до двух часов) заблокирована возможность создавать новые подписки, а проблемное WebSocket-соединение будет разорвано по инициативе сервера с сообщением Too many (>5009) messages in server buffer, closing WebSocket.

  • Предусмотрите в используемом ПО механизм промежуточной записи получаемых сообщений перед их обработкой

  • Разделите подписки на несколько WebSocket-соединений

Большое количество активных WebSocket-соединений негативно сказывается на стабильности работы системы. Действия, наносящие вред системе, могут привести ко временной блокировке пользователя, допустившего такое поведение.

Ограничьте количество одновременно устанавливаемых соединений до 10 штук, распределив между ними действующие подписки на интересующие информационные каналы.