Files

169 lines
6.6 KiB
Markdown

# etf-gyro
Бот для автоматического ребалансирования инвестиционного портфеля через API T-Invest (Т-Инвестиции).
Бот рассчитан на балансировку ETF-портфеля (т.е. с использованием паевых фондов для гибкости долей), но при большом портфеле можно использовать и для иных фин. инструментов.
## Возможности
- Расчёт текущих долей активов и сравнение с целевыми весами
- Автоматическое планирование покупок и продаж при отклонении от цели
- Коридор допустимого отклонения — мелкие расхождения игнорируются
- Автоматическая продажа активов, не входящих в конфиг
- Распределение избытка рублёвого кэша пропорционально целевым весам
- Режим dry-run — расчёт плана без реальных сделок
- Уведомления в Telegram с отчётом по каждому запуску
## Требования
- Python 3.13+
- Токен T-Invest API
- Telegram-бот
## Установка
```bash
git clone https://github.com/ada-dmitry/etf-gyro.git
cd etf-gyro
pip install -r requirements.txt
```
Или через `uv`:
```bash
uv sync
```
## Конфигурация
Скопируй `.env.example` в `.env` и заполни:
```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: [Настройки → Токены](https://www.tbank.ru/invest/settings/)
- **TINVEST_ACCOUNT_ID** — ID счёта; узнать через `python tools/get_instrument.py accounts`
- **TELEGRAM_BOT_TOKEN** — создать бота через [@BotFather](https://t.me/botfather)
- **TELEGRAM_USER_ID** — узнать через [@userinfobot](https://t.me/userinfobot)
## Настройка портфеля
Отредактируй `config/target.yaml`:
```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.0
- `corridor` — порог отклонения, ниже которого сделка не создаётся (0.02 = 2%)
- `RUB` — специальный тикер для кэша; избыток сверх `weight` автоматически распределяется по остальным активам
## Запуск
Утилиту можно запускать локально, если хочется контроля над операциями (сначала прогнать на dry-run, а потом уже на реальных сделках).
```bash
# Dry-run — только расчёт плана, без реальных сделок
DRY_RUN_OVERRIDE=true python main.py
# С реальными сделками (по умолчанию)
python main.py
```
## Автоматизация через cron
Для запуска на сервере (VPS, HomeLab и др.) задание в crontab:
```bash
crontab -e
```
```cron
# Ребалансировка каждый понедельник в 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`.
Проверить, что задание отработало:
```bash
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 без запуска основного бота:
```bash
# Список счетов и их 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