https://github.com/vitalets/tinkoff-local-broker
Локальный сервер для тестирования торговых роботов на Tinkoff Invest API
https://github.com/vitalets/tinkoff-local-broker
tinkoff tinkoff-invest
Last synced: 5 months ago
JSON representation
Локальный сервер для тестирования торговых роботов на Tinkoff Invest API
- Host: GitHub
- URL: https://github.com/vitalets/tinkoff-local-broker
- Owner: vitalets
- Created: 2022-05-23T17:55:30.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-05-23T19:00:53.000Z (over 3 years ago)
- Last Synced: 2025-03-31T13:04:23.009Z (7 months ago)
- Topics: tinkoff, tinkoff-invest
- Language: TypeScript
- Homepage:
- Size: 111 KB
- Stars: 9
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
![]()
tinkoff-local-broker
Локальный сервер для тестирования торговых роботов на [Tinkoff Invest API](https://tinkoff.github.io/investAPI/).
Предоставляет полностью идентичное API и позволяет быстро прогнать любую стратегию на исторических данных.- [Идея](#%D0%B8%D0%B4%D0%B5%D1%8F)
- [Что умеет сервер](#%D1%87%D1%82%D0%BE-%D1%83%D0%BC%D0%B5%D0%B5%D1%82-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80)
- [Запуск сервера](#%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D0%BA-%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80%D0%B0)
- [Конфигурация](#%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B0%D1%86%D0%B8%D1%8F)
- [Tick](#tick)
- [Примеры](#%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B)
- [Разработка](#%D1%80%D0%B0%D0%B7%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0)
- [Планы](#%D0%BF%D0%BB%D0%B0%D0%BD%D1%8B)
- [Связанные проекты](#%D1%81%D0%B2%D1%8F%D0%B7%D0%B0%D0%BD%D0%BD%D1%8B%D0%B5-%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D1%8B)
- [Лицензия](#%D0%BB%D0%B8%D1%86%D0%B5%D0%BD%D0%B7%D0%B8%D1%8F)## Идея
Идея проекта - сделать "локальную" биржу, которая отвечает по Tinkoff Invest API.
Подменив в роботе API эндпойнт, можно полноценно его тестировать на истории свечей в условиях приближённых к боевым.
При этом язык программирования робота может быть любой.Процесс выглядит так:
1. Вы локально запускаете сервер, который в точности повторяет API Тинькоф инвестиций
2. Передаете URL этого сервера в свой код вместо настоящего API
3. Конфигурируете сервер: задать шаг и диапазон дат для итерации
4. В цикле вызываете у сервера метод `tick()`. На каждом вызове сервер возвращает новую актуальную дату, а также обрабатывает все заявки и позиции в портфеле
5. После завершения цикла рассчитывается прибыльность стратегии## Что умеет сервер
По сути все то же самое, что делает реальный брокер при взаимодействии с ним через API:* автоматическая загрузка и кеширование свечей
* прием и исполнение заявок (лимитных и рыночных)
* корректная блокировка средств и расчет баланса
* списание комиссий
* обновление позиций в портфеле
* ведение списка операций
* расчет прибыли
* отправка событий в стрим## Запуск сервера
Запустить сервер удобнее всего через докер:
```
docker run --init --rm \
-p 8080:8080 \
-v $(pwd)/.cache:/app/.cache \
-e 'DEBUG=tinkoff-local-broker:*' \
vitalets/tinkoff-local-broker
```
После скачивания образа и запуска API Тинькофф доступно локально по адресу: `localhost:8080`.
Передав этот адрес вместо боевого API, вы сможете тестировать вашего робота.## Конфигурация
Перед каждым прогоном на исторических данных сервер необходимо сконфигурировать: задать шаг для свечей и диапазон дат, по которому будет проходить итерация.
Чтобы не добавлять новых методов в API, конфигурация сделана через отправку специальной заявки методом `postOrder()`.
Нужно указать в поле `accountId=config`, а сам конфиг положить в поле `figi` (остальные поля не важны).Пример - прогон по минутным свечам за 29 апреля (js):
```js
// сам конфиг
const config = {
/** Интервал свечей / шаг */
candleInterval: CandleInterval.CANDLE_INTERVAL_1_MIN,
/** Стартовая дата бэктестинга */
from: '2022-04-29T10:00:00+03:00',
/** Конечная дата бэктестинга */
to: '2022-04-29T19:00:00+03:00',
/** Начальный капитал */
initialCapital: 100000,
/** Комиссия брокера, % от суммы сделки */
brokerFee: 0.3,
};// отправка специальной заявки с конфигом
api.orders.postOrder({
accountId: 'config',
figi: JSON.stringify(config),
quantity: 0,
direction: 0,
orderType: 0,
orderId: '',
});
```
После этого сревер готов к итерациям.## Tick
При каждом тике сервер перемещает текущую дату и выполняет все действия с заявками.
В ответе приходит новая дата, которую необходимо использовать во всех запросах как текущую.
Вызов тика происходит также с помощью специальной заявки со значением `accountId=tick` (остальные поля не важны):
```js
const order = await api.orders.postOrder({
accountId: 'tick',
figi: '',
quantity: 0,
direction: 0,
orderType: 0,
orderId: '',
});if (order.message) {
// в order.message лежит дата текущей свечи. ее необходимо использовать как текущую для запросов
} else {
// если в message пусто, значит все свечи пройдены, пора считать прибыль :)
}
```
Удобно завернуть вызов тика в функцию, тогда сам цикл выглядит примерно так:
```
// конфигурацияwhile (tick()) {
// вызвать код робота
}// расчет прибыли
```## Примеры
Полный пример тестирования робота можно посмотреть в папке [examples](/examples).## Разработка
Запуск сервера из исходников:
```
npm start
```Запуск тестов:
```
npm t
```Релиз новой версии:
```bash
./scripts/release.sh latest
# или
./scripts/release.sh x.x
```## Планы
Сейчас на стороне робота приходится после каждого тика выставлять дату.
Хочется придумать способ, чтобы этого не делать, а сервер рассчитывал смещение автоматически.## Связанные проекты
* [tinkoff-invest-api](https://github.com/vitalets/tinkoff-invest-api) - Node.js клиент для работы с Tinkoff Invest API.## Лицензия
MIT @ [Vitaliy Potapov](https://github.com/vitalets)