mirror of
https://github.com/ada-dmitry/etf-gyro.git
synced 2026-09-23 23:20:15 +00:00
169 lines
6.6 KiB
Markdown
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
|