You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
buffer_platform/data/trade_review.html

410 lines
26 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>期货智析 - 交易复盘</title>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,BlinkMacSystemFont,sans-serif;background:#f5f7fa;color:#333;line-height:1.6}
.header{background:#fff;border-bottom:1px solid #e8e8e8;padding:0 24px;height:56px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100}
.header-left{display:flex;align-items:center;gap:8px}
.logo{font-size:16px;font-weight:600}
.nav-tabs{display:flex;gap:24px}
.nav-tab{padding:16px 0;font-size:14px;color:#666;cursor:pointer;border-bottom:2px solid transparent}
.nav-tab.active{color:#1890ff;border-bottom-color:#1890ff;font-weight:500}
.header-right{font-size:12px;color:#999}
.main{max-width:1400px;margin:0 auto;padding:24px}
.toolbar{display:flex;align-items:center;gap:12px;margin-bottom:20px;flex-wrap:wrap}
.btn{padding:8px 16px;border:none;border-radius:6px;font-size:14px;cursor:pointer;display:flex;align-items:center;gap:6px}
.btn-primary{background:#1890ff;color:#fff}
.btn-danger{background:#fff;color:#ff4d4f;border:1px solid #ffccc7}
.btn-default{background:#fff;color:#666;border:1px solid #d9d9d9}
.date-picker{padding:8px 12px;border:1px solid #d9d9d9;border-radius:6px;font-size:14px}
.date-range{display:flex;align-items:center;gap:8px}
.toolbar-right{margin-left:auto;display:flex;gap:12px}
.cards{display:grid;grid-template-columns:repeat(6,1fr);gap:16px;margin-bottom:24px}
.card{background:#fff;border-radius:8px;padding:16px;text-align:center;box-shadow:0 1px 2px rgba(0,0,0,0.05)}
.card-label{font-size:12px;color:#999;margin-bottom:8px}
.card-value{font-size:24px;font-weight:600;margin-bottom:4px}
.card-sub{font-size:12px;color:#999}
.green{color:#52c41a}
.red{color:#ff4d4f}
.box{background:#fff;border-radius:8px;padding:20px;margin-bottom:24px;box-shadow:0 1px 2px rgba(0,0,0,0.05)}
.box-title{font-size:16px;font-weight:500;margin-bottom:16px}
.chart{width:100%;height:350px}
.tbl-box{background:#fff;border-radius:8px;padding:20px;margin-bottom:24px;box-shadow:0 1px 2px rgba(0,0,0,0.05);overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:13px}
th{background:#fafafa;padding:12px 8px;text-align:left;font-weight:500;color:#666;border-bottom:1px solid #e8e8e8;white-space:nowrap}
td{padding:12px 8px;border-bottom:1px solid #f0f0f0;white-space:nowrap}
tr:hover{background:#f5f7fa}
.link{color:#1890ff;cursor:pointer;text-decoration:none}
.modal-bg{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);z-index:1000;justify-content:center;align-items:center}
.modal-bg.show{display:flex}
#vmod,#tmod{z-index:1001}
.modal{background:#fff;border-radius:12px;width:90%;max-width:1000px;max-height:90vh;overflow-y:auto}
.modal-hd{padding:20px 24px;border-bottom:1px solid #e8e8e8;display:flex;justify-content:space-between;align-items:center}
.modal-close{width:32px;height:32px;border:none;background:#f5f5f5;border-radius:50%;cursor:pointer;font-size:18px}
.modal-bd{padding:24px}
.ov{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:24px}
.ov-item{background:#f5f7fa;border-radius:8px;padding:16px;text-align:center}
.ov-label{font-size:12px;color:#999}
.ov-val{font-size:20px;font-weight:600}
.ktb{display:flex;gap:8px;margin-bottom:16px}
.kbtn{padding:6px 12px;border:1px solid #d9d9d9;background:#fff;border-radius:4px;cursor:pointer;font-size:13px}
.kbtn.active{background:#1890ff;color:#fff;border-color:#1890ff}
.bubble{width:100%;height:400px}
.ai-box{background:linear-gradient(135deg, #f0f7ff 0%, #e6f4ff 100%);border:1px solid #bae0ff;border-radius:8px;padding:20px;margin-bottom:24px;position:relative}
.ai-title{font-size:16px;font-weight:600;color:#0958d9;margin-bottom:12px;display:flex;align-items:center;gap:8px}
.ai-content{font-size:14px;color:#333;line-height:1.8}
.ai-tag{display:inline-block;background:#e6f4ff;color:#0958d9;padding:2px 8px;border-radius:4px;font-size:12px;margin-right:8px;margin-bottom:8px}
.variety-sec{margin-top:24px;border-top:1px solid #e8e8e8;padding-top:20px}
@media(max-width:1200px){.cards{grid-template-columns:repeat(3,1fr)}}
@media(max-width:768px){.cards{grid-template-columns:repeat(2,1fr)}}
</style>
</head>
<body>
<div class="header">
<div class="header-left"><div class="logo">&#9670; 期货智析</div></div>
<div class="nav-tabs"><div class="nav-tab">品种分析</div><div class="nav-tab">自选</div><div class="nav-tab">复盘计划</div><div class="nav-tab active">交易复盘</div></div>
<div class="header-right"><span style="color:#52c41a">&#9679;</span> LIVE &nbsp; 2026-06-21 22:41:23</div>
</div>
<div class="main">
<div class="toolbar">
<button class="btn btn-primary">导入结算单</button><button class="btn btn-primary">批量导入</button>
<div class="date-range"><input type="date" class="date-picker" value="2026-06-01"><span>~</span><input type="date" class="date-picker" value="2026-06-12"></div>
<button class="btn btn-default">查询</button>
<div class="toolbar-right"><button class="btn btn-danger">删除当日</button><button class="btn btn-default">批次管理</button></div>
</div>
<div class="cards">
<div class="card"><div class="card-label">总盈亏</div><div class="card-value red">-656.43</div><div class="card-sub">平仓盈亏</div></div>
<div class="card"><div class="card-label">净盈亏</div><div class="card-value red">-3502.86</div><div class="card-sub">扣除手续费后</div></div>
<div class="card"><div class="card-label">胜率</div><div class="card-value">14.2%</div><div class="card-sub">盈亏比: 5.72</div></div>
<div class="card"><div class="card-label">交易笔数</div><div class="card-value">398</div><div class="card-sub">10个交易日</div></div>
<div class="card"><div class="card-label">最大回撤</div><div class="card-value red">-1768.27</div><div class="card-sub">2026-06-03</div></div>
<div class="card"><div class="card-label">日均盈亏</div><div class="card-value red">-65.64</div><div class="card-sub">最大连盈5/连亏5</div></div>
</div>
<div class="box"><div class="box-title">账户权益曲线(累计净盈亏 + 每日盈亏)</div><div class="chart" id="eq"></div></div>
<div class="box"><div class="box-title">品种盈亏分布(气泡大小=手续费占比,颜色=净盈亏)</div><div class="bubble" id="bb"></div></div>
<div class="tbl-box"><div class="box-title">每日交易详情(点击日期查看详情)</div>
<table><thead><tr><th>日期</th><th>笔数</th><th>平仓盈亏</th><th>手续费</th><th>净盈亏</th><th>盈利笔</th><th>亏损笔</th><th>胜率</th><th>最大盈利</th><th>最大亏损</th><th>品种数</th></tr></thead><tbody id="dtb"></tbody></table></div>
<div class="tbl-box"><div class="box-title">品种盈亏排行(点击查看品种详情)</div>
<table><thead><tr><th>排名</th><th>代码</th><th>名称</th><th>净盈亏</th><th>平仓盈亏</th><th>手续费</th><th>胜率</th><th>盈亏比</th><th>笔数</th><th>操作</th></tr></thead><tbody id="vtb"></tbody></table></div>
</div>
<div class="modal-bg" id="vmod">
<div class="modal">
<div class="modal-hd"><div class="box-title" id="vtitle">品种详情</div><button class="modal-close" onclick="cm('vmod')">&times;</button></div>
<div class="modal-bd">
<div class="ov">
<div class="ov-item"><div class="ov-label">净盈亏</div><div class="ov-val red" id="vn">-</div></div>
<div class="ov-item"><div class="ov-label">胜率</div><div class="ov-val" id="vw">-</div></div>
<div class="ov-item"><div class="ov-label">盈亏比</div><div class="ov-val" id="vr">-</div></div>
<div class="ov-item"><div class="ov-label">交易笔数</div><div class="ov-val" id="vc">-</div></div>
<div class="ov-item"><div class="ov-label">手续费</div><div class="ov-val" id="vf">-</div></div>
<div class="ov-item"><div class="ov-label">最大单笔盈利</div><div class="ov-val green" id="vm">-</div></div>
</div>
<div class="box" style="margin-bottom:16px">
<div class="ktb"><button class="kbtn active">日线</button><button class="kbtn">60分钟</button><button class="kbtn">15分钟</button><button class="kbtn">5分钟</button><button class="btn btn-default" style="margin-left:auto">刷新K线</button></div>
<div class="chart" id="kc" style="height:400px"></div>
</div>
<div class="tbl-box"><div class="box-title">该品种交易记录</div>
<table><thead><tr><th>开仓时间</th><th>方向</th><th>开仓价</th><th>平仓价</th><th>盈亏</th><th>手续费</th><th>操作</th></tr></thead><tbody id="vttb"></tbody></table></div>
</div></div></div>
<div class="modal-bg" id="tmod">
<div class="modal" style="max-width:700px">
<div class="modal-hd"><div class="box-title" id="ttitle">交易详情</div><button class="modal-close" onclick="cm('tmod')">&times;</button></div>
<div class="modal-bd">
<div class="ov">
<div class="ov-item"><div class="ov-label">品种</div><div class="ov-val" id="tv">-</div></div>
<div class="ov-item"><div class="ov-label">方向</div><div class="ov-val red" id="td">-</div></div>
<div class="ov-item"><div class="ov-label">开仓日期</div><div class="ov-val" id="tod">-</div></div>
<div class="ov-item"><div class="ov-label">开仓时间</div><div class="ov-val" id="tot">-</div></div>
<div class="ov-item"><div class="ov-label">开仓价</div><div class="ov-val" id="top">-</div></div>
<div class="ov-item"><div class="ov-label">平仓价</div><div class="ov-val" id="tcp">-</div></div>
<div class="ov-item"><div class="ov-label">手数</div><div class="ov-val" id="tvol">-</div></div>
<div class="ov-item"><div class="ov-label">手续费</div><div class="ov-val" id="tfee">-</div></div>
<div class="ov-item"><div class="ov-label">净盈亏</div><div class="ov-val red" id="tpnl">-</div></div>
</div>
<div class="box" style="margin-top:20px"><div class="box-title">K线走势与买卖点</div><div class="chart" id="tkc" style="height:300px"></div></div>
<div style="margin-top:20px;text-align:center"><button class="btn btn-primary">开始AI分析</button></div>
</div></div></div>
<div class="modal-bg" id="dmod">
<div class="modal" style="max-width:1000px">
<div class="modal-hd"><div class="box-title" id="dtitle">每日详情</div><button class="modal-close" onclick="cm('dmod')">&times;</button></div>
<div class="modal-bd">
<div class="ov">
<div class="ov-item"><div class="ov-label">平仓盈亏</div><div class="ov-val red" id="dpnl">-</div></div>
<div class="ov-item"><div class="ov-label">净盈亏</div><div class="ov-val red" id="dnpnl">-</div></div>
<div class="ov-item"><div class="ov-label">胜率</div><div class="ov-val" id="dwr">-</div></div>
<div class="ov-item"><div class="ov-label">手续费</div><div class="ov-val" id="dfee">-</div></div>
<div class="ov-item"><div class="ov-label">最大盈利</div><div class="ov-val green" id="dmp">-</div></div>
<div class="ov-item"><div class="ov-label">最大亏损</div><div class="ov-val red" id="dml">-</div></div>
</div>
<div class="ai-box">
<div class="ai-title">&#129302; AI 交易诊断报告</div>
<div class="ai-content" id="dai"></div>
</div>
<div class="variety-sec">
<div class="box-title" style="margin-bottom:12px">当日品种盈亏统计(点击品种名查看详情)</div>
<div class="chart" id="dv_chart" style="height:280px;margin-bottom:16px"></div>
<div class="tbl-box"><table><thead><tr><th>品种</th><th>笔数</th><th>平仓盈亏</th><th>手续费</th><th>净盈亏</th><th>胜率</th><th>操作</th></tr></thead><tbody id="dvtb"></tbody></table></div>
</div>
<div class="tbl-box" style="margin-top:24px"><div class="box-title">当日交易流水</div>
<table><thead><tr><th>时间</th><th>品种</th><th>方向</th><th>开仓价</th><th>平仓价</th><th>盈亏</th><th>手续费</th></tr></thead><tbody id="dttb"></tbody></table></div>
</div></div></div>
<script>
var D=[
{d:"06-01",fd:"2026-06-01",t:33,p:-1042.18,c:982.18,w:7,l:25,wr:"21.9%",mp:1271.67,ml:-1128.42,v:8},
{d:"06-02",fd:"2026-06-02",t:46,p:-14.49,c:239.49,w:5,l:32,wr:"13.5%",mp:487.48,ml:-465.71,v:8},
{d:"06-03",fd:"2026-06-03",t:40,p:-1768.27,c:113.27,w:5,l:30,wr:"14.3%",mp:149.99,ml:-1512.02,v:8},
{d:"06-04",fd:"2026-06-04",t:64,p:-797.55,c:367.55,w:5,l:42,wr:"10.6%",mp:387.98,ml:-1128.78,v:8},
{d:"06-05",fd:"2026-06-05",t:44,p:-749.88,c:249.88,w:1,l:31,wr:"3.1%",mp:221.09,ml:-778.98,v:7},
{d:"06-08",fd:"2026-06-08",t:37,p:512.71,c:207.29,w:1,l:27,wr:"3.6%",mp:711.09,ml:-45.6,v:5},
{d:"06-09",fd:"2026-06-09",t:46,p:544.93,c:175.07,w:9,l:29,wr:"23.7%",mp:320,ml:-270,v:11},
{d:"06-10",fd:"2026-06-10",t:33,p:1497.85,c:212.15,w:6,l:21,wr:"22.2%",mp:468.04,ml:-45.6,v:9},
{d:"06-11",fd:"2026-06-11",t:34,p:960.64,c:169.36,w:4,l:24,wr:"14.3%",mp:1315.44,ml:-370,v:9},
{d:"06-12",fd:"2026-06-12",t:21,p:199.81,c:130.19,w:3,l:18,wr:"14.3%",mp:154.11,ml:-30.4,v:7}
];
var V=[
{c:"BU",n:"沥青",np:2495.94,p:2530,f:34.06,wr:"41.7%",pr:3.1,t:24},
{c:"MA",n:"甲醇",np:997.28,p:1090,f:92.72,wr:"50%",pr:2.5,t:8},
{c:"P",n:"棕榈油",np:419.52,p:480,f:60.48,wr:"37.5%",pr:1.8,t:24},
{c:"RU",n:"橡胶",np:46.97,p:50,f:3.03,wr:"50%",pr:1.2,t:2},
{c:"PS",n:"多晶硅",np:-4.1,p:0,f:4.1,wr:"0%",pr:0,t:1},
{c:"LC",n:"碳酸锂",np:-12.2,p:0,f:12.2,wr:"0%",pr:0,t:6},
{c:"SH",n:"烧碱",np:-11.52,p:0,f:11.52,wr:"25%",pr:0,t:4},
{c:"AG",n:"沪银",np:-32.8,p:0,f:32.8,wr:"0%",pr:0,t:28},
{c:"NI",n:"沪镍",np:-29.45,p:0,f:29.45,wr:"0%",pr:0,t:13},
{c:"AO",n:"氧化铝",np:-26.79,p:20,f:46.79,wr:"37.5%",pr:0.5,t:8},
{c:"CF",n:"棉花",np:-209.63,p:-175,f:34.63,wr:"33.3%",pr:0.7,t:15},
{c:"SC",n:"原油",np:-161.6,p:0,f:161.6,wr:"0%",pr:0,t:31},
{c:"EC",n:"集运欧线",np:-127.42,p:575,f:702.42,wr:"25%",pr:1.5,t:4},
{c:"CU",n:"沪铜",np:-95.95,p:0,f:95.95,wr:"0%",pr:0,t:26},
{c:"SN",n:"沪锡",np:-71.3,p:0,f:71.3,wr:"0%",pr:0,t:78},
{c:"OI",n:"菜油",np:-752.62,p:-690,f:62.62,wr:"19.4%",pr:0.6,t:31},
{c:"MO",n:"锰硅",np:-820.8,p:0,f:820.8,wr:"0%",pr:0,t:47},
{c:"TA",n:"PTA",np:-276.02,p:-270,f:6.02,wr:"0%",pr:0,t:3},
{c:"AP",n:"苹果",np:-315.04,p:-290,f:25.04,wr:"0%",pr:0,t:2},
{c:"JM",n:"焦煤",np:-2457.42,p:-2000,f:457.42,wr:"18.8%",pr:0.82,t:16}
];
V.sort(function(a,b){return b.np-a.np});
// Seeded RNG for consistent mock data
function mulberry32(a) {
return function() {
var t = a += 0x6D2B79F5;
t = Math.imul(t ^ t >>> 15, t | 1);
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
return ((t ^ t >>> 14) >>> 0) / 4294967296;
}
}
function hashDate(str) {
var h = 0;
for (var i = 0; i < str.length; i++) {
h = Math.imul(31, h) + str.charCodeAt(i) | 0;
}
return h;
}
function genDailyVariety(date) {
var seed = hashDate(date);
var rand = mulberry32(seed);
var dayData = D.filter(function(d){return d.fd===date})[0];
var total_p = dayData.p;
var total_c = dayData.c;
var result = [];
V.forEach(function(v) {
if (rand() > 0.3) {
var factor = (rand() - 0.5) * 2;
var pnl = total_p * factor * (rand() * 2);
var fee = Math.max(0, total_c * (rand() * 0.1));
var trades = Math.floor(rand() * 5) + 1;
var wins = Math.floor(rand() * trades);
result.push({ c: v.c, n: v.n, pnl: pnl, fee: fee, trades: trades, wins: wins, winRate: Math.round((wins / trades) * 100) + '%' });
}
});
result.sort(function(a,b){return b.pnl-a.pnl});
return result;
}
function renderDailyVariety(date) {
var data = genDailyVariety(date);
var tbody = document.getElementById("dvtb");
tbody.innerHTML = "";
var categories = data.map(function(x){return x.n});
var values = data.map(function(x){return x.pnl});
if(data.length===0){tbody.innerHTML="<tr><td colspan='7' style='text-align:center'>当日无品种交易数据</td></tr>";return;}
data.forEach(function(item) {
var pnlClass = item.pnl >= 0 ? 'green' : 'red';
var pnlStr = item.pnl >= 0 ? '+' + item.pnl.toFixed(2) : item.pnl.toFixed(2);
tbody.innerHTML += "<tr>" +
"<td><span class='link' onclick='ov(V.findIndex(function(v){return v.c==\""+item.c+"\"}), "+JSON.stringify(item.c)+", "+JSON.stringify(item.n)+")'>"+item.c+"</span></td>" +
"<td>"+item.trades+"</td><td class='"+pnlClass+"'>"+pnlStr+"</td><td>"+item.fee.toFixed(2)+"</td><td class='"+pnlClass+"'>"+pnlStr+"</td><td>"+item.winRate+"</td>" +
"<td><span class='link' onclick='ot("+JSON.stringify(item.n)+", \"做多\")'>详情</span></td></tr>";
});
var chartDom = document.getElementById("dv_chart");
if (dvc) dvc.dispose();
dvc = echarts.init(chartDom);
var barData = values.map(function(v){return{value:v,itemStyle:{color:v>=0?'#52c41a':'#ff4d4f'}}});
dvc.setOption({
tooltip: { trigger: 'axis', formatter: '{b}: {c}元' },
grid: {left: '3%', right: '4%', bottom: '12%', containLabel: true},
xAxis: { type: 'category', data: categories, axisLabel: {interval: 0, rotate: 30} },
yAxis: {type: 'value', name: '盈亏'},
series: [{ data: barData, type: 'bar', label: {show: true, position: 'top', fontSize: 10, formatter: function(p){return p.value>=0?'+':''+p.value.toFixed(0)}} }]
});
}
function rd(){
document.getElementById("dtb").innerHTML=D.map(function(x){
var np=x.p-x.c;
return "<tr style='cursor:pointer' onclick='od("+JSON.stringify(x.fd)+")'><td class='link'>"+x.fd+"</td><td>"+x.t+"</td><td class='"+(x.p>=0?"green":"red")+"'>"+(x.p>=0?"+":"")+x.p.toFixed(2)+"</td><td>"+x.c.toFixed(2)+"</td><td class='"+(np>=0?"green":"red")+"'>"+(np>=0?"+":"")+np.toFixed(2)+"</td><td>"+x.w+"</td><td>"+x.l+"</td><td>"+x.wr+"</td><td class='green'>+"+x.mp.toFixed(2)+"</td><td class='red'>"+x.ml.toFixed(2)+"</td><td>"+x.v+"</td></tr>";
}).join("");
}
function rv(){
document.getElementById("vtb").innerHTML=V.map(function(x,i){
var ic=i<3?["","&#129352;","&#129353;"][i]:(i+1);
var pr=x.np>=0;
return "<tr><td>"+ic+"</td><td><span class='link' onclick='ov("+i+", "+JSON.stringify(x.c)+", "+JSON.stringify(x.n)+")'>"+x.c+"</span></td><td>"+x.n+"</td><td class='"+(pr?"green":"red")+"'>"+(pr?"+":"")+x.np.toFixed(2)+"</td><td class='"+(x.p>=0?"green":"red")+"'>"+(x.p>=0?"+":"")+x.p.toFixed(2)+"</td><td>"+x.f.toFixed(2)+"</td><td>"+x.wr+"</td><td>"+x.pr.toFixed(2)+"</td><td>"+x.t+"</td><td><span class='link' onclick='ov("+i+", "+JSON.stringify(x.c)+", "+JSON.stringify(x.n)+")'>详情</span></td></tr>";
}).join("");
}
var ec,bc,kc,tkc,dvc;
function ie(){
ec=echarts.init(document.getElementById("eq"));
var cum=0;var cd=D.map(function(x){cum+=(x.p-x.c);return cum});
var dp=D.map(function(x){return x.p-x.c});
var dt=D.map(function(x){return x.fd});
ec.setOption({
tooltip:{trigger:"axis",formatter:function(p){var s=p[0].name+"<br/>";p.forEach(function(q){s+=q.marker+q.seriesName+": "+(q.value>=0?"+":"")+q.value.toFixed(2)+"<br/>"});return s}},
legend:{data:["累计净盈亏","每日净盈亏"],top:0},
grid:{left:"3%",right:"4%",bottom:"3%",containLabel:true},
xAxis:{type:"category",data:dt,axisLabel:{rotate:30}},
yAxis:[{type:"value",name:"累计净盈亏"},{type:"value",name:"每日净盈亏",splitLine:{show:false}}],
series:[
{name:"累计净盈亏",type:"line",data:cd,smooth:true,lineStyle:{width:3},areaStyle:{opacity:0.1},itemStyle:{color:"#1890ff"}},
{name:"每日净盈亏",type:"bar",yAxisIndex:1,data:dp.map(function(v){return{value:v,itemStyle:{color:v>=0?"#52c41a":"#ff4d4f"}}}),barWidth:20}
]
});
}
function ib(){
bc=echarts.init(document.getElementById("bb"));
var d=V.map(function(x,i){return{name:x.n,value:[x.t,x.np,Math.sqrt(Math.abs(x.f))*5+5,i],itemStyle:{color:x.np>=0?"#52c41a":"#ff4d4f"}}});
bc.setOption({
tooltip:{formatter:function(p){return p.name+"<br/>笔数: "+p.value[0]+"<br/>净盈亏: "+p.value[1].toFixed(2)+"<br/>手续费: "+V[p.value[3]].f.toFixed(2)}},
xAxis:{name:"交易笔数",nameLocation:"middle",nameGap:30},
yAxis:{name:"净盈亏",nameLocation:"middle",nameGap:50},
series:[{type:"scatter",data:d,symbolSize:function(a){return a[2]},label:{show:true,formatter:function(a){return a.name},position:"top",fontSize:11}}]
});
}
function gk(bp,days,vol){
var dates=[],data=[];var price=bp;var sd=new Date("2026-04-01");
for(var i=0;i<days;i++){var dd=new Date(sd);dd.setDate(dd.getDate()+i);var ds=dd.getFullYear()+"-"+(dd.getMonth()+1<10?"0":"")+(dd.getMonth()+1)+"-"+(dd.getDate()<10?"0":"")+dd.getDate();dates.push(ds);var o=price;var cc=o+(Math.random()-0.5)*vol;var h=Math.max(o,cc)+Math.random()*vol*0.5;var l=Math.min(o,cc)-Math.random()*vol*0.5;data.push([o,cc,l,h]);price=cc}
return{dates:dates,data:data}
}
function ik(cid,bp,vol,bp2,sp2){
var ch=echarts.init(document.getElementById(cid));
var kl=gk(bp,60,vol);
var op={
tooltip:{trigger:"axis",formatter:function(p){var d=kl.dates[p[0].dataIndex];return d+"<br/>开: "+p[0].value[1].toFixed(2)+"<br/>收: "+p[0].value[2].toFixed(2)+"<br/>低: "+p[0].value[3].toFixed(2)+"<br/>高: "+p[0].value[4].toFixed(2)}},
grid:{left:"3%",right:"3%",bottom:"15%",containLabel:true},
xAxis:{type:"category",data:kl.dates,axisLabel:{rotate:45,fontSize:10},splitLine:{show:false}},
yAxis:{type:"value",scale:true,splitLine:{lineStyle:{type:"dashed"}}},
dataZoom:[{type:"inside",start:60,end:100},{type:"slider",show:true,start:60,end:100,height:20,bottom:0}],
series:[{type:"candlestick",data:kl.data,itemStyle:{color:"#52c41a",color0:"#ff4d4f",borderColor:"#52c41a",borderColor0:"#ff4d4f"}}]
};
if(bp2&&bp2.length)op.series.push({type:"scatter",data:bp2.map(function(b){return[b.di,kl.data[b.di][3]]}),symbol:"triangle",symbolSize:12,itemStyle:{color:"#52c41a"},label:{show:true,formatter:"买",position:"bottom",fontSize:10,color:"#52c41a"}});
if(sp2&&sp2.length)op.series.push({type:"scatter",data:sp2.map(function(s){return[s.di,kl.data[s.di][4]]}),symbol:"pin",symbolSize:12,itemStyle:{color:"#ff4d4f"},label:{show:true,formatter:"卖",position:"top",fontSize:10,color:"#ff4d4f"}});
ch.setOption(op);return ch;
}
function cm(id){document.getElementById(id).classList.remove("show")}
function ov(idx,code,name){
var x=V[idx];if(!x)return;
document.getElementById("vtitle").textContent="品种详情:"+name+" ("+code+")";
document.getElementById("vn").textContent=(x.np>=0?"+":"")+x.np.toFixed(2);
document.getElementById("vn").className="ov-val "+(x.np>=0?"green":"red");
document.getElementById("vw").textContent=x.wr;
document.getElementById("vr").textContent=x.pr.toFixed(2);
document.getElementById("vc").textContent=x.t;
document.getElementById("vf").textContent=x.f.toFixed(2);
document.getElementById("vm").textContent="+"+Math.abs(x.p*0.5).toFixed(2);
document.getElementById("vmod").classList.add("show");
if(kc)kc.dispose();
var bp={"JM":2000,"BU":3500,"MA":2500,"P":9000,"CF":16000};
kc=ik("kc",bp[code]||5000,code==="JM"?50:code==="CF"?200:30,[{di:15},{di:45}],[{di:30}]);
var rows=[];
for(var i=0;i<Math.min(x.t,8);i++){
var dir=Math.random()>0.5?"做多":"做空";
var op2=bp[code]||5000;var cp=op2+(Math.random()-0.5)*200;
var pnl=(dir==="做多"?cp-op2:op2-cp)*1;
rows.push("<tr><td>2026-06-"+(i<9?"0":"")+(i+1)+" 10:30</td><td class='"+(dir==="做多"?"green":"red")+"'>"+dir+"</td><td>"+op2.toFixed(2)+"</td><td>"+cp.toFixed(2)+"</td><td class='"+(pnl>=0?"green":"red")+"'>"+(pnl>=0?"+":"")+pnl.toFixed(2)+"</td><td>"+x.f.toFixed(2)+"</td><td><span class='link' onclick='ot("+JSON.stringify(name)+", "+JSON.stringify(dir)+")'>查看</span></td></tr>");
}
document.getElementById("vttb").innerHTML=rows.join("");
}
function ot(name,dir){
document.getElementById("ttitle").textContent=name+" "+dir+" 交易详情";
document.getElementById("tv").textContent=name;
document.getElementById("td").textContent=dir;
document.getElementById("tod").textContent="2026-06-01";
document.getElementById("tot").textContent="11:02:11";
document.getElementById("top").textContent="16300.00";
document.getElementById("tcp").textContent="16375.00";
document.getElementById("tvol").textContent="1";
document.getElementById("tfee").textContent="4.33";
document.getElementById("tpnl").textContent="-379.33";
document.getElementById("tmod").classList.add("show");
if(tkc)tkc.dispose();
tkc=ik("tkc",16000,200,[{di:20}],[{di:35}]);
}
function genAI(x){
var tags=[], txt="";
var wr = parseFloat(x.wr);
var np = x.p - x.c;
if(np<0) tags.push("亏损"); else tags.push("盈利");
if(wr<10) tags.push("低胜率"); else if(wr>30) tags.push("高胜率");
if(x.t>40) tags.push("频繁交易");
if(x.c>Math.abs(x.p)) tags.push("高手续费");
tags.forEach(function(t){txt+='<span class="ai-tag">'+t+'</span>'});
txt+="<br/><strong>1. 交易质量诊断:</strong><br/>";
if(wr<15) txt+="当日胜率仅"+x.wr+",显著低于正常水平,建议减少冲动开单。<br/>";
else txt+="胜率尚可,但需关注盈亏比是否合理。<br/>";
txt+="<br/><strong>2. 手续费分析:</strong><br/>";
if(x.c>Math.abs(x.p)*0.5) txt+="手续费("+x.c.toFixed(2)+")占比过高,侵蚀了利润。建议优化开仓频率或申请低费率。<br/>";
else txt+="手续费控制合理。<br/>";
txt+="<br/><strong>3. 改进建议:</strong><br/>";
if(x.l>x.w) txt+="亏损笔数较多,建议设置严格止损,避免扛单。<br/>";
txt+="建议复盘前3笔亏损交易寻找共性问题。";
return txt;
}
function od(date){
var x=D.find(function(d){return d.fd===date});
if(!x) return;
document.getElementById("dtitle").textContent="每日详情:"+date;
document.getElementById("dpnl").textContent=(x.p>=0?"+":"")+x.p.toFixed(2);
document.getElementById("dpnl").className="ov-val "+(x.p>=0?"green":"red");
var np=x.p-x.c;
document.getElementById("dnpnl").textContent=(np>=0?"+":"")+np.toFixed(2);
document.getElementById("dnpnl").className="ov-val "+(np>=0?"green":"red");
document.getElementById("dwr").textContent=x.wr;
document.getElementById("dfee").textContent=x.c.toFixed(2);
document.getElementById("dmp").textContent="+"+x.mp.toFixed(2);
document.getElementById("dml").textContent=x.ml.toFixed(2);
document.getElementById("dai").innerHTML=genAI(x);
var rows=[];
for(var i=0;i<x.t;i++){
var time="09:"+(30+Math.floor(i*1.2)%30)+":"+(Math.random()<0.5?"0":"")+Math.floor(Math.random()*60);
var varName=["JM","BU","MA","P","CF"][Math.floor(Math.random()*5)];
var dir=Math.random()>0.5?"做多":"做空";
var op=1000+Math.random()*1000;
var cp=op+(Math.random()-0.5)*200;
var pnl=(dir==="做多"?cp-op:op-cp);
var fee=Math.random()*10;
rows.push("<tr><td>"+time+"</td><td>"+varName+"</td><td>"+dir+"</td><td>"+op.toFixed(2)+"</td><td>"+cp.toFixed(2)+"</td><td class='"+(pnl>=0?"green":"red")+"'>"+(pnl>=0?"+":"")+pnl.toFixed(2)+"</td><td>"+fee.toFixed(2)+"</td></tr>");
}
document.getElementById("dttb").innerHTML=rows.join("");
document.getElementById("dmod").classList.add("show");
setTimeout(function(){renderDailyVariety(date)},100);
}
window.onload=function(){rd();rv();ie();ib()};
</script>
</body>
</html>