62 lines
2.0 KiB
Python
62 lines
2.0 KiB
Python
"""基金深度分析的数据整理层。"""
|
||
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],
|
||
},
|
||
}
|