Автоматически пополняется Бендером после каждого бага/фикса/открытия. Порог ротации: 150+ записей — разбить по проектам или архивировать старые. Читается в начале каждой сессии.
|| null вместо ?? null — funding=0 теряется (falsy-zero bug)Грабля: fundingMap.get(symbol) || null — если funding rate ровно 0 (нормально в flat рынке), 0 falsy → заменяется на null → funding context никогда не срабатывает для таких символов.
Решение: rawFunding != null ? rawFunding * 100 : null — явная проверка на null/undefined.
Грабля: signals.js кэширует premiumIndex под ключом 'funding_rates', liq-sweep читал 'premiumIndex' → всегда cache miss → лишний API call каждые 60с.
Решение: Передавать getFundingMap как dep через dependency injection, не дублировать fetch.
Грабля: outcomeTracker использовал Math.abs(rawPct) для NEUTRAL direction (straddle/strangle), что всегда давало положительный P&L → 100% WR. 112 сигналов были фейково WIN.
Решение: Каждая нога считается отдельно: callDelta×spotMove - callPremium + putDelta×spotMove - putPremium. Пересчитано → WR 57%→44%.
Запомнить: Math.abs() для P&L = мгновенно подозрительно. Всегда проверять edge cases с NEUTRAL/bi-directional стратегиями.
Грабля: SOL PUT lastPrice=$0.56 но maxPrice=$0.51. BUY LIMIT по lastPrice = "Price greater than max price". TP тоже клампится → +39% вместо +100%.
Решение: clampPrice() для entry + TP room check: если maxPrice не позволяет ≥50% gain — сделка пропускается.
Запомнить: Binance eAPI PRICE_FILTER maxPrice — обязательно проверять перед ордером. TP room = entry×1.5 ≤ maxPrice.
Грабля: Графики на 15m, 1h, 4h, 1d перестали обновляться live. Legacy endpoint wss://fstream.binance.com/stream перестал отдавать kline данные для таймфреймов ≥15m. 1m/5m продолжали работать.
Решение: Миграция на wss://fstream.binance.com/market/stream (роутированный endpoint). Подтверждено тестами: legacy=0 тиков, market=20 тиков за 12с.
Запомнить: Binance перевели WS на роутированные endpoints (/public, /market, /private). Klines → /market/stream. Проверять доки при WS проблемах.
Грабля: Потенциальный риск — использование Telegram токена Бендера (claude-code-telegram) для нотификаций в других проектах. Решение: Каждый проект (weather-bot, btc-5m-bot, etc.) — свой отдельный Telegram бот ИЛИ веб-интерфейс. Бендер = только Бендер. Запомнить: НИКОГДА не использовать токен Бендера для сторонних ботов без ЯВНОГО разрешения Rick'а.
Грабля: При смене TF отправляли UNSUBSCRIBE старых стримов и SUBSCRIBE новых на том же WS соединении. На некоторых TF тики не приходили — race condition между unsub и resub.
Решение: Полностью убивать WS (ws.close(), mc.ws = null) и создавать новое соединение. Плюс RE-SUB safety net (если 0 тиков через 5с — пересоздать стримы из видимых чартов).
Запомнить: При смене контекста WS проще kill+recreate чем unsub+resub. Добавлять safety net timeout.
Грабля: Sorted-merge для S/R уровней мёрджил пивоты "цепочкой" — каждый следующий "чуть ближе" к предыдущему, в итоге крайние точки кластера далеко друг от друга. Решение: Заменили на DBSCAN (inline, без npm — клиентский код). Каждая точка проверяется от каждой, кластер реально плотный. Запомнить: Для кластеризации ценовых данных использовать DBSCAN, не sorted-merge.
Грабля: Старый алгоритм разрешал 15% свечей пересекать трендлайн. Визуально — линия проходит через тело свечей, выглядит неправильно. Решение: Gradient descent slope optimization с ZERO violations (neurotrader888 подход). Также enforce slope direction: support slope>0, resistance slope<0. Запомнить: Трендлайн должен иметь 0 нарушений. Support = восходящая по лоям, Resistance = нисходящая по хаям.
Грабля: Писали S/R и trendline алгоритмы с нуля, когда на GitHub полно проверенных реализаций (trendln 697★, neurotrader888 552★). Решение: Ресёрч → адаптация лучших подходов (DBSCAN, gradient descent, zigzag, volume profile). Запомнить: Перед написанием нетривиального алгоритма — 15 мин ресёрча на GitHub/TradingView.
Грабля: lightweight-charts-drawing@0.1.1 — setActiveTool() просто хранит имя, handleClick() делает только selection
Решение: Создавать вручную через ToolRegistry.createDrawing(type, id, anchors, style, opts) + manager.addDrawing(drawing)
Запомнить: Библиотека drawing tools — обёртка, рисунки создаются через ToolRegistry, не через DrawingManager
Грабля: Мобильный touchend handler вызывал preventDefault() — убивал синтетический click — библиотека не получала событие через chart.subscribeClick
Решение: return early в touchend когда DrawingManager активен
Запомнить: На мобилке preventDefault в touch-хэндлерах ломает синтетические клики LWC
Грабля: createTextWatermark() (v5 primitive API) бросал TypeError: attachPrimitive is not a function, крашил openCoinModal() целиком — чарт показывал 2-3 свечи вместо 1000
Решение: Обернуть в try/catch. rAF/double-rAF НЕ помогают — проблема не в размерах
Запомнить: Всегда try/catch вокруг LWC v5 primitives (watermark, markers) — они могут крашить тихо
Грабля: CDN lightweight-charts-drawing@0.1.1 — v4-only, 404 на v5, мог ломать internals
Решение: npm install + раздавать UMD локально через Fastify route
Запомнить: Всегда раздавать JS библиотеки локально, не CDN — контроль версий
Грабля: .mc-modal.hidden { display:none } — элемент вне layout, createChart получает size 0
Решение: visibility:hidden + opacity:0 + pointer-events:none — элемент всегда в layout
Запомнить: LWC чарты нельзя создавать в display:none контейнерах
Грабля: WS подключался при старте без подписок → Binance закрывал idle соединение → reconnect loop каждые 5с Решение: Lazy connect при первом subscribe(), ping keepalive 3мин, race condition fix для concurrent subscribes в CONNECTING state Запомнить: Не подключать WS до первой подписки. Binance убивает idle WS.
Грабля: JWT_SECRET генерировался при старте → каждый PM2 restart сбрасывал все токены Решение: Фиксированный секрет через PM2 env var Запомнить: Секреты для JWT — ВСЕГДА через env, никогда random при старте
Грабля: Один toggle "Browser notifications" управлял и in-tab toast и серверным push — выключение на десктопе убивало push на телефоне
Решение: Разделить на signalNotifications (in-tab) и signalPush (серверный) — каждое устройство независимо
Запомнить: Push и in-tab уведомления — разные вещи, разные toggles
Грабля: Конкурентность 10 + scan всех 537 символов при старте → IP забанен дважды Решение: Concurrency 10→3, 500ms delay, batch 10/20s pause, graceful skip на 429, skip unsubscribed symbols Запомнить: Binance банит IP агрессивно. Warmup: 10 sym/batch, 20s pause. Max concurrency 3.
Грабля: cache/proxyCache Maps не удаляли expired entries, books bids/asks без TTL → Heap 89% (133MB) Решение: Детерминированный cleanup каждые 10-30с, TTL на все кеши, removeAllListeners при WS reconnect Запомнить: Каждый Map/cache ОБЯЗАН иметь TTL + периодический cleanup. Проверять heap после рестарта.
Грабля: High conf (80+) OI сигналы имели R:R 0.86 — экстремальные OI скачки запаздывают (уже поздно входить) Решение: Bell-curve: sweet spot 4-8% OI change → conf 67-78, >10% → conf падает Запомнить: Для запаздывающих индикаторов (OI) — экстремальные значения = хуже, средние = лучше
Грабля: signalId = sig.id + "_" + Date.now() → дедуп искал по sig.id без суффикса → 99.3% дублей
Решение: Дедуп по стабильным полям: strategy + underlying в окне 6ч
Запомнить: ID для дедупликации должен состоять из стабильных полей, не включать timestamp
Грабля: Premium = per-contract, но XRP 1 контракт = 100 XRP → breakeven показывал $3.50 вместо $1.40
Решение: fetchContractUnits() из exchangeInfo, нормализация в buildTradeRec/PnL Calculator
Запомнить: Binance options — ВСЕГДА делить premium на contractUnit для per-unit цены
Грабля: Код искал ex.realStrikeAmount, Binance отдаёт ex.realStrikePrice → фоллбек на strike → ROI 59,000%
Решение: Считать intrinsic value самим, не доверять strikeResult от Binance
Запомнить: Binance eAPI exercise history — поля именуются неочевидно, strikeResult ненадёжен
Грабля: Gamma Play и Whale имели SL 50-70% — бессмысленно для покупки опционов (премия = max loss) Решение: slPct=100% для ВСЕХ типов покупки Запомнить: При покупке опционов SL не нужен — максимальный убыток = уплаченная премия
Грабля: IV Skew генерировался в dashboard.js, но не в scheduler.js → 0 записей в SignalLog Решение: Добавить генерацию в scheduler slowUpdate() Запомнить: Сигналы должны генерироваться в ОДНОМ месте (scheduler), не в UI-рендере
Грабля: Бот входил при Z=4.75 (FFUSDT) — это breakout. WR 83.5% но PnL -$31 Решение: Z-cap 2.5 — skip при |Z| > 2.5 Запомнить: Для MR стратегий экстремальные Z-scores = momentum/breakout, не MR. Ограничивать сверху.
Грабля: EMA slope 0.05% за 3 свечи блокировал ВСЕ MR сигналы (229 скипов, 1 сделка/день) Решение: Порог 0.05% → 0.4%. Для MR когда цена ниже VWAP, EMA естественно падает Запомнить: EMA direction filter для MR должен быть мягким (0.3-0.5%), иначе блокирует всё
Грабля: Добавил ema_slope расчёт но забыл return из функции → NameError при распаковке → скан тихо крашился 35 мин Решение: Всегда проверять return tuple после добавления новых полей Запомнить: asyncio проглатывает NameError/TypeError в tasks — добавлять try/except с логированием
Грабля: STOP_MARKET ордера возвращают algoId, conditional orders не видны в openOrders API
Решение: Проверять позицию напрямую вместо ордера, sleep 0.5s после partial TP перед SL update
Запомнить: Binance Futures conditional orders (STOP_MARKET/TAKE_PROFIT) — отдельный API, не в openOrders
Грабля: При пропаже позиции бот всегда писал Reason=SL, даже если TP сработал. 75/122 сделок неверно Решение: Проверять статус TP order перед записью reason Запомнить: Определять причину закрытия по статусу ордеров, не по отсутствию позиции
Грабля: XAU/XAG/XAUT/PAXG/CL — error -4411 даже при подписанном TradFi agreement Решение: Все TradFi в blacklist Запомнить: Binance TradFi-перпы (металлы, нефть) требуют отдельных agreement'ов для каждого
Грабля: Статьи публиковались под ID=1 (личный serg5585) вместо ID=2 (PIEWell)
Решение: Всегда post_author: 2
Запомнить: WordPress автор — ВСЕГДА ID=2 (PIEWell), никогда ID=1
Грабля: Holy Basil ASIN B001GAOGPU перестал работать — 404
Решение: curl-проверка перед вставкой, verified список в скилле
Запомнить: ВСЕГДА проверять ASIN перед вставкой. Amazon удаляет товары без предупреждения.
Грабля: Определил escAttr() и lsSet() в app.js, но этот файл не загружается через <script> в index.html. Настройки, плотности и сигналы сломались — undefined functions.
Решение: Перенести глобальные хелперы в inline <script> в index.html перед всеми модулями. Проверять порядок загрузки скриптов!
Запомнить: ВСЕГДА проверять index.html на наличие <script src="..."> перед добавлением глобальных функций в файл.
Грабля: const fs = require('fs') объявлен на строке 399, но density cache на строке 209 ссылается на fs.promises.writeFile — ReferenceError.
Решение: Использовать require('fs').promises.writeFile inline в ранних функциях.
Запомнить: В Node.js порядок const деклараций важен — нельзя ссылаться до объявления (TDZ).
Грабля: cors: { origin: '*' } в конструкторе Fastify v5 тихо игнорировалось — CORS не работал вообще.
Решение: Установить @fastify/cors плагин и зарегистрировать через fastify.register().
Запомнить: Fastify v5 НЕ поддерживает cors в конструкторе. Всегда через @fastify/cors плагин.
Грабля: 536 depth стримов в одном WS → Binance дропает каждые 5с → reconnect loop, density не работает
Решение: Класс BinanceWSConnection, max 190 стримов, автоматическое создание новых соединений
Запомнить: Binance WS hard limit = 200 streams/connection. Всегда разбивать на несколько.
Грабля: IndexedDB хранил старые свечи, delta fetch не всегда бриджил гэп (limit 500 < gap size), merge создавал дыры Решение: Убрали IDB tier полностью, Memory cache → Server SQLite напрямую (достаточно быстро) Запомнить: Сложный multi-tier cache с delta merge = источник багов. Если сервер быстрый — не усложнять.
Грабля: Тип уровня определялся по типу пивота (high=resistance, low=support). При пампе 142% все старые resistance оказывались ниже цены → фильтровались → 0 уровней Решение: Тип = позиция vs текущая цена: ниже = support, выше = resistance Запомнить: S/R тип всегда определять относительно текущей цены, не по исторической классификации.
Грабля: 31 Mar 2026 — Бендер отредактировал файлы в /home/app/claude-code-telegram/, сломал себя. Rick чинил СУТКИ.
Решение: Абсолютный запрет на любые изменения в claude-code-telegram/ без явного разрешения
Запомнить: НИКОГДА не трогать /home/app/claude-code-telegram/ — это мой собственный код, одна ошибка = сутки даунтайма
Грабля: bot.py имел forecast_cache dict, но в else ветке всё равно вызывал get_forecast_and_probability() вместо использования кэша. 171 маркет × brackets = сотни запросов без паузы → Open-Meteo 429 бан. Решение: При cache hit — берём forecast_value+sigma из кэша, пересчитываем только probability для конкретного bracket threshold. Добавили retry 3x с backoff (5s→10s→20s) + global cooldown 5 мин. Запомнить: Всегда проверять что кэш РЕАЛЬНО используется в else-ветке, а не просто объявлен.
Грабля: loguru по умолчанию пишет в stderr (handler id=0). logger.add(file) добавляет второй handler. PM2 захватывает оба → каждая строка лога дважды. 7MB лога за 12 мин. Решение: logger.remove() перед logger.add() — убрать дефолтный stderr handler. Запомнить: При loguru + PM2 всегда делать logger.remove() первым делом.
Грабля: Resolver считал profit = (1-price) × size, но size = доллары, а не кол-во shares. shares = size/price. Реальный P&L был в 10-100x неправильный.
Решение: WIN: size × (1-price) / price, LOSS: -size (теряешь всю ставку).
Запомнить: В prediction markets ВСЕГДА конвертировать dollars→shares перед расчётом P&L.
Грабля: Для "exactly 21°C": threshold±0.5 → ±1.0 (двойной padding). Вероятность завышалась в 2 раза → фейковый edge → убыточные сделки. Решение: Один уровень padding: ±0.5 для eq, threshold_low-0.5/threshold_high+0.5 для between. Запомнить: Проверять формулы вероятности на конкретных числах перед деплоем.
Грабля: Модель думала что прогноз точен до ±1.5°F. Реально NWS MAE = 2.5-3°F. Результат: модель завышала вероятности узких brackets, создавала фейковый edge. Решение: Sigma увеличен в 2x (1.5→3.0, 2.0→3.5, etc.). Модель стала менее уверенной. Запомнить: Перед калибровкой модели — проверить реальные MAE данные (NWS, ECMWF).
Грабля: 7 из 7 YES ставок при market_prob<10% проиграли. Модель систематически overconfident на low-prob events. Решение: Фильтр: не ставить YES когда рынок даёт <10%. Запомнить: Если рынок и модель оба говорят <10%, но модель говорит 30% — рынок прав.
Грабля: 171 HTTP запросов через blocking requests.get() + time.sleep(1.0) в async event loop. Uvicorn зависает на 60-90с, PM2 убивает процесс → 21+ рестартов. Решение: asyncio.to_thread() для всех blocking вызовов (scan, forecast, place_bet, resolve). Запомнить: В FastAPI/asyncio НИКОГДА не использовать blocking calls напрямую. Всегда to_thread().