16 KiB
DCA Bot для Tinkoff Invest
Автоматический бот для реализации стратегии Dollar Cost Averaging (DCA) через API Tinkoff Invest. Поддерживает работу с акциями, ETF, облигациями и валютами на реальном брокерском счете.
Обновление
Т-Банк обновил свой SDK для работы с биржей, видимо из-за блока на PyPy. Теперь для использования, надо заменить tinvest на t_tech.
Особенность
Бот спокойно работает с акциями, ETF, облигациями и валютами, но лучше всего себя показывает с ETF, т.к. имеет меньшую цену за пай, что позволяет более гибко регулировать объемы инвестирования в разные инструменты.
Что это такое?
DCA (Dollar Cost Averaging) — это инвестиционная стратегия, при которой вы регулярно покупаете финансовые инструменты на фиксированную сумму, независимо от их текущей цены. Это помогает снизить влияние волатильности рынка на общую стоимость инвестиций.
Требования
- Python 3.8+
- Реальный брокерский счет в Tinkoff
- API токен с правами на торговлю
Установка
- Клонируйте репозиторий:
git clone https://github.com/ada-dmitry/t_tech-gyro.git
cd dca_bot
- Установите зависимости:
Рекомендуется использование виртуального окружения Python.
pip install -r requirements.txt
- Скопируйте файл с переменными окружения:
cp .env.example .env
- Заполните
.envфайл:
TINKOFF_TOKEN="ваш_токен"
TINKOFF_ACCOUNT_ID="ваш_id_счета" # опционально
Настройка
Создайте файл конфигурации config.yml со списком инструментов и их весами:
assets:
- figi: "BBG004730N88" # Сбербанк
weight: 0.3 # 30%
- figi: "BBG00475KKY8" # Яндекс
weight: 0.2 # 20%
- figi: "BBG333333333" # ОФЗ
weight: 0.3 # 30%
- figi: "BBG444444444" # Доллар США
weight: 0.2 # 20%
Важно: Сумма весов должна равняться 1.0!
Использование
Основная команда
python main.py --config config.yml --rub-budget 10000
Режим симуляции (тестирование)
python main.py --config config.yml --rub-budget 10000 --dry-run
Расписание и ежедневный запуск
Бот теперь предполагает ежедневный запуск в фиксированное время (через cron/Systemd и т.п.) и сам решает, исполнять ли сделки сегодня.
Правила:
- В конфиге задаёте портфель, а день месяца указываете ключом
--day-of-month(по умолчанию 5). - Если запланированный день выпадает на выходной, а флаг
--allow-weekendне передан — сделки автоматически переносятся на ближайший понедельник. - Во все остальные дни бот просто завершает работу и пишет в лог статус
SKIPPED_NOT_SCHEDULED_TODAY(expected=YYYY-MM-DD).
Пример ежедневного cron на 10:00:
0 10 * * * cd /path/to/dca_bot && python main.py --config config.yml --rub-budget 10000 --day-of-month 5
Чтобы разрешить сделки в выходные именно в запланированный день:
0 10 * * * cd /path/to/dca_bot && python main.py --config config.yml --rub-budget 10000 --day-of-month 5 --allow-weekend
Дополнительные параметры
python main.py \
--config config.yml \
--rub-budget 10000 \
--dry-run \
--fee-buf-bps 300 \
--safe-rub-pct 0.97 \
--wait-tradable-sec 60 \
--poll-sec 10 \
--allow-weekend
Параметры:
--config— путь к YAML файлу конфигурации (обязательно)--rub-budget— общий бюджет в рублях для данного запуска (обязательно)--dry-run— режим симуляции, реальные ордера не размещаются--fee-buf-bps— буфер для комиссий в базисных пунктах (по умолчанию 300 = 3%)--safe-rub-pct— использовать только N% от доступных средств (по умолчанию 0.97 = 97%)--wait-tradable-sec— ждать до N секунд пока инструмент станет торгуемым (по умолчанию 0)--poll-sec— интервал проверки торгового статуса в секундах (по умолчанию 10)--allow-weekend— разрешить размещать ордера в субботу/воскресенье. По умолчанию при запуске в выходные бот фиксирует отложенные сделки в CSV со статусомDEFERRED_TO_MONDAY(<дата>)и завершает работу без размещения ордеров.--day-of-month— день месяца (1..28), в который бот должен исполнять сделки. Если выпадает на выходной и не указан--allow-weekend, сделки переносятся на ближайший понедельник. В остальные дни бот завершает работу со статусомSKIPPED_NOT_SCHEDULED_TODAY.
Вспомогательные инструменты
В папке tools/ находятся полезные утилиты для работы с API Tinkoff Invest:
1. Проверка баланса (check_balance.py)
python tools/check_balance.py
Назначение: Показывает текущее состояние вашего брокерского счета.
Что показывает:
- ID активного счета
- Свободные рубли (RUB free)
- Заблокированные рубли (RUB blocked)
- Доступные для торговли рубли (RUB available)
- Общая оценка портфеля в валютах (если доступно)
Пример вывода:
ACCOUNT_ID: 2235046505
RUB free: 25000.00
RUB blocked: 1500.00
RUB available: 23500.00
Portfolio total_amount_currencies: 150000.50
Когда использовать:
- Перед запуском DCA бота для проверки достаточности средств
- Для мониторинга состояния счета
- При отладке проблем с размещением ордеров
2. Проверка инструментов (check_figi.py)
python tools/check_figi.py
Назначение: Проверяет корректность FIGI из вашей конфигурации и получает актуальные рыночные данные.
Настройка: Отредактируйте список FIGI в начале файла, добавив ваши FIGI из config.yml:
FIGI = [
"BBG004730N88", # Сбербанк
"BBG00475KKY8", # Яндекс
"BBG0013HGFT4", # USD000UTSTOM
# добавьте ваши FIGI здесь
]
Что показывает:
- Информацию об инструменте (тикер, название, размер лота, валюта)
- Текущие рыночные цены
- Список инструментов без доступных цен
Пример вывода:
BBG004730N88: SBER | ПАО Сбербанк | lot=10 | curr=rub
BBG00475KKY8: YNDX | Яндекс Н.В. | lot=1 | curr=rub
PRICE BBG004730N88: 285.50
PRICE BBG00475KKY8: 2850.00
Нет last price для: []
Когда использовать:
- При настройке нового
config.yml - Для проверки актуальности FIGI перед запуском
- При отладке проблем с получением цен
3. Поиск инструментов (search.py)
python tools/search.py
Назначение: Помогает найти FIGI для нужных финансовых инструментов по тикеру или названию.
Текущие поисковые запросы в скрипте:
- Поиск золота по тикеру "TGLD@"
- Поиск ОФЗ 26212 по названию
- Поиск ETF "TPAY"
- Поиск основных валют (USD, EUR, GBP, JPY)
Как настроить под свои нужды:
- Поиск по тикеру акции:
shares = client.instruments.shares()
for s in shares.instruments:
if s.ticker == "SBER": # замените на нужный тикер
print(s.ticker, s.figi, s.name)
- Поиск облигаций по названию:
bonds = client.instruments.bonds()
for b in bonds.instruments:
if "Сбербанк" in b.name: # замените на нужное название
print(b.name, b.figi)
- Поиск ETF:
etfs = client.instruments.etfs()
for e in etfs.instruments:
if "TECH" in e.ticker: # замените на нужный тикер
print(e.ticker, e.figi, e.name)
- Поиск валют:
currencies = client.instruments.currencies()
for cur in currencies.instruments:
if "USD" in (cur.ticker or ""):
print(cur.ticker, cur.figi, cur.name)
Пример вывода:
TGLD@ BBG222222222 Золото
ОФЗ 26212 BBG00Y91R9T3 ОФЗ 26212
TPAY BBG111111111 TCS Payments
USD000UTSTOM BBG0013HGFT4 Доллар США
Когда использовать:
- При составлении нового портфеля
- Для поиска альтернативных инструментов
- При обновлении FIGI (например, для новых выпусков ОФЗ)
Полезные советы по работе с инструментами
-
Всегда проверяйте FIGI перед добавлением в конфигурацию с помощью
check_figi.py -
Для облигаций FIGI может изменяться при новых выпусках, регулярно обновляйте
-
Валютные пары имеют разные FIGI для разных сроков поставки (TOM, TOD, SPOT)
-
ETF и фонды могут иметь ограничения по времени торговли
-
Используйте поиск для нахождения похожих инструментов в той же отрасли
Автоматизация проверок
Можно создать скрипт для автоматической проверки перед запуском DCA:
#!/bin/bash
echo "=== Проверка баланса ==="
python tools/check_balance.py
echo -e "\n=== Проверка инструментов ==="
python tools/check_figi.py
echo -e "\n=== Запуск DCA (dry-run) ==="
python main.py --config config.yml --rub-budget 10000 --dry-run
Логирование
Все операции записываются в файл orders_log.csv со следующими полями:
ts— временная меткаperiod_key— ключ периода (YYYY-MM)figi— FIGI инструментаticker— тикерname— название инструментаinstrument_type— тип (share, bond, etf, currency)lots— количество лотовlot_size— размер лотаfilled_price_per_share— цена исполнения за бумагуcost_rub— общая стоимость в рубляхstatus— статус операцииorder_request_id— ID запроса (если не dry-run)
Особенности работы
Облигации
Для облигаций автоматически рассчитывается полная стоимость с учетом номинала и накопленного купонного дохода (НКД).
Защита от ошибок
- Автоматическое уменьшение размера ордера при ошибке 30042 (недостаток средств)
- Проверка торгового статуса инструментов
- Пропуск неторгуемых инструментов
- Буферы для комиссий и проскальзывания
Валюты
Поддерживаются только инструменты в рублях. Валютные инструменты пропускаются.
Безопасность
- Никогда не коммитьте
.envфайл — он содержит секретные токены - Используйте токены только с необходимыми правами
- Тестируйте конфигурацию в режиме
--dry-run - Проверяйте баланс перед запуском
Получение токена
- Перейдите в личный кабинет Tinkoff Invest
- Настройки → API → Создать токен
- Выберите права: "Торговля" и "Чтение счетов"
- Скопируйте токен в
.envфайл
Автоматизация
Для регулярного запуска можно использовать cron:
# Ежедневно в 10:00 (бот сам решит исполнять ли сделки сегодня)
0 10 * * * cd /path/to/dca_bot && python main.py --config config.yml --rub-budget 10000 --day-of-month 5
Структура проекта
dca_bot/
├── main.py # Основной скрипт
├── config.yml # Конфигурация портфеля (создать самостоятельно)
├── requirements.txt # Зависимости Python
├── .env # Переменные окружения (создать из .env.example)
├── .env.example # Шаблон переменных окружения
├── orders_log.csv # Лог операций (создается автоматически)
├── tools/
│ ├── check_balance.py # Проверка баланса
│ ├── check_figi.py # Проверка инструментов
│ └── search.py # Поиск инструментов
└── README.md # Этот файл
Лицензия
MIT License
Отказ от ответственности
Этот бот предоставляется "как есть" без каких-либо гарантий. Автор не несет ответственности за возможные финансовые потери. Используйте на свой страх и риск. Всегда тестируйте в режиме --dry-run перед реальной торговлей.