수정
This commit is contained in:
@@ -36,8 +36,19 @@ def _to_float(val) -> float:
|
||||
return 0.0
|
||||
|
||||
|
||||
def _parse_strategy(entry_reason: Optional[str]) -> str:
|
||||
"""entry_reason 문자열에서 전략 이름 추출."""
|
||||
def _parse_strategy(entry_reason: Optional[str], strategy_type: Optional[str] = None) -> str:
|
||||
"""strategy_type 컬럼 우선, 없으면 entry_reason 문자열에서 전략 이름 추출."""
|
||||
# strategy_type 컬럼이 있으면 우선 사용
|
||||
if strategy_type and strategy_type.strip():
|
||||
st = strategy_type.strip().lower()
|
||||
_type_map = {
|
||||
"swing": "mean_reversion",
|
||||
"daytrading": "day_trade",
|
||||
"kosdaq_scan": "kosdaq_scanner",
|
||||
"short_term": "short_term",
|
||||
}
|
||||
return _type_map.get(st, st)
|
||||
|
||||
if not entry_reason:
|
||||
return "unknown"
|
||||
reason = entry_reason.lower()
|
||||
@@ -439,7 +450,7 @@ async def analyze_performance(db: AsyncSession, days: int = 30) -> Dict[str, Any
|
||||
# ── 전략별 성과 ──────────────────────────────────────────────────────
|
||||
by_strategy: Dict[str, list] = {}
|
||||
for t in trades:
|
||||
strat = _parse_strategy(t.entry_reason)
|
||||
strat = _parse_strategy(t.entry_reason, getattr(t, "strategy_type", None))
|
||||
by_strategy.setdefault(strat, []).append(_to_float(t.profit_loss_rate))
|
||||
|
||||
strategy_stats = {}
|
||||
@@ -491,8 +502,9 @@ async def analyze_performance(db: AsyncSession, days: int = 30) -> Dict[str, Any
|
||||
stock_pnl[code] = stock_pnl.get(code, 0.0) + _to_float(t.net_profit_loss)
|
||||
|
||||
sorted_stocks = sorted(stock_pnl.items(), key=lambda x: x[1])
|
||||
worst_stocks = [{"stock_code": c, "net_pnl": round(p, 2)} for c, p in sorted_stocks[:5]]
|
||||
best_stocks = [{"stock_code": c, "net_pnl": round(p, 2)} for c, p in sorted_stocks[-5:][::-1]]
|
||||
# 손실 종목만 (음수), 수익 종목만 (양수) 필터링하여 색상 혼동 방지
|
||||
worst_stocks = [{"stock_code": c, "net_pnl": round(p, 2)} for c, p in sorted_stocks if p < 0][:5]
|
||||
best_stocks = [{"stock_code": c, "net_pnl": round(p, 2)} for c, p in sorted_stocks[::-1] if p > 0][:5]
|
||||
|
||||
# ── 리스크 조정 수익률 지표 ────────────────────────────────────────────
|
||||
risk_metrics = _calc_risk_adjusted_metrics(trades)
|
||||
@@ -660,7 +672,7 @@ def generate_journal_for_trade(trade: TradeHistory, perf_context: Optional[Dict]
|
||||
pl_amount = _to_float(trade.net_profit_loss)
|
||||
exec_price = _to_float(trade.executed_price)
|
||||
exec_qty = trade.executed_quantity or trade.order_quantity or 0
|
||||
strategy = _parse_strategy(trade.entry_reason)
|
||||
strategy = _parse_strategy(trade.entry_reason, getattr(trade, "strategy_type", None))
|
||||
exit_type = _parse_exit_type(trade.exit_reason)
|
||||
|
||||
# 결과 평가
|
||||
@@ -729,7 +741,7 @@ async def create_journal_record(
|
||||
) -> TradeJournal:
|
||||
"""TradeJournal 레코드를 DB에 저장 후 반환."""
|
||||
pl_rate = _to_float(trade.profit_loss_rate)
|
||||
strategy = _parse_strategy(trade.entry_reason)
|
||||
strategy = _parse_strategy(trade.entry_reason, getattr(trade, "strategy_type", None))
|
||||
exit_type = _parse_exit_type(trade.exit_reason)
|
||||
|
||||
mood = "positive" if pl_rate > 0 else ("neutral" if pl_rate > -3.0 else "negative")
|
||||
|
||||
Reference in New Issue
Block a user