alphax/static/strategy.html
2026-05-16 14:52:10 +08:00

48 lines
6.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}策略 — AlphaX Agent Crypto{% endblock %}
{% block nav_links %}
<a class="sidebar-link" href="/app"><svg class="link-icon"><use href="#svg-dashboard"/></svg>看板</a>
<a class="sidebar-link" href="/market"><svg class="link-icon"><use href="#svg-target"/></svg>市场总览</a>
<a class="sidebar-link" href="/sentiment"><svg class="link-icon"><use href="#svg-sentiment"/></svg>舆情</a>
<a class="sidebar-link" href="/onchain"><svg class="link-icon"><use href="#svg-onchain"/></svg>链上异动</a>
<a class="sidebar-link" href="/subscription"><svg class="link-icon"><use href="#svg-subscribe"/></svg>订阅</a>
<a class="sidebar-link" href="/referral"><svg class="link-icon"><use href="#svg-referral"/></svg>推荐</a>
<div class="sidebar-section-label admin-link" style="display:none">研发</div>
<a class="sidebar-link admin-link" href="/pipeline" style="display:none"><svg class="link-icon"><use href="#svg-pipeline"/></svg>链路日志</a>
<a class="sidebar-link admin-link" href="/cron" style="display:none"><svg class="link-icon"><use href="#svg-cron"/></svg>调度中心</a>
<a class="sidebar-link admin-link" href="/llm-insights" style="display:none"><svg class="link-icon"><use href="#svg-ai"/></svg>AI 记录</a>
<a class="sidebar-link active admin-link" href="/strategy" style="display:none"><svg class="link-icon"><use href="#svg-target"/></svg>策略</a>
<a class="sidebar-link admin-link" href="/iteration" style="display:none"><svg class="link-icon"><use href="#svg-iterate"/></svg>迭代</a>
<a class="sidebar-link admin-link" href="/admin.html" style="display:none"><svg class="link-icon"><use href="#svg-admin"/></svg>管理</a>
{% endblock %}
{% block extra_head_css %}
<style>
.shell{width:min(100% - 40px,1180px);margin:0 auto;padding:24px 0 48px}.page-head{margin-bottom:20px}.page-head h1{font-size:28px;letter-spacing:-.8px}.page-head p{color:var(--stone);font-size:14px;margin-top:4px}.metrics{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:12px}.metric{border:1px solid var(--hairline-soft);background:var(--canvas);border-radius:var(--radius-xl);padding:18px;text-align:center}.metric .num{font-size:30px;font-weight:900;letter-spacing:-.8px}.metric .lbl{font-size:12px;color:var(--stone);font-weight:700;margin-top:4px}.disclaimer{font-size:12px;color:var(--stone);background:var(--surface);border:1px solid var(--hairline-soft);border-radius:var(--radius-lg);padding:10px 14px;margin-bottom:16px}.flow{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:16px}.flow-step{border:1px solid var(--hairline-soft);background:var(--canvas);border-radius:var(--radius-lg);padding:12px}.flow-step b{display:block;color:var(--ink);font-size:13px;margin-bottom:5px}.flow-step span{display:block;color:var(--stone);font-size:12px;line-height:1.55}.flow-link{color:var(--primary);font-weight:900;text-decoration:none}.panel{border:1px solid var(--hairline-soft);background:var(--canvas);border-radius:var(--radius-xl);padding:18px;margin-bottom:16px}.panel h2{font-size:16px;margin-bottom:12px}.grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}.table{width:100%;border-collapse:collapse}.table th,.table td{padding:9px 8px;border-bottom:1px solid var(--hairline-soft);font-size:12px;text-align:left}.table th{color:var(--stone);font-weight:800}.pos{color:var(--green);font-weight:800}.neg{color:var(--red);font-weight:800}.tag{display:inline-flex;border-radius:var(--radius-full);background:var(--surface);padding:3px 8px;font-weight:800}.empty{color:var(--stone);font-size:13px;padding:16px;background:var(--surface);border-radius:var(--radius-lg)}@media(max-width:980px){.metrics{grid-template-columns:repeat(2,1fr)}.flow{grid-template-columns:repeat(2,1fr)}}@media(max-width:820px){.grid{grid-template-columns:1fr}.shell{width:min(100% - 24px,1180px)}}@media(max-width:520px){.flow{grid-template-columns:1fr}}
</style>
{% endblock %}
{% block content %}
<div class="shell">
<div class="page-head"><h1>策略</h1><p>系统可信度、版本表现、因子归因与市场环境归因。</p></div>
<div class="metrics" id="metrics"></div>
<div class="disclaimer">数据基于历史信号跟踪,仅用于策略研究与模型评估,不构成收益承诺或投资建议。</div>
<div class="flow">
<div class="flow-step"><b>发现</b><span>粗筛只进观察/候选,不直接计交易绩效。</span></div>
<div class="flow-step"><b>确认</b><span>只有新鲜触发和入场计划达标才进入可交易口径。</span></div>
<div class="flow-step"><b>复盘</b><span>只用48h窗口样本更新有效表现。</span></div>
<div class="flow-step"><b>迭代</b><span>候选规则经发布闸门后才生效。<a class="flow-link" href="/iteration">查看迭代</a></span></div>
</div>
<div class="grid">
<section class="panel"><h2>版本表现</h2><div id="versionPerf"></div></section>
<section class="panel"><h2>市场环境归因</h2><div id="envPerf"></div></section>
</div>
<section class="panel"><h2>因子归因</h2><div id="factorPerf"></div></section>
</div>
{% endblock %}
{% block extra_script %}
<script>
function pct(x){x=Number(x||0);return (x>=0?'+':'')+x.toFixed(2)+'%'}function cls(x){return Number(x||0)>=0?'pos':'neg'}
function table(rows,key){if(!rows||!rows.length)return'<div class="empty">暂无数据</div>';return '<table class="table"><thead><tr><th>名称</th><th>次数</th><th>命中率</th><th>平均表现</th><th>最大表现</th><th>最大回撤</th></tr></thead><tbody>'+rows.map(r=>'<tr><td><span class="tag">'+(r[key]||'--')+'</span></td><td>'+r.total_count+'</td><td>'+Number(r.win_rate_pct||0).toFixed(1)+'%</td><td class="'+cls(r.avg_pnl_pct)+'">'+pct(r.avg_pnl_pct)+'</td><td class="pos">'+pct(r.max_gain_pct)+'</td><td class="neg">'+Number(r.max_drawdown_pct||0).toFixed(2)+'%</td></tr>').join('')+'</tbody></table>'}
async function load(){try{var d=await (await fetch('/api/strategy/insights')).json();var o=d.overview||{};var active=await (await fetch('/api/recommendations/active?actionable_only=false&hours=12')).json();metrics.innerHTML=['总信号|'+(o.total_signals||0)+'|','已验证|'+(o.resolved_count||0)+'|','信号命中率|'+Number(o.win_rate_pct||0).toFixed(1)+'%|green','当前有效机会|'+(Array.isArray(active)?active.length:0)+'|blue','最大表现|'+pct(o.max_gain_pct)+'|green','最大回撤|'+Number(o.max_drawdown_pct||0).toFixed(1)+'%|red'].map(s=>{var a=s.split('|');return '<div class="metric"><div class="num" '+(a[2]?'style="color:var(--'+a[2]+')"':'')+'>'+a[1]+'</div><div class="lbl">'+a[0]+'</div></div>'}).join('');versionPerf.innerHTML=table(d.version_performance,'strategy_version');envPerf.innerHTML=table(d.market_environment,'environment');factorPerf.innerHTML=table(d.factor_attribution,'factor')}catch(e){metrics.innerHTML='<div class="empty">加载失败</div>'}}load();
</script>
{% endblock %}