feat(tg): detailed trading report on Трейдинг button + LLM analytics - #198
Conversation
… (A/B, DCA, basket, T2, freqtrade, MM, scoreboard, services) + LLM analytics/scenarios via balancer (async send, honest framing: paper-only, no financial advice)
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
| threading.Thread(target=_bg_llm, args=(api, chat_id, snap), daemon=True).start() | ||
| elif data == "crypto_refresh": | ||
| from tg_bot.treasury import _handle_treasury_intent as _hti | ||
| _hti(api, chat_id, "крипто заработок") |
There was a problem hiding this comment.
🔥 The Roast: Вы разделили nav_trading и crypto_refresh, но зачем-то поменяли текст у crypto_refresh с "казначайство и резервы" на "крипто заработок". Это не в scope PR про кнопку «Трейдинг». Пользователь нажимает "обновить крипту" — а ему прилетает отчёт о заработке. Сюрприз!
🩹 The Fix: Либо верните прежний текст "казначайство и резервы", либо вынесите смену текста в отдельный коммит с обоснованием. В PR описание должно отражать все изменения поведения.
📏 Severity: warning
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| realized = sum(float(v.get("realized_pnl_usd", 0.0) or 0.0) for v in exchanges) | ||
| gross = sum(float(v.get("gross_pnl_usd", 0.0) or 0.0) for v in exchanges) | ||
| fees = sum(float(v.get("fees_paid_usd", 0.0) or 0.0) for v in exchanges) | ||
| positions = [(ex, pos) for ex, v in zip( |
There was a problem hiding this comment.
🔥 The Roast: zip здесь работает как телепорт: ключи фильтруются только по имени, а значения ещё и по типу dict. Если в JSON окажется не-дикт для не-исключённого ключа, zip обрежет список, и позиции посчитаются криво. Молча. Пользователь увидит открытых: 0 там, где их 5.
🩹 The Fix: Добавьте isinstance(v2, dict) в список ключей, чтобы фильтрация была одинаковой:
positions = [(ex, pos) for ex, v in zip(
[k for k, v2 in data.items() if k not in ("cross_arbitrage", "_risk_state") and isinstance(v2, dict)],
exchanges) for pos in (v.get("positions") or {}).values() if pos]📏 Severity: warning
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| w += " ⚠️" | ||
| basket = sb.get("top10_basket_pct") | ||
| basket_s = f"{basket:+.2f}%" if basket is not None else "—" | ||
| lines.append(f"🏆 <b>Scoreboard {sb['date']}</b>: DV2 {sb['dv2']['pnl_pct']:+.2f}% | " |
There was a problem hiding this comment.
🔥 The Roast: sb['date'], sb['dv2']['pnl_pct'], sb['market_mean_pct'] — три прямых доступа к внешнему JSON. Если scoreboard-файл окажется без поля date или dv2, отчёт упадёт с KeyError вместо graceful-сообщения "нет данных". Надежда на идеальные данные — это не стратегия обработки ошибок.
🩹 The Fix: Замените прямые доступы на безопасные .get() с дефолтами, чтобы падение внешнего JSON не убило весь отчёт.
📏 Severity: suggestion
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| sb = snap["scoreboard"] | ||
| if sb: | ||
| v = sb.get("verdict") or {} | ||
| parts.append(f"Scoreboard {sb['date']}: победитель {v.get('winner')}") |
There was a problem hiding this comment.
🔥 The Roast: sb['date'] снова в плюс-доступе. Если prompt_for_llm получит scoreboard без date, LLM-промпт упадёт, и пользователь не получит вообще никакого отчёта. Надежда на то, что JSON никогда не сломается, — это не план.
🩹 The Fix: Замените sb['date'] на sb.get('date', '—'), чтобы отсутствие поля в scoreboard не сломало LLM-промпт.
📏 Severity: suggestion
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review Roast 🔥Verdict: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)
🏆 Best part: Модуль 💀 Worst part: Случайное изменение текста кнопки 📊 Overall: Как первый пул-реквест нового разработчика — много полезного кода, но пара случайных изменений в соседних кнопках, от которых веет хаосом. Fix these issues in Kilo Cloud Files Reviewed (3 files)
Reviewed by free · Input: 75.6K · Output: 29.5K · Cached: 488.3K |
Кнопка Трейдинг: детальный отчёт всех портфелей + LLM-аналитика и сценарии (paper-only, дисклеймер). Данные мгновенно, LLM в фоновом потоке.