DEV Community

Cover image for bcs-trade-go: Удобный клиент для алготрейдинга на Московской бирже через БКС
Igor
Igor

Posted on

bcs-trade-go: Удобный клиент для алготрейдинга на Московской бирже через БКС

Для разработчиков на Go, интересующихся алгоритмической торговлей на Московской бирже, появление качественных и удобных инструментов для взаимодействия с брокерскими API — всегда важное событие. Сегодня мы рассмотрим именно такой инструмент — библиотеку bcs-trade-go, которая представляет собой готовый клиент для нового торгового API от БКС Брокера.

Эта статья будет полезна Go-разработчикам, которые хотят автоматизировать свои торговые стратегии, создавать торговых ботов, анализировать рыночные данные или просто интегрировать свой портфель в БКС с собственными приложениями.

Что такое BCS Trade API?

BCS Trade API — это современный программный интерфейс от БКС Брокера, построенный на основе REST и WebSocket. Он предоставляет полный спектр возможностей для работы на бирже:

  • Получение рыночных данных: котировки, исторические свечи (OHLCV), биржевой стакан (Level 2).
  • Управление портфелем: получение информации об активах, балансе, лимитах и маржинальных показателях.
  • Торговые операции: выставление, изменение и отмена лимитных и рыночных заявок.
  • Справочная информация: данные об инструментах, расписании торгов и т.д.

Авторизация в API происходит по стандарту OAuth 2.0, с использованием пары refresh и access токенов, что обеспечивает безопасность, но добавляет дополнительный слой логики, который нужно реализовывать разработчику.

Зачем нужен bcs-trade-go? Проблема и решение

Хотя наличие документированного API — это уже большой плюс, прямая работа с ним сопряжена с рядом рутинных задач:

  1. Управление токенами: access токен живёт всего 24 часа, и его нужно регулярно обновлять с помощью refresh токена. Этот процесс требует написания дополнительного кода для отслеживания срока жизни токена и его своевременного обновления.
  2. Пагинация: При запросе исторических данных, например, свечей, API возвращает не более 1000 элементов за раз. Для получения больших объемов данных нужно делать несколько последовательных запросов, корректно сдвигая временные окна.
  3. Работа с WebSocket: WebSocket — мощный инструмент для получения данных в реальном времени, но он требует обработки переподключений при обрывах связи, а также корректного управления подписками.
  4. Обработка ошибок и повторные запросы: Сетевые взаимодействия не всегда стабильны. Нужно обрабатывать ошибки, связанные с превышением лимитов запросов (rate limits), и реализовывать логику повторных попыток (retry).

Библиотека bcs-trade-go элегантно решает все эти проблемы, предоставляя высокоуровневый, готовый к использованию клиент. Она абстрагирует всю сложность взаимодействия с API, позволяя разработчику сосредоточиться на бизнес-логике своего приложения.

Ключевые возможности bcs-trade-go

Рассмотрим основные преимущества и функции, которые делают эту библиотеку отличным выбором.

Функция Описание
Полное покрытие API Реализованы все HTTP-эндпоинты и WebSocket-каналы, описанные в официальной документации БКС.
Автоматическое управление OAuth2 Клиент самостоятельно получает и обновляет access токен. При получении ошибки 401 (Unauthorized) он автоматически пытается обновить токен и повторить запрос.
Умная пагинация свечей Метод GetCandlesPaginated позволяет запросить исторические свечи за любой период, а библиотека сама разобьет запрос на части нужного размера и склеит результат.
Надежные WebSocket-соединения При обрыве WebSocket-соединения клиент автоматически пытается восстановить его с экспоненциальной задержкой, что обеспечивает стабильность получения потоковых данных.
Типобезопасность Все запросы и ответы API представлены в виде строго типизированных Go-структур, что исключает ошибки и делает работу с данными удобной.
Контекстно-ориентированный дизайн Все методы клиента принимают context.Context, что позволяет легко управлять таймаутами, отменой запросов и интегрировать библиотеку в современные Go-приложения.
Продуманная обработка ошибок Библиотека определяет кастомные типы ошибок (например, AuthError, RateLimitError, ValidationError), что позволяет гибко реагировать на различные сбои.
Потокобезопасность Клиент спроектирован для безопасной работы из нескольких горутин одновременно.

Начало работы

Начать использовать библиотеку очень просто.

Установка

go get github.com/tigusigalpa/bcs-trade-go
Enter fullscreen mode Exit fullscreen mode

Настройка

Для работы с API вам понадобится refresh токен. Его можно получить в личном кабинете БКС Мир Инвестиций в разделе настроек API. Токен можно выпустить с правами "только для чтения" (trade-api-read) или с полными правами для торговли (trade-api-write).

