From cc236d3dacbb855cadb1e576c3940b1fda0a0a83 Mon Sep 17 00:00:00 2001 From: shuim Date: Thu, 26 Feb 2026 13:21:58 +0900 Subject: [PATCH] =?UTF-8?q?=ED=83=80=EC=9E=85=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/main.py | 54 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/backend/app/main.py b/backend/app/main.py index 487d016..af8e696 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -124,9 +124,11 @@ async def batch_analysis_scheduler(): "recommendations:latest", TTL_RECOMMENDATIONS, normalized ) if ok: + rec_by_rule = normalized.get('recommendations_by_rule', []) + rec_count = len(rec_by_rule) if isinstance(rec_by_rule, (list, dict)) else 0 logger.info( f"πŸ’Ύ [Batch] Redis μΊμ‹œ κ°±μ‹  μ™„λ£Œ: recommendations:latest " - f"(rule 수: {len(normalized.get('recommendations_by_rule', {}))}, " + f"(rule 수: {rec_count}, " f"TTL: {TTL_RECOMMENDATIONS}s)" ) @@ -191,9 +193,11 @@ async def auto_trade_scheduler(): # ── Redis μΊμ‹œ 확인 (10λΆ„ 배치 κ²°κ³Ό, TTL 30λΆ„) ──────────────── rec = await get_json("recommendations:latest") if rec: + rec_by_rule = rec.get('recommendations_by_rule', []) + rec_count = len(rec_by_rule) if isinstance(rec_by_rule, (list, dict)) else 0 logger.info( "⚑ Redis cache hit: recommendations:latest " - f"(rule 수: {len(rec.get('recommendations_by_rule', {}))}) " + f"(rule 수: {rec_count}) " "β†’ DB 쑰회 μƒλž΅" ) # 포맷 μ •κ·œν™” (λ‹€λ₯Έ ν‚€ μ‘°ν•© λŒ€μ‘) @@ -205,15 +209,14 @@ async def auto_trade_scheduler(): if rec and rec.get("recommendations_by_rule"): # ── MCP RISK_ASSESSMENT (곡톡 ν•¨μˆ˜, 이슈 4) ────────── - recommendations = rec.get("recommendations_by_rule", {}) - trade_plan = { - "action": "BUY", - "strategy": "rule_based_batch", - "recommendation_count": sum( - len(v) for v in recommendations.values() - ), - "rules": list(recommendations.keys()), - "top_stocks": [ + recommendations = rec.get("recommendations_by_rule", []) + + # Handle both list and dict formats for backwards compatibility + if isinstance(recommendations, dict): + # Old format: {rule_name: [stocks]} + recommendation_count = sum(len(v) for v in recommendations.values()) + rules_list = list(recommendations.keys()) + top_stocks_list = [ item.get("stock_code") or item.get("code", "") for rule_items in recommendations.values() for item in ( @@ -221,12 +224,37 @@ async def auto_trade_scheduler(): if isinstance(rule_items, list) else [] ) - ][:10], + ][:10] + else: + # New format: [{rule_id, rule_name, stocks: [...]}] + recommendation_count = sum( + len(rule_group.get("stocks", [])) + for rule_group in recommendations + if isinstance(rule_group, dict) + ) + rules_list = [ + rule_group.get("rule_name", rule_group.get("rule_id", "")) + for rule_group in recommendations + if isinstance(rule_group, dict) + ] + top_stocks_list = [ + item.get("stock_code") or item.get("code", "") + for rule_group in recommendations + if isinstance(rule_group, dict) + for item in rule_group.get("stocks", [])[:3] + ][:10] + + trade_plan = { + "action": "BUY", + "strategy": "rule_based_batch", + "recommendation_count": recommendation_count, + "rules": rules_list, + "top_stocks": top_stocks_list, } portfolio: dict = {} signals = { "source": "db_recommendations", - "rules_triggered": list(recommendations.keys()), + "rules_triggered": rules_list, } approve, reason = await request_mcp_risk_assessment( trade_plan, portfolio, signals