Автоматическая ребалансировка портфеля ETF: как мы написали бота для Тинькофф Инвестиций
Автоматическая ребалансировка портфеля: бот следит за целевыми весами и торгует вместо вас.
Допустим, у вас есть портфель из четырёх ETF: TMOS, TBRU, TRUR и кэш в рублях. По 25% на каждый. Рынок вырос — TMOS стал 32%, а TBRU просел до 18%. Классическая теория говорит: продай то, что выросло, купи то, что просело. Ребалансировка.
Проблема в том, что делать это руками — мучительно. Особенно если аккаунтов несколько, стратегия включает маржу, а ребалансировать нужно каждый час. Мы написали бота, который делает это автоматически.
TIEBB (Tinkoff Invest ETF Balancer Bot) — open-source бот на TypeScript, который подключается к API Тинькофф Инвестиций и автоматически поддерживает целевую аллокацию портфеля. Четыре режима балансировки, маржинальная торговля, мульти-аккаунт, dry-run для тестирования.
Кратко
- Open-source (Apache 2.0) бот для автоматической ребалансировки ETF-портфеля
- 4 режима балансировки: ручной, по рыночной капитализации, по AUM, декорреляционный
- Маржинальная торговля до 4x с риск-менеджментом
- Мульти-аккаунт: неограниченное количество счетов с индивидуальными настройками
- TypeScript + Bun — быстро, типизированно, без боли
- Dry-run режим — считает ордера, но не исполняет
Зачем вообще нужна ребалансировка

Идея простая: вы определяете целевые доли активов в портфеле (например, 25% TMOS, 25% TBRU, 25% TRUR, 25% RUB). Со временем рынок двигается, и реальные доли отклоняются от целевых. Ребалансировка — это возврат к целевым весам путём продажи того, что выросло, и покупки того, что просело.
Зачем это нужно:
- Контроль риска — если один актив разрастается до 60% портфеля, вы зависите от одного инструмента
- Систематическая фиксация прибыли — вы автоматически продаёте то, что выросло
- Покупка на просадках — автоматически докупаете просевшие активы
- Дисциплина — никаких эмоций, только алгоритм
Проблема — делать это вручную утомительно. Особенно если:
- У вас несколько счетов
- Ребалансировка нужна каждый час (не раз в квартал)
- Стратегия включает маржинальную торговлю
- Нужно учитывать лоты, минимальные суммы и время работы биржи
Как работает бот
Основной цикл
1. Проверяем, открыта ли MOEX
2. Получаем текущие позиции и цены
3. Рассчитываем желаемую аллокацию (4 режима)
4. Генерируем ордера: продажи, потом покупки
5. Исполняем рыночными ордерами
6. Ждём BALANCE_INTERVAL и повторяем
Бот работает в бесконечном цикле. Интервал настраивается — от минуты до суток. По умолчанию — час.
Четыре режима балансировки

1. Ручной (manual)
Самый простой. Вы задаёте веса вручную:
{
"desired_wallet": {
"TMOS": 25,
"TBRU": 25,
"TRUR": 25,
"RUB": 25
}
}
Бот нормализует проценты до 100% и поддерживает эти доли.
2. По рыночной капитализации (marketcap)
Веса пропорциональны рыночной капитализации каждого фонда. Логика: чем крупнее фонд, тем больше его доля. Данные берутся с сайта T-Bank и investfunds.ru.
3. По объёму активов под управлением (aum)
Веса пропорциональны AUM (Assets Under Management) каждого фонда. Данные с t-capital-funds.ru. Отражает популярность фонда среди инвесторов.
4. Декорреляционный (decorrelation)
Самый интересный. Формула:
decorrelationPct = (marketCap - AUM) / AUM * 100
metric = max_decorrelationPct - individual_decorrelationPct
weight = metric / sum(metrics) * 100
Идея: находим инструменты, где рыночная капитализация отличается от AUM, и балансируем между этими метриками. Если рынок оценивает фонд выше, чем объём вложений в него — это сигнал.
Генерация ордеров
Бот умный: сначала продаёт, потом покупает. Это важно, потому что:
- Продажа высвобождает средства для покупки
- Не нужен запас кэша на счёте
- Работает даже при нулевом свободном остатке
Все инструменты торгуются лотами. Бот конвертирует целевую сумму в рубли → в количество лотов → округляет → генерирует ордер.
Продвинутые фичи
Маржинальная торговля

