Closed Jolids closed 1 year ago
Добрый день! Спасибо за интересный кейс!
То, что вы описали в задаче больше похоже на небольшой пользовательский торговый сценарий, не стоит его включать в базовое АПИ из-за специфичности. Давайте мы попробуем реализовать его отдельно, используя уже имеющиеся методы, в виде скрипта с небольшим количеством параметров (токены, список инструментов, периодичность захода на рынок и т.п.). Так как торговых операций тут не будет, только анализ и оповещение, то скрипт получится довольно коротким.
Например, для быстрого и качественного поиска аномалий хорошо себя зарекомендовал метод Хампеля. Для этого в задачах #112 #113 #114 (фича сборка: pip install TKSBrokerAPI==1.6.dev139
) уже реализованы методы HampelFilter()
(который умеет фильтровать ряд чисел), и HampelAnomalyDetection()
(который возвращает индекс первого локального максимума или аномальное значение чисел в ряду). Примеры можно посмотреть в юпитер-ноутбуке: https://nbviewer.org/github/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/HampelFilteringExample.ipynb
(Комментарий для меня, чтобы не забыть). На первый взгляд, первый пункт задачи можно будет сделать примерно так:
...
ordersBook = GetCurrentPrices(show=False) # TKSBrokerAPI: https://tim55667757.github.io/TKSBrokerAPI/docs/tksbrokerapi/TKSBrokerAPI.html#TinkoffBrokerServer.GetCurrentPrices
volumesOfSellers = [v["quantity"] for v in ordersBook ["buy"]] # Числовой ряд с объёмами предложений продавцов по возрастанию цены
volumesOfBuyers = [v["quantity"] for v in ordersBook ["sell"]] # Числовой ряд с объёмами предложений покупателей по убыванию цены
# Ищем индекс первой аномалии или локальный максимум среди предложений продавцов в стакане:
firstAnomalyIndexSellers = HampelAnomalyDetection(series=volumesOfSellers, window=len(volumesOfSellers))
# Ищем индекс первой аномалии или локальный максимум среди предложений покупателей в стакане:
firstAnomalyIndexBuyers = HampelAnomalyDetection(series=volumesOfBuyers , window=len(volumesOfBuyers))
...
Но возможно, что придется искать все аномалии и выводить их списком, используя HampelFilter()
, а не только первый элемент.
Спасибо большое за очень развернутый ответ. Выпуск скачал tksbrokerapi 1.6.dev139 Вообще меня очень удивил очень крутой подход. Никогда не видел чтоб так грамотно и много писали по данной теме! Проект пока не использовал - только изучаю как настроить все.
Прям респект!
😊 Спасибо! Мы с нашей небольшой командой старались! Если будут вопросы по конкретным методам или консольным командам, которые непонятно или неполно написаны в документации - задавайте тут, в разделе Issues, постараемся расширять примеры.
Сейчас готовится к выпуску релиз 1.6.* с большим числом новых интересных функций и команд. Документация по тестовым версиям 1.6.dev*** также обновляется с каждой новой фича-сборкой: https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/README.md и со временем войдет в релиз.
У меня вопрос - Реализовать новый пример сценария: выявлять аномальные объемы покупателей/продавцов в стакане и отправлять TG-уведомления А как это будет реализовано? То-есть отдельным сценарием? Например, я хочу наблюдать только за аномальными покупками без трейдинга, чтоб самостоятельно принимать решения о покупке. И как поднять данную функцию в приоритет? сколько это может стоить? (можно написать сюда telegram @vstred) Спасибо.
Вопрос прям очень интересует.
Добрый вечер! :) Вообще, та часть опенсорсного проекта, который выставлен сюда наружу в открытый доступ, пока что развивается за счёт поддержки и донатов всех желающих :)
На основе платформы TKSBrokerAPI мы также разрабатываем сценарии и фичи на заказ. В вашем сценарии некоторая дополнительная разработка, конечно же, потребуется.
"Отдельным сценарием" я имел в виду, что на выходе получится примерно такой скрипт, как мы приводили в примере торгового сценария (с параметризацией, документацией и подробными комментариями к коду): https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/scenario1a.py
Только в вашем случае, скрипт будет аналитический, без торговых условий и шагов. Такой скрипт можно запускать самостоятельно в консоли. Можно дополнительно настроить расписание, чтобы запустить один раз и не трогать, а дальше "оно само работает и шлёт оповещения".
Я думал заняться задачей в течение февраля (поэтому и написал комментарии для себя, чтобы не забыть потом). Но если вам срочно нужно, я напишу вам в телеграмм завтра, в течение дня, созвонимся, обсудим детали и ожидания.
Но если вам срочно нужно, я напишу вам в телеграмм завтра, в течение дня, созвонимся, обсудим детали и ожидания. Да. Спасибо. Буду ждать. И спасибо за развернутый комментарий.
Ожидания от скрипта-сценария
Кратко: наблюдаем за объёмами покупателей и продавцов в стакане, ищем аномалии в числовом ряду объёмов, оповещаем в ТГ. В оповещении должны присутствовать текущие цены и цены с аномальными объёмами.
Скрипт аналитический, без торговых условий и шагов, для самостоятельного запуска в консоли.
Основные шаги:
Скрипт выходит на рынок по расписанию (например, в формате crontab:timeToWork: "*/2 10-21 * * 1-5" # С 10:00 утра до 22:00 вечера (включительно) в будние дни, каждые 2 минуты
(см. другие примеры).
В параллельном (мультипроцессном) режиме запрашивает данные по состоянию биржевого стакана по указанным инструментам и указанной глубины стакана (depth <= 50
).
Для каждого стакана ищет все текущие аномалии в объёмах продавцов и покупателей (фильтрация методом Хампеля по всей длине текущего стакана).
Если список аномалий по инструменту получился не пустой, то сформировать читаемую табличку с оповещением, например, вида:
Обнаружены аномальные объёмы!
Тикер: [TMOS]
Инструмент: [Shares] [Тинькофф iMOEX]
Дата и время: [2023-01-18 15:55:51 UTC]
Текущая цена / объём / стоимость в стакане:
Аномалии среди предложений продавцов, цена / объём / стоимость:
Аномалии среди предложений покупателей, цена / объём / стоимость:
Подключиться к указанному ТГ-боту по токену и отправить через него сформированное оповещение.
Дополнительно потребуется:
Промежуточные итоги:
config.yaml
(для основных параметров) и secrets.yaml
(для локального хранения секретов и учёток). Их можно не указывать при запуске, если используются эти стандартные имена, либо указать полный путь к ним, если используются учётки для различных пользователей.ConfigDecorator()
— обёртка (декоратор) для загрузки файлов конфигурации и секретов, управления временем запуска итераций по расписанию, для однократного запуска или в бесконечном режиме, а также для параметризации менеджера;
ConfigDecorator()
загружает настройки из файлов конфигурации, проверяет количество доступных для распараллеливания запросов CPU, проверяет рабочее ли сейчас время (согласно настройкам crontab) и однократно или в бесконечном режиме запускает менеджер.TradeManager()
— менеджер для инициализации, запуска и управления параллельными конвейерами, на которых будет исполняться анализ состояния стакана для конкретного набора тикеров;
TradeManager()
инициализирует репортер (экземпляр класса TinkoffBrokerServer()
для генерации отчётов), однократно обновляет кеш по инструментам и получает портфель пользователя, чтобы они не обновлялись на каждом конвейере лишний раз, запускает итерацию по всем тикерам, разбивает их на наборы и каждый набор отправляет на свой конвейер.Сейчас запуск выглядит примерно так (нужно указать в secrets.yaml
как минимум, userAccount
и userToken
):
% python3 TKSAVDetector.py config.yaml secrets.yaml
TKSAVDetector.py L:91 DEBUG [2023-01-22 18:48:58,943] Real available Host CPU count: 8
TKSAVDetector.py L:92 DEBUG [2023-01-22 18:48:58,943] How many CPUs will be used for parallel computing: 7
TKSAVDetector.py L:93 INFO [2023-01-22 18:48:58,943] TKSAVDetector just started. Crontab: [*/2 10-21 * * 1-5]. Waiting for the next working period...
TKSAVDetector.py L:134 WARNING [2023-01-22 18:48:58,943] TKSAVDetector launches one time during non-working period! Crontab: [*/2 10-21 * * 1-5]
TKSAVDetector.py L:179 DEBUG [2023-01-22 18:48:58,943] --- Scenario runs: [John Doe] [**********] [My-test-account] [TKSAVDetector]
TKSBrokerAPI.py L:159 DEBUG [2023-01-22 18:48:58,943] Bearer token for Tinkoff OpenAPI set up from class variable `token`
TKSBrokerAPI.py L:171 DEBUG [2023-01-22 18:48:58,943] Main account ID [**********] set up from class variable `accountId`
TKSBrokerAPI.py L:223 DEBUG [2023-01-22 18:48:58,947] Broker API server: https://invest-public-api.tinkoff.ru/rest
TKSBrokerAPI.py L:399 DEBUG [2023-01-22 18:48:59,024] Local cache with raw instruments data is used: [dump.json]. Last modified: [2023-01-22 14:28:07] UTC
TKSBrokerAPI.py L:1777 DEBUG [2023-01-22 18:48:59,024] Requesting portfolio of a client. Wait, please...
TKSBrokerAPI.py L:1604 DEBUG [2023-01-22 18:48:59,024] Requesting current actual user's portfolio. Wait, please...
TKSBrokerAPI.py L:1629 DEBUG [2023-01-22 18:48:59,310] Requesting current open positions in currencies and instruments. Wait, please...
TKSBrokerAPI.py L:1654 DEBUG [2023-01-22 18:48:59,411] Requesting current actual pending limit orders. Wait, please...
TKSBrokerAPI.py L:1662 DEBUG [2023-01-22 18:48:59,529] [0] records about pending limit orders received
TKSBrokerAPI.py L:1684 DEBUG [2023-01-22 18:48:59,529] Requesting current actual stop orders. Wait, please...
TKSBrokerAPI.py L:1692 DEBUG [2023-01-22 18:48:59,652] [0] records about stop orders received
TKSAVDetector.py L:195 DEBUG [2023-01-22 18:48:59,655] Split list of tickers: [['YNDX'], ['VKCO'], ['GAZP'], ['MTSS'], ['PIKK'], ['ROSN'], ['SBER', 'TCSG', 'TRUR', 'TMOS', 'TBRU']]
TKSAVDetector.py L:199 DEBUG [2023-01-22 18:48:59,655] ... DO SOME TRADE JOBS WITH ALL TICKERS ...
TKSAVDetector.py L:231 DEBUG [2023-01-22 18:48:59,655] --- Operations completed for all instruments: [John Doe] [**********] [My-test-account] [TKSAVDetector]
Далее в разработке обёртка для конвейера, на котором будет выполняться набор тикеров и класс TradeScenario()
, который реализует и запускает отдельные шаги для операций с инструментами (подключение к аккаунту, скачивание стакана, анализ стакана на аномалии и т.п.).
Промежуточные итоги (в дополнение к предыдущим):
_IWrapper()
и IRunner()
) для конвейера, на котором будет выполняться набор тикеров. Обертка используется для параметризации каждого инстанса класса торгового сценария.TradeScenario(TinkoffBrokerServer)
, который запускает отдельные шаги для операций с инструментами (подключение к аккаунту, скачивание стакана, анализ стакана на аномалии и т.п.)._UpdateOrderBook()
класса, который умеет получать данные с биржи и расчитывать некоторые параметры объёмов.Run()
класса, который является его основным раннером. Именно его нужно запускать для выполнения сценария по заданному набору инструментов.Сейчас скрипт умеет выполнять приблизительно такую последовательность действий:
config.yaml
и secrets.yaml
";CPU - 1
;Run()
класса TradeScenario(TinkoffBrokerServer)
, для параллельной и одновременной работы конвейеров, каждого со своим набором тикеров;% python3 TKSAVDetector.py config.yaml secrets.yaml
TKSAVDetector.py L:268 DEBUG [2023-01-25 19:27:58,195] Real available Host CPU count: 8
TKSAVDetector.py L:269 DEBUG [2023-01-25 19:27:58,195] How many CPUs will be used for parallel computing: 7
TKSAVDetector.py L:270 INFO [2023-01-25 19:27:58,195] TKSAVDetector just started. Crontab: [*/2 10-21 * * 1-5]. Waiting for the next working period...
TKSAVDetector.py L:311 WARNING [2023-01-25 19:27:58,195] TKSAVDetector launches one time during non-working period! Crontab: [*/2 10-21 * * 1-5]
TKSAVDetector.py L:356 DEBUG [2023-01-25 19:27:58,195] --- Scenario runs: [John Doe] [My-test-account] [TKSAVDetector]
... SKIPPED ...
TKSBrokerAPI.py L:151 DEBUG [2023-01-25 19:27:58,908] Bearer token for Tinkoff OpenAPI set up from environment variable `TKS_API_TOKEN`. See https://tinkoff.github.io/investAPI/token/
TKSBrokerAPI.py L:164 DEBUG [2023-01-25 19:27:58,908] Main account ID [**********] set up from environment variable `TKS_ACCOUNT_ID`
TKSBrokerAPI.py L:223 DEBUG [2023-01-25 19:27:58,909] Broker API server: https://invest-public-api.tinkoff.ru/rest
TKSBrokerAPI.py L:399 DEBUG [2023-01-25 19:27:58,959] Local cache with raw instruments data is used: [/Users/tim/projects/TKSBrokerAPI/docs/examples/AnomalyVolumesDetector/dump.json]. Last modified: [2023-01-25 13:43:06] UTC
... SKIPPED ...
TKSAVDetector.py L:118 DEBUG [2023-01-25 19:27:58,960] Pipeline [1]: init completed
TKSAVDetector.py L:118 DEBUG [2023-01-25 19:27:58,991] Pipeline [2]: init completed
TKSAVDetector.py L:118 DEBUG [2023-01-25 19:27:59,019] Pipeline [3]: init completed
TKSAVDetector.py L:118 DEBUG [2023-01-25 19:27:59,047] Pipeline [4]: init completed
TKSAVDetector.py L:118 DEBUG [2023-01-25 19:27:59,074] Pipeline [5]: init completed
TKSAVDetector.py L:118 DEBUG [2023-01-25 19:27:59,099] Pipeline [6]: init completed
TKSAVDetector.py L:118 DEBUG [2023-01-25 19:27:59,126] Pipeline [7]: init completed
TKSAVDetector.py L:395 INFO [2023-01-25 19:27:59,126] [John Doe] [My-test-account] [TKSAVDetector] All pipelines initialized, count: [7], tickers for trading:
[1]: ['YNDX']
[2]: ['VKCO']
[3]: ['GAZP']
[4]: ['MTSS']
[5]: ['PIKK']
[6]: ['ROSN']
[7]: ['SBER', 'TCSG', 'TRUR', 'TMOS', 'TBRU']
TKSAVDetector.py L:186 DEBUG [2023-01-25 19:27:59,128] [1] [John Doe] [**********] [My-test-account] [TKSAVDetector] Processing tickers list: ['YNDX']
TKSAVDetector.py L:198 DEBUG [2023-01-25 19:27:59,128] [1] [John Doe] [**********] [My-test-account] [TKSAVDetector] [YNDX] ticker processing...
TKSBrokerAPI.py L:1199 DEBUG [2023-01-25 19:27:59,128] Requesting current prices: ticker [YNDX], FIGI [BBG006L8G4H1]. Wait, please...
... SKIPPED ...
TKSAVDetector.py L:144 DEBUG [2023-01-25 19:27:59,247] [YNDX] Orders book was received success, see `self._ordersBook` variable:
TKSAVDetector.py L:145 DEBUG [2023-01-25 19:27:59,247] - Current price / volume / value in the order book:
TKSAVDetector.py L:146 DEBUG [2023-01-25 19:27:59,247] - Buy (1st seller price): 1909.8 / 11 / 21007.80 rub
TKSAVDetector.py L:147 DEBUG [2023-01-25 19:27:59,247] - Sell (1st buyer price): 1909.6 / 130 / 248248.00 rub
TKSAVDetector.py L:148 DEBUG [2023-01-25 19:27:59,247] - Sum of all volumes in the order book (depth = 20):
TKSAVDetector.py L:149 DEBUG [2023-01-25 19:27:59,247] - Buyers: 2280
TKSAVDetector.py L:150 DEBUG [2023-01-25 19:27:59,247] - Sellers: 3879
TKSAVDetector.py L:221 INFO [2023-01-25 19:27:59,247] [1] [John Doe] [**********] [My-test-account] [TKSAVDetector] [YNDX] [success] All trade steps were finished success
TKSAVDetector.py L:230 DEBUG [2023-01-25 19:27:59,247] [1] [John Doe] [**********] [My-test-account] [TKSAVDetector] [YNDX] ticker processed
... SKIPPED ...
TKSAVDetector.py L:406 DEBUG [2023-01-25 19:27:59,739] --- Operations completed for all instruments: [John Doe] [My-test-account] [TKSAVDetector]
Дорабатывается: метод Steps()
класса TradeScenario(TinkoffBrokerServer)
, в котором будут выполняться шаги анализа объёмов на аномалии, формирование оповещения и отправка через бота.
Промежуточные итоги (в дополнение к предыдущим):
Разработан метод Steps()
класса TradeScenario(TinkoffBrokerServer)
, в котором выполняются шаги:
Добавлены шаблоны (EN_TEMPLATE
и RU_TEMPLATE
) и свёрстаны сообщения о найденных аномалиях на двух языках. Добавлен переключатель языка в конфиг: msgLanguage: "en"
(можно указать "en" / "ru").
Разработан метод _CreateMessage()
, который форматирует шаблоны информацией об аномалиях.
В консольных логах это выглядит так:
Осталось:
Финальные итоги (в дополнение к предыдущим):
Добавлена настройка размера скользящего окна для поиска аномалий методом Хампеля. Можно использовать переменную windowHampel
в файле конфигурации config.yaml
(рекомендуется: 0 <= windowHampel <= depth
). Если параметр равен 0, то используется автоматически подбираемая ширина окна по фактической длине полученных данных об объёмах.
Подготовлена документация с инструкциями по работе с ботом и подробно прокомментирован каждый параметр в файлах конфигурации config.yaml
и secrets.yaml
.
Реализован метод _TGSender()
для отправки сформированных сообщений о найденных аномалиях через Телеграм бот. Подготовлены шаблоны для оповещений на русском и английском языках: RU_TEMPLATE
и EN_TEMPLATE
. Оповещения в Телеграм чате с ботом выглядят так:
In english | На русском |
---|---|
Добавил в инструкцию описание, что делать с ошибками импорта: https://github.com/Tim55667757/TKSBrokerAPI/blob/develop/docs/examples/AnomalyVolumesDetector/README.md#Запуск-бота
Копия:
Возможно, что после запуска бота вы увидите ошибку импорта такого вида:
File "./tksbrokerapi/TKSBrokerAPI.py", line 105, in <module>
from Templates import * # Some html-templates used by reporting methods in TKSBrokerAPI module
ModuleNotFoundError: No module named 'Templates'
Это означает, что каталог с библиотеками для той версии Python, куда была установлена платформа TKSBrokerAPI, не виден в системном окружении. Нужно добавить его в переменную окружения PYTHONPATH
(смотрите объяснение и примеры для разных ОС по ссылке). Например, под Linux/MacOS:
export PYTHONPATH=/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/tksbrokerapi
echo $PYTHONPATH
Чтобы не устанавливать переменную PYTHONPATH
каждый раз при открытии терминала, можно установить её в системное окружение своей ОС.
Добрый день!
Добавьте пожалуйста, параметр, игнорировать объемы меньше определённой величины. Не слать информацию меньше 4 - 0000 цифр.(разрядов) С возможностью вкл/выкл. - это на ваше усмотрение.
Ps. В течении дня, смотрел, знаете, даже 4 разряда нельзя отнести к аномалии. Лучше сделать от 5.
@Jolids Добрый вечер!
В конфиг был добавлен новый параметр: volumeIgnored
. Объёмы, меньшие, либо равные этому числу будут игнорироваться и не учитываться как аномалии. Если volumeIgnored == 0
, то будут учитываться любые значения объёмов.
Скачайте обновление кода: git pull
в каталоге со скриптом.
Не слать информацию меньше 4 - 0000 цифр.(разрядов)
Чтобы этого добиться, следует установить volumeIgnored == 9999
, тогда будут учитываться только объёмы большие, чем 9999, больше 4 разрядов, то есть, начиная с 10000.
Добрый день!
Возможно добавить функционал: