мониторинг через дашборд, A/B-тесты разных стратегий, контейнеризация (Docker) +1 месяц Плагин-модуль легко стартует и останавливается внутри приложения Максимум кода переиспользует существующий data-pipeline Развитие от MVP (чёткая базовая логика) к продвинутому самообучению и мониторингу Гибкость: можно добавить дополнительные стратегии, подключить другие биржи или развернуть отдельный сервис в будущем Этот план даёт чёткую дорожную карту: от прототипа до промышленного решения, минимизируя повторную работу и сохраняя единую архитектуру с основным приложением. Удачи в воплощении! Позже эта архитектура и легла в основу платформы. Стоит отметить также, что на тот момент у меня уже была попытка разработать относительно небольшой проект. Это был скальперский скринер который следит за волатильностью и крупными плотностями по всему крипторынку на 7 биржах. По сей день он является частью логики торгового модуля и поставщиком данных. Реальный стек «под капотом» Простой веб-стек не справился бы с нагрузкой. По мере разработки, по совету ИИ, система обросла более серьезными инструментами: Numba: Для ускорения критически важных расчетов в Python, особенно в ядре контроллера. River: Библиотека для онлайн-машинного обучения. LightGBM / XGBoost: Применяются для пакетного офлайн-обучения моделей. DEAP: Фреймворк для генетических алгоритмов. Лежит в основе будущей фичи по эволюционному поиску прибыльных стратегий. Pandas-ta: Рабочая лошадка для расчета десятков технических индикаторов. Процесс разработки: реальные проблемы и постановки задач Я выступал в роли менеджера проекта, а ИИ — в роли команды разработки. Иногда я давал ему четкие ТЗ, но часто решения, порой гениальные, рождались в процессе обычного диалога. Я просто спрашивал, какие есть варианты реализации определенной фичи, и ИИ предлагал несколько вариантов, из которых я дальше уже мог выбирать, на мой взгляд, лучшее. Глубокое погружение: Создание Executor'а — сердца торгового бота Архитектура, предложенная ИИ, была логичной. Но дьявол, как всегда, в деталях. Самым сложным и критически важным компонентом в самом начале разработки стал executor.py — модуль, отвечающий за прямое взаимодействие с API биржи. Здесь не было права на ошибку, ведь он управляет реальными ордерами. Я решил отказаться от готовых библиотек типа ccxt в пользу прямой реализации на aiohttp и websockets. Почему? В предыдущем проекте (скринере) я использовал ccxt и, несмотря на все удобство, столкнулся с его ограничениями в скорости и надежности для задач, требующих минимальных задержек, как скальпинг, поэтому осознанно было принято решение писать прямую реализацию. Это позволило добиться нужной производительности и отказоустойчивости. Моя первая постановка задачи для ИИ была сфокусирована на создании полностью асинхронного класса BinanceExecutor, которому предстояло использовать aiohttp для отправки ордеров (POST /api/v3/order) и websockets для подключения к User Data Stream. Итерация №1: Наивный клиент Первая версия, сгенерированная ИИ, была простой и функциональной. Она умела подписывать REST-запросы и отправлять ордера. # Первая версия: отправка ордера async def place_order(self, symbol: str, side: str, quantity: float): endpoint = "/api/v3/order" params = { 'symbol': symbol, 'side': side.upper(), 'type': 'MARKET', 'quantity': quantity, } # (Логика подписи запроса) async with self.session.post(self.base_url + endpoint, params=params) as response: return await response.json() Проблема стала очевидна сразу: отправив ордер, мы ничего не знаем о его судьбе. Исполнился ли он? По какой цене? Делать REST-запросы каждую секунду для проверки статуса (GET /api/v3/order) — это медленно, неэффективно и быстро исчерпывает лимиты API. Для скальпинга такой подход неприемлем. Итерация №2: Добавляем WebSocket. Решение — User Data Stream. Это персональный WebSocket-канал, куда биржа в реальном времени присылает все, что происходит с вашим аккаунтом: исполнение ордеров, изменение баланса и т.д. Соответственно, я уточнил задачу для ИИ: необходимо было добавить в BinanceExecutor метод start_user_data_stream. Этот метод должен был получить listenKey через REST, подключиться к WebSocket-каналу биржи и в цикле выводить все входящие сообщения. ИИ сгенерировал рабочий код, но после нескольких минут тестов соединение обрывалось. Проблема №1: Разрыв соединения. Сеть нестабильна. Без автоматического переподключения система нежизнеспособна. Проблема №2: Истечение listenKey. Ключ для подключения к userData stream живет всего 60 минут и его нужно периодически продлевать. Итерация №3: Переподключение и Keep-Alive Пришлось снова обратиться к ИИ, описав проблемы и сформулировав детальные технические требования к надежности. Ключевые пункты моей новой задачи были следующими: Модифицировать start_user_data_stream так, чтобы основной цикл прослушивания сообщений был обернут в while True для автоматического переподключения при любом разрыве. Добавить экспоненциальную задержку между попытками переподключения (5с, 7.5с, 11с…). Создать отдельную фоновую задачу (asyncio.Task), которая каждые 30 минут будет отправлять PUT-запрос на /api/v3/userDataStream для продления жизни listenKey. Это привело к созданию гораздо более сложной, но надежной архитектуры внутри Executor. Кейс: Специфичная ошибка окружения (битва с aiodns в Windows) Когда базовая логика была готова, я столкнулся с ошибкой, которую не мог решить несколько итераций. При запуске бота на Windows он падал с ошибкой: RuntimeError: aiodns needs a SelectorEventLoop on Windows. Я скормил ИИ полный трейсбек и спросил, в чем дело. Первые несколько ответов были общими: «попробуйте обновить библиотеки», «установите другую политику asyncio». Это не помогало. Прорыв случился, когда я сформулировал для ИИ более конкретную роль и задачу. Я попросил его выступить в роли senior Python-разработчика с опытом отладки asyncio на Windows и поставил узкоспециализированный вопрос: как заставить aiohttp не использовать aiodns, а переключиться на свой стандартный потоковый DNS-резолвер, не меняя при этом глобальную политику asyncio для всего приложения? Ответ был мгновенным и точным: «Проблема в том, что aiohttp автоматически использует aiodns, если он установлен. Чтобы принудительно использовать другой резолвер, создайте TCPConnector с явно указанным ThreadedResolver и передайте его в aiohttp.ClientSession.» # Решение проблемы с aiodns from aiohttp import ThreadedResolver resolver = ThreadedResolver() connector = aiohttp.TCPConnector(resolver=resolver) session = aiohttp.ClientSession(connector=connector) Это сработало. Урок: иногда нужно не просто описывать проблему, а спрашивать у ИИ, как достичь конкретного технического результата, направляя его в нужную сторону. Финальный код: Собираем все вместе После всех итераций и исправлений, ключевая часть Executor, отвечающая за userData stream, стала выглядеть так. Этот код — результат десятков уточнений и исправлений, предложенных ИИ в ответ на мои запросы. # bot_module/executor.py class BinanceExecutor: # Честно говоря, в первой версии я вообще не понимал, # как управлять lifecycle этих задач. Пришлось гуглить и задавать вопросы про asyncio. async def _user_data_ws_listener_loop(self): """ Основной цикл, который получает listenKey, подключается к WS и обеспечивает автоматическое переподключение. """ reconnect_delay = 5 # Начальная задержка перед реконнектом while self._user_data_running: try: # 1. Получаем ключ для подключения listen_key = await self.get_listen_key() if not listen_key: logger.error(f"Failed to get listenKey, retrying in {reconnect_delay}s…") await asyncio.sleep(reconnect_delay) continue ws_url = f"{self.ws_base_url}/ws/{listen_key}" # 2. Устанавливаем WebSocket-соединение async with websockets.connect(ws_url, ping_interval=20, ping_timeout=10) as ws: self._user_data_ws = ws logger.info("User data WebSocket CONNECTED.") reconnect_delay = 5 # Сбрасываем задержку при успехе # 3. Запускаем фоновую задачу для продления ключа keepalive_task = asyncio.create_task(self._user_data_keepalive_loop(listen_key)) # 4. Слушаем входящие сообщения async for message in ws: if not self._user_data_running: break try: data = json.loads(message) # Вызываем callback, переданный из Controller'а await self._user_data_callback(data) except json.JSONDecodeError: logger.warning(f"Received non-JSON user data: {message[:200]}") # Отменяем задачу keep-alive, если вышли из цикла keepalive_task.cancel() except (ConnectionClosed, asyncio.TimeoutError, WebSocketException) as e: logger.warning(f"User data WS connection error: {e}. Reconnecting in {reconnect_delay}s…") except Exception as e: logger.error(f"Unexpected error in WS listener loop: {e}", exc_info=True) finally: self._user_data_ws = None if self._user_data_running: await asyncio.sleep(reconnect_delay) reconnect_delay = min(reconnect_delay * 1.5, 60) # Экспоненциальная задержка до 1 минуты async def _user_data_keepalive_loop(self, listen_key: str): """В фоне каждые 30-50 минут продлевает жизнь listenKey.""" while self._user_data_running: await asyncio.sleep(config.USER_DATA_PING_INTERVAL) # Ждем 30-50 минут if not self._user_data_running: break logger.info(f"Attempting to keep-alive listenKey…") await self.keep_alive_listen_key(listen_key) Выводы по разработке Executor'а Надежность превыше всего: Для торгового робота недостаточно, чтобы код просто "работал", он должен быть устойчив к сбоям сети, ошибкам API и проблемам окружения. Асинхронность не магия: Управление несколькими фоновыми задачами (слушатель, keep-alive) требует четкого понимания asyncio.Task и их жизненного цикла. ИИ мощный отладчик: При правильной постановке вопроса ИИ способен находить причину сложных и специфичных для окружения ошибок, экономя дни работы. Разработка этого компонента стала самым сложным, но и самым важным этапом создания торгового модуля в первый день. Именно здесь закладывался фундамент для стабильной и быстрой работы всего бота, позже большая часть кода была не раз переписана. Проблема №2: Генерация ядра векторного бэктестера Для реализации генетического алгоритма поиска стратегий нужно было решить проблему производительности, если запускать тысячи полноценных бэктестов, то я даже не представляю сколько времени уйдет на это. Тогда я попросил сделать быстрый бэктестер на Pandas, ИИ выдал не очень эффективный код с циклами .iterrows(). Я уточнил задачу, сформулировав более четкие требования к ядру векторного бэктестера, подчеркнув необходимость избегать циклов в пользу векторизованных операций Pandas и NumPy. Мое техническое задание выглядело так: Сгенерировать Python-класс, который принимает на вход DataFrame с колонками OHLCV и двумя boolean-колонками: 'enter_long' и 'exit_long'. Реализовать метод run() для симуляции сделок. Определять точки входа, когда 'enter_long' становится True, а позиция была закрыта. Для каждой сделки рассчитывать фиксированные SL и TP в % от цены входа. Векторизованно находить, какая из целей (SL или TP) была достигнута первой на последующих свечах. Собирать лог сделок (вход, выход, цена, pnl) и возвращать итоговые KPI. Использовать np.where, .shift(), .cumsum() и другие векторизованные методы. После нескольких итераций я получил рабочее и быстрое ядро для первичной оценки генетических стратегий. Этот модуль еще требует доработки и тестирования, но первые результаты показывают ускорение в ~100 раз по сравнению с обычным бэктестером. Это лишь пара примеров из тысяч диалогов, которые привели к созданию DepthSight, платформы, которой иначе бы не существовало. Возможно AI пишет не идеальный код, но ведь и многие люди тоже. В любом случае будущее уже наступило. То, что вчера было невозможно, — сегодня стало реальностью. Итог: Платформа, где ИИ не только инструмент разработки, а главный продукт Этот процесс привел к созданию продукта, где AI непосредственно участвует в создании и тестировании стратегий. 1. AI-Ассистент: От трейдерского жаргона до рабочего алгоритма Главная фича — парсинг сложных торговых идей, описанных на естественном языке, прямо в готовые блоки визуального редактора. Трейдер может описать свою систему так, как писал бы в блокноте. Вот реальный пример такого текстового описания, которое AI-ассистент принимает на вход: ТВХ: Набором, с добавлениями тремя-пятью частями. Первые части — вариативно: а) Первая часть в минутной/пятиминутной проторговке перед часовым или дневным максимумом, в пробой локальной проторговки, если в момент локального пробоя появляется активность в ленте; б) Первая часть в середине проторговки при наличии плотности/появления плотности на споте и фьючерсе; в) Первая часть от нижней границы проторговки. При наличии тренда и плотностей/завалов плотностей ниже. Вторая-четвёртая часть в промежуточный каскадный максимум (часовой/дневной) Третья-пятая часть в крайний максимум формации, в момент пробоя. ТП: Движение после пробоя (частичная фиксация 3-10 частями). Суть стратегии не локальный пробой, а пробой крайнего максимума. Фиксирую от 3R|5R 1/5|2/10 остаются до БУ или на выход выше первого импульса СЛ: На 1/3 за лой локальной проторговки ( до 1% в движении цены), 0.33%-0.5% от общего депозита. Есть вероятность пробоя, нужно пробовать входить. На 2/3 стоп в БУ|-0.5% от депозита. Вероятность пробоя увеличилась На 3/3 стоп в БУ|-0.3/-1% от депозита. Вероятность пробоя Вероятность пробоя увеличилась, но стоп после набора 3/3 зависит от того были ли микро-стопы до набора полной позиции. ОСНОВАНИЯ: Имеются часовые и/или дневные максимумы Наличие каскадов с 2% шагом Инструмент ликвидный (160млн+) Увеличиваются объёмы или не падают Наличие круглого, как доп. фактор Комбинированный вход с добавлением в каждый максимум Рост ОИ, как доп. фактор Есть стаканные основания (плотность в поддержку) и уровень защищается (небольшие плотности/завалы в сопротивление) Отсутствие прокидов по ленте, которые могут сильно развернуть цену Возможность выставить короткий стоп и не выбиться по АТР в минус или БУ BTC не растет и инструмент не коррелирует с поводырем. Желательно проторговка BTC в боковике или без сильной активности. BTC не начинает сильно падать и не мешает началу пробоя. На истории инструмент хорошо пробивает похожие максимумы AI-ассистент парсит этот текст и за минуту генерирует готовую структуру в визуальном редакторе, которую можно подправить руками и тут же отправить на бэктест. Генерация стратегии из текста 2. Итеративный AI-анализ: Превращаем убытки в данные После каждого бэктеста есть кнопка «Проанализировать с AI». Ассистент получает доступ ко всем сделкам и контексту, включая причины отклонения сигналов, и что немаловажно, комбинации сработавших или нет оснований, благодаря чему помогает найти неочевидные закономерности и давать рекомендации. Пример анализа от AI: «Я проанализировал твои 58 сделок. 80% убыточных позиций были открыты, когда индекс волатильности BTC был выше 75-го перцентиля. Рекомендация: Добавь фильтр, который блокирует входы, если ATR на 5-минутном графике BTC превышает X. Хочешь, я сгенерирую новую версию стратегии с этим фильтром?» 3. Взвешенные основания: Код для «трейдерской чуйки» Это наш ответ на бинарную логику «ДА/НЕТ» всех существующих конструкторов. Каждое условие для входа в сделку имеет не только переключатель, но и «вес». Плотность в стакане? Вес 30. Пробой уровня? Вес 50. Ускорение ленты? Вес 20. Вы устанавливаете «порог срабатывания», например, 70. Сигнал на вход сработает, только если исполнится комбинация условий с суммарным весом >= 70. В нашем случае это уровень + лента (70) или уровень + плотность (80). Это позволяет формализовать интуицию, когда решение принимается на основе совокупности факторов, а не одного жесткого триггера. Не уверен, существует ли где-либо нечто подобное, учитывая сложность «промпта» в котором учитывается лента, стакан, открытый интерес, корреляция с поводырем, частичные входы и выходы, а также анализ бектестов с ассистентом и взвешенные основания, напишите, пожалуйста, в комментариях. Визуализация сложности проекта На определенном этапе я попросил ИИ проанализировать весь код и сгенерировать GraphML-файл для визуализации архитектуры. Вот карта проекта. Карта проекта Почему для одних ИИ — гений, а у других — идиот? Перед тем как написать эту статью, я много читал обсуждения разработки с ИИ, в том числе на Хабре и заметил странный парадокс. Одни люди пишут: "LLM — это революция. Он сделал то, до чего я бы не додумался." Другие (часто более опытные разработчики) пишут: "Пробовал. Ерунда. Код нерабочий." Это один и тот же инструмент, но результаты диаметрально противоположные. Почему? Моя гипотеза: дело не в ИИ, а в ментальной модели Я пришёл к выводу, что эффективность работы с ИИ зависит от одного критического фактора: готовности принять, что ИИ может знать больше меня, что в свою очередь позволяло мне задавать вопросы и искать истину в диалогах. Звучит абсурдно. "Как машина может знать больше сеньёра с 15-летним опытом?" Но факт в том, что ИИ обучен на миллиардах строк кода. Он видел паттерны на всех возможных языках программирования, которые senior-разработчик никогда не использовал. Он знает решения проблем, с которыми сталкивались тысячи других разработчиков. Объективно, статистическая модель знает больше, чем любой человек. Две модели взаимодействия Подход 1: "Делай как я сказал" Ты говоришь: "Сделай X вот так." AI делает по-другому. Ты думаешь: "Неправильно. Переделывай." Итог: постоянное разочарование. Подход 2: "А как ты думаешь?" Ты спрашиваешь: "Как лучше решить X?" AI предлагает незнакомое решение. Ты: "Интересно. Почему так? Объясни." Итог: новое знание + работающий код. Угадайте, какая модель даёт "гения", а какая — "идиота"? Почему мой ИИ — "гений"? Потому что я принял простую истину: ИИ видел больше кода, чем я увижу за всю жизнь. Да, он может ошибаться. Да, иногда он галлюцинирует. Но когда он предлагает решение, которое мне незнакомо, я не думаю: "Ерунда какая-то.". Я думаю: "Это интересно. Почему именно так? Чему я могу научиться? Какие еще есть варианты?" Это не значит, что я считаю себя глупее. Это значит, что я объективно признаю: база знаний модели шире, чем моя. А минусы есть? Конечно, не все было гладко, бывали моменты стойкого ощущения, что ИИ отупел когда он не мог выполнить простейшие на мой взгляд задачи в сравнении с теми которые решал раньше. Рефакторинг — иногда проще переписать, особенно для профессионального разработчика, чем объяснять AI что именно не так. Специфичные баги — AI отлично решает типичные задачи, но часто буксует столкнувшись с неизвестными. Технический долг — да, он быстро накапливается, но так же быстро и решается. Но ни одна из этих проблем не остановила проект. Вопрос к читателям Хабра Многие комментарии под постами об ИИ в разработке полны скепсиса: "Пробовал, ничего путного не вышло." "Это для простых задач, а реальные проблемы ИИ не решит." Но что если дело не в возможностях ИИ, а в способе взаимодействия? Что если разница между "ИИ — бесполезная игрушка" и "ИИ — революционный инструмент" лежит не в технологии, а в готовности спросить: "Как бы ТЫ это сделал?" вместо "Сделай так, как я сказал." Я не утверждаю, что познал истину, я лишь пытаюсь разобраться в этом феномене, но я уверен в одном: с точки зрения трейдинга этот проект имеет огромный потенциал, потому что я нигде еще не видел ничего подобного. И я прошу сообщество помочь мне разобраться имеет ли он такой же потенциал с точки зрения разработки. У меня нет опыта коммерческой разработки Я создал платформу в 220,000 строк кода Она работает, решает реальную задачу, хотя и в бете И я не выгорел в процессе Что дальше? Безопасность как приоритет: принципы открытой беты Платформа работает. Но я прекрасно понимаю, что продукт связанный с финансами, требует максимальной надежности. Моя главная задача на текущем этапе — убедиться в стабильности и корректности работы всей системы, не подвергая пользователей риску. Поэтому в текущей открытой бета-версии Live-торговля отключена. По умолчанию доступны такие функции: 5 бэктестов в день 5 запросов к АИ-ассистенту в день 30 дней истории для бэктестинга 10 монет Я бы с удовольствием сделал лимиты больше, но пока вряд ли потяну. Это позволяет попробовать платформу в деле и даже собрать и протестировать стратегию на исторических данных. Если вы хотите проверить, насколько надёжен AI-generated код — проект в открытом бета-тесте: depthsight.pro . Буду благодарен за любую обратную связь или сообщения о багах и уязвимостях. В ближайших планах — развитие генетического модуля, где пользователи смогут «скрещивать» свои стратегии или отдельные их части (например, взять систему входа от одной стратегии, а риск-менеджмент от другой), чтобы эволюционно находить новые, более эффективные комбинации. Доработка оптимизации стратегий, обучения моделей, интеграция коннекторов других бирж помимо Binance. Вопросы для сообщества Для разработчиков: Как ИИ изменил ваш workflow? Какие самые сложные задачи вы ему доверяете? Для тимлидов: Готовы ли вы принимать сгенерированный код в production? Для всех: А ваш ИИ гений или идиот? Спасибо, что дочитали. Буду рад ответить на любые вопросы в комментариях. Evolve. Or don't look up. P.S. Следить за развитием проекта можно в Telegram-канале . Теги: Source: https://habr.com/ru/articles/965480/