TraderStack
Инструмент помогающий писать торговые стратегии используя визуальный редактор.
Работает на API ТИНЬКОФФ Инвестиций
Инструкция по запуску
appName - traderstack
-
Сборка docker image (не обязательно. Образ опубликован на Docker Hub)
git clone https://github.com/liderman/traderstack.git
cd traderstack
docker build -t "liderman/traderstack:latest" .
-
Запустите приложение
(!) ВАЖНО: не забудьте заменить ТОКЕН_ПЕСОЧНИЦЫ
и БОЕВОЙ_ТОКЕН
на свои.
Если вы переживаете указывать боевой токен, то можете указать вместо него токен
песочницы, НО в таком режиме будут выставляться ордера только в режиме тестирования стека,
а в режиме работы стратегии будут ошибки.
docker run --rm -p9000:8080 \
--name traderstack \
-e TS_BROKER_SANDBOX_API_TOKEN=ТОКЕН_ПЕСОЧНИЦЫ \
-e TS_BROKER_API_TOKEN=БОЕВОЙ_ТОКЕН \
liderman/traderstack
-
Откройте TraderStack в браузере: http://127.0.0.1:9000/
-
Создайте свой первый Стек
Стеки > Создать стек
Введите название Стратегия RSI
и нажмите Создать...
-
Используя панель инструментов создайте следующий сценарий
$figi : FigiByTicker(TCS)
$lowerRsiThreshold : Integer(30)
$takeProfit : Decimal(15)
$stopLoss : Decimal(5)
$lots : Integer(1)
$rsi : RSI($figi, 14)
$signalBuy : <=($rsi, $lowerRsiThreshold)
$lotsProfile : PortfolioLots($figi)
$buyResult : ActionBuyMarket($signalBuy, $figi, $lots)
$takeProfitResult : ActionTakeProfit($figi, $takeProfit)
$stopLossResult : ActionStopLoss($figi, $stopLoss)
-
Нажмите Сохранить
и нажмите Тест
, чтобы протестировать Стек.
В окне Протестировать стек
выберите Дату и время
за которую
подгрузятся данные и счёт (песочницы).
Если счёта нет, то не беда, зайдите Песочница > Счета > Создать счёт
.
Там же можно и пополнить его.
-
Настало время превратить Стек в Стратегию.
Откройте Стратегии > Создать стратегию
и заполните поля:
- Аккаунт (тут уже реальный аккаунт на бирже)
- Стек -
Стратегия RSI
- Периодичность запуска -
86400
(будет запускаться раз в сутки, но можно указать любое другое число)
- Стратегия - переключите во
Включено
Нажмите Сохранить
-
Отслеживайте результаты стратегии
В карточке стратегии Логи > Обновить
- отобразятся логи.
В логах можно увидеть запуски, ошибки, попытки исполнения действий
Features
- 100% визуальное создание стратегии
- Поддержка функций управления песочницей
- Встроенный инструмент тестирования и отладки стратегии в песочнице на исторических данных
- Автоматическая торговля по расписанию
- Создание заявок на реальной бирже с гибкими проверками
- Возможность легко добавлять новые блоки (без правки frontend)
Описание встроенных функций
Индикаторы
RSI(figi string, period integer) -> decimal
- рассчитывает RSI для указанного инструмента и периода
Селекторы
FigiByTicker(figi string) -> string
- ищет по тикеру, figi или названию компании и возвращает figi
Получение информации
InOrdersBuyMarketLots(figi string) -> integer
- возвращает количество лотов для всех открытых рыночных заявок на покупку для инструмента
InOrdersSellMarketLots(figi string) -> integer
- возвращает количество лотов для всех открытых рыночных заявок на продажу для инструмента
PortfolioLots(figi string) -> integer
- вернёт количество лотов инструмента в портфеле
Действия
ActionSellMarket(condition boolean, figi string, lots integer) -> boolean
- в зависимости от условия выставляет рыночную заявку на продажу с указанным количеством лотов. Учитывает время работы биржи и возможность исполнения заявки
ActionBuyMarket(condition boolean, figi string, lots integer) -> boolean
- в зависимости от условия выставляет рыночную заявку на покупку с указанным количеством лотов. Учитывает время работы биржи и возможность исполнения заявки
ActionStopLoss(figi string, percent decimal) -> boolean
- если цена актива упадёт на заданный %, то выставит рыночную заявку на продажу. Учитывает время работы биржи и наличие позиций
ActionTakeProfit(figi string, percent decimal) -> boolean
- если цена актива вырастет на заданный %, то выставит рыночную заявку на продажу. Учитывает время работы биржи и наличие позиций
Переменные
Boolean(value boolean) -> boolean
- устанавливает и возвращает переменную boolean
Integer(value integer) -> integer
- устанавливает и возвращает переменную integer
Decimal(value decimal) -> decimal
- устанавливает и возвращает переменную decimal
String(value string) -> string
- устанавливает и возвращает переменную string
Условия
>=(left numeric, right numeric) -> boolean
- условие, что left >= right
<=(left numeric, right numeric) -> boolean
- условие, что left <= right
==(left numeric, right numeric) -> boolean
- условие, что left равно right
!=(left numeric, right numeric) -> boolean
- условие, что left НЕ равно right
Математические
-(left numeric, right numeric) -> numeric
- вычитание: left - right
+(left numeric, right numeric) -> numeric
- сложение: left + right
*(left numeric, right numeric) -> numeric
- умножение: left * right
/(left numeric, right numeric) -> numeric
- деление: left / right
abs(value numeric) -> numeric
- абсолютное число без знака
mod(value numeric) -> numeric
- остаток от деления двух заданных значений
round(value numeric, places integer) -> numeric
- округление до целого с заданной точностью
Технологии
- backend - golang 1.18 (взаимодействует с брокером и предоставляет API управления стратегиями для frontend)
- frontend - nodejs (v16.15.0) - сборка, JavaScript (Vue, Vuetify) - UI для браузера
- транспорт backend<-->frontend - gRPC Web
- контейнеризация - Docker
Ограничения
- автор не несёт ответственности за работу TraderStack и возможные убытки. Все действия вы делаете на свой страх и риск
ActionSellMarket
и ActionBuyMarket
не проверяют наличия открытых заявок и наличие бумаги в портфеле (предполагается, что это будет учтено в алгоритме)
- данные нигде не сохраняются. После перезапуска приложения всё будет забыто
Для разработчиков
Полезные утилиты и настройка окружения
Перегенерация gRPC-клиентов Tinkoff на основе proto-фалов:
docker run --rm -v $PWD/internal/grpc:/data namely/protoc-all \
-i /data/proto/tinkoff/investapi -d /data/proto/tinkoff/investapi -o /data/gen/tinkoff/investapi -l go
Перегенерация gRPC-сервера:
docker run --rm -v "$(pwd)/internal/grpcsrv:/work" uber/prototool:latest prototool generate
cp -R ./internal/grpcsrv/gen/js/ ./web/grpc/gen/js/
Запуск линтера .proto фалов:
docker run --rm -v "$(pwd)/internal/grpcsrv:/work" uber/prototool:latest prototool lint
Перегенерация моков:
go generate ./...
Запуск в режиме разработки:
cd cmd/traderstack
go build
./traderstack --use-dev-proxy
cd web
yarn
yarn dev
Dev URL: http://127.0.0.1:8080/
Как реализовать новую функцию?
-
в директории internal/stackfuncs
создайте файл функции реализующий интерфейс StackFuncRun
-
зарегистрируйте функцию в StackFuncRepository
(cmd/traderstack/main.go
)
Например, так:
sfr := engine.NewStackFuncRepository()
sfr.Register(stackfuncs.NewMyFunc())
Все функции выполняющие действия на бирже должны иметь префикс Action
в имени
Testing
Unit-tests:
go test -v -race ./...
CONTRIBUTE
- write code
- run
go fmt ./...
- run
docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.46.2 golangci-lint run -v
- run all linters and tests (see above)
- create a PR describing the changes
LICENSE
Apache License 2.0
MAINTAINER
Konstantin Osipov