alex

package module
v0.0.0-...-f7f5d23 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 23, 2022 License: Apache-2.0 Imports: 18 Imported by: 0

README

Alex

SDK для создания, тестирования на исторических данных и в песочнице, и выполнения на реальном счетё торговых стратегий, созданных на golang.

Быстрый старт

0. Зарегистрируйтесь в Tinkoff, и получите токен доступа к API Токен для работы с TINKOFF INVEST API

1. Соберите проект

Скопируйте исходный код проекта себе

git clone https://github.com/go-trading/alex

Для получения исполняемого файла командной строки, перейдите в каталог alex и выполните следующию команду (требуется установленнай компилятор golang версии 1.18 или выше):

go build .

Для получения docker образа в корневом каталоге выполните

docker build .

2. Скачайте историю свечей по инструменту

./alex load --figi=BBG000000001 --token=******************

Можно указать сразу несколько бумаг, указав атрибут figi несколько раз.

По умолчанию скачивается последняя неделя, с помощью аргументов from и to можно указать какой период интересует.

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

См. все возможные аргументы с помощью аргумента -h.

3. Протестируйте робота на исторических данных

./alex bot history --figi=BBG000000001 --timeframe=7 --rsi4buy=45 --rsi4sell=55

4. Откройте счёт в песочнице

./alex sandbox open --token=**********

**5. Положите на счет средства (по умолчанию кладётся 200 тысяч :))) **

./alex sandbox pay-in --account=значение-с-предыдущего-шага --token=**********

6. Запустите робота в песочнице

./alex bot rsi --account=значение-с-предыдущего-шага --figi=BBG000000001 --timeframe=7 --rsi4buy=45 --rsi4sell=55 --token=**********

** Если в параметре account, будет указан номер боевого счёта, то робот будет торгавать на бою**

7. Узнайте номер боевого счёта

./alex accounts --token=**********

Структура проекта

alex — Утилита командной строки, позволяющая использовать функциональность библиотек. См. описание утилиты

bots — Примеры торговых роботов. См. написание торгового робота

history — Клиент, реализация тестирования на исторических данных

tinkoff — Клиент для тестирования в песочнице, или торговле на реальном счёте Tinkoff

grafana - Исходники примера дашборта grafana, и его скриншот

корневой каталог — SDK для написания роботов

MAINTAINER

Alexey Nebotov

Documentation

Index

Constants

This section is empty.

Variables

Functions

func Duration2CandleInterval

func Duration2CandleInterval(d time.Duration) proto.CandleInterval

func Duration2SubscriptionInterval

func Duration2SubscriptionInterval(period time.Duration) proto.SubscriptionInterval

func FindSeries

func FindSeries(series *techan.TimeSeries, time time.Time) int

TODO очень не оптимально, надо переделывать, например на деление пополам с кешированием последней найденной позиции

func IsLimitError

func IsLimitError(e error) bool

TODO надо вводить свой класс ошибок

func LoadTimeSeries

func LoadTimeSeries(dataDir string, figi string, period time.Duration) (*techan.TimeSeries, error)

func NewDecimal

func NewDecimal(q *proto.Quotation) big.Decimal

func NewMoneyValue

func NewMoneyValue(m *Money) *proto.MoneyValue

func NewQuotation

func NewQuotation(d big.Decimal) *proto.Quotation

func SaveTimeSeries

func SaveTimeSeries(dataDir string, figi string, period time.Duration, timeSeries *techan.TimeSeries) error

func SetLogger

func SetLogger(logger *zap.Logger)

func SubscriptionInterval2Duration

func SubscriptionInterval2Duration(subscriptionInterval proto.SubscriptionInterval) time.Duration

func UnitsNano2Decimal

func UnitsNano2Decimal(units int64, nano int32) big.Decimal

func UpsertSeries

func UpsertSeries(series *techan.TimeSeries, newCandle *techan.Candle)

Types

type Account

type Account interface {
	AccountDescription
	AccountEngine
	AccountSmart
}

Интерфейс торгового счёта

type AccountDescription

type AccountDescription interface {
	GetId() string
	GetType() proto.AccountType
	GetEngineType() EngineType
	GetName() string
	GetStatus() proto.AccountStatus
	GetAccessLevel() proto.AccessLevel
	GetClosedDate() time.Time
	GetOpenedDate() time.Time
}

описание счёта (совместим с proto интерфейсами tinkoff инвестиции)

type AccountEngine

