From 92a1c81ef1b57d8fc9f7f25edf3080538399b5b7 Mon Sep 17 00:00:00 2001 From: shuim Date: Thu, 26 Feb 2026 13:33:24 +0900 Subject: [PATCH] =?UTF-8?q?MCP=20=EC=B0=A8=EB=8B=A8=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/main.py | 7 +++++++ backend/app/services/day_trading_strategy.py | 4 +++- backend/app/services/trade_executor.py | 8 ++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/backend/app/main.py b/backend/app/main.py index af8e696..6721b69 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -694,6 +694,13 @@ async def websocket_endpoint(websocket: WebSocket, client_id: str): websocket_manager.disconnect(client_id) logger.info(f"Client {client_id} disconnected") +@app.post("/api/admin/reset-daily-loss") +async def reset_daily_loss(): + """테스트용 일일 손실 한도 강제 리셋""" + from app.services.mdd_manager import mdd_manager + mdd_manager.reset() # 이미 reset() 메서드 존재 [cite:9] + return {"status": "ok", "message": "daily loss limit reset"} + if __name__ == "__main__": import uvicorn diff --git a/backend/app/services/day_trading_strategy.py b/backend/app/services/day_trading_strategy.py index 6380e96..52221a7 100644 --- a/backend/app/services/day_trading_strategy.py +++ b/backend/app/services/day_trading_strategy.py @@ -494,9 +494,11 @@ def is_daily_loss_exceeded( total_assets: float, realized_pnl_today: float, ) -> bool: - """일일 손실 한도 초과 여부 (전체 자본 -3%)""" if total_assets <= 0: return False + # realized_pnl_today가 0이면 손실 없음 → 한도 미초과 + if realized_pnl_today >= 0: + return False return (realized_pnl_today / total_assets) <= DAILY_LOSS_LIMIT diff --git a/backend/app/services/trade_executor.py b/backend/app/services/trade_executor.py index 56a59a2..bde0b06 100644 --- a/backend/app/services/trade_executor.py +++ b/backend/app/services/trade_executor.py @@ -63,6 +63,14 @@ async def _mcp_validate_buy(stock: dict) -> tuple: return True, f"mcp_approved(conf={confidence:.2f})" else: return False, f"mcp_rejected(decision={decision}, conf={confidence:.2f})" + + except httpx.HTTPStatusError as e: + if e.response.status_code == 500: + # 500 에러 → MCP 서버 내부 오류 → 룰 기반으로 우회 + logger.warning(f"⚠️ MCP 서버 500 에러 — 룰 기반으로 우회: {e}") + return True, "mcp_500_fallback_to_rules" + logger.warning(f"⚠️ MCP 검증 실패 — 매매 차단: {e}") + return False, "mcp_unavailable" except Exception as e: logger.warning(f"⚠️ MCP 검증 실패 — 매매 차단: {e}")