This commit is contained in:
aaron 2026-05-20 22:29:00 +08:00
parent e43760e006
commit 583280294b
2 changed files with 18 additions and 6 deletions

View File

@ -1171,6 +1171,12 @@ def _periodized_return_pct(total_return_pct: float, running_days: float, period_
return round((growth ** (period_days / running_days) - 1) * 100, 4)
def _periodized_return_label(total_return_pct: float, running_days: float, period_days: float) -> str:
if running_days < 30:
return "样本不足"
return _fmt_pct(_periodized_return_pct(total_return_pct, running_days, period_days))
def send_paper_trading_report(days: int = 30) -> dict:
days = max(1, min(_safe_int(days, 30), 365))
summary = get_paper_trading_summary(days=days)
@ -1186,8 +1192,10 @@ def send_paper_trading_report(days: int = 30) -> dict:
return_pct = _safe_float(summary.get("account_total_return_pct"))
win_rate = _safe_float(summary.get("win_rate"))
running_days = _paper_running_days()
monthly_return_pct = _periodized_return_pct(return_pct, running_days, 30)
annualized_return_pct = _periodized_return_pct(return_pct, running_days, 365)
monthly_return_pct = _periodized_return_pct(return_pct, running_days, 30) if running_days >= 30 else None
annualized_return_pct = _periodized_return_pct(return_pct, running_days, 365) if running_days >= 30 else None
monthly_return_label = _periodized_return_label(return_pct, running_days, 30)
annualized_return_label = _periodized_return_label(return_pct, running_days, 365)
template = "green" if total_pnl >= 0 else "red"
elements = [
{
@ -1206,8 +1214,8 @@ def send_paper_trading_report(days: int = 30) -> dict:
"background_style": "default",
"columns": [
{"tag": "column", "width": "weighted", "weight": 1, "elements": [_card_field("账户收益率", _fmt_pct(return_pct))]},
{"tag": "column", "width": "weighted", "weight": 1, "elements": [_card_field("月化收益率", _fmt_pct(monthly_return_pct))]},
{"tag": "column", "width": "weighted", "weight": 1, "elements": [_card_field("年化收益率", _fmt_pct(annualized_return_pct))]},
{"tag": "column", "width": "weighted", "weight": 1, "elements": [_card_field("月化收益率", monthly_return_label)]},
{"tag": "column", "width": "weighted", "weight": 1, "elements": [_card_field("年化收益率", annualized_return_label)]},
],
},
{
@ -1250,6 +1258,8 @@ def send_paper_trading_report(days: int = 30) -> dict:
"running_days": running_days,
"monthly_return_pct": monthly_return_pct,
"annualized_return_pct": annualized_return_pct,
"monthly_return_label": monthly_return_label,
"annualized_return_label": annualized_return_label,
"summary": summary,
"sent_at": _now(),
"push_result": push_result,

View File

@ -428,8 +428,10 @@ def test_send_paper_trading_report_pushes_performance_summary(monkeypatch, buy_n
assert result["ok"] is True
assert result["running_days"] >= 1
assert "monthly_return_pct" in result
assert "annualized_return_pct" in result
assert result["monthly_return_pct"] is None
assert result["annualized_return_pct"] is None
assert result["monthly_return_label"] == "样本不足"
assert result["annualized_return_label"] == "样本不足"
assert pushed[-1]["metadata"]["event_type"] == "trade_report"
text = _visible_card_text(pushed[-1])
assert "交易报告" in text