type AccountEngine interface {
	GetPositions(ctx context.Context) (*Positions, error)
	GetOrders(ctx context.Context) ([]Order, error)
	GetBalance(ctx context.Context, i Instrument) int64
	GetBlocked(ctx context.Context, i Instrument) int64
	PostOrder(ctx context.Context, instrument Instrument, quantity int64, price big.Decimal, direction proto.OrderDirection, orderType proto.OrderType, orderId string) (Order, error)
	CancelOrder(ctx context.Context, orderId string) (time.Time, error)
	GetClient() Client // возвращает интерфейс Client, в рамках которого создан данный счёт
}

реализация торговых поручений

type AccountSmart

type AccountSmart interface {
	// стремиться достичь требуемую позицию используя лимитированные заявки с ценой на минимальный шаг лучше текущей лучшей цены
	DoPosition(ctx context.Context, bot Bot, instrument Instrument, targetPosition int64) TargetPosition
	// стремиться достичь требуемую позицию используя лимитированные заявки с ценой на priceIncriment лучше текущей лучшей цены
	DoPositionExtended(ctx context.Context, bot Bot, instrument Instrument, targetPosition int64, priceIncriment big.Decimal) TargetPosition
	// отправляет лимитированную заявку с ценой на priceIncriment лучше текущей лучшей цены
	PostOrderWithBestPrice(ctx context.Context, instrument Instrument, quantity int64, priceIncriment big.Decimal) (Order, error)
}

функции, позволяющие писать робота в парадигме "сейчас нужна позиция XXX", вместо нужно выставить сделку

type Bot

type Bot interface {
	Start() error             // вызывается при старте робота. Отличное место чтобы подписатсья на рыночную информацию
	Stop() error              // вызывается при остановки робота. Отличное место чтобы отписаться от рыночной информации, закрыть позиции.
	Context() context.Context // контекст робота, именно от него происходит взаимодействие с tinkoff api
	Name() string             // имя робота, желательно читаемое и уникальное. Активно используется в качестве меток метрик
}

интерфейс, который должны реализовывать роботы

type BotConfig

type BotConfig struct {
	Name       string         // имя робота
	Account    Account        // счёт, на котором робот будет торгавать
	Instrument Instrument     // инструмент, которым робот будет торгавать
	Values     map[string]any // произвольные параметры робота
}

настройки для робота

func NewConfig

func NewConfig(name string, account Account, instrument Instrument, values map[string]any) *BotConfig

func (*BotConfig) GetAny

func (c *BotConfig) GetAny(key string) any

func (*BotConfig) GetDurationOrDie

func (c *BotConfig) GetDurationOrDie(key string) time.Duration

func (*BotConfig) GetIntOrDie

func (c *BotConfig) GetIntOrDie(key string) int

func (*BotConfig) GetStringOrDie

func (c *BotConfig) GetStringOrDie(key string) string

type Bots

type Bots []Bot

тип для роботы с массивами роботов

func (Bots) StartAll

func (bs Bots) StartAll() error

func (Bots) StopAll

func (bs Bots) StopAll() (result error)

type CandleChan

type CandleChan chan *techan.Candle

канал получения информации о изменении свечей

type Candles

type Candles interface {
	GetFigi() string
	GetPeriod() time.Duration
	GetSeries() *techan.TimeSeries
	Load(ctx context.Context, from time.Time, to time.Time) error
	Subscribe() (candleChan CandleChan, err error)
	Unsubscribe(candleChan CandleChan) error
}

интерфейс работы со свечами

type Client

type Client interface {
	// получить параметры инструмента и рыночные данные о торгах
	// на каждый вызов, для одного и того же figi будет возвращён один и тот же объект
	GetInstrument(figi string) Instrument
	// текущее время
	// например, если считаем свечку закрытой, через 10 секунд после наступления нового периода,
	// или если заявку по плохой цене держим ещё в течении минуты
	// то, оринтироваться надо именно на это время, т.к. в режиме тестирования на истории время time.Now() будет возвращять не то, что ожидает робот
	Now() time.Time
	// если в процессе торговли робот выводи сообщения, то их выводить следует через данную функцию,
	// т.к. в зависимости от режима торгов, назначение вывода может меняться. Например, при тестировании на истории, вывод робота игнорируется
	Printf(format string, arg ...any) (n int, err error)
}

Корневой элемент, через который робот может получить информацию об окружающем мире

type EngineType

type EngineType int32

Тип счёта.

const (
	EngineType_UNSPECIFIED EngineType = iota // значение не определено
	EngineType_HISTORICAL  EngineType = iota // счёт для тестирования на истории
	EngineType_SANDBOX     EngineType = iota // счёт для песочницы
	EngineType_REAL        EngineType = iota // боевой счёт
)

type Instrument

