Блог им. Volokola
Я — профессиональный программист. Уже достаточно давно. Последние N лет разработчик БД. В основном пишу на sql процедуры и функции. Другие языки программирования начинаю забывать (так как нет практики по ним). В свое время писал на Visual FoxPro (да, это уже «мертвый» язык, он уже давно не поддерживается Microsoft). Но у нас до сих пор крутится задача, где клиентская частью написана на VFP.
Так вот. Встала тут задача написать небольшую консольную утилиту с доступом к БД. Сначала хотел написать на Питоне, но не хотелось на компьютере клиента качать и устанавливать его. И стал я присматриваться к другим языкам программирования. C# не хотелось, во первых чисто субъективно, во вторых, клиент в дальнейшем собирался переходить на Linux (хотя вроде есть core net под линукс). И тогда cтал я присматриваться к языку Go.
Прочитал по нему несколько статей. По описанию, он как никто подходил к поставленной задаче: крост-платформенный. Компилируется в один исполняемый файл, который не требует зависимостей.
Скачал и прочитал пару книжек. Для изучения Не первого языка программирования, Go оказался очень прост по структуре и синтаксису. Начать кодить на нем можно достаточно быстро.
Написал утилитку по работе. И этот язык мне так понравился, что я решил его изучать дальше. Но что за изучение языка без практического навыка? Обязательно в этом случае нужен «Пет-проект». А так как я уже некоторое время занимаюсь спекуляцией на рынках (давно написан и крутится в работе бот-помощник для торговли), то проект решил делать в финансовом направлении.
Выбор пал на создание коннектора к брокеру Финам к его Trade API через REST.
Первоначально начал искать аналоги для ознакомления.
На сайте с примерами в основном проекты на Python. И есть один на Goland от DBoyara (на текущий момент он в статусе архива = не поддерживается). Он реализует протокол gRPC. Для меня, только начинающего изучать эту технологию, это сложновато. Хотелось начать с чего то попроще, с REST API
Нашел хороший «звездный» проект: коннектор кBinance API . Изучил его и некоторые идеи стал использовать в своей разработке.
Спасибо тем, кто смог дочитать до этого места.
Сразу дам ссылку проекта на github.
Весь код бесплатный. Использовать на свой страх и риск. В боевых условиях не тестировалось. Возможны ошибки.
Реализован почти весь базовый функционал, который есть по протоколу REST API
// AccessTokens проверка подлинности токена AccessTokens(ctx context.Context) (ok bool, err error) // GetPortfolio получить данные по портфелю GetPortfolio(ctx context.Context, opts ...Option) (Portfolio, error) // GetSecurity получить список инструментов (Максимальное Количество запросов в минуту = 1 ) GetSecurity(ctx context.Context, board, symbol string) (Securities, error) // GetCandles получить свечи GetCandles(ctx context.Context, board, symbol string, timeFrame TimeFrame, opts ...Option) ([]Candle, error) // получить список заявок GetOrders(ctx context.Context, opts ...Option) ([]Order, error) // отменить заявку DeleteOrder(ctx context.Context, transactionId int64) error // создать новую заявку //SendOrder(ctx context.Context, order NewOrderRequest) (int64, error) // купить по рынку BuyMarket(ctx context.Context, symbol, board string, lot int32) (int64, error) // выставить лимитную заявку на покупку BuyLimit(ctx context.Context, board, symbol string, lot int32, price float64) (int64, error) // продать по рынку SellMarket(ctx context.Context, board, symbol string, lot int32) (int64, error) // выставить лимитную заявку на продажу SellLimit(ctx context.Context, board, symbol string, lot int32, price float64) (int64, error) // TODO // получить список стоп-заявок // создать новую стоп-заявку // отменить стоп-заявку
Не доделано выставление стоп-заявок. Возможно это будет в будущем.
В планах также реализовать создание «еванса получение новой свечи». В штатном функционале Финама этого нет (даже по протоколу gRPC).
Приведу пример кода на goland по работе с коннектором (Другие примеры можно увидеть на странице проекта в папке example):
// создание клиента token := "ваш token" clientId := "ваш client_id" client, err := finam.NewClient(token, clientId) if err != nil { slog.Error("main", slog.Any("ошибка создания finam.client", err)) } // Пример получения данных о портфеле portfolio, err := client.GetPortfolio(ctx, finam.WithIncludePositions(true), finam.WithIncludeCurrencies(true), finam.WithIncludeMoney(true), finam.WithIncludeMaxBuySell(true)) if err != nil { slog.Error("main.GetPortfolio", "err", err.Error()) return } // баланс счета slog.Info("Balance", "Equity", portfolio.Equity, "Balance", portfolio.Balance) // список позиций for _, pos := range portfolio.Positions { slog.Info("position", slog.Any("pos", pos)) } // список валют счета slog.Info("portfolio.Currencies", slog.Any("Currencies", portfolio.Currencies)) // список денег slog.Info("portfolio.Money", slog.Any("Money", portfolio.Money))
1. Разная структура и точки вызова свечей. Почему-то проектировщики api в финаме решили разделить дневные и внутридневные свечи.
2. Очень «мало» информации (полей) в Security (инструменты). В частности, мне для анализа, нужно поле «Открытый интерес».
3. В api нет подписок на появления новых свечей (зато есть возможность реализовать данный функционал самому :) ).
А дальше, уже практически готов, коннектор к брокеру Алор. К его Alor OpenAPI V2
Базовый функционал уже реализован. Проект на github выложил в свободном доступе.
Пока не знаю, нужно ли, писать отдельную статью по коннектору к Алор?
И в работе проект по доступу к ISS Московкой биржи и его новому проекту ALGOPACK
Доктор, Примерно так :)
В «идеале» не хотел быть зависимым от «внешних» библиотек.
Gambler, веб сокеты реализовал к коннектору Алор .
У Финама нет такой технологии в протоколе. Они пошли по технологии gRPC
Веб сокеты — это транспорт. gRPC — это формат передачи данных через транспорт. Не путаем )
Ты ответь на вопрос. А почему Go? Ладно сишарп, может и прав. Но ведь очевидно что Питон берут для тредйинга.