Последняя свеча
Этот метод WebSocket API позволяет получать последнюю свечу по инструменту в режиме реального времени для заданного таймфрейма.
🔌 WebSocket URL
wss://ws.broker.ru/trade-api-market-data-connector/api/v1/market-data/ws
🔐 Аутентификация
Перед установкой WebSocket-соединения клиент должен передать access-token в HTTP-заголовке:
Authorization: Bearer <ACCESS_TOKEN>
Подробнее об авторизации см. раздел Авторизация.
🧱 Общий формат сообщений
Все сообщения в WebSocket передаются в формате JSON.
- Клиент → сервер: команды подписки / отписки.
- Сервер → клиент: подтверждения подписки, данные свечей, ошибки.
📤 Сообщения client → server
После установления WebSocket-соединения клиент отправляет сообщение на подписку.
Подписка на последнюю свечу
Назначение: подписка на обновление последней свечи по инструменту и таймфрейму.
{
"subscribeType": 0,
"dataType": 1,
"timeFrame": "M1",
"instruments": [
{
"classCode": "TQBR",
"ticker": "SBER"
}
]
}
Поля запроса
| Поле | Где | Тип | Обяз. | Описание |
|---|---|---|---|---|
subscribeType | Тело | number (enum) | да | Тип сообщения:0 — Подписка1 — Отписка |
dataType | Тело | number (enum) | да | Тип данных:1 — Свечи |
timeFrame | Тело | string (enum) | да | Таймфрейм свечи:M1 — 1 минутаM5 — 5 минутM15 — 15 минутM30 — 30 минутH1 — 1 часH4 — 4 часаD — 1 деньW — 1 неделяMN — 1 месяц |
instruments | Тело | array | да | Список инструментов для подписки |
instruments[].ticker | Тело | string | да | Биржевой тикер |
instruments[].classCode | Тело | string | да | Код класса ценной бумаги |
Отписка от последней свечи
Чтобы отписаться, используется то же сообщение, но с subscribeType = 1:
{
"subscribeType": 1,
"dataType": 1,
"timeFrame": "M1",
"instruments": [
{
"classCode": "TQBR",
"ticker": "SBER"
}
]
}
📥 Сообщения server → client
Сервер отправляет сообщения о результате подписки и обновлениях свечей.
Успешный ответ о подписке
{
"responseType": "CandleStickSuccess",
"subscribeType": 0,
"ticker": "SBER",
"classCode": "TQBR",
"timeFrame": "M1",
"dateTime": "2024-11-10T10:30:00.000Z"
}
Структура данных успешной подписки
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
responseType | string (enum) | да | CandleStickSuccess – успешная подписка |
subscribeType | number (enum) | да | Тип сообщения:0 — Подписка1 — Отписка |
ticker | string | да | Код инструмента |
classCode | string | да | Код класса ценной бумаги |
timeFrame | string (enum) | да | Таймфрейм свечи:M1 — 1 минутаM5 — 5 минутM15 — 15 минутM30 — 30 минутH1 — 1 часH4 — 4 часаD — 1 деньW — 1 неделяMN — 1 месяц |
dateTime | string (datetime) | да | Дата и время ответа (UTC) |
Успешный ответ с данными свечи
{
"responseType": "CandleStick",
"ticker": "SBER",
"classCode": "TQBR",
"timeFrame": "M1",
"open": 244.20,
"close": 244.50,
"high": 244.70,
"low": 243.90,
"volume": 3200,
"dateTime": "2024-11-10T10:30:00.000Z"
}
Структура данных ответа с данными
| Поле | Тип | Обяз. | Описание |
|---|---|---|---|
responseType | string (enum) | да | CandleStick – получение данных |
ticker | string | да | Код инструмента |
classCode | string | да | Код класса ценной бумаги |
timeFrame | string (enum) | да | Таймфрейм свечи:M1 — 1 минутаM5 — 5 минутM15 — 15 минутM30 — 30 минутH1 — 1 часH4 — 4 часаD — 1 деньW — 1 неделяMN — 1 месяц |
open | number | да | Цена открытия |
close | number | да | Цена закрытия |
high | number | да | Максимальная цена |
low | number | да | Минимальная цена |
volume | number | да | Объём торгов в валюте |
dateTime | string (datetime) | да | Дата и время свечи (UTC) |
Пример ответа с ошибкой
{
"responseType": "CandleStick",
"errors": [
{
"message": "Input JSON structure does not match structure, 'timeFrame' field is undefined.",
"code": "INCORRECT_JSON"
}
]
}
Структура данных ошибки
| Поле | Тип | Описание |
|---|---|---|
responseType | string (enum) | Тип сообщения. Для ошибок по сделкам — CandleStick |
errors[].message | string | Текст ошибки |
errors[].code | string (enum) | Код ошибки:NO_DATE — нет данныхNOT_FOUND — инструмент не найденINCORRECT_JSON – невалидный jsonBAD_REQUEST — ошибка выполненияUNAUTHORIZED — клиент не авторизован |
💻 Примеры использования
Во всех примерах ниже предполагается, что у вас уже есть корректный ACCESS_TOKEN.
- JavaScript (Node.js)
- Python
- Go (Golang)
- Java
- C#
import WebSocket from "ws";
const URL = "wss://ws.broker.ru/trade-api-market-data-connector/api/v1/market-data/ws";
const ws = new WebSocket(URL, {
headers: {
Authorization: "Bearer YOUR_ACCESS_TOKEN",
},
});
ws.on("open", () => {
const subscribeMessage = {
subscribeType: 0,
dataType: 1,
timeFrame: "M1",
instruments: [{ classCode: "TQBR", ticker: "SBER" }],
};
ws.send(JSON.stringify(subscribeMessage));
});
ws.on("message", (event) => {
const payload = JSON.parse(event.toString());
console.log("Received:", payload);
});
ws.on("error", (error) => {
console.error("WebSocket error:", error);
});
import asyncio
import json
import websockets
URL = "wss://ws.broker.ru/trade-api-market-data-connector/api/v1/market-data/ws"
TOKEN = "YOUR_ACCESS_TOKEN"
async def main():
async with websockets.connect(
URL,
additional_headers={"Authorization": f"Bearer {TOKEN}"},
) as ws:
subscribe_message = {
"subscribeType": 0,
"dataType": 1,
"timeFrame": "M1",
"instruments": [{"classCode": "TQBR", "ticker": "SBER"}],
}
await ws.send(json.dumps(subscribe_message))
print("Sent subscribe for last candle")
async for message in ws:
data = json.loads(message)
print("Received:", data)
if __name__ == "__main__":
asyncio.run(main())
package main
import (
"log"
"net/http"
"github.com/gorilla/websocket"
)
func main() {
header := http.Header{}
header.Add("Authorization", "Bearer YOUR_ACCESS_TOKEN")
c, _, err := websocket.DefaultDialer.Dial(
"wss://ws.broker.ru/trade-api-market-data-connector/api/v1/market-data/ws",
header,
)
if err != nil {
log.Fatal("dial:", err)
}
defer c.Close()
subscribeMessage := map[string]interface{}{
"subscribeType": 0,
"dataType": 1,
"timeFrame": "M1",
"instruments": []map[string]string{
{"classCode": "TQBR", "ticker": "SBER"},
},
}
if err := c.WriteJSON(subscribeMessage); err != nil {
log.Fatal("write:", err)
}
for {
var payload map[string]interface{}
if err := c.ReadJSON(&payload); err != nil {
log.Println("read:", err)
return
}
log.Printf("received: %#v", payload)
}
}
import okhttp3.*;
public class LastCandleWs {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("wss://ws.broker.ru/trade-api-market-data-connector/api/v1/market-data/ws")
.addHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN")
.build();
WebSocketListener listener = new WebSocketListener() {
@Override
public void onOpen(WebSocket webSocket, Response response) {
String subscribeMessage = """
{
"subscribeType": 0,
"dataType": 1,
"timeFrame": "M1",
"instruments": [
{ "classCode": "TQBR", "ticker": "SBER" }
]
}
""";
webSocket.send(subscribeMessage);
}
@Override
public void onMessage(WebSocket webSocket, String text) {
System.out.println(text);
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
t.printStackTrace();
}
};
client.newWebSocket(request, listener);
}
}
using System;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var ws = new ClientWebSocket();
ws.Options.SetRequestHeader("Authorization", "Bearer YOUR_ACCESS_TOKEN");
await ws.ConnectAsync(
new Uri("wss://ws.broker.ru/trade-api-market-data-connector/api/v1/market-data/ws"),
CancellationToken.None
);
var subscribeMessage = new
{
subscribeType = 0,
dataType = 1,
timeFrame = "M1",
instruments = new[]
{
new { classCode = "TQBR", ticker = "SBER" }
}
};
string payload = JsonSerializer.Serialize(subscribeMessage);
await ws.SendAsync(
Encoding.UTF8.GetBytes(payload),
WebSocketMessageType.Text,
endOfMessage: true,
cancellationToken: CancellationToken.None
);
var buffer = new byte[8192];
while (ws.State == WebSocketState.Open)
{
var result = await ws.ReceiveAsync(buffer, CancellationToken.None);
if (result.MessageType == WebSocketMessageType.Close)
{
break;
}
var json = Encoding.UTF8.GetString(buffer, 0, result.Count);
Console.WriteLine(json);
}
}
}
❗ Ошибки
| HTTP | Текст | Описание |
|---|---|---|
| 400 | BadRequest | Неверные параметры |
| 500 | Internal Server Error | Внутренняя ошибка сервера |