Самый простой способ передать токен в приложение — через переменные окружения:

export BCS_TRADE_REFRESH_TOKEN="ваш-refresh-token"
export BCS_TRADE_CLIENT_ID="trade-api-read" # или trade-api-write
Enter fullscreen mode Exit fullscreen mode

После этого можно инициализировать клиент.

Примеры использования

Инициализация клиента и получение портфеля

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/tigusigalpa/bcs-trade-go"
)

func main() {
    ctx := context.Background()

    // Инициализация клиента из переменных окружения
    client, err := bcstrade.NewFromEnv(ctx)
    if err != nil {
        log.Fatalf("Ошибка создания клиента: %v", err)
    }

    // Получение данных портфеля
    portfolio, err := client.Portfolio.Get(ctx)
    if err != nil {
        log.Fatalf("Ошибка получения портфеля: %v", err)
    }

    fmt.Printf("Стоимость портфеля: %.2f %s\n",
        portfolio.Summary.TotalValue,
        portfolio.Summary.Currency)
}
Enter fullscreen mode Exit fullscreen mode

Получение исторических свечей

Используем GetCandlesPaginated для загрузки данных за неделю.

params := models.GetCandlesParams{
    ClassCode: "TQBR", // Акции и паи
    Ticker:    "SBER",
    StartDate: time.Now().AddDate(0, 0, -7),
    EndDate:   time.Now(),
    TimeFrame: models.TimeFrameH1, // Часовые свечи
}

candles, err := client.MarketData.GetCandlesPaginated(ctx, params)
if err != nil {
    log.Fatalf("Ошибка получения свечей: %v", err)
}

fmt.Printf("Загружено %d свечей для SBER\n", len(candles.Bars))
for _, bar := range candles.Bars {
    fmt.Printf("[%s] O:%.2f H:%.2f L:%.2f C:%.2f V:%.0f\n",
        bar.Time.Format("2006-01-02 15:04"),
        bar.Open, bar.High, bar.Low, bar.Close, bar.Volume)
}
Enter fullscreen mode Exit fullscreen mode

Подписка на котировки через WebSocket

Получение котировок в реальном времени — ключевая задача для торговых ботов.

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

// Подписка на котировки по SBER и GAZP
quoteCh, errCh, err := client.WebSocket.Quotes(ctx, []string{"TQBR:SBER", "TQBR:GAZP"})
if err != nil {
    log.Fatalf("Ошибка подписки на котировки: %v", err)
}

fmt.Println("Ожидание котировок...")

for {
    select {
    case q := <-quoteCh:
        fmt.Printf("Тикер: %s, Bid: %.2f, Ask: %.2f, Last: %.2f\n", q.Ticker, q.Bid, q.Ask, q.Last)
    case err := <-errCh:
        // Логируем ошибку, но не выходим, т.к. клиент попытается переподключиться
        log.Printf("Ошибка WebSocket: %v", err)
    case <-ctx.Done():
        fmt.Println("Контекст отменен, завершение работы.")
        return
    }
}
Enter fullscreen mode Exit fullscreen mode

Архитектура библиотеки

Код bcs-trade-go хорошо структурирован и легко читается. Основные компоненты:

  • client.go: Содержит главную структуру Client, которая является точкой входа и агрегирует все сервисы.
  • bcs.go: Определяет константы и основные типы, такие как ClientID.
  • config.go: Конфигурация клиента.
  • auth.go: Вся логика, связанная с OAuth 2.0 и управлением токенами.
  • transport.go: Кастомный http.RoundTripper, который "оборачивает" стандартный транспорт и добавляет в каждый запрос заголовок Authorization, а также реализует логику повторного запроса при ошибке 401.
  • services/: Директория, где каждый сервис (Portfolio, Orders, MarketData и т.д.) вынесен в отдельный файл, что соответствует разделению эндпоинтов в официальном API.
  • websocket/: Логика для работы с WebSocket, включая подписки и переподключения.

Такая архитектура делает библиотеку расширяемой и простой в поддержке.

Заключение

bcs-trade-go — это зрелый и качественный инструмент, который значительно упрощает разработку торговых приложений на Go для клиентов БКС. Автор проделал большую работу, скрыв под капотом всю сложность сетевого взаимодействия и авторизации, и предоставил разработчикам чистый и идиоматичный интерфейс.

Если вы ищете надежное решение для алготрейдинга на Московской бирже с использованием Go, bcs-trade-go определенно заслуживает вашего внимания.

Полезные ссылки:

Top comments (0)