Files
etf-gyro/README.md
T

6.6 KiB

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.0
  • corridor — порог отклонения, ниже которого сделка не создаётся (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