Skip to content

Локальный сервер для тестирования торговых роботов на Tinkoff Invest API

Notifications You must be signed in to change notification settings

vitalets/tinkoff-local-broker

Repository files navigation

tinkoff-local-broker

Локальный сервер для тестирования торговых роботов на Tinkoff Invest API. Предоставляет полностью идентичное API и позволяет быстро прогнать любую стратегию на исторических данных.

Идея

Идея проекта - сделать "локальную" биржу, которая отвечает по 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):

// сам конфиг
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 (остальные поля не важны):

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.

Разработка

Запуск сервера из исходников:

npm start

Запуск тестов:

npm t

Релиз новой версии:

./scripts/release.sh latest
# или
./scripts/release.sh x.x

Планы

Сейчас на стороне робота приходится после каждого тика выставлять дату. Хочется придумать способ, чтобы этого не делать, а сервер рассчитывал смещение автоматически.

Связанные проекты

Лицензия

MIT @ Vitaliy Potapov

About

Локальный сервер для тестирования торговых роботов на Tinkoff Invest API

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published

Languages