{
"margin_trading": {
"enabled": true,
"multiplier": 2,
"free_threshold": 5000,
"max_margin_size": 50000,
"balancing_strategy": "keep_if_small"
}
}
Бот поддерживает плечо до 4x. Три стратегии управления маржой:
- keep — держим маржинальные позиции всегда
- remove — закрываем маржу к концу торгового дня
- keep_if_small — держим, если размер маржи меньше порога
Бот сам определяет, что скоро закрытие биржи (18:45 МСК), и применяет стратегию автоматически. Учитывает комиссию за перенос (1% от позиции свыше 5000 руб.).
Мульти-аккаунт
Один CONFIG.json — неограниченное количество счетов. У каждого свои:
- Токен API
- Целевая аллокация
- Режим балансировки
- Интервал ребалансировки
- Настройки маржи
{
"accounts": [
{
"id": "main_broker",
"name": "Основной брокерский",
"desired_wallet": { "TMOS": 50, "TBRU": 50 },
"balance_interval": 3600000
},
{
"id": "iis_account",
"name": "ИИС",
"desired_wallet": { "TRUR": 100 },
"balance_interval": 86400000
}
]
}
Минимальный порог прибыли
{
"min_profit_percent_for_close_position": 5
}
Не продавать позицию, если прибыль меньше 5%. Или наоборот — установить -2 как стоп-лосс (максимальный убыток 2%).
Dry-run режим
{
"exchange_closure_behavior": {
"mode": "dry_run",
"update_iteration_result": true
}
}
Бот рассчитывает все ордера, логирует их, но не отправляет на биржу. Идеально для тестирования стратегии.
Diff-based корректировка
{
"diff": "iteration",
"diff_multiplier": 50
}
Веса корректируются на основе изменений с последней ребалансировки (или с начала дня). Multiplier от 0 до 100 определяет силу влияния.
Стек и архитектура
| Компонент | Технология |
|---|---|
| Runtime | Bun 1.0+ (или Node.js 18+) |
| Язык | TypeScript |
| API | Tinkoff Invest gRPC (tinkoff-sdk-grpc-js) |
| Конфигурация | CONFIG.json + .env |
| Метрики | Puppeteer (скрапинг MarketCap, AUM) |
Почему Bun? В 20-30 раз быстрее Node.js на старте, нативная поддержка TypeScript, встроенный тест-раннер. Для бота, который запускается и работает в цикле, это менее критично — но для разработки Bun удобнее.
Архитектура модульная:
- Provider — общение с API, управление портфелем
- Balancer — алгоритм ребалансировки (4 режима)
- OrderManager — генерация и исполнение ордеров
- MarginCalculator — расчёт маржи и рисков
- Tools — скрапинг метрик, сбор данных
Быстрый старт
curl -fsSL https://bun.sh/install | bash
git clone https://github.com/suenot/tinkoff-invest-etf-balancer-bot.git
cd tinkoff-invest-etf-balancer-bot
bun install
cp .env-example .env
cp CONFIG.example.json CONFIG.json
bun run start # Нормальный режим
bun run dev # С отладкой
bun run dev -- --once # Одна итерация
Утилиты для управления:
bun run accounts # Список доступных счетов
bun run config list # Все аккаунты в конфиге
bun run config validate # Проверка конфига
Ограничения и дисклеймер
- Работает только с рублёвыми акциями и фондами. Другие инструменты на счёте — не трогать.
- Это бета-версия. Модели не гарантируют прибыль.
- Вы несёте полную ответственность за результаты торговли.
- Рекомендуем начать с dry-run режима.
Попробуйте
- Исходный код: github.com/suenot/tinkoff-invest-etf-balancer-bot
- Лицензия: Apache 2.0
- Конкурс: участвует в Tinkoff Invest Robot Contest
Ссылки:
- GitHub: github.com/suenot/tinkoff-invest-etf-balancer-bot
- Tinkoff Invest API: invest-api.tinkoff.ru
Цитирование
@software{soloviov2026etfbalancer,
author = {Soloviov, Eugen},
title = {Автоматическая ребалансировка портфеля ETF: бот для Тинькофф Инвестиций},
year = {2026},
url = {https://marketmaker.cc/ru/blog/post/etf-balancer-bot-tinkoff},
description = {Open-source бот на TypeScript для автоматической ребалансировки ETF-портфеля в Тинькофф Инвестициях.}
}
MarketMaker.cc Team
Количественные исследования и стратегии