Как один рычаг тюнера чуть не остановил Snipe совсем
Snipe шесть суток не находил ни одного сигнала. Причина — тюнер, который в шторм зажимал сразу три фильтра без единого противовеса.
Есть особенно неприятный тип бага в системах с автоматической подстройкой параметров: код не падает, тесты зелёные, метрики формально не выглядят катастрофой, а бот просто медленно перестаёт что-либо делать. Такой сбой не кидает исключение и не будит ночью алертом — он проявляется только как тишина, растянутая на дни, и заметить его можно только если специально спросить “а когда была последняя реальная активность”. Именно это происходило со Snipe — движком отслеживания активности крупных кошельков на Solana DEX, одним из пяти ботов Challenge. Кластеров сигналов не находилось уже около 143 часов подряд — почти шесть суток. Автопилот каждые полтора часа честно писал в лог “Clusters found: 0” и продолжал жить дальше, как будто всё в порядке.
Первый подозреваемый оказался не главным
Первым делом проверили порог минимальной ликвидности MIN_LIQ — он оказался выставлен за пределы собственных границ тюнера (100000 вместо разрешённых максимум 25000), что само по себе было багом. Починили и заодно добавили самолечение: теперь tune() при каждом запуске проверяет, не вышел ли какой-то параметр за BOUNDS, и возвращает его в границы сам. Логично было бы ожидать, что на этом всё. Не на этом — дискавери всё ещё был почти на нуле.
Настоящее узкое место
Изолированная проверка каждого порога отдельно на живых данных 133 реальных пар с DexScreener показала: с текущими боевыми настройками через фильтр проходит один-единственный токен. При этом если ослабить только порог MIN_BUY_SELL_RATIO с 3.0 до 1.0, ничего больше не трогая, проходит уже 11. Вот он, настоящий стоп-фактор — и формально не баг, значение было строго внутри разрешённого диапазона 0.5–4.0.
Причина крылась не в конкретном числе, а в логике, которая его туда поставила. Когда win rate закрытых сделок опускается ниже 35% при достаточной выборке, тюнер одновременно ужесточает сразу три порога — ликвидность, соотношение покупок к продажам и минимальное число кошельков в кластере — без какого-либо противовеса. Получается самоусиливающаяся спираль: чем хуже win rate, тем плотнее закрыт дискавери, тем меньше новых сделок закрывается, тем медленнее вообще есть шанс, что win rate отреагирует на улучшение рынка. Формально это не портит статистику — ноль сделок означает ноль проигрышей, метрика даже выглядит нейтрально. Но саму цель проекта (удвоить бюджет, а не стоять на месте) такая логика убивает полностью, просто тихо.
Решение с предохранителем, а не заплаткой
Сначала руками вернули MIN_BUY_SELL_RATIO с 3.0 к 1.0 — тому же значению, что уже стояло по умолчанию до серии ужесточений, подтверждённому изолированным тестом на живых данных. Но точечный откат одного значения не решает системную проблему — тюнер мог бы точно так же зажать его обратно при следующем провале win rate. Поэтому в tune() добавили третий, необязательный параметр — данные дискавери за сутки. Если кластеров найдено ноль, тюнер теперь обязан ослабить на шаг тот из порогов ликвидности или соотношения покупок к продажам, который по логам отсеивает больше кандидатов — независимо от того, что говорит win rate. Это прямой антидот спирали: раньше система умела только зажиматься сама по себе, теперь у неё есть встроенная обязанность разжаться, если активность падает до нуля.
Фикс прогнали через шесть синтетических сценариев — от “дискавери отключен” до “оба порога уже на предельных границах BOUNDS” — все прошли. Отдельно поставили живой end-to-end тест: реальный кандидат-токен с 20 кошельками-покупателями (ровно на границе минимального требования) теперь успешно проходит весь пайплайн целиком. Единственное, что осталось непроверенным на момент фикса — как поведёт себя полноценный суточный цикл живого обучения на реальном, а не синтетическом рынке. Это уже вопрос ближайших дней наблюдения, а не разовой правки кода.
Разбор похожего случая — постмортем по багу стоп-лосса, который стоил Snipe почти всего бюджета в первом раунде — можно почитать в посте про итоги Round 1. Оба случая объединяет одно: в автоматической торговле система, которая “просто ничего не делает”, не менее опасна, чем система, которая делает не то — только замечают её обычно позже.
Живой счёт всех пяти ботов Round 2, включая Snipe с уже исправленным дискавери — на странице Challenge.
Рассылка новых статей
Выберите, куда присылать новые статьи и разборы — без спама, только новые материалы.
Чтобы получать статьи на email, сначала привяжите email в личном кабинете.
Чтобы получать статьи в Telegram, войдите через Telegram-кнопку на странице входа.
Получайте новые статьи и разборы
Подпишитесь через email — без спама, только новые материалы.