etf-gyro
Бот для автоматического ребалансирования инвестиционного портфеля через API T-Invest (Т-Инвестиции).
Бот рассчитан на балансировку ETF-портфеля (т.е. с использованием паевых фондов для гибкости долей), но при большом портфеле можно использовать и для иных фин. инструментов.
Возможности
- Расчёт текущих долей активов и сравнение с целевыми весами
- Автоматическое планирование покупок и продаж при отклонении от цели
- Коридор допустимого отклонения — мелкие расхождения игнорируются
- Автоматическая продажа активов, не входящих в конфиг
- Распределение избытка рублёвого кэша пропорционально целевым весам
- Режим dry-run — расчёт плана без реальных сделок
- Уведомления в Telegram с отчётом по каждому запуску
Требования
- Python 3.13+
- Токен T-Invest API
- Telegram-бот
Установка
git clone https://github.com/ada-dmitry/etf-gyro.git
cd etf-gyro
pip install -r requirements.txt
Или через uv:
uv sync
Конфигурация
Скопируй .env.example в .env и заполни:
TINVEST_TOKEN=t.your_token_here
TINVEST_ACCOUNT_ID=your_account_id
TELEGRAM_BOT_TOKEN=your_telegram_bot_token
TELEGRAM_USER_ID=your_telegram_user_id
- TINVEST_TOKEN — токен T-Invest API: Настройки → Токены
- TINVEST_ACCOUNT_ID — ID счёта; узнать через
python tools/get_instrument.py accounts - TELEGRAM_BOT_TOKEN — создать бота через @BotFather
- TELEGRAM_USER_ID — узнать через @userinfobot
Настройка портфеля
Отредактируй config/target.yaml:
portfolio:
TMOS@:
name: "Крупнейшие компании РФ"
figi: "TCS60A101X76"
uid: "f509af83-6e71-462f-901f-bcb073f6773b"
weight: 0.98
RUB:
name: "Рублевый кэш"
figi: "RUB000UTSTOM"
uid: "a92e2e25-a698-45cc-a781-167cf465257c"
weight: 0.02
corridor: 0.02
uid— уникальный идентификатор инструмента в T-Invest; найти черезtools/get_instrument.py yaml <ticker>weight— целевая доля (0.0–1.0); сумма всех весов должна быть ≈ 1.0corridor— порог отклонения, ниже которого сделка не создаётся (0.02 = 2%)RUB— специальный тикер для кэша; избыток сверхweightавтоматически распределяется по остальным активам
Запуск
Утилиту можно запускать локально, если хочется контроля над операциями (сначала прогнать на dry-run, а потом уже на реальных сделках).
# Dry-run — только расчёт плана, без реальных сделок
DRY_RUN_OVERRIDE=true python main.py
# С реальными сделками (по умолчанию)
python main.py
Автоматизация через cron
Для запуска на сервере (VPS, HomeLab и др.) задание в crontab:
crontab -e
# Ребалансировка каждый понедельник в 10:30
30 10 * * 1 cd /path/to/etf-gyro && /path/to/uv run main.py >> /var/log/gyro.log 2>&1
Пути к uv и проекту — абсолютные, иначе cron не найдёт их в своём окружении. Узнать путь к uv: which uv.
Переменные окружения cron не наследует из шелла, поэтому .env файл должен быть заполнен — скрипт читает его через python-dotenv.
Проверить, что задание отработало:
tail -f /var/log/gyro.log
Автоматизация через GitHub Actions
Если своего сервера нет или хочется держать на стабильной инфраструктуре, то можно использовать GitHub Actions.
Воркфлоу .github/workflows/rebalance.yml запускает ребалансировку каждый понедельник в 10:30 МСК.
Добавь в настройках репозитория → Settings → Environments окружение tinvest и пропиши секреты:
TINVEST_TOKEN
TINVEST_ACCOUNT_ID
TELEGRAM_BOT_TOKEN
TELEGRAM_USER_ID
Запуск вручную доступен через Actions → Weekly Portfolio Rebalance → Run workflow, с возможностью включить режим симуляции.
Утилита поиска инструментов
tools/get_instrument.py — CLI для работы с T-Invest API без запуска основного бота:
# Список счетов и их ID
python tools/get_instrument.py accounts
# Поиск инструмента по тикеру, ISIN или названию
python tools/get_instrument.py search TMOS@
python tools/get_instrument.py search "Тинькофф" -n 5
# Готовый сниппет для вставки в config/target.yaml
python tools/get_instrument.py yaml TMOS@
# Текущие позиции портфеля с долями и стоимостью
python tools/get_instrument.py portfolio
python tools/get_instrument.py portfolio --account <id>
Структура проекта
etf-gyro/
├── main.py # Точка входа
├── config/
│ └── target.yaml # Целевые веса активов и коридор
├── app/
│ ├── load_config.py # Загрузка конфига из YAML
│ ├── notifier.py # Telegram-уведомления
│ └── rebalance.py # Логика ребалансирования
└── tools/
└── get_instrument.py # CLI: search / yaml / accounts / portfolio
Лицензия
MIT