"""基金深度分析的数据整理层。""" from __future__ import annotations from decimal import Decimal from typing import Iterable def _number(value): if isinstance(value, Decimal): return float(value) return value def _display_value(value): if value is None: return "暂无" if isinstance(value, float): return f"{value:g}" return str(value) def _build_analysis_text(fund: dict, metrics: list[dict]) -> str: fund_name = fund.get("fund_name") or fund.get("fund_code") or "该基金" if not metrics: return f"{fund_name}暂无足够业绩数据,暂无法形成完整解读。" latest = metrics[-1] period = _display_value(latest.get("period")) return_rate = _display_value(latest.get("return_rate")) max_drawdown = _display_value(latest.get("max_drawdown")) sharpe = _display_value(latest.get("sharpe")) return ( f"{fund_name}在{period}的历史收益率为{return_rate}%," f"最大回撤为{max_drawdown}%,夏普比率为{sharpe}。" "以上仅基于历史业绩数据,不代表未来收益。" ) def build_fund_analysis(fund: dict, performance_rows: Iterable[dict]) -> dict: metrics = [] for row in performance_rows: metrics.append( { key: _number(value) for key, value in row.items() } ) return { "fund_code": fund.get("fund_code"), "fund_name": fund.get("fund_name"), "risk_level": fund.get("risk_level"), "metrics": metrics, "analysis_text": _build_analysis_text(fund, metrics), "chart_data": { "periods": [row.get("period") for row in metrics], "return_rate": [row.get("return_rate") for row in metrics], "annual_volatility": [row.get("annual_volatility") for row in metrics], "max_drawdown": [row.get("max_drawdown") for row in metrics], "sharpe": [row.get("sharpe") for row in metrics], }, }