feat: qualification改per-regime(策略可适应多温区)+激活用当前温区判定,替代单best_regime限制
This commit is contained in:
@@ -648,7 +648,7 @@ def api_research_strategies():
|
||||
# 2026-08-16 资格评估 + 手动可用性(标准A:长期10y/近期2y/当下1y 适应温区年化>大盘)
|
||||
try:
|
||||
sys.path.insert(0, "/home/hmo/MoFin/deploy/profile-scripts")
|
||||
from strategy_qualify import get_benchmarks as _qbench, evaluate_strategy as _qeval, is_available as _qavail, load_availability as _qload
|
||||
from strategy_qualify import get_benchmarks as _qbench, evaluate_all_regimes as _qeval, is_available as _qavail, load_availability as _qload
|
||||
except Exception:
|
||||
_qbench = _qeval = _qavail = _qload = None
|
||||
_qbench_data = _qbench() if _qbench else {}
|
||||
@@ -795,28 +795,29 @@ def api_research_strategies():
|
||||
s['current'] = s['version'] in _active_set
|
||||
# 2026-08-15 适应温区(前端方案A:策略只在适应温区表显示一行)
|
||||
s['best_regime'] = _best_regime_map.get(s['version'])
|
||||
# 2026-08-16 资格评估(标准A:长期10y/近期2y/当下1y 适应温区年化>大盘)
|
||||
_qual = _qeval(s['version'], (s.get('market') or 'a') if (s.get('market') or 'a') != 'all' else 'a',
|
||||
best_regime=s.get('best_regime'), bench=_qbench_data) if _qeval else None
|
||||
if _qual:
|
||||
s['qualification'] = {
|
||||
'long_ok': _qual.get('long_ok'), 'mid_ok': _qual.get('mid_ok'),
|
||||
'short_ok': _qual.get('short_ok'),
|
||||
'cagr_10y': _qual.get('cagr_10y'), 'cagr_2y': _qual.get('cagr_2y'),
|
||||
'cagr_1y': _qual.get('cagr_1y'),
|
||||
# 2026-08-16 资格评估(标准A)——per-regime,策略可适应多个温区
|
||||
_mkt_v = (s.get('market') or 'a') if (s.get('market') or 'a') != 'all' else 'a'
|
||||
_quals = _qeval(s['version'], _mkt_v, bench=_qbench_data) if _qeval else {}
|
||||
s['qualification'] = {}
|
||||
for _rg, _q in _quals.items():
|
||||
s['qualification'][_rg] = {
|
||||
'long_ok': _q.get('long_ok'), 'mid_ok': _q.get('mid_ok'),
|
||||
'short_ok': _q.get('short_ok'),
|
||||
'cagr_10y': _q.get('cagr_10y'), 'cagr_2y': _q.get('cagr_2y'),
|
||||
'cagr_1y': _q.get('cagr_1y'),
|
||||
'bench_10y': _qbench_data.get('10y'), 'bench_2y': _qbench_data.get('2y'),
|
||||
'bench_1y': _qbench_data.get('1y'),
|
||||
}
|
||||
else:
|
||||
s['qualification'] = None
|
||||
# 当前温区资格(激活判定用)
|
||||
_cur_regime_q = (s.get('qualification') or {}).get(_weights.get('state') or '')
|
||||
_l_ok = bool(_cur_regime_q and _cur_regime_q.get('long_ok'))
|
||||
_m_ok = bool(_cur_regime_q and _cur_regime_q.get('mid_ok'))
|
||||
_s_ok = bool(_cur_regime_q and _cur_regime_q.get('short_ok'))
|
||||
# 2026-08-16 手动可用性(老莫把关):激活只能是可用的策略
|
||||
s['manual_available'] = _qavail(s['version']) if _qavail else True
|
||||
# 2026-08-15 证伪数据驱动:从 strategy_research.deprecated 读(替代前端硬编码)
|
||||
s['deprecated'] = _deprecated.get(s['version'])
|
||||
# ── 2026-08-16 三状态(派生):激活=当前温区+手动可用+三项达标;可用=手动可用+长期近期过 ──
|
||||
_l_ok = bool(_qual and _qual.get('long_ok'))
|
||||
_m_ok = bool(_qual and _qual.get('mid_ok'))
|
||||
_s_ok = bool(_qual and _qual.get('short_ok'))
|
||||
|
||||
_qual_ok_3 = _l_ok and _m_ok and _s_ok
|
||||
_qual_ok_2 = _l_ok and _m_ok
|
||||
if s['version'] in _active_set:
|
||||
|
||||
Reference in New Issue
Block a user