|
|
<!DOCTYPE html>
|
|
|
<html lang="zh-CN">
|
|
|
<head>
|
|
|
<meta charset="UTF-8">
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
|
|
<title>交易反思系统 - Demo</title>
|
|
|
<style>
|
|
|
:root {
|
|
|
--bg-page: #F5F5F7;
|
|
|
--bg-card: #FFFFFF;
|
|
|
--text-primary: #1D1D1F;
|
|
|
--text-secondary: #6E6E73;
|
|
|
--text-tertiary: #86868B;
|
|
|
--color-up: #FF3B30;
|
|
|
--color-down: #34C759;
|
|
|
--color-neutral: #FF9F0A;
|
|
|
--color-brand: #007AFF;
|
|
|
--color-ai: #AF52DE;
|
|
|
--shadow-sm: 0 1px 3px rgba(0,0,0,0.04);
|
|
|
--shadow-md: 0 4px 12px rgba(0,0,0,0.06);
|
|
|
--shadow-lg: 0 8px 24px rgba(0,0,0,0.08);
|
|
|
--radius-card: 20px;
|
|
|
--radius-btn: 12px;
|
|
|
--radius-pill: 9999px;
|
|
|
--radius-sm: 12px;
|
|
|
}
|
|
|
|
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
body {
|
|
|
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", "PingFang SC", sans-serif;
|
|
|
background-color: var(--bg-page);
|
|
|
color: var(--text-primary);
|
|
|
-webkit-font-smoothing: antialiased;
|
|
|
padding-bottom: 40px;
|
|
|
}
|
|
|
|
|
|
.header {
|
|
|
position: sticky; top: 0; z-index: 100; height: 64px;
|
|
|
background: rgba(255, 255, 255, 0.8);
|
|
|
backdrop-filter: saturate(180%) blur(20px);
|
|
|
-webkit-backdrop-filter: saturate(180%) blur(20px);
|
|
|
border-bottom: 1px solid rgba(0,0,0,0.05);
|
|
|
display: flex; align-items: center; justify-content: space-between; padding: 0 32px;
|
|
|
}
|
|
|
.logo { font-size: 18px; font-weight: 600; letter-spacing: -0.02em; }
|
|
|
.demo-badge { background: var(--color-up); color: #fff; padding: 4px 12px; border-radius: var(--radius-pill); font-size: 11px; font-weight: 600; }
|
|
|
|
|
|
.container { max-width: 1200px; margin: 0 auto; padding: 24px 32px; }
|
|
|
|
|
|
/* 子 Tab 栏 */
|
|
|
.sub-tabs {
|
|
|
display: flex; gap: 8px; margin-bottom: 24px;
|
|
|
background: var(--bg-card); padding: 8px; border-radius: var(--radius-btn);
|
|
|
box-shadow: var(--shadow-sm); width: fit-content;
|
|
|
}
|
|
|
.sub-tab {
|
|
|
padding: 10px 24px; border-radius: 8px; font-size: 14px; font-weight: 500;
|
|
|
cursor: pointer; transition: all 0.2s; color: var(--text-secondary);
|
|
|
border: none; background: transparent;
|
|
|
}
|
|
|
.sub-tab:hover { background: var(--bg-page); color: var(--text-primary); }
|
|
|
.sub-tab.active { background: var(--color-brand); color: #fff; box-shadow: 0 2px 8px rgba(0,122,255,0.25); }
|
|
|
|
|
|
.view { display: none; }
|
|
|
.view.active { display: block; }
|
|
|
|
|
|
/* ========== 统计分析视图(完全复制原始交易复盘页面) ========== */
|
|
|
.tr-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; flex-wrap: wrap; gap: 12px; }
|
|
|
.tr-toolbar-left, .tr-toolbar-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
|
|
|
.tr-btn { padding: 10px 20px; border-radius: var(--radius-btn); font-size: 14px; font-weight: 600; cursor: pointer; border: none; display: flex; align-items: center; gap: 8px; transition: all 0.2s; font-family: inherit; }
|
|
|
.tr-btn-primary { background: var(--color-brand); color: #fff; }
|
|
|
.tr-btn-primary:hover { background: #0066d6; box-shadow: 0 4px 10px rgba(0,122,255,0.3); }
|
|
|
.tr-btn-secondary { background: #fff; color: var(--text-secondary); box-shadow: var(--shadow-sm); border: 1px solid rgba(0,0,0,0.05); }
|
|
|
.tr-btn-secondary:hover { background: var(--bg-page); }
|
|
|
.tr-btn-danger { background: rgba(255,59,48,0.1); color: var(--color-up); border: 1px solid rgba(255,59,48,0.2); }
|
|
|
.tr-btn-danger:hover { background: rgba(255,59,48,0.2); }
|
|
|
.tr-btn-link { background: transparent; color: var(--color-brand); padding: 6px 12px; font-size: 13px; font-weight: 500; cursor: pointer; border: none; font-family: inherit; }
|
|
|
.tr-btn-link:hover { text-decoration: underline; }
|
|
|
.tr-date-input { background: #fff; border: 1px solid rgba(0,0,0,0.05); border-radius: var(--radius-btn); padding: 0 14px; height: 40px; font-size: 13px; color: var(--text-primary); box-shadow: var(--shadow-sm); outline: none; font-family: inherit; }
|
|
|
.tr-date-input:focus { border-color: var(--color-brand); box-shadow: 0 0 0 3px rgba(0,122,255,0.15); }
|
|
|
|
|
|
.tr-stats-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 14px; margin-bottom: 24px; }
|
|
|
.tr-stat-card { background: var(--bg-card); border-radius: var(--radius-card); padding: 18px; text-align: center; box-shadow: var(--shadow-sm); transition: transform 0.2s; }
|
|
|
.tr-stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
|
|
|
.tr-stat-label { font-size: 11px; color: var(--text-tertiary); margin-bottom: 6px; font-weight: 600; }
|
|
|
.tr-stat-value { font-size: 24px; font-weight: 700; margin-bottom: 4px; }
|
|
|
.tr-stat-value.profit { color: var(--color-down); }
|
|
|
.tr-stat-value.loss { color: var(--color-up); }
|
|
|
.tr-stat-sub { font-size: 12px; color: var(--text-tertiary); margin-top: 4px; }
|
|
|
|
|
|
.tr-chart-box { background: var(--bg-card); border-radius: var(--radius-card); padding: 20px; margin-bottom: 24px; box-shadow: var(--shadow-sm); }
|
|
|
.tr-chart-title { font-size: 16px; font-weight: 600; color: var(--text-primary); margin-bottom: 16px; }
|
|
|
.tr-chart-container { width: 100%; height: 350px; }
|
|
|
.tr-bubble-container { width: 100%; height: 400px; }
|
|
|
.tr-chart-placeholder { width: 100%; height: 200px; background: var(--bg-page); border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; color: var(--text-tertiary); font-size: 14px; }
|
|
|
|
|
|
.tr-tbl-box { background: var(--bg-card); border-radius: var(--radius-card); padding: 20px; margin-bottom: 24px; box-shadow: var(--shadow-sm); overflow-x: auto; }
|
|
|
.tr-tbl-title { font-size: 16px; font-weight: 600; color: var(--text-primary); margin-bottom: 16px; }
|
|
|
.tr-table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
|
|
.tr-table th { background: var(--bg-page); padding: 12px 8px; text-align: left; font-weight: 600; color: var(--text-tertiary); font-size: 12px; white-space: nowrap; border-bottom: 1px solid rgba(0,0,0,0.06); }
|
|
|
.tr-table td { padding: 12px 8px; border-bottom: 1px solid rgba(0,0,0,0.04); color: var(--text-primary); white-space: nowrap; }
|
|
|
.tr-table tbody tr { transition: background 0.15s; }
|
|
|
.tr-table tbody tr:hover { background: rgba(0,122,255,0.03); }
|
|
|
.tr-pnl-positive { color: var(--color-down); font-weight: 600; }
|
|
|
.tr-pnl-negative { color: var(--color-up); font-weight: 600; }
|
|
|
|
|
|
.tr-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 200px; gap: 12px; }
|
|
|
.tr-empty-icon { font-size: 56px; opacity: 0.3; }
|
|
|
.tr-empty-text { font-size: 15px; color: var(--text-tertiary); }
|
|
|
|
|
|
/* ========== 反思视图 ========== */
|
|
|
.ref-date-selector { display: flex; align-items: center; gap: 16px; margin-bottom: 24px; background: var(--bg-card); padding: 12px 20px; border-radius: var(--radius-btn); box-shadow: var(--shadow-sm); }
|
|
|
.ref-date-btn { background: var(--bg-page); border: none; color: var(--text-primary); padding: 8px 16px; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 500; }
|
|
|
.ref-date-btn:hover { background: #E5E5EA; }
|
|
|
.ref-date-display { font-size: 18px; color: var(--text-primary); font-weight: 600; min-width: 120px; text-align: center; }
|
|
|
|
|
|
.ref-stats-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 24px; }
|
|
|
.ref-stat-card { background: var(--bg-card); border-radius: var(--radius-card); padding: 18px; box-shadow: var(--shadow-sm); }
|
|
|
.ref-stat-label { font-size: 12px; color: var(--text-tertiary); margin-bottom: 4px; font-weight: 600; }
|
|
|
.ref-stat-value { font-size: 24px; font-weight: 700; }
|
|
|
.ref-stat-value.profit { color: var(--color-down); }
|
|
|
|
|
|
.ref-daily-section { background: var(--bg-card); border-radius: var(--radius-card); padding: 20px; margin-bottom: 24px; box-shadow: var(--shadow-sm); border-left: 4px solid var(--color-brand); }
|
|
|
.ref-daily-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
|
|
|
.ref-daily-title { font-size: 16px; font-weight: 600; color: var(--text-primary); }
|
|
|
.ref-daily-btn { background: var(--color-brand); color: #fff; border: none; padding: 8px 16px; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 500; }
|
|
|
.ref-daily-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
|
|
|
.ref-daily-item { background: var(--bg-page); border-radius: var(--radius-sm); padding: 12px; }
|
|
|
.ref-daily-label { font-size: 11px; color: var(--text-tertiary); margin-bottom: 4px; font-weight: 600; }
|
|
|
.ref-daily-value { font-size: 14px; color: var(--text-primary); font-weight: 500; }
|
|
|
.ref-stars { color: var(--color-neutral); }
|
|
|
|
|
|
.ref-pair-card { background: var(--bg-card); border-radius: var(--radius-card); padding: 20px; margin-bottom: 16px; box-shadow: var(--shadow-sm); }
|
|
|
.ref-pair-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
|
|
|
.ref-pair-title { font-size: 16px; font-weight: 600; color: var(--text-primary); }
|
|
|
.ref-pair-pnl { font-size: 18px; font-weight: 700; }
|
|
|
.ref-pair-pnl.profit { color: var(--color-down); }
|
|
|
.ref-pair-pnl.loss { color: var(--color-up); }
|
|
|
|
|
|
.ref-flow { display: flex; align-items: center; gap: 16px; }
|
|
|
.ref-node { background: var(--bg-page); padding: 12px 20px; border-radius: var(--radius-sm); flex: 1; }
|
|
|
.ref-node-type { font-size: 11px; color: var(--color-brand); margin-bottom: 4px; font-weight: 600; }
|
|
|
.ref-node-detail { font-size: 14px; color: var(--text-primary); }
|
|
|
.ref-arrow { color: var(--color-brand); font-size: 24px; }
|
|
|
|
|
|
.ref-actions { display: flex; gap: 8px; margin-top: 12px; align-items: center; flex-wrap: wrap; }
|
|
|
.ref-status-badge { padding: 6px 12px; border-radius: var(--radius-pill); font-size: 12px; font-weight: 600; }
|
|
|
.ref-status-badge.done { background: rgba(52,199,89,0.1); color: var(--color-down); }
|
|
|
.ref-status-badge.pending { background: rgba(255,159,10,0.1); color: var(--color-neutral); }
|
|
|
.ref-status-badge.none { background: rgba(0,0,0,0.04); color: var(--text-tertiary); }
|
|
|
.ref-action-btn { padding: 6px 14px; border-radius: 8px; border: 1px solid rgba(0,0,0,0.08); background: var(--bg-card); color: var(--text-secondary); cursor: pointer; font-size: 13px; font-weight: 500; transition: all 0.2s; }
|
|
|
.ref-action-btn:hover { background: var(--bg-page); color: var(--text-primary); }
|
|
|
.ref-action-btn.primary { background: var(--color-brand); color: #fff; border-color: var(--color-brand); }
|
|
|
.ref-action-btn.primary:hover { background: #0066d6; }
|
|
|
|
|
|
.ref-unpaired { background: var(--bg-card); border-radius: var(--radius-card); padding: 16px; margin-bottom: 12px; border: 1px dashed rgba(0,0,0,0.12); box-shadow: var(--shadow-sm); }
|
|
|
.ref-unpaired-header { display: flex; align-items: center; justify-content: space-between; }
|
|
|
.ref-unpaired-info { color: var(--text-primary); font-size: 14px; }
|
|
|
.ref-unpaired-sub { color: var(--text-tertiary); font-size: 12px; margin-left: 8px; }
|
|
|
|
|
|
/* ========== 经验库视图 ========== */
|
|
|
.exp-filters { display: flex; gap: 12px; margin-bottom: 20px; }
|
|
|
.exp-search { flex: 1; background: var(--bg-card); border: 1px solid rgba(0,0,0,0.08); border-radius: var(--radius-btn); padding: 10px 16px; font-size: 14px; color: var(--text-primary); outline: none; box-shadow: var(--shadow-sm); }
|
|
|
.exp-search:focus { border-color: var(--color-brand); box-shadow: 0 0 0 3px rgba(0,122,255,0.15); }
|
|
|
.exp-select { background: var(--bg-card); border: 1px solid rgba(0,0,0,0.08); border-radius: var(--radius-btn); padding: 10px 16px; font-size: 14px; color: var(--text-primary); outline: none; box-shadow: var(--shadow-sm); }
|
|
|
.exp-view-switcher { display: flex; gap: 8px; margin-bottom: 16px; }
|
|
|
.exp-view-btn { padding: 8px 16px; border-radius: 8px; border: 1px solid rgba(0,0,0,0.08); background: var(--bg-card); color: var(--text-secondary); cursor: pointer; font-size: 13px; font-weight: 500; }
|
|
|
.exp-view-btn.active { background: var(--color-brand); color: #fff; border-color: var(--color-brand); }
|
|
|
|
|
|
.exp-card { background: var(--bg-card); border-radius: var(--radius-card); padding: 20px; margin-bottom: 16px; box-shadow: var(--shadow-sm); border-left: 4px solid var(--color-neutral); }
|
|
|
.exp-card.lesson { border-left-color: var(--color-brand); }
|
|
|
.exp-card.warning { border-left-color: var(--color-up); }
|
|
|
.exp-meta { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
|
|
|
.exp-date { font-size: 12px; color: var(--text-tertiary); }
|
|
|
.exp-type { padding: 4px 10px; border-radius: var(--radius-pill); font-size: 12px; font-weight: 600; }
|
|
|
.exp-type.lesson { background: rgba(0,122,255,0.1); color: var(--color-brand); }
|
|
|
.exp-type.tip { background: rgba(52,199,89,0.1); color: var(--color-down); }
|
|
|
.exp-type.warning { background: rgba(255,59,48,0.1); color: var(--color-up); }
|
|
|
.exp-title { font-size: 16px; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; }
|
|
|
.exp-content { font-size: 14px; color: var(--text-secondary); line-height: 1.6; margin-bottom: 12px; }
|
|
|
.exp-tags { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
|
|
|
.exp-tag { padding: 4px 10px; border-radius: var(--radius-pill); font-size: 11px; font-weight: 500; background: var(--bg-page); color: var(--text-secondary); }
|
|
|
.exp-actions { display: flex; gap: 8px; }
|
|
|
.exp-action-link { color: var(--color-brand); text-decoration: none; font-size: 13px; font-weight: 500; }
|
|
|
.exp-action-link:hover { text-decoration: underline; }
|
|
|
|
|
|
/* Modal - Apple 风格 */
|
|
|
.modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.4); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); z-index: 2000; align-items: center; justify-content: center; }
|
|
|
.modal-overlay.show { display: flex; }
|
|
|
.modal { background: var(--bg-card); border-radius: var(--radius-card); width: 90%; max-width: 600px; max-height: 85vh; overflow-y: auto; box-shadow: var(--shadow-lg); animation: modal-in 0.25s ease; }
|
|
|
@keyframes modal-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } }
|
|
|
.modal-header { display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; border-bottom: 1px solid rgba(0,0,0,0.06); }
|
|
|
.modal-title { font-size: 18px; font-weight: 700; color: var(--text-primary); }
|
|
|
.modal-close { width: 32px; height: 32px; border-radius: 50%; border: none; background: var(--bg-page); font-size: 16px; cursor: pointer; display: flex; align-items: center; justify-content: center; color: var(--text-secondary); transition: all 0.2s; }
|
|
|
.modal-close:hover { background: #E5E5EA; }
|
|
|
.modal-body { padding: 24px; }
|
|
|
|
|
|
.form-group { margin-bottom: 16px; }
|
|
|
.form-label { display: block; font-size: 13px; color: var(--text-secondary); margin-bottom: 6px; font-weight: 500; }
|
|
|
.form-textarea { width: 100%; background: var(--bg-page); border: 1px solid rgba(0,0,0,0.08); border-radius: var(--radius-sm); padding: 10px 14px; font-size: 14px; color: var(--text-primary); outline: none; min-height: 80px; resize: vertical; font-family: inherit; }
|
|
|
.form-textarea:focus { border-color: var(--color-brand); box-shadow: 0 0 0 3px rgba(0,122,255,0.15); }
|
|
|
.form-select { width: 100%; background: var(--bg-page); border: 1px solid rgba(0,0,0,0.08); border-radius: var(--radius-sm); padding: 10px 14px; font-size: 14px; color: var(--text-primary); outline: none; font-family: inherit; }
|
|
|
.radio-group { display: flex; gap: 16px; }
|
|
|
.radio-label { display: flex; align-items: center; gap: 6px; color: var(--text-primary); cursor: pointer; font-size: 14px; }
|
|
|
.modal-footer { display: flex; gap: 12px; justify-content: flex-end; margin-top: 24px; padding-top: 16px; border-top: 1px solid rgba(0,0,0,0.06); }
|
|
|
.btn-cancel { background: var(--bg-page); color: var(--text-secondary); border: none; padding: 10px 20px; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 500; }
|
|
|
.btn-cancel:hover { background: #E5E5EA; }
|
|
|
.btn-save { background: var(--color-brand); color: #fff; border: none; padding: 10px 20px; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 500; }
|
|
|
.btn-save:hover { background: #0066d6; }
|
|
|
.btn-analyze { background: var(--color-down); color: #fff; border: none; padding: 10px 20px; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 500; }
|
|
|
.btn-analyze:hover { background: #2db84e; }
|
|
|
|
|
|
.tag-selector { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
|
.tag-item { padding: 6px 12px; border-radius: var(--radius-pill); font-size: 12px; cursor: pointer; border: 1px solid rgba(0,0,0,0.08); background: var(--bg-page); color: var(--text-secondary); transition: all 0.2s; }
|
|
|
.tag-item:hover { background: #E5E5EA; }
|
|
|
.tag-item.selected { background: var(--color-brand); color: #fff; border-color: var(--color-brand); }
|
|
|
.tag-category { width: 100%; color: var(--text-tertiary); font-size: 11px; font-weight: 600; margin-top: 8px; }
|
|
|
|
|
|
.ai-box { background: linear-gradient(135deg, #f0f7ff 0%, #e6f4ff 100%); border: 1px solid #bae0ff; border-radius: var(--radius-sm); padding: 20px; margin-top: 16px; }
|
|
|
.ai-box-title { font-size: 16px; font-weight: 600; color: #0958d9; margin-bottom: 12px; }
|
|
|
.ai-box-content { font-size: 14px; color: var(--text-primary); line-height: 1.8; margin-bottom: 12px; }
|
|
|
|
|
|
@media (max-width: 1200px) { .tr-stats-grid { grid-template-columns: repeat(3, 1fr); } }
|
|
|
@media (max-width: 768px) { .tr-stats-grid { grid-template-columns: repeat(2, 1fr); } }
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
|
<header class="header">
|
|
|
<div class="logo">◈ 期货智析 - 交易复盘</div>
|
|
|
<span class="demo-badge">DEMO</span>
|
|
|
</header>
|
|
|
|
|
|
<div class="container">
|
|
|
<!-- 子 Tab 栏 -->
|
|
|
<div class="sub-tabs">
|
|
|
<button class="sub-tab active" onclick="switchSubTab('stats')">统计分析</button>
|
|
|
<button class="sub-tab" onclick="switchSubTab('reflection')">交易反思</button>
|
|
|
<button class="sub-tab" onclick="switchSubTab('experience')">经验库</button>
|
|
|
</div>
|
|
|
|
|
|
<!-- ========== 统计分析视图(完整保留所有原始功能) ========== -->
|
|
|
<div id="stats-view" class="view active">
|
|
|
<!-- 工具栏 -->
|
|
|
<div class="tr-toolbar">
|
|
|
<div class="tr-toolbar-left">
|
|
|
<input type="file" id="tr-file-input" accept=".xls,.xlsx" style="display:none" />
|
|
|
<input type="file" id="tr-batch-file-input" accept=".xls,.xlsx" multiple style="display:none" />
|
|
|
<button id="tr-btn-import" class="tr-btn tr-btn-primary"><span>📥</span><span>导入结算单</span></button>
|
|
|
<button id="tr-btn-batch-import" class="tr-btn tr-btn-primary" title="同时导入多个结算单文件"><span>📂</span><span>批量导入</span></button>
|
|
|
<input type="date" id="tr-start-date" class="tr-date-input" title="开始日期" />
|
|
|
<span style="color:var(--text-tertiary);font-size:13px;">~</span>
|
|
|
<input type="date" id="tr-end-date" class="tr-date-input" title="结束日期" />
|
|
|
<button id="tr-btn-query" class="tr-btn tr-btn-secondary">查询</button>
|
|
|
</div>
|
|
|
<div class="tr-toolbar-right">
|
|
|
<button id="tr-btn-delete-date" class="tr-btn tr-btn-danger" title="删除当前查询日期的所有交易记录"><span>🗑️</span><span>删除当日</span></button>
|
|
|
<button id="tr-btn-batches" class="tr-btn tr-btn-secondary"><span>📋</span><span>批次管理</span></button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 6个统计卡片 -->
|
|
|
<div id="tr-stats-grid" class="tr-stats-grid">
|
|
|
<div class="tr-stat-card"><div class="tr-stat-label">总盈亏</div><div class="tr-stat-value profit">+¥3,200</div><div class="tr-stat-sub">平仓盈亏</div></div>
|
|
|
<div class="tr-stat-card"><div class="tr-stat-label">净盈亏</div><div class="tr-stat-value profit">+¥2,800</div><div class="tr-stat-sub">扣除手续费</div></div>
|
|
|
<div class="tr-stat-card"><div class="tr-stat-label">胜率</div><div class="tr-stat-value">75%</div><div class="tr-stat-sub">3盈1亏</div></div>
|
|
|
<div class="tr-stat-card"><div class="tr-stat-label">盈亏比</div><div class="tr-stat-value">1.5</div><div class="tr-stat-sub">平均盈利/平均亏损</div></div>
|
|
|
<div class="tr-stat-card"><div class="tr-stat-label">交易笔数</div><div class="tr-stat-value">4</div><div class="tr-stat-sub">期货+期权</div></div>
|
|
|
<div class="tr-stat-card"><div class="tr-stat-label">最大回撤</div><div class="tr-stat-value loss">-¥800</div><div class="tr-stat-sub">单笔最大亏损</div></div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 账户权益曲线 -->
|
|
|
<div class="tr-chart-box">
|
|
|
<div class="tr-chart-title">账户权益曲线(累计净盈亏 + 每日盈亏)</div>
|
|
|
<div class="tr-chart-placeholder">📈 ECharts 图表区域(现有功能)</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 品种盈亏分布气泡图 -->
|
|
|
<div class="tr-chart-box">
|
|
|
<div class="tr-chart-title">品种盈亏分布(气泡大小=手续费占比,颜色=净盈亏)</div>
|
|
|
<div class="tr-bubble-container" style="height:300px;background:var(--bg-page);border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;color:var(--text-tertiary);font-size:14px;">🫧 ECharts 气泡图区域(现有功能)</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 每日交易详情表 -->
|
|
|
<div class="tr-tbl-box">
|
|
|
<div class="tr-tbl-title">每日交易详情(点击日期查看详情)</div>
|
|
|
<table class="tr-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><th>操作</th></tr>
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
<tr>
|
|
|
<td>2026-07-05</td><td>4</td><td class="tr-pnl-positive">+¥3,600</td><td>-¥400</td>
|
|
|
<td class="tr-pnl-positive">+¥3,200</td><td>3</td><td>1</td><td>75%</td>
|
|
|
<td class="tr-pnl-positive">+¥2,800</td><td class="tr-pnl-negative">-¥800</td><td>3</td>
|
|
|
<td><button class="tr-btn tr-btn-link" onclick="showDailyDetail()">查看详情</button></td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>2026-07-04</td><td>3</td><td class="tr-pnl-positive">+¥1,500</td><td>-¥300</td>
|
|
|
<td class="tr-pnl-positive">+¥1,200</td><td>2</td><td>1</td><td>67%</td>
|
|
|
<td class="tr-pnl-positive">+¥1,000</td><td class="tr-pnl-negative">-¥500</td><td>2</td>
|
|
|
<td><button class="tr-btn tr-btn-link" onclick="showDailyDetail()">查看详情</button></td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>2026-07-03</td><td>2</td><td class="tr-pnl-negative">-¥500</td><td>-¥200</td>
|
|
|
<td class="tr-pnl-negative">-¥700</td><td>1</td><td>1</td><td>50%</td>
|
|
|
<td class="tr-pnl-positive">+¥300</td><td class="tr-pnl-negative">-¥800</td><td>2</td>
|
|
|
<td><button class="tr-btn tr-btn-link" onclick="showDailyDetail()">查看详情</button></td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
</div>
|
|
|
|
|
|
<!-- 品种盈亏排行表 -->
|
|
|
<div class="tr-tbl-box">
|
|
|
<div class="tr-tbl-title">品种盈亏排行(点击查看品种详情)</div>
|
|
|
<table class="tr-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>
|
|
|
<tr><td>1</td><td>IF</td><td>沪深300</td><td class="tr-pnl-positive">+¥2,800</td><td>+¥3,000</td><td>-¥200</td><td>100%</td><td>--</td><td>1</td><td><button class="tr-btn tr-btn-link">查看详情</button></td></tr>
|
|
|
<tr><td>2</td><td>AG</td><td>沪银</td><td class="tr-pnl-positive">+¥1,200</td><td>+¥1,400</td><td>-¥200</td><td>100%</td><td>--</td><td>1</td><td><button class="tr-btn tr-btn-link">查看详情</button></td></tr>
|
|
|
<tr><td>3</td><td>RB</td><td>螺纹钢</td><td class="tr-pnl-negative">-¥800</td><td>-¥600</td><td>-¥200</td><td>0%</td><td>--</td><td>1</td><td><button class="tr-btn tr-btn-link">查看详情</button></td></tr>
|
|
|
<tr><td>4</td><td>CU</td><td>沪铜</td><td class="tr-pnl-negative">-¥400</td><td>-¥200</td><td>-¥200</td><td>0%</td><td>--</td><td>1</td><td><button class="tr-btn tr-btn-link">查看详情</button></td></tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- ========== 交易反思视图 ========== -->
|
|
|
<div id="reflection-view" class="view">
|
|
|
<div class="ref-date-selector">
|
|
|
<button class="ref-date-btn" onclick="prevDay()">← 前一天</button>
|
|
|
<div class="ref-date-display" id="currentDate">2026-07-05</div>
|
|
|
<button class="ref-date-btn" onclick="nextDay()">后一天 →</button>
|
|
|
</div>
|
|
|
|
|
|
<div class="ref-stats-row">
|
|
|
<div class="ref-stat-card"><div class="ref-stat-label">总盈亏</div><div class="ref-stat-value profit">+¥3,200</div></div>
|
|
|
<div class="ref-stat-card"><div class="ref-stat-label">交易笔数</div><div class="ref-stat-value">4 笔</div></div>
|
|
|
<div class="ref-stat-card"><div class="ref-stat-label">胜率</div><div class="ref-stat-value">75%</div></div>
|
|
|
<div class="ref-stat-card"><div class="ref-stat-label">已反思</div><div class="ref-stat-value">2/4</div></div>
|
|
|
</div>
|
|
|
|
|
|
<div class="ref-daily-section">
|
|
|
<div class="ref-daily-header">
|
|
|
<div class="ref-daily-title">当日反思</div>
|
|
|
<button class="ref-daily-btn" onclick="openDailyReflection()">编辑</button>
|
|
|
</div>
|
|
|
<div class="ref-daily-grid">
|
|
|
<div class="ref-daily-item"><div class="ref-daily-label">情绪状态</div><div class="ref-daily-value">平静</div></div>
|
|
|
<div class="ref-daily-item"><div class="ref-daily-label">执行纪律</div><div class="ref-daily-value ref-stars">★★★★☆</div></div>
|
|
|
<div class="ref-daily-item"><div class="ref-daily-label">总体评价</div><div class="ref-daily-value ref-stars">★★★★☆</div></div>
|
|
|
<div class="ref-daily-item"><div class="ref-daily-label">市场判断</div><div class="ref-daily-value">震荡偏多</div></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="ref-pair-card">
|
|
|
<div class="ref-pair-header"><div class="ref-pair-title">AG2608 多头</div><div class="ref-pair-pnl profit">+¥1,200</div></div>
|
|
|
<div class="ref-flow">
|
|
|
<div class="ref-node"><div class="ref-node-type">开仓</div><div class="ref-node-detail">09:30 @ 7,850 × 2手</div></div>
|
|
|
<div class="ref-arrow">→</div>
|
|
|
<div class="ref-node"><div class="ref-node-type">平仓</div><div class="ref-node-detail">14:20 @ 7,910 × 2手</div></div>
|
|
|
</div>
|
|
|
<div class="ref-actions">
|
|
|
<span class="ref-status-badge done">反思 ✓</span>
|
|
|
<span class="ref-status-badge done">AI分析 ✓</span>
|
|
|
<button class="ref-action-btn" onclick="openTradeTags()">标签 (2)</button>
|
|
|
<button class="ref-action-btn primary" onclick="showAIResult()">查看分析</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="ref-pair-card">
|
|
|
<div class="ref-pair-header"><div class="ref-pair-title">RB2610 空头</div><div class="ref-pair-pnl loss">-¥800</div></div>
|
|
|
<div class="ref-flow">
|
|
|
<div class="ref-node"><div class="ref-node-type">开仓</div><div class="ref-node-detail">10:15 @ 3,680 × 3手</div></div>
|
|
|
<div class="ref-arrow">→</div>
|
|
|
<div class="ref-node"><div class="ref-node-type">平仓</div><div class="ref-node-detail">11:30 @ 3,710 × 3手</div></div>
|
|
|
</div>
|
|
|
<div class="ref-actions">
|
|
|
<span class="ref-status-badge done">反思 ✓</span>
|
|
|
<span class="ref-status-badge none">未分析</span>
|
|
|
<button class="ref-action-btn" onclick="openTradeTags()">标签 (1)</button>
|
|
|
<button class="ref-action-btn primary" onclick="triggerReanalyze()">重新AI分析</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="ref-pair-card">
|
|
|
<div class="ref-pair-header"><div class="ref-pair-title">IF2609 多头</div><div class="ref-pair-pnl profit">+¥2,800</div></div>
|
|
|
<div class="ref-flow">
|
|
|
<div class="ref-node"><div class="ref-node-type">开仓</div><div class="ref-node-detail">09:45 @ 4,120 × 1手</div></div>
|
|
|
<div class="ref-arrow">→</div>
|
|
|
<div class="ref-node"><div class="ref-node-type">平仓</div><div class="ref-node-detail">15:00 @ 4,190 × 1手</div></div>
|
|
|
</div>
|
|
|
<div class="ref-actions">
|
|
|
<span class="ref-status-badge pending">待分析</span>
|
|
|
<button class="ref-action-btn" onclick="openReflection()">写反思</button>
|
|
|
<button class="ref-action-btn" onclick="openTradeTags()">标签</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="ref-unpaired">
|
|
|
<div class="ref-unpaired-header">
|
|
|
<div><span class="ref-unpaired-info">CU2609 买开 09:45 @ 78,500 × 1手</span><span class="ref-unpaired-sub">未平仓</span></div>
|
|
|
<div style="display:flex;gap:8px;">
|
|
|
<button class="ref-action-btn" onclick="openReflection()">写反思</button>
|
|
|
<button class="ref-action-btn">手动配对</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- ========== 经验库视图 ========== -->
|
|
|
<div id="experience-view" class="view">
|
|
|
<div class="exp-filters">
|
|
|
<input type="text" class="exp-search" placeholder="搜索经验...">
|
|
|
<select class="exp-select"><option value="">全部标签</option><option>追涨杀跌</option><option>严格执行计划</option><option>违反止损</option></select>
|
|
|
<select class="exp-select"><option value="">全部类型</option><option value="lesson">经验</option><option value="tip">技巧</option><option value="warning">警告</option></select>
|
|
|
</div>
|
|
|
|
|
|
<div class="exp-view-switcher">
|
|
|
<button class="exp-view-btn active">列表视图</button>
|
|
|
<button class="exp-view-btn">时间线视图</button>
|
|
|
<button class="exp-view-btn">分类视图</button>
|
|
|
</div>
|
|
|
|
|
|
<div class="exp-card warning">
|
|
|
<div class="exp-meta"><span class="exp-date">2026-07-05</span><span class="exp-type warning">⚠️ 警告</span></div>
|
|
|
<div class="exp-title">追涨杀跌导致亏损 - AG2608</div>
|
|
|
<div class="exp-content">在突破不明显的情况下追多,未设止损,持仓期间市场反转导致亏损。应等待明确突破信号后再入场,并严格执行止损。</div>
|
|
|
<div class="exp-tags"><span class="exp-tag">追涨杀跌</span><span class="exp-tag">违反止损</span></div>
|
|
|
<div class="exp-actions"><a href="#" class="exp-action-link">查看原交易</a><a href="#" class="exp-action-link">编辑</a></div>
|
|
|
</div>
|
|
|
|
|
|
<div class="exp-card lesson">
|
|
|
<div class="exp-meta"><span class="exp-date">2026-07-04</span><span class="exp-type lesson">💡 经验</span></div>
|
|
|
<div class="exp-title">严格执行计划带来稳定收益 - RB2610</div>
|
|
|
<div class="exp-content">按计划入场,按止损出场,避免情绪干扰。即使最终止损,也保持了良好的交易纪律,长期来看这是正确的做法。</div>
|
|
|
<div class="exp-tags"><span class="exp-tag">严格执行计划</span><span class="exp-tag">趋势跟踪</span></div>
|
|
|
<div class="exp-actions"><a href="#" class="exp-action-link">查看原交易</a><a href="#" class="exp-action-link">编辑</a></div>
|
|
|
</div>
|
|
|
|
|
|
<div class="exp-card lesson">
|
|
|
<div class="exp-meta"><span class="exp-date">2026-07-03</span><span class="exp-type tip">✨ 技巧</span></div>
|
|
|
<div class="exp-title">回调入场时机把握 - IF2609</div>
|
|
|
<div class="exp-content">在上升趋势中等待回调至 MA20 附近入场,胜率显著提高。配合 RSI 超卖信号,入场点更加精准。</div>
|
|
|
<div class="exp-tags"><span class="exp-tag">回调交易</span><span class="exp-tag">趋势跟踪</span></div>
|
|
|
<div class="exp-actions"><a href="#" class="exp-action-link">查看原交易</a><a href="#" class="exp-action-link">编辑</a></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 反思编辑 Modal -->
|
|
|
<div class="modal-overlay" id="reflectionModal">
|
|
|
<div class="modal">
|
|
|
<div class="modal-header"><div class="modal-title">反思编辑 - AG2608 多头</div><button class="modal-close" onclick="closeModal('reflectionModal')">✕</button></div>
|
|
|
<div class="modal-body">
|
|
|
<div class="form-group"><label class="form-label">入场理由</label><textarea class="form-textarea" placeholder="为什么选择在这个时机入场?">看到突破 7800 阻力位,配合成交量放大</textarea></div>
|
|
|
<div class="form-group"><label class="form-label">入场时机</label><div class="radio-group"><label class="radio-label"><input type="radio" name="entryTiming"> 良好</label><label class="radio-label"><input type="radio" name="entryTiming" checked> 一般</label><label class="radio-label"><input type="radio" name="entryTiming"> 较差</label></div></div>
|
|
|
<div class="form-group"><label class="form-label">仓位管理反思</label><textarea class="form-textarea">仓位 2 手合理,但未预留加仓空间</textarea></div>
|
|
|
<div class="form-group"><label class="form-label">出场理由</label><textarea class="form-textarea">达到目标位 7910,按计划平仓</textarea></div>
|
|
|
<div class="form-group"><label class="form-label">出场时机</label><div class="radio-group"><label class="radio-label"><input type="radio" name="exitTiming" checked> 良好</label><label class="radio-label"><input type="radio" name="exitTiming"> 一般</label><label class="radio-label"><input type="radio" name="exitTiming"> 较差</label></div></div>
|
|
|
<div class="form-group"><label class="form-label">纪律评分</label><div class="radio-group"><label class="radio-label"><input type="radio" name="discipline"> ☆</label><label class="radio-label"><input type="radio" name="discipline"> ☆☆</label><label class="radio-label"><input type="radio" name="discipline"> ☆☆☆</label><label class="radio-label"><input type="radio" name="discipline" checked> ★★★★</label><label class="radio-label"><input type="radio" name="discipline"> ★★★★★</label></div></div>
|
|
|
<div class="form-group"><label class="form-label">自由反思</label><textarea class="form-textarea">整体执行较好,但入场稍显急躁</textarea></div>
|
|
|
<div class="form-group"><label class="form-label">标签</label><div class="tag-selector"><div class="tag-category">操作类</div><span class="tag-item" onclick="toggleTag(this)">追涨杀跌</span><span class="tag-item" onclick="toggleTag(this)">逆市操作</span><div class="tag-category">纪律类</div><span class="tag-item selected" onclick="toggleTag(this)">严格执行计划</span><span class="tag-item" onclick="toggleTag(this)">违反止损</span><div class="tag-category">技术类</div><span class="tag-item selected" onclick="toggleTag(this)">突破交易</span></div></div>
|
|
|
</div>
|
|
|
<div class="modal-footer"><button class="btn-cancel" onclick="closeModal('reflectionModal')">取消</button><button class="btn-save" onclick="saveReflection()">保存</button><button class="btn-analyze" onclick="saveAndAnalyze()">保存并 AI 分析</button></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 当日反思 Modal -->
|
|
|
<div class="modal-overlay" id="dailyReflectionModal">
|
|
|
<div class="modal">
|
|
|
<div class="modal-header"><div class="modal-title">当日反思 - 2026-07-05</div><button class="modal-close" onclick="closeModal('dailyReflectionModal')">✕</button></div>
|
|
|
<div class="modal-body">
|
|
|
<div class="form-group"><label class="form-label">情绪状态</label><select class="form-select"><option>平静</option><option>兴奋</option><option>焦虑</option></select></div>
|
|
|
<div class="form-group"><label class="form-label">市场判断</label><textarea class="form-textarea">震荡偏多,上午突破后回落,下午企稳</textarea></div>
|
|
|
<div class="form-group"><label class="form-label">执行纪律</label><div class="radio-group"><label class="radio-label"><input type="radio" name="dailyDiscipline"> ☆</label><label class="radio-label"><input type="radio" name="dailyDiscipline" checked> ★★★★</label><label class="radio-label"><input type="radio" name="dailyDiscipline"> ★★★★★</label></div></div>
|
|
|
<div class="form-group"><label class="form-label">总结</label><textarea class="form-textarea">今天整体表现不错,严格执行了计划</textarea></div>
|
|
|
<div class="form-group"><label class="form-label">改进方向</label><textarea class="form-textarea">入场时机可以再耐心一些</textarea></div>
|
|
|
</div>
|
|
|
<div class="modal-footer"><button class="btn-cancel" onclick="closeModal('dailyReflectionModal')">取消</button><button class="btn-save" onclick="saveDailyReflection()">保存</button></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- AI 分析结果 Modal -->
|
|
|
<div class="modal-overlay" id="aiResultModal">
|
|
|
<div class="modal">
|
|
|
<div class="modal-header"><div class="modal-title">AI 分析结果 - AG2608 多头 (版本 1)</div><button class="modal-close" onclick="closeModal('aiResultModal')">✕</button></div>
|
|
|
<div class="modal-body">
|
|
|
<div class="ai-box"><div class="ai-box-title">综合评价</div><div class="ai-box-content">这笔交易整体执行良好。入场时机选择在突破 7800 阻力位后,配合成交量放大,符合突破交易的基本原则。</div></div>
|
|
|
<div class="ai-box"><div class="ai-box-title">✓ 优点</div><ul><li>入场信号明确(突破+放量)</li><li>严格执行目标位出场</li></ul></div>
|
|
|
<div class="ai-box"><div class="ai-box-title">✗ 不足</div><ul><li>入场稍显急躁,可等待更多确认</li></ul></div>
|
|
|
<div style="margin-top:16px;padding-top:16px;border-top:1px solid rgba(0,0,0,0.06);">
|
|
|
<div class="ai-box-title" style="color:var(--color-down);">经验提炼建议</div>
|
|
|
<div class="exp-card lesson" style="margin-top:12px;">
|
|
|
<div class="exp-title">突破交易确认信号的重要性</div>
|
|
|
<div class="exp-content">在突破交易中,等待价格突破后回踩确认再入场,可以显著提高胜率。</div>
|
|
|
<div class="exp-tags"><span class="exp-tag">突破交易</span><span class="exp-tag">严格执行计划</span></div>
|
|
|
<div class="exp-actions" style="margin-top:8px;"><button class="btn-save" onclick="saveExperience()">保存到经验库</button><button class="btn-cancel">编辑</button></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="modal-footer"><button class="btn-cancel" onclick="closeModal('aiResultModal')">关闭</button></div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<script>
|
|
|
function switchSubTab(tab) {
|
|
|
document.querySelectorAll('.sub-tab').forEach((t, i) => {
|
|
|
t.classList.toggle('active', ['stats','reflection','experience'][i] === tab);
|
|
|
});
|
|
|
const map = { 'stats': 'stats-view', 'reflection': 'reflection-view', 'experience': 'experience-view' };
|
|
|
document.querySelectorAll('.view').forEach(v => v.classList.toggle('active', v.id === map[tab]));
|
|
|
}
|
|
|
|
|
|
let currentDate = new Date('2026-07-05');
|
|
|
function formatDate(d) { return d.toISOString().split('T')[0]; }
|
|
|
function prevDay() { currentDate.setDate(currentDate.getDate() - 1); document.getElementById('currentDate').textContent = formatDate(currentDate); }
|
|
|
function nextDay() { currentDate.setDate(currentDate.getDate() + 1); document.getElementById('currentDate').textContent = formatDate(currentDate); }
|
|
|
|
|
|
function openModal(id) { document.getElementById(id).classList.add('show'); }
|
|
|
function closeModal(id) { document.getElementById(id).classList.remove('show'); }
|
|
|
function openReflection() { openModal('reflectionModal'); }
|
|
|
function openDailyReflection() { openModal('dailyReflectionModal'); }
|
|
|
function openTradeTags() { alert('Demo: 打开标签管理弹窗'); }
|
|
|
function showAIResult() { openModal('aiResultModal'); }
|
|
|
function showDailyDetail() { alert('Demo: 打开每日详情弹窗(现有功能)'); }
|
|
|
function toggleTag(el) { el.classList.toggle('selected'); }
|
|
|
|
|
|
function saveReflection() { alert('Demo: 反思已保存'); closeModal('reflectionModal'); }
|
|
|
function saveAndAnalyze() { alert('Demo: 反思已保存,正在触发 AI 分析...'); closeModal('reflectionModal'); setTimeout(() => { alert('Demo: AI 分析完成!'); openModal('aiResultModal'); }, 1500); }
|
|
|
function saveDailyReflection() { alert('Demo: 当日反思已保存'); closeModal('dailyReflectionModal'); }
|
|
|
function triggerReanalyze() { alert('Demo: 正在重新 AI 分析...'); setTimeout(() => { alert('Demo: AI 分析完成!版本 2 已保存。'); }, 1500); }
|
|
|
function saveExperience() { alert('Demo: 经验已保存到经验库'); }
|
|
|
</script>
|
|
|
</body>
|
|
|
</html>
|