fix: 进化面板完整版——基线对比+健康度+迭代历史+回测教训(标注来源)
This commit is contained in:
+32
-9
@@ -1979,24 +1979,47 @@ async function loadEvolutionBox() {
|
|||||||
try {
|
try {
|
||||||
const r = await fetch('/api/evolution/dashboard');
|
const r = await fetch('/api/evolution/dashboard');
|
||||||
const d = await r.json();
|
const d = await r.json();
|
||||||
let h = '<div class="flex items-center justify-between mb-1"><span class="text-sm font-semibold text-emerald-400">🧬 策略自我进化</span><button onclick="loadEvolutionBox()" class="text-xs text-blue-400 hover:text-blue-300">刷新</button></div>';
|
let h = '<div class="flex items-center justify-between mb-2"><span class="text-base font-semibold text-emerald-400">🧬 策略自我进化</span><button onclick="loadEvolutionBox()" class="text-sm text-blue-400 hover:text-blue-300">刷新</button></div>';
|
||||||
|
|
||||||
|
// ── 基线对比 ──
|
||||||
if (d.baseline) {
|
if (d.baseline) {
|
||||||
h += '<div class="grid grid-cols-3 gap-2 mb-2 text-sm">';
|
h += '<div class="grid grid-cols-3 gap-2 mb-3"><span class="text-sm text-slate-500 col-span-3">5年回测基线:</span>';
|
||||||
for (const [v, b] of Object.entries(d.baseline)) {
|
for (const [v, b] of Object.entries(d.baseline)) {
|
||||||
const clr = v === 'v_next4' ? 'text-emerald-400' : 'text-slate-300';
|
const clr = v === 'v_next4' ? 'text-emerald-400' : 'text-slate-300';
|
||||||
h += '<div class="bg-slate-900/50 rounded px-2 py-1"><span class="'+clr+' font-mono font-bold">'+v+'</span><br><span class="text-slate-500 text-xs">胜率'+b.win_rate+'% 收益'+b.total_return+'% 回撤'+b.max_dd+'%</span></div>';
|
h += '<div class="bg-slate-900/50 rounded px-2 py-1"><span class="'+clr+' font-mono font-bold text-sm">'+v+'</span><br><span class="text-slate-500 text-xs">胜率'+b.win_rate+'% 收益'+b.total_return+'% 回撤'+b.max_dd+'%</span></div>';
|
||||||
}
|
}
|
||||||
h += '</div>';
|
h += '</div>';
|
||||||
}
|
}
|
||||||
if (d.health && d.health.length > 0) { const hs = d.health[0]; const sc = hs.health_score;
|
|
||||||
|
// ── 健康度 ──
|
||||||
|
if (d.health && d.health.length > 0) {
|
||||||
|
const hs = d.health[0]; const sc = hs.health_score;
|
||||||
const color = sc >= 70 ? 'text-emerald-400' : sc >= 50 ? 'text-amber-400' : 'text-red-400';
|
const color = sc >= 70 ? 'text-emerald-400' : sc >= 50 ? 'text-amber-400' : 'text-red-400';
|
||||||
h += '<div class="text-sm '+color+'">健康度: '+sc+'分 (实盘'+hs.live_trades+'笔)</div>'; }
|
h += '<div class="mb-2 text-sm"><span class="'+color+' font-bold">健康度: '+sc+'分</span><span class="text-slate-500"> (实盘'+hs.live_trades+'笔 vs 回测'+hs.backtest_wr+'%胜率)</span>';
|
||||||
if (d.lessons && d.lessons.length > 0) {
|
if (hs.live_trades === 0) h += '<span class="text-slate-600 text-xs"> [暂无实盘数据, 分数为中性]</span>';
|
||||||
h += '<div class="text-sm text-slate-400 mt-2">📝 最近教训:</div>';
|
h += '</div>';
|
||||||
for (const l of d.lessons.slice(0,3)) h += '<div class="text-sm text-slate-300">'+(l.lesson_type==='win_pattern'?'✅':'❌')+' '+l.lesson_text+'</div>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── 进化历史 ──
|
||||||
|
if (d.evolution && d.evolution.length > 0) {
|
||||||
|
h += '<div class="text-sm text-slate-400 mb-1">🔄 迭代历史:</div>';
|
||||||
|
for (const e of d.evolution.slice(0,5)) {
|
||||||
|
h += '<div class="text-sm text-slate-300 mb-0.5">'+e.parent_version+' → '+e.child_version+' <span class="text-slate-500">'+e.change_description+'</span>'+(e.promoted?' <span class="text-emerald-400 text-xs">✅采纳</span>':'')+'</div>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
h += '<div class="text-sm text-slate-600 mb-1">🔄 迭代历史: 暂无 (auto_iterator 待触发)</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── 教训 ──
|
||||||
|
if (d.lessons && d.lessons.length > 0) {
|
||||||
|
h += '<div class="text-sm text-slate-400 mt-2 mb-1">📝 回测教训 (基于v_next4 5y交易分析):</div>';
|
||||||
|
for (const l of d.lessons.slice(0,5)) {
|
||||||
|
h += '<div class="text-sm text-slate-300 mb-0.5">'+(l.lesson_type==='win_pattern'?'✅盈利规律':'❌亏损规律')+' '+l.lesson_text+' <span class="text-slate-600 text-xs">'+Math.round(l.confidence*100)+'%置信</span></div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
box.innerHTML = h;
|
box.innerHTML = h;
|
||||||
} catch (e) { box.innerHTML = '<div class="text-xs text-red-400">加载失败</div>'; }
|
} catch (e) { box.innerHTML = '<div class="text-sm text-red-400">进化模块加载失败: '+e.message+'</div>'; }
|
||||||
}
|
}
|
||||||
// 研究Tab活跃时加载进化模块
|
// 研究Tab活跃时加载进化模块
|
||||||
new MutationObserver(()=>{if(!document.getElementById('tab-research')?.classList?.contains('hidden'))loadEvolutionBox();}).observe(document.body,{attributes:true,subtree:true});
|
new MutationObserver(()=>{if(!document.getElementById('tab-research')?.classList?.contains('hidden'))loadEvolutionBox();}).observe(document.body,{attributes:true,subtree:true});
|
||||||
|
|||||||
Reference in New Issue
Block a user