# 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 ` - `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 ``` ## Структура проекта ``` 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