type Instrument interface {
	GetCandles(period time.Duration) Candles                           // Получить интерфейс дл работы со свечами указанного периода
	GetFigi() string                                                   // Figi-идентификатор инструмента.
	GetExchange() string                                               // Торговая площадка.
	GetClassCode() string                                              // Класс-код (секция торгов).
	GetIsin() string                                                   // Isin-идентификатор инструмента.
	GetLot() int32                                                     //Количество в лоте
	GetTicker() string                                                 // Тикер  инструмента.
	GetCurrency() string                                               // Валюта расчётов.
	GetName() string                                                   // Название инструмента.
	GetLastPrices(ctx context.Context) ([]*LastPrice, error)           // Получить массив последних цен инструмента
	GetOrderBook(ctx context.Context, depth int32) (*OrderBook, error) // Получить стакан инструмента
	GetMinPriceIncrement() big.Decimal                                 // Шаг цены.
	IsStatus(tradingStatus ...proto.SecurityTradingStatus) bool        // Проверяет, является ли статус инструмента, любым из указанных в аргументах
	IsLimitOrderAvailable() bool                                       // Можно ли выставлять лимитные заявки по данному инструменту
	IsMarketOrderAvailable() bool                                      // Можно ли выставлять рыночные заявки по данному инструменту
	Now() time.Time                                                    // Текущее (для тестирования на истории)
}

получение информации по инструменту

type LastPrice

type LastPrice struct {
	Figi  string      //Идентификатор инструмента.
	Price big.Decimal //Последняя цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.
	Time  time.Time   //Время получения последней цены в часовом поясе UTC по времени биржи.
}

Информация о цене.

func NewLastPrice

func NewLastPrice(figi string, price big.Decimal, time time.Time) *LastPrice

type Money

type Money struct {
	Currency string      // строковый ISO-код валюты
	Value    big.Decimal // сумма
}

func NewMoney

func NewMoney(mv *proto.MoneyValue) *Money

type Order

type Order interface {
	GetFigi() string                                            //Идентификатор инструмента.
	GetExecutionReportStatus() proto.OrderExecutionReportStatus //Текущий статус заявки.
	GetDirection() proto.OrderDirection                         //Направление сделки.
	GetLotsRequested() int64                                    //Запрошено лотов.
	GetLotsExecuted() int64                                     //Исполнено лотов.
	GetOrderId() string                                         // Идентификатор заявки
	GetOrderDate() time.Time                                    //Дата и время выставления заявки в часовом поясе UTC.
	GetInitialOrderPrice() *Money                               //Начальная цена заявки. Произведение количества запрошенных лотов на цену.
	Cancel(ctx context.Context) (time.Time, error)              // Отменить заявку
	IsActive() bool                                             // Является ли заявка активной
	IsBestInOrderBook(ctx context.Context) bool                 // Является ли заявка лучшей в стакане
}

информация о торговом поручении

type OrderBook

type OrderBook struct {
	Figi       string           //Figi-идентификатор инструмента.
	Depth      int32            //Глубина стакана.
	Bids       []OrderBookOrder //Множество пар значений на покупку.
	Asks       []OrderBookOrder //Множество пар значений на продажу.
	LastPrice  big.Decimal      //Цена последней сделки за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.
	ClosePrice big.Decimal      //Цена закрытия за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.
	LimitUp    big.Decimal      //Верхний лимит цены за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.
	LimitDown  big.Decimal      //Нижний лимит цены за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.
}

Информация о стакане.

func NewOrderBook

func NewOrderBook(ob *proto.GetOrderBookResponse) *OrderBook

type OrderBookOrder

type OrderBookOrder struct {
	Price    big.Decimal //Цена за 1 инструмент. Для получения стоимости лота требуется умножить на лотность инструмента.
	Quantity int64       //Количество в лотах.
}

информация о заявке

func NewOrderBookOrders

func NewOrderBookOrders(orders []*proto.Order) []OrderBookOrder

type Position

type Position interface {
	GetFigi() string   //Figi-идентификатор.
	GetBlocked() int64 //Заблокировано.
	GetBalance() int64 //Текущий незаблокированный баланс.
}

Баланс позиции

type Positions

type Positions struct {
	Money                   []*Money            //Массив валютных позиций портфеля.
	Blocked                 []*Money            //Массив заблокированных валютных позиций портфеля.
	Positions               map[string]Position //Список позиций портфеля (обединяет ценно-бумажные и фьючерсы). Ключ figi.
	LimitsLoadingInProgress bool                //Признак идущей в данный момент выгрузки лимитов.
}

Портфель по счёту.

type TargetPosition

type TargetPosition interface {
	Error() string
	GetError() error
	IsLimitError() bool
}

объект возвращаемый DoPosition, который сообщает о статусе достежения требуемой позиции, и об ошибках, если они были

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL