diff --git a/server.py b/server.py index d6004862..ff0c4182 100644 --- a/server.py +++ b/server.py @@ -130,6 +130,22 @@ def _compute_regime_winrates_cached(pt, _approx_univ): if not _trades: continue _rmap = _rmap_a if _mkt != 'hk' else _rmap_hk + # ── 温区天数(该策略 trades 窗口内,线性年化用)── + _pt_days = {"total": 0, "regimes": {}} + try: + _eds = [t.get("entry_date", "") for t in _trades if t.get("entry_date")] + _eds = [d for d in _eds if d in _rmap] + if _eds: + _d_min, _d_max = min(_eds), max(_eds) + _cnt = {} + _tot = 0 + for _d, _reg in _rmap.items(): + if _d_min <= _d <= _d_max: + _tot += 1 + _cnt[_reg] = _cnt.get(_reg, 0) + 1 + _pt_days = {"total": _tot, "regimes": _cnt} + except Exception: + pass _by_regime = _dd(list) for _t in _trades: _ed = _t.get("entry_date", "") @@ -143,8 +159,14 @@ def _compute_regime_winrates_cached(pt, _approx_univ): if not _sim: continue _wr_v = _extra.get("win_rate") - _cagr_v = _sim.get("cagr_pct") + # 2026-08-15 温区年化线性放大:收益 × (窗口总天数/该温区天数),消除复利爆炸 _ret_v = _sim.get("total_return_pct") + _reg_days = (_pt_days.get("regimes") or {}).get(_reg, 0) + _pt_total = _pt_days.get("total", 0) + if _ret_v is not None and _reg_days > 0 and _pt_total > 0: + _cagr_v = round(_ret_v * (_pt_total / _reg_days), 1) + else: + _cagr_v = None _dd_v = _sim.get("portfolio_max_dd_pct") _cf_v = _sim.get("capital_final") _pt_v = _sim.get("positions_taken")