feat(observability): fine-grained metrics for summary, trades, and cycle log
CI/CD / build-and-push (push) Successful in 1m51s

api/summary — new fields:
  open_trades_count, closed_trades_count, cash_available (bankroll−deployed),
  legacy_incomplete_count, reentry_guard_blocks_24h
  parallel fetch via asyncio.gather for sub-ms overhead

api/trades?status=open — trade enrichment:
  days_open (float, rounded to 1 decimal)
  signal_components {fg, mom, news, mfld} parsed from reasoning via regex
  Old trades without feat_str in reasoning return signal_components: null

bayesian.py — reasoning now embeds feat_str:
  "fg=+0.0600 mom=+0.0000 news=+0.0000 mfld=-0.7483 |"
  Manifold counters: _manifold_fetched / _manifold_on_trade per cycle
  get_cycle_stats() exposes manifold_matches_accepted / manifold_matches_rejected

bot/main.py — CYCLE SUMMARY 4 new fields:
  reentry_guard_blocked, legacy_incomplete_seen,
  family_conflicts_prevented, manifold_matches_accepted/rejected
  legacy_incomplete_count queried from DB once per cycle

db.py — get_legacy_incomplete_count(): open trades with NULL edge_net

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
chemavx
2026-04-21 09:48:31 +00:00
parent e2fb697c0c
commit 46f8f4b79a
4 changed files with 83 additions and 6 deletions
+14 -1
View File
@@ -100,6 +100,7 @@ async def run_trading_loop(
len(inverted_guard), sorted(inverted_guard),
)
reentry_guard_count = 0
cycle_trades = 0
for market in markets:
if market.id in inverted_guard:
@@ -107,6 +108,7 @@ async def run_trading_loop(
"reentry_guard_triggered market=%s | skipping — closed for inversion within 24h | %s",
market.id, market.question[:60],
)
reentry_guard_count += 1
continue
# evaluate() returns None for all skips — reasons are logged internally
@@ -142,6 +144,7 @@ async def run_trading_loop(
# 8. [CYCLE SUMMARY] — one block per cycle, stable format for grep/compare
stats = strategy.get_cycle_stats()
legacy_incomplete_count = await db.get_legacy_incomplete_count()
n_total = len(markets)
n_uncertainty = sum(1 for m in markets if 0.35 <= m.yes_price <= 0.65)
n_eval = stats["evaluated_count"]
@@ -164,7 +167,12 @@ async def run_trading_loop(
" blocked_by_edge_net_nonpositive:%d\n"
" blocked_by_edge_net_below_regime:%d\n"
" trades_executed: %d\n"
" gnews_queries_used: %d/%d",
" gnews_queries_used: %d/%d\n"
" reentry_guard_blocked: %d\n"
" legacy_incomplete_seen: %d\n"
" family_conflicts_prevented: %d\n"
" manifold_matches_accepted: %d\n"
" manifold_matches_rejected: %d",
n_total,
n_uncertainty,
stats["max_edge_gross"],
@@ -177,6 +185,11 @@ async def run_trading_loop(
stats["skip_edge_net_below_regime"],
cycle_trades,
stats["gnews_queries_used"], MAX_NEWS_QUERIES_PER_CYCLE,
reentry_guard_count,
legacy_incomplete_count,
stats["skip_family"],
stats["manifold_matches_accepted"],
stats["manifold_matches_rejected"],
)
# 9. Update daily metrics