# DCA Bot для Tinkoff Invest Автоматический бот для реализации стратегии Dollar Cost Averaging (DCA) через API Tinkoff Invest. Поддерживает работу с акциями, ETF, облигациями и валютами на реальном брокерском счете. ## Что это такое? DCA (Dollar Cost Averaging) — это инвестиционная стратегия, при которой вы регулярно покупаете финансовые инструменты на фиксированную сумму, независимо от их текущей цены. Это помогает снизить влияние волатильности рынка на общую стоимость инвестиций. ## Основные возможности - ✅ Автоматическое распределение бюджета по заданным весам между инструментами - ✅ Поддержка акций, ETF, облигаций и валют - ✅ Корректный расчет стоимости облигаций (номинал + НКД) - ✅ Проверка торгового статуса инструментов - ✅ Защита от ошибок недостатка средств с автоматическим уменьшением размера ордера - ✅ Детальное логирование всех операций в CSV - ✅ Режим симуляции (dry-run) для тестирования - ✅ Буферы для комиссий и проскальзывания - ✅ Работа только с реальными счетами (без песочницы) ## Требования - Python 3.8+ - Реальный брокерский счет в Tinkoff - API токен с правами на торговлю ## Установка 1. Клонируйте репозиторий: ```bash git clone cd dca_bot ``` 2. Установите зависимости: > Рекомендуется использование виртуального окружения Python. ```bash pip install -r requirements.txt ``` 3. Скопируйте файл с переменными окружения: ```bash cp .env.example .env ``` 4. Заполните `.env` файл: ```env TINKOFF_TOKEN="ваш_токен" TINKOFF_ACCOUNT_ID="ваш_id_счета" # опционально ``` ## Настройка Создайте файл конфигурации `config.yml` со списком инструментов и их весами: ```yaml 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! ## Использование ### Основная команда ```bash python main.py --config config.yml --rub-budget 10000 ``` ### Режим симуляции (тестирование) ```bash 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: ```bash 0 10 * * * cd /path/to/dca_bot && python main.py --config config.yml --rub-budget 10000 --day-of-month 5 ``` Чтобы разрешить сделки в выходные именно в запланированный день: ```bash 0 10 * * * cd /path/to/dca_bot && python main.py --config config.yml --rub-budget 10000 --day-of-month 5 --allow-weekend ``` ### Дополнительные параметры ```bash 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`) ```bash 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`) ```bash python tools/check_figi.py ``` **Назначение:** Проверяет корректность FIGI из вашей конфигурации и получает актуальные рыночные данные. **Настройка:** Отредактируйте список `FIGI` в начале файла, добавив ваши FIGI из `config.yml`: ```python 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`) ```bash python tools/search.py ``` **Назначение:** Помогает найти FIGI для нужных финансовых инструментов по тикеру или названию. **Текущие поисковые запросы в скрипте:** - Поиск золота по тикеру "TGLD@" - Поиск ОФЗ 26212 по названию - Поиск ETF "TPAY" - Поиск основных валют (USD, EUR, GBP, JPY) **Как настроить под свои нужды:** 1. **Поиск по тикеру акции:** ```python shares = client.instruments.shares() for s in shares.instruments: if s.ticker == "SBER": # замените на нужный тикер print(s.ticker, s.figi, s.name) ``` 2. **Поиск облигаций по названию:** ```python bonds = client.instruments.bonds() for b in bonds.instruments: if "Сбербанк" in b.name: # замените на нужное название print(b.name, b.figi) ``` 3. **Поиск ETF:** ```python etfs = client.instruments.etfs() for e in etfs.instruments: if "TECH" in e.ticker: # замените на нужный тикер print(e.ticker, e.figi, e.name) ``` 4. **Поиск валют:** ```python 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 (например, для новых выпусков ОФЗ) ### Полезные советы по работе с инструментами 1. **Всегда проверяйте FIGI** перед добавлением в конфигурацию с помощью `check_figi.py` 2. **Для облигаций** FIGI может изменяться при новых выпусках, регулярно обновляйте 3. **Валютные пары** имеют разные FIGI для разных сроков поставки (TOM, TOD, SPOT) 4. **ETF и фонды** могут иметь ограничения по времени торговли 5. **Используйте поиск** для нахождения похожих инструментов в той же отрасли ### Автоматизация проверок Можно создать скрипт для автоматической проверки перед запуском DCA: ```bash #!/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 (недостаток средств) - Проверка торгового статуса инструментов - Пропуск неторгуемых инструментов - Буферы для комиссий и проскальзывания ### Валюты Поддерживаются только инструменты в рублях. Валютные инструменты пропускаются. ## Безопасность 1. **Никогда не коммитьте `.env` файл** — он содержит секретные токены 2. **Используйте токены только с необходимыми правами** 3. **Тестируйте конфигурацию в режиме `--dry-run`** 4. **Проверяйте баланс перед запуском** ## Получение токена 1. Перейдите в [личный кабинет Tinkoff Invest](https://www.tinkoff.ru/invest/) 2. Настройки → API → Создать токен 3. Выберите права: "Торговля" и "Чтение счетов" 4. Скопируйте токен в `.env` файл ## Автоматизация Для регулярного запуска можно использовать cron: ```bash # Ежедневно в 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` перед реальной торговлей.