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/app/static/futures_analysis.html

1715 lines
110 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">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>期货智析 - 智能期货期权分析系统</title>
<link rel="stylesheet" href="/static/futures_analysis.css">
<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;
}
* { 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;
padding: 0 32px;
}
.logo { font-size: 18px; font-weight: 600; letter-spacing: -0.02em; margin-right: 40px; }
.nav-items { display: flex; gap: 24px; flex: 1; justify-content: center; }
.nav-item { font-size: 14px; color: var(--text-secondary); cursor: pointer; transition: color 0.2s; text-decoration: none; }
.nav-item:hover { color: var(--text-primary); }
.nav-item.active { color: var(--color-brand); font-weight: 500; }
.live-badge { font-size: 11px; color: var(--color-down); display: flex; align-items: center; gap: 4px; }
.dot { width: 6px; height: 6px; background: var(--color-down); border-radius: 50%; }
.container { max-width: 1200px; margin: 0 auto; padding: 24px 32px; }
.toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; flex-wrap: wrap; gap: 16px; }
.toolbar-left { display: flex; align-items: center; gap: 16px; flex: 1; }
.toolbar-actions { display: flex; gap: 10px; }
.search-box {
background: #FFFFFF;
border: none;
border-radius: var(--radius-btn);
padding: 10px 16px;
font-size: 14px;
width: 300px;
box-shadow: var(--shadow-sm);
outline: none;
transition: box-shadow 0.2s;
}
.search-box:focus { box-shadow: 0 0 0 3px rgba(0, 122, 255, 0.2); }
.pills { display: flex; gap: 8px; }
.pill {
padding: 6px 16px;
border-radius: var(--radius-pill);
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
background: #FFFFFF;
color: var(--text-secondary);
box-shadow: var(--shadow-sm);
border: none;
}
.pill:hover { background: #F5F5F7; }
.pill.active { background: var(--color-brand); color: #FFFFFF; box-shadow: 0 4px 10px rgba(0,122,255,0.3); }
.stats-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 32px; }
.stat-card {
background: var(--bg-card);
border-radius: 16px;
padding: 16px 20px;
display: flex;
align-items: center;
gap: 16px;
box-shadow: var(--shadow-sm);
transition: transform 0.2s, box-shadow 0.2s;
}
.stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.stat-icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 18px; }
.stat-icon.blue { background: rgba(0,122,255,0.1); color: var(--color-brand); }
.stat-icon.red { background: rgba(255,59,48,0.1); color: var(--color-up); }
.stat-icon.green { background: rgba(52,199,89,0.1); color: var(--color-down); }
.stat-icon.orange { background: rgba(255,159,10,0.1); color: var(--color-neutral); }
.stat-val { font-size: 24px; font-weight: 700; line-height: 1.2; }
.stat-label { font-size: 13px; color: var(--text-secondary); }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 20px; }
.card {
background: var(--bg-card);
border-radius: var(--radius-card);
padding: 24px;
box-shadow: var(--shadow-md);
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
position: relative;
overflow: hidden;
cursor: pointer;
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 16px; }
.card-left { display: flex; gap: 12px; align-items: flex-start; }
.code-box { width: 36px; height: 36px; background: #F5F5F7; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600; color: var(--text-tertiary); }
.info-group { display: flex; flex-direction: column; }
.name-row { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 15px; }
.contract-code { font-size: 12px; color: var(--text-tertiary); margin-top: 2px; }
.price-area { text-align: right; }
.price { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; line-height: 1; }
.price.up { color: var(--color-up); }
.price.down { color: var(--color-down); }
.change { font-size: 13px; font-weight: 600; margin-top: 4px; }
.change.up { color: var(--color-up); }
.change.down { color: var(--color-down); }
.action-pill {
display: inline-block;
padding: 4px 12px;
border-radius: var(--radius-pill);
font-size: 12px;
font-weight: 600;
margin-bottom: 16px;
}
.action-pill.do-more { background: rgba(52,199,89,0.1); color: var(--color-down); }
.action-pill.watch { background: rgba(255,159,10,0.1); color: var(--color-neutral); }
.metrics { display: flex; gap: 24px; margin-bottom: 16px; }
.metric { flex: 1; }
.metric-label { font-size: 11px; color: var(--text-tertiary); margin-bottom: 4px; }
.metric-val { font-size: 14px; font-weight: 600; }
.bar-bg { height: 4px; background: #F5F5F7; border-radius: 2px; margin-top: 6px; overflow: hidden; }
.bar-fill { height: 100%; border-radius: 2px; }
.timeframes { display: flex; gap: 8px; margin-bottom: 16px; }
.tf { padding: 4px 10px; border-radius: 8px; font-size: 11px; color: var(--text-tertiary); background: #F5F5F7; cursor: pointer; }
.tf.active { background: #E8F2FF; color: var(--color-brand); font-weight: 500; }
.card-footer { display: flex; justify-content: space-between; align-items: center; border-top: 1px solid #F5F5F7; padding-top: 12px; font-size: 12px; }
.support-resist { color: var(--text-tertiary); }
.support-resist span { margin-right: 8px; }
.support-resist .red { color: var(--color-up); }
.support-resist .green { color: var(--color-down); }
.link { color: var(--color-brand); font-weight: 500; text-decoration: none; }
.link:hover { text-decoration: underline; }
.fav-icon { font-size: 15px; color: #D1D1D6; cursor: pointer; transition: all 0.2s; display: inline-flex; align-items: center; user-select: none; }
.fav-icon:hover { color: #FF9F0A; }
.fav-icon.active { color: #FF9F0A; transform: scale(1.1); }
/* 详情视图样式 */
.view { display: none; }
.view.active { display: block; }
#review-view.active { display: block; }
#watched-view.active { display: block; }
.watched-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; padding: 20px 24px; background: #fff; border-radius: 20px; box-shadow: var(--shadow-sm); }
.watched-header h2 { font-size: 20px; font-weight: 700; }
.watched-count { font-size: 14px; color: var(--text-secondary); background: #F5F5F7; padding: 6px 14px; border-radius: 8px; font-weight: 500; }
.empty-hint { font-size: 13px; color: var(--text-tertiary); margin-top: 8px; }
.detail-actions { display: flex; align-items: center; gap: 12px; margin-bottom: 20px; }
.back-btn, .refresh-btn {
padding: 8px 16px;
border-radius: var(--radius-btn);
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
background: #FFFFFF;
border: none;
box-shadow: var(--shadow-sm);
color: var(--text-secondary);
}
.back-btn:hover, .refresh-btn:hover { background: #F5F5F7; color: var(--text-primary); }
.detail-header {
background: var(--bg-card);
border-radius: var(--radius-card);
padding: 24px;
box-shadow: var(--shadow-md);
margin-bottom: 20px;
}
.header-left { display: flex; align-items: center; gap: 28px; }
.symbol-name { font-size: 28px; font-weight: 700; letter-spacing: -0.5px; }
.symbol-code { font-size: 14px; color: var(--text-tertiary); padding: 4px 12px; background: #F5F5F7; border-radius: 8px; }
.price-main { display: flex; flex-direction: column; align-items: flex-end; }
.detail-price { font-size: 36px; font-weight: 700; letter-spacing: -1px; }
.detail-price.up { color: var(--color-up); }
.detail-price.down { color: var(--color-down); }
.detail-change { font-size: 16px; font-weight: 600; }
.detail-change.up { color: var(--color-up); }
.detail-change.down { color: var(--color-down); }
.quote-grid { display: flex; gap: 32px; margin-top: 16px; }
.quote-item { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.quote-label { font-size: 12px; color: var(--text-tertiary); text-transform: uppercase; font-weight: 600; }
.quote-value { font-size: 16px; font-weight: 600; }
.period-bar { display: flex; align-items: center; gap: 16px; margin-bottom: 20px; }
.period-btns { display: flex; gap: 6px; background: #FFFFFF; padding: 4px; border-radius: 12px; box-shadow: var(--shadow-sm); }
.period-btn {
padding: 8px 20px;
border-radius: 8px;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
background: transparent;
border: none;
color: var(--text-secondary);
}
.period-btn:hover { background: #F5F5F7; color: var(--text-primary); }
.period-btn.active { background: var(--color-brand); color: #FFFFFF; }
.detail-body { display: grid; grid-template-columns: 1fr 400px; gap: 20px; }
.chart-container, .history-container, .panel-card {
background: var(--bg-card);
border-radius: var(--radius-card);
padding: 24px;
box-shadow: var(--shadow-md);
}
.kline-chart { width: 100%; height: 480px; }
/* 模态框样式 */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.4);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
display: none;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-overlay.active { display: flex; }
.modal-content {
background: #FFFFFF;
border-radius: 24px;
width: 90%;
max-width: 640px;
max-height: 80vh;
overflow: hidden;
box-shadow: var(--shadow-lg);
}
.modal-large { max-width: 960px; }
.modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24px 28px;
border-bottom: 1px solid #F5F5F7;
}
.modal-header h3 { font-size: 18px; font-weight: 600; }
.modal-close {
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
background: none;
border: none;
cursor: pointer;
border-radius: 10px;
font-size: 18px;
color: var(--text-secondary);
}
.modal-close:hover { background: #F5F5F7; }
.modal-body { padding: 28px; overflow-y: auto; max-height: 70vh; }
/* Toast 样式 */
.toast-container { position: fixed; top: 88px; right: 32px; z-index: 2000; display: flex; flex-direction: column; gap: 12px; }
.toast {
display: flex;
align-items: center;
gap: 12px;
padding: 16px 22px;
background: #FFFFFF;
border-radius: 16px;
box-shadow: var(--shadow-lg);
min-width: 300px;
max-width: 420px;
}
.toast.success { border-left: 4px solid var(--color-down); }
.toast.error { border-left: 4px solid var(--color-up); }
.toast.warning { border-left: 4px solid var(--color-neutral); }
.toast.info { border-left: 4px solid var(--color-brand); }
.toast-title { font-size: 14px; font-weight: 600; }
.toast-message { font-size: 13px; color: var(--text-secondary); }
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@media (max-width: 1200px) { .detail-body { grid-template-columns: 1fr; } }
@media (max-width: 768px) {
.stats-row { grid-template-columns: repeat(2, 1fr); }
.grid { grid-template-columns: 1fr; }
.header { padding: 0 16px; }
.container { padding: 16px; }
}
/* 复盘计划样式 - 与品种分析页面一致的亮色主题 */
#review-view {
background: var(--bg-page);
border-radius: 20px;
padding: 24px 0;
min-height: 600px;
}
.rv-toolbar { display: flex; gap: 12px; margin-bottom: 24px; align-items: center; justify-content: center; flex-wrap: wrap; }
.rv-date-selector { background: #fff; border: 1px solid rgba(0,0,0,0.05); border-radius: 12px; padding: 0 16px; height: 44px; font-size: 14px; color: var(--text-primary); box-shadow: var(--shadow-sm); min-width: 180px; outline: none; font-family: inherit; }
.rv-date-selector:focus { border-color: var(--color-brand); box-shadow: 0 0 0 3px rgba(0,122,255,0.15); }
.rv-btn { padding: 10px 20px; border-radius: 12px; font-size: 14px; font-weight: 600; cursor: pointer; border: none; display: flex; align-items: center; gap: 8px; transition: all 0.2s; font-family: inherit; }
.rv-btn-primary { background: var(--color-brand); color: #fff; }
.rv-btn-primary:hover { background: #0066d6; box-shadow: 0 4px 10px rgba(0,122,255,0.3); }
.rv-btn-secondary { background: #fff; color: var(--text-secondary); box-shadow: var(--shadow-sm); }
.rv-btn-secondary:hover { background: #F5F5F7; }
.rv-hero { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 20px; padding: 32px; margin-bottom: 24px; text-align: center; color: #fff; }
.rv-hero h1 { font-size: 28px; font-weight: 700; margin-bottom: 8px; color: #fff; }
.rv-hero h1 span { font-size: 18px; opacity: 0.8; }
.rv-hero-subtitle { font-size: 14px; color: rgba(255,255,255,0.7); margin-bottom: 12px; }
.rv-hero-conclusion { font-size: 16px; color: #fff; font-weight: 500; }
.rv-stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 24px; }
.rv-stat-card { background: var(--bg-card); border-radius: 16px; padding: 20px; text-align: center; box-shadow: var(--shadow-sm); transition: transform 0.2s, box-shadow 0.2s; }
.rv-stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.rv-stat-label { font-size: 12px; color: var(--text-tertiary); margin-bottom: 8px; text-transform: uppercase; font-weight: 600; }
.rv-stat-value { font-size: 24px; font-weight: 700; color: var(--text-primary); }
.rv-stat-text { font-size: 13px; color: var(--text-secondary); margin-top: 4px; }
.rv-risk-banner { background: rgba(255,59,48,0.06); border: 1px solid rgba(255,59,48,0.15); border-radius: 16px; padding: 16px 20px; margin-bottom: 24px; }
.rv-risk-title { font-size: 14px; font-weight: 600; color: var(--color-up); margin-bottom: 8px; }
.rv-risk-list { list-style: none; padding: 0; }
.rv-risk-list li { font-size: 13px; color: var(--text-secondary); padding: 4px 0; }
.rv-risk-list li::before { content: "⚠️ "; }
.rv-nav { display: flex; gap: 8px; margin-bottom: 24px; overflow-x: auto; padding-bottom: 8px; position: sticky; top: 64px; background: var(--bg-page); z-index: 10; padding-top: 8px; }
.rv-nav-item { padding: 8px 16px; border-radius: 9999px; font-size: 13px; background: #fff; color: var(--text-secondary); cursor: pointer; white-space: nowrap; transition: all 0.2s; text-decoration: none; box-shadow: var(--shadow-sm); font-weight: 500; }
.rv-nav-item:hover { background: var(--color-brand); color: #fff; box-shadow: 0 4px 10px rgba(0,122,255,0.2); }
.rv-section { margin-bottom: 32px; }
.rv-section-title { font-size: 18px; font-weight: 700; margin-bottom: 16px; padding-bottom: 8px; border-bottom: 2px solid rgba(0,0,0,0.05); color: var(--text-primary); }
.rv-green-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
.rv-opp-card { background: var(--bg-card); border-radius: 20px; padding: 20px; box-shadow: var(--shadow-md); transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); position: relative; overflow: hidden; }
.rv-opp-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.rv-opp-card::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(90deg, var(--color-down), var(--color-brand)); }
.rv-opp-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.rv-opp-symbol { font-size: 16px; font-weight: 700; color: var(--text-primary); }
.rv-opp-score { background: rgba(52,199,89,0.12); color: var(--color-down); padding: 4px 10px; border-radius: 8px; font-size: 12px; font-weight: 700; }
.rv-opp-info { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 12px; font-size: 13px; }
.rv-opp-info-item { display: flex; justify-content: space-between; padding: 4px 0; }
.rv-opp-info-label { color: var(--text-tertiary); }
.rv-score-bars { margin-bottom: 12px; }
.rv-score-bar-item { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; font-size: 12px; }
.rv-score-bar-label { width: 50px; color: var(--text-tertiary); }
.rv-score-bar-track { flex: 1; height: 6px; background: #F5F5F7; border-radius: 3px; overflow: hidden; }
.rv-score-bar-fill { height: 100%; border-radius: 3px; transition: width 0.3s; }
.rv-score-bar-value { width: 30px; text-align: right; font-weight: 600; }
.rv-plan-box { background: #F5F5F7; border-radius: 12px; padding: 12px; font-size: 12px; }
.rv-plan-row { display: flex; justify-content: space-between; margin-bottom: 4px; color: var(--text-secondary); }
.rv-plan-trigger { color: var(--color-ai); margin-top: 8px; font-style: italic; }
.rv-watch-list, .rv-avoid-list { display: flex; flex-wrap: wrap; gap: 12px; }
.rv-watch-item, .rv-avoid-item { background: var(--bg-card); border-radius: 12px; padding: 12px 16px; display: flex; align-items: center; gap: 12px; box-shadow: var(--shadow-sm); transition: all 0.2s; }
.rv-watch-item:hover, .rv-avoid-item:hover { box-shadow: var(--shadow-md); transform: translateY(-1px); }
.rv-watch-item { border-left: 3px solid var(--color-neutral); }
.rv-avoid-item { border-left: 3px solid var(--color-up); }
.rv-item-symbol { font-weight: 600; font-size: 14px; color: var(--text-primary); }
.rv-item-score { font-size: 12px; color: var(--text-tertiary); }
.rv-item-tag { font-size: 11px; padding: 2px 8px; border-radius: 4px; font-weight: 500; }
.rv-tag-bull { background: rgba(52,199,89,0.12); color: var(--color-down); }
.rv-tag-bear { background: rgba(255,59,48,0.12); color: var(--color-up); }
.rv-tag-neutral { background: #F5F5F7; color: var(--text-tertiary); }
/* 列表表格样式(重点关注/规避) */
.rv-list-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.rv-list-table th { background: #F5F5F7; padding: 12px; text-align: left; font-weight: 600; color: var(--text-tertiary); font-size: 12px; }
.rv-list-table td { padding: 10px 12px; border-bottom: 1px solid rgba(0,0,0,0.04); color: var(--text-primary); }
.rv-list-table tbody tr { cursor: pointer; transition: background 0.15s; }
.rv-yellow-table tbody tr:hover { background: rgba(255,149,0,0.05); }
.rv-red-table tbody tr:hover { background: rgba(255,59,48,0.05); }
/* 排序控件 */
.rv-sort-controls { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rv-sort-btn { background: #fff; color: var(--text-secondary); border: 1px solid rgba(0,0,0,0.08); border-radius: 9999px; padding: 6px 14px; font-size: 12px; font-weight: 500; cursor: pointer; transition: all 0.2s; }
.rv-sort-btn:hover { background: #F5F5F7; border-color: var(--color-brand); }
.rv-sort-btn.active { background: var(--color-brand); color: #fff; border-color: var(--color-brand); }
/* 弹窗样式 */
.rv-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); backdrop-filter: blur(8px); z-index: 2000; display: none; align-items: center; justify-content: center; }
.rv-modal-overlay.show { display: flex; }
.rv-modal { background: #fff; border-radius: 20px; width: 90%; max-width: 700px; max-height: 85vh; overflow-y: auto; box-shadow: 0 25px 50px rgba(0,0,0,0.25); animation: rv-modal-in 0.25s ease; }
@keyframes rv-modal-in { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
.rv-modal-header { display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; border-bottom: 1px solid rgba(0,0,0,0.06); }
.rv-modal-title { font-size: 18px; font-weight: 700; color: var(--text-primary); }
.rv-modal-close { width: 32px; height: 32px; border-radius: 50%; border: none; background: #F5F5F7; font-size: 16px; cursor: pointer; display: flex; align-items: center; justify-content: center; color: var(--text-secondary); transition: all 0.2s; }
.rv-modal-close:hover { background: #E5E5E7; }
.rv-modal-body { padding: 20px 24px; }
.rv-modal-section { margin-bottom: 20px; }
.rv-modal-section-title { font-size: 12px; font-weight: 600; color: var(--text-tertiary); margin-bottom: 10px; text-transform: uppercase; letter-spacing: 0.5px; }
.rv-modal-metrics-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.rv-modal-metric { background: #F5F5F7; border-radius: 10px; padding: 12px; text-align: center; }
.rv-modal-metric .mm-label { font-size: 11px; color: var(--text-tertiary); display: block; margin-bottom: 4px; }
.rv-modal-metric .mm-val { font-size: 16px; font-weight: 700; color: var(--text-primary); }
.rv-modal-plan-box { background: #F5F5F7; border-radius: 12px; padding: 14px; }
.rv-modal-plan-row { display: flex; justify-content: space-between; padding: 6px 0; font-size: 13px; }
.rv-modal-plan-row .mp-label { color: var(--text-tertiary); }
.rv-modal-plan-row .mp-val { font-weight: 600; color: var(--text-primary); }
.rv-modal-plan-row .mp-val.stop { color: var(--color-up); }
.rv-modal-plan-row .mp-val.target { color: var(--color-down); }
.rv-modal-pivots { display: flex; flex-wrap: wrap; gap: 8px; }
.rv-data-date-tag { display: inline-block; font-size: 10px; color: var(--text-tertiary); background: #F5F5F7; padding: 2px 6px; border-radius: 4px; margin-left: 4px; }
.rv-ranking-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.rv-ranking-table th { background: #F5F5F7; padding: 12px; text-align: left; font-weight: 600; color: var(--text-tertiary); font-size: 12px; text-transform: uppercase; }
.rv-ranking-table td { padding: 10px 12px; border-bottom: 1px solid rgba(0,0,0,0.04); color: var(--text-primary); }
.rv-ranking-table tr:hover { background: rgba(0,122,255,0.03); }
.rv-table-score-bar { width: 80px; height: 6px; background: #F5F5F7; border-radius: 3px; overflow: hidden; display: inline-block; vertical-align: middle; margin-left: 8px; }
.rv-table-score-fill { height: 100%; border-radius: 3px; }
.rv-detail-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; }
.rv-detail-card { background: var(--bg-card); border-radius: 16px; padding: 16px; box-shadow: var(--shadow-sm); transition: all 0.2s; }
.rv-detail-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.rv-detail-title { font-size: 14px; font-weight: 700; margin-bottom: 12px; color: var(--color-brand); }
.rv-detail-metrics { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; font-size: 12px; }
.rv-detail-metric { display: flex; justify-content: space-between; padding: 6px 8px; background: #F5F5F7; border-radius: 8px; color: var(--text-secondary); }
.rv-pivot-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.rv-pivot-tag { font-size: 11px; padding: 4px 8px; border-radius: 6px; background: #F5F5F7; font-weight: 500; }
.rv-pivot-tag.resist { color: var(--color-up); background: rgba(255,59,48,0.08); }
.rv-pivot-tag.support { color: var(--color-down); background: rgba(52,199,89,0.08); }
.rv-pivot-tag.pivot { color: var(--color-ai); background: rgba(175,82,222,0.08); }
.rv-sector-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 16px; }
.rv-sector-card { background: var(--bg-card); border-radius: 16px; padding: 16px; box-shadow: var(--shadow-sm); transition: all 0.2s; }
.rv-sector-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.rv-sector-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.rv-sector-name { font-size: 15px; font-weight: 700; color: var(--text-primary); }
.rv-sector-heat { font-size: 18px; }
.rv-sector-info { font-size: 12px; color: var(--text-secondary); margin-bottom: 8px; }
.rv-sector-members { display: flex; flex-wrap: wrap; gap: 6px; }
.rv-sector-member { font-size: 11px; padding: 4px 8px; background: #F5F5F7; border-radius: 6px; color: var(--text-secondary); }
.rv-empty-state { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 400px; gap: 16px; }
.rv-empty-icon { font-size: 64px; opacity: 0.3; }
.rv-empty-text { font-size: 16px; color: var(--text-tertiary); }
.rv-loading { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #fff; padding: 32px 48px; border-radius: 20px; z-index: 1000; text-align: center; box-shadow: var(--shadow-lg); }
.rv-loading.active { display: block; }
.rv-loading p { color: var(--text-secondary); font-size: 14px; }
.rv-spinner { width: 40px; height: 40px; border: 3px solid #F5F5F7; border-top-color: var(--color-brand); border-radius: 50%; animation: rv-spin 1s linear infinite; margin: 0 auto 16px; }
@keyframes rv-spin { to { transform: rotate(360deg); } }
/* ============================================
交易复盘页面样式
============================================ */
#trade-review-view { background: var(--bg-page); border-radius: 20px; padding: 24px 0; min-height: 600px; }
.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: 12px; 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:disabled { opacity: 0.5; cursor: not-allowed; }
.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: #F5F5F7; }
.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-date-input { background: #fff; border: 1px solid rgba(0,0,0,0.05); border-radius: 12px; 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); }
/* 6列统计卡片 */
.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-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: #F5F5F7; 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-link { color: var(--color-brand); cursor: pointer; text-decoration: none; font-weight: 500; }
.tr-link:hover { text-decoration: underline; }
/* K线周期按钮 */
.tr-kline-tabs { display: flex; gap: 8px; margin-bottom: 16px; align-items: center; }
.tr-kline-tab { padding: 6px 14px; border: 1px solid rgba(0,0,0,0.08); background: #fff; border-radius: 6px; cursor: pointer; font-size: 13px; font-weight: 500; color: var(--text-secondary); transition: all 0.2s; font-family: inherit; }
.tr-kline-tab:hover { background: var(--color-brand); color: #fff; border-color: var(--color-brand); }
.tr-kline-tab.active { background: var(--color-brand); color: #fff; border-color: var(--color-brand); box-shadow: 0 4px 10px rgba(0,122,255,0.2); }
/* 弹窗通用样式(复用 rv-modal 体系) */
.tr-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); backdrop-filter: blur(8px); z-index: 2000; display: none; align-items: center; justify-content: center; }
.tr-modal-overlay.show { display: flex; }
.tr-modal { background: #fff; border-radius: 20px; width: 90%; max-width: 1000px; max-height: 90vh; overflow-y: auto; box-shadow: 0 25px 50px rgba(0,0,0,0.25); animation: rv-modal-in 0.25s ease; }
.tr-modal-header { display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; border-bottom: 1px solid rgba(0,0,0,0.06); }
.tr-modal-title { font-size: 18px; font-weight: 700; color: var(--text-primary); }
.tr-modal-close { width: 32px; height: 32px; border-radius: 50%; border: none; background: #F5F5F7; font-size: 16px; cursor: pointer; display: flex; align-items: center; justify-content: center; color: var(--text-secondary); transition: all 0.2s; }
.tr-modal-close:hover { background: #E5E5E7; }
.tr-modal-body { padding: 24px; }
/* 弹窗内概览网格 */
.tr-overview-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 24px; }
.tr-overview-item { background: #F5F5F7; border-radius: 12px; padding: 16px; text-align: center; }
.tr-overview-label { font-size: 12px; color: var(--text-tertiary); margin-bottom: 4px; }
.tr-overview-value { font-size: 20px; font-weight: 700; color: var(--text-primary); }
.tr-overview-value.profit { color: var(--color-down); }
.tr-overview-value.loss { color: var(--color-up); }
/* AI诊断框 */
.tr-ai-box { background: linear-gradient(135deg, #f0f7ff 0%, #e6f4ff 100%); border: 1px solid #bae0ff; border-radius: 12px; padding: 20px; margin-bottom: 24px; }
.tr-ai-title { font-size: 16px; font-weight: 600; color: #0958d9; margin-bottom: 12px; display: flex; align-items: center; gap: 8px; }
.tr-ai-content { font-size: 14px; color: var(--text-primary); line-height: 1.8; white-space: pre-wrap; }
.tr-ai-tag { display: inline-block; background: #e6f4ff; color: #0958d9; padding: 2px 8px; border-radius: 4px; font-size: 12px; margin-right: 8px; margin-bottom: 8px; }
/* 品种详情弹窗内K线 */
.tr-kline-chart { width: 100%; height: 400px; }
/* 每日详情 - 品种分区 */
.tr-variety-section { margin-top: 24px; border-top: 1px solid rgba(0,0,0,0.06); padding-top: 20px; }
/* 批次管理 */
.tr-batch-item { display: flex; justify-content: space-between; align-items: center; padding: 14px 16px; background: #F5F5F7; border-radius: 12px; margin-bottom: 10px; }
.tr-batch-info { flex: 1; }
.tr-batch-file { font-size: 14px; font-weight: 600; color: var(--text-primary); margin-bottom: 4px; }
.tr-batch-meta { font-size: 12px; color: var(--text-tertiary); }
.tr-batch-delete { padding: 6px 14px; border-radius: 8px; border: none; background: rgba(255,59,48,0.1); color: var(--color-up); font-size: 12px; font-weight: 600; cursor: pointer; transition: all 0.2s; }
.tr-batch-delete:hover { background: rgba(255,59,48,0.2); }
/* 空状态 */
.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); }
/* ============================================
交易反思子系统样式
============================================ */
.tr-subtabs { display: flex; gap: 8px; margin-bottom: 24px; background: rgba(255,255,255,0.6); padding: 4px; border-radius: 14px; backdrop-filter: blur(8px); width: fit-content; }
.tr-subtab { padding: 8px 20px; border-radius: 10px; font-size: 14px; font-weight: 500; cursor: pointer; border: none; background: transparent; color: var(--text-secondary); transition: all 0.2s; font-family: inherit; }
.tr-subtab:hover { background: rgba(0,0,0,0.03); color: var(--text-primary); }
.tr-subtab.active { background: #fff; color: var(--color-brand); box-shadow: var(--shadow-sm); font-weight: 600; }
.tr-tab-panel { display: none; }
.tr-tab-panel.active { display: block; }
/* 交易反思 - 日期导航 */
.tr-refl-datebar { display: flex; align-items: center; justify-content: center; gap: 16px; margin-bottom: 24px; }
.tr-refl-datebtn { width: 36px; height: 36px; border-radius: 50%; border: none; background: #fff; color: var(--text-secondary); cursor: pointer; box-shadow: var(--shadow-sm); transition: all 0.2s; font-size: 16px; }
.tr-refl-datebtn:hover { background: var(--color-brand); color: #fff; }
.tr-refl-datetext { font-size: 20px; font-weight: 700; color: var(--text-primary); min-width: 120px; text-align: center; }
.tr-refl-actions { display: flex; gap: 10px; margin-left: auto; }
/* 反思统计卡片 */
.tr-refl-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 24px; }
.tr-refl-statcard { background: var(--bg-card); border-radius: var(--radius-card); padding: 20px; text-align: center; box-shadow: var(--shadow-sm); transition: transform 0.2s; }
.tr-refl-statcard:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.tr-refl-statlabel { font-size: 12px; color: var(--text-tertiary); margin-bottom: 8px; font-weight: 600; }
.tr-refl-statvalue { font-size: 26px; font-weight: 700; }
.tr-refl-statvalue.profit { color: var(--color-down); }
.tr-refl-statvalue.loss { color: var(--color-up); }
.tr-refl-reflected { display: inline-flex; align-items: center; gap: 6px; padding: 4px 12px; border-radius: 9999px; font-size: 12px; font-weight: 600; }
.tr-refl-reflected.yes { background: rgba(52,199,89,0.12); color: var(--color-down); }
.tr-refl-reflected.no { background: rgba(255,59,48,0.12); color: var(--color-up); }
/* 当日反思区域 */
.tr-refl-daily { background: var(--bg-card); border-radius: var(--radius-card); padding: 24px; margin-bottom: 24px; box-shadow: var(--shadow-sm); }
.tr-refl-daily-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.tr-refl-daily-title { font-size: 17px; font-weight: 700; color: var(--text-primary); }
.tr-refl-daily-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.tr-refl-daily-item { background: #F5F5F7; border-radius: 12px; padding: 14px; }
.tr-refl-daily-label { font-size: 11px; color: var(--text-tertiary); margin-bottom: 6px; font-weight: 600; text-transform: uppercase; }
.tr-refl-daily-value { font-size: 14px; color: var(--text-primary); font-weight: 500; line-height: 1.4; }
.tr-refl-daily-value.empty { color: var(--text-tertiary); font-style: italic; }
/* 交易配对卡片 */
.tr-refl-section-title { font-size: 17px; font-weight: 700; margin-bottom: 16px; color: var(--text-primary); }
.tr-refl-pairs { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; margin-bottom: 24px; }
.tr-refl-card { background: var(--bg-card); border-radius: var(--radius-card); padding: 20px; box-shadow: var(--shadow-sm); transition: transform 0.2s, box-shadow 0.2s; position: relative; overflow: hidden; }
.tr-refl-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.tr-refl-card::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--color-brand); }
.tr-refl-card.profit::before { background: var(--color-down); }
.tr-refl-card.loss::before { background: var(--color-up); }
.tr-refl-card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
.tr-refl-card-symbol { font-size: 16px; font-weight: 700; }
.tr-refl-card-dir { font-size: 12px; padding: 3px 10px; border-radius: 6px; font-weight: 600; }
.tr-refl-card-dir.long { background: rgba(52,199,89,0.12); color: var(--color-down); }
.tr-refl-card-dir.short { background: rgba(255,59,48,0.12); color: var(--color-up); }
.tr-refl-card-pnl { font-size: 20px; font-weight: 700; text-align: right; }
.tr-refl-card-pnl.profit { color: var(--color-down); }
.tr-refl-card-pnl.loss { color: var(--color-up); }
.tr-refl-card-nodes { font-size: 13px; color: var(--text-secondary); margin-bottom: 14px; line-height: 1.6; }
.tr-refl-card-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.tr-refl-tag { font-size: 11px; padding: 4px 10px; border-radius: 9999px; background: #F5F5F7; color: var(--text-secondary); font-weight: 500; }
.tr-refl-tag.active { background: rgba(0,122,255,0.12); color: var(--color-brand); }
.tr-refl-card-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.tr-refl-card-actions .tr-btn { padding: 6px 12px; font-size: 12px; }
/* 未配对交易 */
.tr-refl-unpaired { background: var(--bg-card); border-radius: var(--radius-card); padding: 20px; box-shadow: var(--shadow-sm); }
.tr-refl-unpaired-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.tr-refl-unpaired-header .tr-refl-section-title { margin-bottom: 0; }
.tr-refl-unpaired-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.tr-refl-unpaired-table th { background: #F5F5F7; padding: 10px 8px; text-align: left; font-weight: 600; color: var(--text-tertiary); font-size: 12px; }
.tr-refl-unpaired-table td { padding: 10px 8px; border-bottom: 1px solid rgba(0,0,0,0.04); color: var(--text-primary); }
.tr-refl-unpaired-table input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--color-brand); cursor: pointer; }
/* 经验库 */
.tr-exp-toolbar { display: flex; gap: 12px; margin-bottom: 20px; flex-wrap: wrap; align-items: center; }
.tr-exp-search { background: #fff; border: 1px solid rgba(0,0,0,0.05); border-radius: 12px; padding: 0 14px; height: 40px; font-size: 14px; width: 260px; outline: none; }
.tr-exp-search:focus { border-color: var(--color-brand); box-shadow: 0 0 0 3px rgba(0,122,255,0.15); }
.tr-exp-filter { background: #fff; border: 1px solid rgba(0,0,0,0.05); border-radius: 10px; padding: 0 12px; height: 36px; font-size: 13px; color: var(--text-primary); outline: none; }
.tr-exp-viewtabs { display: flex; gap: 6px; margin-left: auto; }
.tr-exp-viewtab { padding: 6px 14px; border-radius: 10px; font-size: 13px; cursor: pointer; border: none; background: #fff; color: var(--text-secondary); transition: all 0.2s; }
.tr-exp-viewtab:hover { background: #F5F5F7; }
.tr-exp-viewtab.active { background: var(--color-brand); color: #fff; }
.tr-exp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
.tr-exp-card { background: var(--bg-card); border-radius: var(--radius-card); padding: 20px; box-shadow: var(--shadow-sm); transition: all 0.2s; }
.tr-exp-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.tr-exp-card-title { font-size: 15px; font-weight: 700; margin-bottom: 10px; color: var(--text-primary); }
.tr-exp-card-meta { font-size: 12px; color: var(--text-tertiary); margin-bottom: 12px; }
.tr-exp-card-content { font-size: 13px; color: var(--text-secondary); line-height: 1.7; margin-bottom: 14px; }
.tr-exp-card-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.tr-exp-pagination { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 24px; }
.tr-exp-pageinfo { font-size: 13px; color: var(--text-secondary); font-weight: 500; }
.tr-exp-detail-meta { font-size: 12px; color: var(--text-tertiary); margin-bottom: 16px; }
.tr-exp-detail-content { font-size: 14px; color: var(--text-primary); line-height: 1.8; background: #F5F5F7; border-radius: 12px; padding: 16px; margin-bottom: 16px; white-space: pre-wrap; }
.tr-exp-detail-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 16px; }
.tr-exp-detail-source { font-size: 13px; color: var(--text-secondary); }
.tr-exp-detail-source .link { cursor: pointer; }
/* Modal 表单 */
.tr-form-group { margin-bottom: 18px; }
.tr-form-label { display: block; font-size: 13px; font-weight: 600; color: var(--text-secondary); margin-bottom: 8px; }
.tr-form-input, .tr-form-select, .tr-form-textarea { width: 100%; background: #F5F5F7; border: 1px solid transparent; border-radius: 10px; padding: 10px 12px; font-size: 14px; color: var(--text-primary); font-family: inherit; outline: none; transition: all 0.2s; }
.tr-form-input:focus, .tr-form-select:focus, .tr-form-textarea:focus { border-color: var(--color-brand); background: #fff; box-shadow: 0 0 0 3px rgba(0,122,255,0.1); }
.tr-form-textarea { min-height: 90px; resize: vertical; }
.tr-form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.tr-form-rating { display: flex; gap: 6px; }
.tr-form-star { font-size: 22px; color: #E5E5E7; cursor: pointer; transition: color 0.15s; }
.tr-form-star.active { color: #FF9F0A; }
.tr-form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 24px; }
/* 标签管理 */
.tr-tag-section { margin-bottom: 18px; }
.tr-tag-section-title { font-size: 13px; font-weight: 600; color: var(--text-secondary); margin-bottom: 10px; }
.tr-tag-pool { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.tr-tag-chip { padding: 6px 12px; border-radius: 9999px; font-size: 12px; cursor: pointer; border: 1px solid rgba(0,0,0,0.06); background: #fff; color: var(--text-secondary); transition: all 0.15s; }
.tr-tag-chip:hover { border-color: var(--color-brand); color: var(--color-brand); }
.tr-tag-chip.selected { background: rgba(0,122,255,0.12); border-color: var(--color-brand); color: var(--color-brand); font-weight: 500; }
.tr-tag-custom { display: flex; gap: 8px; margin-top: 12px; }
.tr-tag-custom .tr-form-input { flex: 1; }
/* AI 分析结果 */
.tr-ai-version-row { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; padding: 12px 16px; background: #F5F5F7; border-radius: 12px; }
.tr-ai-version-label { font-size: 13px; font-weight: 600; color: var(--text-tertiary); }
.tr-ai-version-row .tr-form-select { flex: 1; min-width: 200px; margin: 0; }
.tr-ai-result-section { margin-bottom: 18px; }
.tr-ai-result-title { font-size: 14px; font-weight: 700; color: var(--color-brand); margin-bottom: 8px; }
.tr-ai-result-content { font-size: 14px; color: var(--text-primary); line-height: 1.8; background: #F5F5F7; border-radius: 12px; padding: 14px; }
.tr-ai-list { padding-left: 18px; margin: 0; }
.tr-ai-list li { margin-bottom: 6px; line-height: 1.6; }
@media (max-width: 1200px) {
.tr-stats-grid { grid-template-columns: repeat(3, 1fr); }
.tr-refl-stats { grid-template-columns: repeat(2, 1fr); }
.tr-refl-daily-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.tr-stats-grid { grid-template-columns: repeat(2, 1fr); }
.tr-overview-grid { grid-template-columns: repeat(2, 1fr); }
.tr-refl-stats { grid-template-columns: 1fr; }
.tr-refl-daily-grid { grid-template-columns: 1fr; }
.tr-form-row { grid-template-columns: 1fr; }
.tr-refl-pairs { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
.rv-stats-grid { grid-template-columns: 1fr; }
.rv-green-grid { grid-template-columns: 1fr; }
.rv-detail-grid { grid-template-columns: 1fr; }
.rv-sector-grid { grid-template-columns: 1fr; }
}
</style>
</head>
<body>
<header class="header">
<div class="logo">◈ 期货智析</div>
<div class="nav-items">
<a href="#" class="nav-item active" data-page="analysis">品种分析</a>
<a href="#" class="nav-item" data-page="watched">自选</a>
<a href="#" class="nav-item" data-page="market" style="display:none">市场概览</a>
<a href="#" class="nav-item" data-page="risk" style="display:none">风险预警</a>
<a href="#" class="nav-item" data-page="review">复盘计划</a>
<a href="#" class="nav-item" data-page="trade-review">交易复盘</a>
</div>
<div class="live-badge">
<div class="dot"></div> LIVE
<span id="current-time" style="margin-left: 8px; font-size: 11px; color: var(--text-tertiary); font-variant-numeric: tabular-nums;"></span>
</div>
</header>
<div class="container">
<!-- Toast 提示容器 -->
<div class="toast-container" id="toast-container"></div>
<!-- 品种列表视图 -->
<div id="list-view" class="view active">
<!-- Toolbar -->
<div class="toolbar">
<div class="toolbar-left">
<input type="text" class="search-box" id="search-input" placeholder="🔍 搜索品种名称或代码...">
<div class="toolbar-actions">
<button class="refresh-all-btn" id="refresh-all-btn">
<i class="fas fa-sync-alt"></i>
<span>刷新全部</span>
</button>
<button class="ai-analyze-all-btn" id="ai-analyze-all-btn">
<i class="fas fa-brain"></i>
<span>全部分析</span>
</button>
</div>
</div>
<div class="pills">
<button class="pill active" data-category="all">全部 <span id="count-all">32</span></button>
<button class="pill" data-category="energy">能源</button>
<button class="pill" data-category="metal">金属</button>
<button class="pill" data-category="agriculture">农产品</button>
<button class="pill" data-category="finance">金融</button>
</div>
</div>
<!-- Stats -->
<div class="stats-row">
<div class="stat-card" onclick="filterByTrend('all')" style="cursor: pointer;" title="显示全部">
<div class="stat-icon blue"></div>
<div><div class="stat-val" id="total-count">0</div><div class="stat-label">监控品种</div></div>
</div>
<div class="stat-card" onclick="filterByTrend('up')" style="cursor: pointer;" title="筛选上涨趋势">
<div class="stat-icon green"></div>
<div><div class="stat-val" id="up-count">0</div><div class="stat-label">上涨趋势</div></div>
</div>
<div class="stat-card" onclick="filterByTrend('down')" style="cursor: pointer;" title="筛选下跌趋势">
<div class="stat-icon red"></div>
<div><div class="stat-val" id="down-count">0</div><div class="stat-label">下跌趋势</div></div>
</div>
<div class="stat-card" onclick="filterByTrend('neutral')" style="cursor: pointer;" title="筛选震荡整理">
<div class="stat-icon orange"></div>
<div><div class="stat-val" id="neutral-count">0</div><div class="stat-label">震荡整理</div></div>
</div>
</div>
<!-- Grid -->
<div id="futures-grid" class="grid">
<!-- 动态生成 -->
</div>
</div>
<!-- 详情分析视图 -->
<div id="detail-view" class="view">
<div class="detail-actions">
<button class="back-btn" id="back-btn">← 返回</button>
<button class="refresh-btn" id="refresh-symbol-btn">刷新数据</button>
</div>
<div class="detail-header">
<div class="header-left">
<div>
<span class="symbol-name" id="detail-name">--</span>
<span class="symbol-code" id="detail-symbol">--</span>
</div>
<div class="price-main">
<span class="detail-price" id="detail-price">--</span>
<span class="detail-change" id="detail-change">--</span>
</div>
</div>
<div class="quote-grid">
<div class="quote-item">
<span class="quote-label">开盘</span>
<span class="quote-value" id="detail-open">--</span>
</div>
<div class="quote-item">
<span class="quote-label">最高</span>
<span class="quote-value" id="detail-high">--</span>
</div>
<div class="quote-item">
<span class="quote-label">最低</span>
<span class="quote-value" id="detail-low">--</span>
</div>
<div class="quote-item">
<span class="quote-label">成交量</span>
<span class="quote-value" id="detail-volume">--</span>
</div>
</div>
</div>
<div class="period-bar">
<span style="font-size: 14px; color: var(--text-secondary); font-weight: 500;">周期</span>
<div class="period-btns">
<button class="period-btn" data-period="5">5M</button>
<button class="period-btn active" data-period="15">15M</button>
<button class="period-btn" data-period="30">30M</button>
<button class="period-btn" data-period="60">1H</button>
</div>
</div>
<div class="detail-body">
<div class="chart-section">
<div class="chart-container">
<div id="kline-chart" class="kline-chart"></div>
</div>
<div class="history-container">
<div style="font-size: 17px; font-weight: 600; margin-bottom: 16px;">历史分析记录</div>
<div class="history-list" id="history-list"></div>
</div>
</div>
<div class="analysis-sidebar">
<div class="panel-card" id="ai-analysis-panel">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px;">
<span style="font-size: 15px; font-weight: 600;">AI 思维分析</span>
<button class="back-btn" id="ai-analyze-btn" onclick="runAIAnalysis()" style="padding: 6px 12px; font-size: 13px;">智能分析</button>
</div>
<div class="ai-analysis-content" id="ai-analysis-content">
<div style="text-align: center; padding: 28px; color: var(--text-tertiary);">
<p>点击"智能分析"按钮获取AI分析结果</p>
</div>
</div>
</div>
<div class="panel-card">
<div style="font-size: 15px; font-weight: 600; margin-bottom: 16px;">技术指标</div>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
<div style="padding: 14px; background: #F5F5F7; border-radius: 12px;">
<div style="font-size: 12px; color: var(--text-tertiary); font-weight: 600;">MACD</div>
<div style="font-size: 16px; font-weight: 700;" id="macd-signal">--</div>
<div style="font-size: 12px; color: var(--text-secondary);" id="macd-detail">--</div>
</div>
<div style="padding: 14px; background: #F5F5F7; border-radius: 12px;">
<div style="font-size: 12px; color: var(--text-tertiary); font-weight: 600;">RSI</div>
<div style="font-size: 16px; font-weight: 700;" id="rsi-value">--</div>
<div style="font-size: 12px; color: var(--text-secondary);" id="rsi-status">--</div>
</div>
<div style="padding: 14px; background: #F5F5F7; border-radius: 12px;">
<div style="font-size: 12px; color: var(--text-tertiary); font-weight: 600;">BOLL</div>
<div style="font-size: 16px; font-weight: 700;" id="boll-signal">--</div>
<div style="font-size: 12px; color: var(--text-secondary);" id="boll-detail">--</div>
</div>
<div style="padding: 14px; background: #F5F5F7; border-radius: 12px;">
<div style="font-size: 12px; color: var(--text-tertiary); font-weight: 600;">KDJ</div>
<div style="font-size: 16px; font-weight: 700;" id="kdj-signal">--</div>
<div style="font-size: 12px; color: var(--text-secondary);" id="kdj-detail">--</div>
</div>
</div>
</div>
<div class="panel-card">
<div style="font-size: 15px; font-weight: 600; margin-bottom: 16px;">关键点位</div>
<div style="display: flex; flex-direction: column; gap: 10px;">
<div style="font-size: 12px; font-weight: 600; color: var(--color-up); text-transform: uppercase;">压力</div>
<div style="display: flex; justify-content: space-between; padding: 8px 12px; background: #F5F5F7; border-radius: 10px; font-size: 13px;">
<span style="color: var(--text-secondary);">R1</span>
<span style="font-weight: 600;" id="resistance-1">--</span>
</div>
<div style="display: flex; justify-content: space-between; padding: 8px 12px; background: #F5F5F7; border-radius: 10px; font-size: 13px;">
<span style="color: var(--text-secondary);">R2</span>
<span style="font-weight: 600;" id="resistance-2">--</span>
</div>
<div style="height: 1px; background: #F5F5F7;"></div>
<div style="display: flex; justify-content: space-between; padding: 10px 14px; background: rgba(175,82,222,0.1); border-radius: 12px;">
<span style="color: var(--color-ai); font-weight: 600;">中枢 (PP)</span>
<span style="color: var(--color-ai); font-size: 16px; font-weight: 700;" id="pivot-point">--</span>
</div>
<div style="height: 1px; background: #F5F5F7;"></div>
<div style="font-size: 12px; font-weight: 600; color: var(--color-down); text-transform: uppercase;">支撑</div>
<div style="display: flex; justify-content: space-between; padding: 8px 12px; background: #F5F5F7; border-radius: 10px; font-size: 13px;">
<span style="color: var(--text-secondary);">S1</span>
<span style="font-weight: 600;" id="support-1">--</span>
</div>
<div style="display: flex; justify-content: space-between; padding: 8px 12px; background: #F5F5F7; border-radius: 10px; font-size: 13px;">
<span style="color: var(--text-secondary);">S2</span>
<span style="font-weight: 600;" id="support-2">--</span>
</div>
</div>
</div>
<div class="panel-card">
<div style="font-size: 15px; font-weight: 600; margin-bottom: 16px;">多周期趋势</div>
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;" id="period-trends"></div>
</div>
<div class="panel-card" id="scenario-panel" style="display:none;">
<div style="font-size: 15px; font-weight: 600; margin-bottom: 16px;">情景预案</div>
<div style="display: flex; flex-direction: column; gap: 12px;" id="scenario-plans"></div>
</div>
</div>
</div>
</div>
<!-- 自选视图 -->
<div id="watched-view" class="view">
<div class="watched-header">
<h2>我的自选</h2>
<div class="watched-count" id="watched-total-count">0 个品种</div>
</div>
<div id="watched-grid" class="grid">
<!-- 动态生成 -->
</div>
<div id="watched-empty" class="empty-state" style="display: none;">
<div class="empty-icon"></div>
<div class="empty-text">暂无自选品种</div>
<div class="empty-hint">在品种列表中点击 ★ 添加自选</div>
</div>
</div>
<!-- 复盘计划视图 - V2 -->
<div id="review-view" class="view">
<!-- 工具栏 -->
<div class="rv-toolbar">
<input type="date" id="rv-date-selector" class="rv-date-selector" />
<button id="rv-btn-generate" class="rv-btn rv-btn-primary">
<span>📊</span>
<span>复盘与计划</span>
</button>
<button id="rv-btn-clear" class="rv-btn rv-btn-secondary">
<span>🗑️</span>
<span>清除数据</span>
</button>
</div>
<!-- 加载指示器 -->
<div id="rv-loading" class="rv-loading">
<div class="rv-spinner"></div>
<p>正在生成复盘计划,请稍候...</p>
</div>
<!-- 内容区域 -->
<div id="rv-content-area" style="display: none;">
<!-- Hero -->
<section id="rv-hero-section" class="rv-hero"></section>
<!-- 统计卡片 -->
<section id="rv-stats-grid" class="rv-stats-grid"></section>
<!-- 风险提示 -->
<section id="rv-risk-banner" class="rv-risk-banner" style="display: none;">
<div class="rv-risk-title">⚠️ 风险提示</div>
<ul id="rv-risk-list" class="rv-risk-list"></ul>
</section>
<!-- 导航 -->
<nav class="rv-nav">
<a href="#rv-hero-section" class="rv-nav-item">顶部</a>
<a href="#rv-green-section" class="rv-nav-item">交易机会</a>
<a href="#rv-yellow-section" class="rv-nav-item">重点关注</a>
<a href="#rv-red-section" class="rv-nav-item">规避</a>
<a href="#rv-table-section" class="rv-nav-item">全品种排名</a>
<a href="#rv-details-section" class="rv-nav-item">品种详情</a>
<a href="#rv-sectors-section" class="rv-nav-item">板块热度</a>
</nav>
<!-- 交易机会 -->
<section id="rv-green-section" class="rv-section" style="display: none;">
<h2 class="rv-section-title">🟢 交易机会品种</h2>
<div id="rv-green-grid" class="rv-green-grid"></div>
</section>
<!-- 重点关注 -->
<section id="rv-yellow-section" class="rv-section" style="display: none;">
<h2 class="rv-section-title">👀 重点关注品种</h2>
<div style="overflow-x: auto;">
<table class="rv-list-table rv-yellow-table">
<thead>
<tr>
<th>#</th>
<th>品种</th>
<th>收盘价</th>
<th>涨跌幅</th>
<th>综合评分</th>
<th>振幅%</th>
<th>量比</th>
<th>方向</th>
<th>数据日期</th>
</tr>
</thead>
<tbody id="rv-yellow-list"></tbody>
</table>
</div>
</section>
<!-- 规避 -->
<section id="rv-red-section" class="rv-section" style="display: none;">
<h2 class="rv-section-title">🔴 规避品种</h2>
<div style="overflow-x: auto;">
<table class="rv-list-table rv-red-table">
<thead>
<tr>
<th>#</th>
<th>品种</th>
<th>收盘价</th>
<th>涨跌幅</th>
<th>综合评分</th>
<th>振幅%</th>
<th>量比</th>
<th>方向</th>
<th>数据日期</th>
</tr>
</thead>
<tbody id="rv-red-list"></tbody>
</table>
</div>
</section>
<!-- 全品种排名 -->
<section id="rv-table-section" class="rv-section" style="display: none;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
<h2 class="rv-section-title" style="margin-bottom: 0;">📊 全品种综合排名</h2>
<div class="rv-sort-controls" id="rv-sort-controls">
<span style="font-size: 12px; color: var(--text-tertiary); margin-right: 6px;">排序:</span>
<button class="rv-sort-btn active" data-sort="composite_score" data-order="desc">综合评分</button>
<button class="rv-sort-btn" data-sort="activity_score" data-order="desc">活跃度</button>
<button class="rv-sort-btn" data-sort="volume_ratio" data-order="desc">量比</button>
<button class="rv-sort-btn" data-sort="direction_tag" data-order="asc">方向</button>
</div>
</div>
<div style="overflow-x: auto;">
<table id="rv-ranking-table" class="rv-ranking-table"></table>
</div>
</section>
<!-- 品种详情 -->
<section id="rv-details-section" class="rv-section" style="display: none;">
<h2 class="rv-section-title">📋 品种详情</h2>
<div id="rv-details-grid" class="rv-detail-grid"></div>
</section>
<!-- 板块热度 -->
<section id="rv-sectors-section" class="rv-section" style="display: none;">
<h2 class="rv-section-title">🔥 板块热度</h2>
<div id="rv-sectors-grid" class="rv-sector-grid"></div>
</section>
<!-- 页脚 -->
<footer style="text-align: center; padding: 24px 0; color: var(--text-tertiary); font-size: 12px; border-top: 1px solid rgba(0,0,0,0.05); margin-top: 32px;">
<p>本报告由系统自动生成,仅供投资参考,不构成具体投资建议。</p>
<p>投资有风险,入市需谨慎。请结合自身情况独立判断。</p>
</footer>
</div>
<!-- 空状态 -->
<div id="rv-empty-state" class="rv-empty-state">
<div class="rv-empty-icon">📊</div>
<div class="rv-empty-text">请选择日期或点击"复盘与计划"按钮生成分析报告</div>
</div>
</div>
<!-- 交易复盘视图 -->
<div id="trade-review-view" class="view">
<!-- 子 Tab 切换栏 -->
<div class="tr-subtabs" id="tr-subtabs">
<button class="tr-subtab active" data-subtab="stats">统计分析</button>
<button class="tr-subtab" data-subtab="reflection">交易反思</button>
<button class="tr-subtab" data-subtab="experience">经验库</button>
</div>
<!-- 统计分析子 Tab -->
<div id="tr-tab-stats" class="tr-tab-panel 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>
<!-- 账户权益曲线 -->
<div class="tr-chart-box">
<div class="tr-chart-title">账户权益曲线(累计净盈亏 + 每日盈亏)</div>
<div class="tr-chart-container" id="tr-equity-chart"></div>
</div>
<!-- 品种盈亏分布气泡图 -->
<div class="tr-chart-box">
<div class="tr-chart-title">品种盈亏分布(气泡大小=手续费占比,颜色=净盈亏)</div>
<div class="tr-bubble-container" id="tr-bubble-chart"></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 id="tr-daily-body"></tbody>
</table>
<div id="tr-daily-empty" class="tr-empty" style="display:none;">
<div class="tr-empty-icon">📊</div>
<div class="tr-empty-text">暂无交易数据,请先导入结算单</div>
</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>
</tr>
</thead>
<tbody id="tr-variety-body"></tbody>
</table>
<div id="tr-variety-empty" class="tr-empty" style="display:none;">
<div class="tr-empty-icon">📋</div>
<div class="tr-empty-text">暂无品种数据</div>
</div>
</div>
</div>
<!-- 交易反思子 Tab -->
<div id="tr-tab-reflection" class="tr-tab-panel">
<div class="tr-refl-datebar">
<button class="tr-refl-datebtn" id="tr-refl-prev" title="前一天"></button>
<span class="tr-refl-datetext" id="tr-refl-current-date">-</span>
<button class="tr-refl-datebtn" id="tr-refl-next" title="后一天"></button>
<div class="tr-refl-actions">
<button class="tr-btn tr-btn-secondary" id="tr-refl-edit-daily">
<span>✏️</span><span>当日反思编辑</span>
</button>
</div>
</div>
<div class="tr-refl-stats">
<div class="tr-refl-statcard">
<div class="tr-refl-statlabel">总盈亏</div>
<div class="tr-refl-statvalue" id="tr-refl-stat-pnl">-</div>
</div>
<div class="tr-refl-statcard">
<div class="tr-refl-statlabel">交易笔数</div>
<div class="tr-refl-statvalue" id="tr-refl-stat-trades">-</div>
</div>
<div class="tr-refl-statcard">
<div class="tr-refl-statlabel">胜率</div>
<div class="tr-refl-statvalue" id="tr-refl-stat-winrate">-</div>
</div>
<div class="tr-refl-statcard">
<div class="tr-refl-statlabel">已反思</div>
<div id="tr-refl-stat-reflected">-</div>
</div>
</div>
<div class="tr-refl-daily">
<div class="tr-refl-daily-header">
<div class="tr-refl-daily-title">当日反思</div>
</div>
<div class="tr-refl-daily-grid">
<div class="tr-refl-daily-item">
<div class="tr-refl-daily-label">情绪状态</div>
<div class="tr-refl-daily-value" id="tr-refl-emotion">-</div>
</div>
<div class="tr-refl-daily-item">
<div class="tr-refl-daily-label">执行纪律</div>
<div class="tr-refl-daily-value" id="tr-refl-discipline">-</div>
</div>
<div class="tr-refl-daily-item">
<div class="tr-refl-daily-label">总体评价</div>
<div class="tr-refl-daily-value" id="tr-refl-overall">-</div>
</div>
<div class="tr-refl-daily-item">
<div class="tr-refl-daily-label">市场判断</div>
<div class="tr-refl-daily-value" id="tr-refl-market">-</div>
</div>
</div>
</div>
<div class="tr-refl-section-title">交易配对</div>
<div id="tr-refl-pairs" class="tr-refl-pairs"></div>
<div class="tr-refl-unpaired">
<div class="tr-refl-unpaired-header">
<div class="tr-refl-section-title">未配对交易</div>
<button class="tr-btn tr-btn-primary" id="tr-refl-manual-pair-btn">
<span>🔗</span><span>手动配对</span>
</button>
</div>
<table class="tr-refl-unpaired-table">
<thead>
<tr><th><input type="checkbox" id="tr-refl-unpaired-select-all" title="全选"></th><th>时间</th><th>品种</th><th>开平</th><th>方向</th><th>价格</th><th>手数</th><th>盈亏</th></tr>
</thead>
<tbody id="tr-refl-unpaired-body"></tbody>
</table>
<div id="tr-refl-unpaired-empty" class="tr-empty" style="display:none;">
<div class="tr-empty-text">暂无未配对交易</div>
</div>
</div>
</div>
<!-- 经验库子 Tab -->
<div id="tr-tab-experience" class="tr-tab-panel">
<div class="tr-exp-toolbar">
<input type="text" class="tr-exp-search" id="tr-exp-search" placeholder="搜索经验...">
<select class="tr-exp-filter" id="tr-exp-tag-filter">
<option value="">全部标签</option>
</select>
<select class="tr-exp-filter" id="tr-exp-type-filter">
<option value="">全部类型</option>
<option value="lesson">教训</option>
<option value="insight">心得</option>
<option value="strategy">策略</option>
<option value="discipline">纪律</option>
</select>
<div class="tr-exp-viewtabs">
<button class="tr-exp-viewtab active" data-view="list">列表</button>
<button class="tr-exp-viewtab" data-view="timeline">时间线</button>
<button class="tr-exp-viewtab" data-view="category">分类</button>
</div>
</div>
<div id="tr-exp-container" class="tr-exp-grid"></div>
<div id="tr-exp-empty" class="tr-empty" style="display:none;">
<div class="tr-empty-icon">📚</div>
<div class="tr-empty-text">暂无经验记录</div>
</div>
<div class="tr-exp-pagination" id="tr-exp-pagination" style="display:none;">
<button class="tr-btn tr-btn-secondary" id="tr-exp-prev">上一页</button>
<span class="tr-exp-pageinfo" id="tr-exp-pageinfo"></span>
<button class="tr-btn tr-btn-secondary" id="tr-exp-next">下一页</button>
</div>
</div>
<!-- 反思编辑 Modal -->
<div id="tr-refl-edit-modal" class="tr-modal-overlay" onclick="if(event.target===this)trReflCloseEditModal()">
<div class="tr-modal" style="max-width:720px;">
<div class="tr-modal-header">
<span class="tr-modal-title">写反思</span>
<button class="tr-modal-close" onclick="trReflCloseEditModal()"></button>
</div>
<div class="tr-modal-body">
<form id="tr-refl-edit-form">
<input type="hidden" id="tr-refl-edit-pair-id">
<div class="tr-form-row">
<div class="tr-form-group">
<label class="tr-form-label">入场理由</label>
<textarea class="tr-form-textarea" id="tr-refl-entry-reason" placeholder="当时为什么入场?"></textarea>
</div>
<div class="tr-form-group">
<label class="tr-form-label">出场理由</label>
<textarea class="tr-form-textarea" id="tr-refl-exit-reason" placeholder="为什么在这个位置出场?"></textarea>
</div>
</div>
<div class="tr-form-row">
<div class="tr-form-group">
<label class="tr-form-label">入场时机评价</label>
<select class="tr-form-select" id="tr-refl-entry-timing">
<option value="">请选择</option>
<option value="excellent">优秀</option>
<option value="good">良好</option>
<option value="average">一般</option>
<option value="poor">较差</option>
<option value="bad">糟糕</option>
</select>
</div>
<div class="tr-form-group">
<label class="tr-form-label">出场时机评价</label>
<select class="tr-form-select" id="tr-refl-exit-timing">
<option value="">请选择</option>
<option value="excellent">优秀</option>
<option value="good">良好</option>
<option value="average">一般</option>
<option value="poor">较差</option>
<option value="bad">糟糕</option>
</select>
</div>
</div>
<div class="tr-form-group">
<label class="tr-form-label">仓位管理反思</label>
<textarea class="tr-form-textarea" id="tr-refl-position" placeholder="仓位是否合理?是否有改进空间?"></textarea>
</div>
<div class="tr-form-group">
<label class="tr-form-label">纪律评分</label>
<div class="tr-form-rating" id="tr-refl-discipline-score">
<span class="tr-form-star" data-score="1"></span>
<span class="tr-form-star" data-score="2"></span>
<span class="tr-form-star" data-score="3"></span>
<span class="tr-form-star" data-score="4"></span>
<span class="tr-form-star" data-score="5"></span>
</div>
</div>
<div class="tr-form-group">
<label class="tr-form-label">自由反思</label>
<textarea class="tr-form-textarea" id="tr-refl-free" placeholder="还有什么想记录的?"></textarea>
</div>
<div class="tr-form-group">
<label class="tr-form-label">标签</label>
<div id="tr-refl-edit-tags" class="tr-tag-pool"></div>
</div>
<div class="tr-form-actions">
<button type="button" class="tr-btn tr-btn-secondary" onclick="trReflCloseEditModal()">取消</button>
<button type="submit" class="tr-btn tr-btn-primary">保存反思</button>
</div>
</form>
</div>
</div>
</div>
<!-- 当日反思编辑 Modal -->
<div id="tr-refl-daily-modal" class="tr-modal-overlay" onclick="if(event.target===this)trReflCloseDailyModal()">
<div class="tr-modal" style="max-width:640px;">
<div class="tr-modal-header">
<span class="tr-modal-title">当日反思编辑</span>
<button class="tr-modal-close" onclick="trReflCloseDailyModal()"></button>
</div>
<div class="tr-modal-body">
<form id="tr-refl-daily-form">
<div class="tr-form-row">
<div class="tr-form-group">
<label class="tr-form-label">情绪状态</label>
<select class="tr-form-select" id="tr-refl-daily-emotion">
<option value="">请选择</option>
<option value="calm">平静</option>
<option value="confident">自信</option>
<option value="anxious">焦虑</option>
<option value="greedy">贪婪</option>
<option value="fearful">恐惧</option>
<option value="impulsive">冲动</option>
<option value="tired">疲惫</option>
</select>
</div>
<div class="tr-form-group">
<label class="tr-form-label">执行纪律评分</label>
<div class="tr-form-rating" id="tr-refl-daily-discipline-score">
<span class="tr-form-star" data-score="1"></span>
<span class="tr-form-star" data-score="2"></span>
<span class="tr-form-star" data-score="3"></span>
<span class="tr-form-star" data-score="4"></span>
<span class="tr-form-star" data-score="5"></span>
</div>
</div>
</div>
<div class="tr-form-row">
<div class="tr-form-group">
<label class="tr-form-label">总体评价</label>
<select class="tr-form-select" id="tr-refl-daily-overall">
<option value="">请选择</option>
<option value="excellent">优秀</option>
<option value="good">良好</option>
<option value="average">一般</option>
<option value="poor">较差</option>
<option value="bad">糟糕</option>
</select>
</div>
<div class="tr-form-group">
<label class="tr-form-label">市场判断</label>
<select class="tr-form-select" id="tr-refl-daily-market">
<option value="">请选择</option>
<option value="accurate">准确</option>
<option value="basically">基本准确</option>
<option value="deviated">有所偏差</option>
<option value="wrong">错误</option>
</select>
</div>
</div>
<div class="tr-form-group">
<label class="tr-form-label">总结</label>
<textarea class="tr-form-textarea" id="tr-refl-daily-summary" placeholder="今天交易的最大收获是什么?"></textarea>
</div>
<div class="tr-form-group">
<label class="tr-form-label">改进方向</label>
<textarea class="tr-form-textarea" id="tr-refl-daily-improvement" placeholder="明天要注意什么?"></textarea>
</div>
<div class="tr-form-actions">
<button type="button" class="tr-btn tr-btn-secondary" onclick="trReflCloseDailyModal()">取消</button>
<button type="submit" class="tr-btn tr-btn-primary">保存当日反思</button>
</div>
</form>
</div>
</div>
</div>
<!-- 标签管理 Modal -->
<div id="tr-refl-tags-modal" class="tr-modal-overlay" onclick="if(event.target===this)trReflCloseTagsModal()">
<div class="tr-modal" style="max-width:560px;">
<div class="tr-modal-header">
<span class="tr-modal-title">标签管理</span>
<button class="tr-modal-close" onclick="trReflCloseTagsModal()"></button>
</div>
<div class="tr-modal-body">
<input type="hidden" id="tr-refl-tags-pair-id">
<div id="tr-refl-tags-preset"></div>
<div class="tr-tag-custom">
<input type="text" class="tr-form-input" id="tr-refl-tag-input" placeholder="输入自定义标签">
<button type="button" class="tr-btn tr-btn-secondary" onclick="trReflAddCustomTag()">添加</button>
</div>
<div class="tr-form-actions">
<button type="button" class="tr-btn tr-btn-secondary" onclick="trReflCloseTagsModal()">取消</button>
<button type="button" class="tr-btn tr-btn-primary" onclick="trReflSaveTags()">保存标签</button>
</div>
</div>
</div>
</div>
<!-- 经验详情 Modal -->
<div id="tr-exp-detail-modal" class="tr-modal-overlay" onclick="if(event.target===this)trExpCloseDetailModal()">
<div class="tr-modal" style="max-width:600px;">
<div class="tr-modal-header">
<span class="tr-modal-title" id="tr-exp-detail-title">经验详情</span>
<button class="tr-modal-close" onclick="trExpCloseDetailModal()"></button>
</div>
<div class="tr-modal-body">
<div class="tr-exp-detail-meta" id="tr-exp-detail-meta"></div>
<div class="tr-exp-detail-content" id="tr-exp-detail-content"></div>
<div class="tr-exp-detail-tags" id="tr-exp-detail-tags"></div>
<div class="tr-exp-detail-source" id="tr-exp-detail-source"></div>
<div class="tr-form-actions">
<button type="button" class="tr-btn tr-btn-secondary" onclick="trExpCloseDetailModal()">关闭</button>
</div>
</div>
</div>
</div>
<!-- AI 分析结果 Modal -->
<div id="tr-refl-ai-modal" class="tr-modal-overlay" onclick="if(event.target===this)trReflCloseAIModal()">
<div class="tr-modal" style="max-width:680px;">
<div class="tr-modal-header">
<span class="tr-modal-title">AI 分析结果</span>
<button class="tr-modal-close" onclick="trReflCloseAIModal()"></button>
</div>
<div class="tr-modal-body">
<input type="hidden" id="tr-refl-ai-pair-id">
<div class="tr-ai-version-row">
<label class="tr-ai-version-label" for="tr-refl-ai-version">版本</label>
<select class="tr-form-select" id="tr-refl-ai-version"></select>
</div>
<div class="tr-ai-result-section">
<div class="tr-ai-result-title">综合评价</div>
<div class="tr-ai-result-content" id="tr-refl-ai-overall">-</div>
</div>
<div class="tr-ai-result-section">
<div class="tr-ai-result-title">优点</div>
<ul class="tr-ai-list" id="tr-refl-ai-strengths"></ul>
</div>
<div class="tr-ai-result-section">
<div class="tr-ai-result-title">不足</div>
<ul class="tr-ai-list" id="tr-refl-ai-weaknesses"></ul>
</div>
<div class="tr-ai-result-section">
<div class="tr-ai-result-title">经验提炼建议</div>
<div class="tr-ai-result-content" id="tr-refl-ai-suggestion">-</div>
</div>
<div class="tr-form-actions">
<button type="button" class="tr-btn tr-btn-secondary" onclick="trReflCloseAIModal()">关闭</button>
<button type="button" class="tr-btn tr-btn-primary" onclick="trReflSaveExperience()">保存到经验库</button>
</div>
</div>
</div>
</div>
</div>
<!-- 每日详情弹窗 -->
<div id="tr-daily-modal" class="rv-modal-overlay" onclick="if(event.target===this)trCloseDailyModal()">
<div class="rv-modal" style="max-width:1000px;">
<div class="rv-modal-header">
<span class="rv-modal-title" id="tr-daily-modal-title">每日详情</span>
<button class="rv-modal-close" onclick="trCloseDailyModal()"></button>
</div>
<div class="rv-modal-body">
<div id="tr-daily-modal-stats" class="tr-overview-grid"></div>
<div class="tr-ai-box">
<div class="tr-ai-title">🤖 AI 交易诊断报告</div>
<div class="tr-ai-content" id="tr-daily-ai-content"></div>
</div>
<div class="tr-variety-section">
<div class="tr-tbl-title" style="margin-bottom:12px">当日品种盈亏统计</div>
<div class="tr-chart-container" id="tr-daily-variety-chart" style="height:280px;margin-bottom:16px;"></div>
<div class="tr-tbl-box" style="padding:0;box-shadow:none;">
<table class="tr-table">
<thead><tr><th>品种</th><th>笔数</th><th>平仓盈亏</th><th>手续费</th><th>净盈亏</th><th>胜率</th><th>操作</th></tr></thead>
<tbody id="tr-daily-variety-body"></tbody>
</table>
</div>
</div>
<div class="tr-tbl-box" style="margin-top:24px;padding:0;box-shadow:none;">
<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></tr></thead>
<tbody id="tr-daily-trades-body"></tbody>
</table>
</div>
</div>
</div>
</div>
<!-- 品种详情弹窗 -->
<div id="tr-variety-modal" class="rv-modal-overlay" onclick="if(event.target===this)trCloseVarietyModal()">
<div class="rv-modal" style="max-width:1000px;">
<div class="rv-modal-header">
<span class="rv-modal-title" id="tr-variety-modal-title">品种详情</span>
<button class="rv-modal-close" onclick="trCloseVarietyModal()"></button>
</div>
<div class="rv-modal-body">
<div id="tr-variety-modal-stats" class="tr-overview-grid"></div>
<div class="tr-chart-box" style="margin-bottom:16px;">
<div class="tr-kline-tabs">
<button class="tr-kline-tab active" data-period="daily" onclick="trSwitchVarietyKlinePeriod('daily')">日线</button>
<button class="tr-kline-tab" data-period="60min" onclick="trSwitchVarietyKlinePeriod('60min')">60分钟</button>
<button class="tr-kline-tab" data-period="15min" onclick="trSwitchVarietyKlinePeriod('15min')">15分钟</button>
<button class="tr-kline-tab" data-period="5min" onclick="trSwitchVarietyKlinePeriod('5min')">5分钟</button>
<button id="tr-variety-reload-kline" class="tr-btn tr-btn-secondary" style="margin-left:auto;">刷新K线</button>
</div>
<div class="tr-kline-chart" id="tr-variety-kline-chart"></div>
</div>
<div class="tr-tbl-box" style="padding:0;box-shadow:none;">
<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></tr></thead>
<tbody id="tr-variety-trades-body"></tbody>
</table>
</div>
</div>
</div>
</div>
<!-- 交易详情弹窗 -->
<div id="tr-detail-modal" class="rv-modal-overlay" onclick="if(event.target===this)trCloseDetailModal()">
<div class="rv-modal" style="max-width:700px;">
<div class="rv-modal-header">
<span class="rv-modal-title" id="tr-detail-title">交易详情</span>
<button class="rv-modal-close" onclick="trCloseDetailModal()"></button>
</div>
<div class="rv-modal-body">
<div id="tr-detail-info" class="tr-overview-grid"></div>
<div class="tr-chart-box" style="margin-top:20px;">
<div class="tr-chart-title">K线走势与买卖点</div>
<div class="tr-kline-tabs">
<button class="tr-kline-tab active" data-period="daily" onclick="trSwitchKlinePeriod('daily')">日线</button>
<button class="tr-kline-tab" data-period="60min" onclick="trSwitchKlinePeriod('60min')">60分钟</button>
<button class="tr-kline-tab" data-period="15min" onclick="trSwitchKlinePeriod('15min')">15分钟</button>
<button class="tr-kline-tab" data-period="5min" onclick="trSwitchKlinePeriod('5min')">5分钟</button>
<button id="tr-detail-reload-kline" class="tr-btn tr-btn-secondary" style="margin-left:auto;">刷新K线</button>
</div>
<div id="tr-detail-kline" style="width:100%;height:300px;"></div>
</div>
<div style="margin-top:20px;text-align:center;">
<button id="tr-detail-ai-btn" class="tr-btn tr-btn-primary">开始AI分析</button>
</div>
<div id="tr-detail-ai-content" class="tr-ai-box" style="display:none;margin-top:16px;"></div>
</div>
</div>
</div>
<!-- 批次管理弹窗 -->
<div id="tr-batch-modal" class="rv-modal-overlay" onclick="if(event.target===this)trCloseBatchModal()">
<div class="rv-modal" style="max-width:600px;">
<div class="rv-modal-header">
<span class="rv-modal-title">导入批次管理</span>
<button class="rv-modal-close" onclick="trCloseBatchModal()"></button>
</div>
<div class="rv-modal-body">
<div id="tr-batch-list"></div>
</div>
</div>
</div>
<!-- 批量导入结果弹窗 -->
<div id="tr-batch-import-modal" class="rv-modal-overlay" onclick="if(event.target===this)trCloseBatchImportModal()">
<div class="rv-modal" style="max-width:700px;">
<div class="rv-modal-header">
<span class="rv-modal-title">批量导入结果</span>
<button class="rv-modal-close" onclick="trCloseBatchImportModal()"></button>
</div>
<div class="rv-modal-body">
<div id="tr-batch-import-summary" style="margin-bottom:16px;font-size:14px;font-weight:600;color:var(--text-primary);"></div>
<div id="tr-batch-import-details" style="max-height:400px;overflow-y:auto;"></div>
</div>
</div>
</div>
</div>
<!-- 复盘品种详情弹窗(移到 review-view 外部) -->
<div id="rv-detail-modal" class="rv-modal-overlay" onclick="if(event.target===this)rvCloseDetailModal()">
<div class="rv-modal">
<div class="rv-modal-header">
<span id="rv-modal-title" class="rv-modal-title">品种详情</span>
<button class="rv-modal-close" onclick="rvCloseDetailModal()"></button>
</div>
<div id="rv-modal-body" class="rv-modal-body">
<!-- 由 JS 动态填充 -->
</div>
</div>
</div>
<!-- AI分析详情对话框 -->
<div class="modal-overlay" id="ai-analysis-modal">
<div class="modal-content modal-large">
<div class="modal-header">
<h3>AI 四维联合分析报告</h3>
<button class="modal-close" onclick="closeModal('ai-analysis-modal')"></button>
</div>
<div class="modal-body" id="ai-analysis-modal-body">
<!-- 动态生成 -->
</div>
</div>
</div>
<!-- AI建议详情对话框 -->
<div class="modal-overlay" id="suggestion-modal">
<div class="modal-content">
<div class="modal-header">
<h3>AI 交易建议详情</h3>
<button class="modal-close" onclick="closeModal('suggestion-modal')"></button>
</div>
<div class="modal-body" id="suggestion-modal-body">
<!-- 动态生成 -->
</div>
</div>
</div>
<!-- 历史记录详情对话框 -->
<div class="modal-overlay" id="history-modal">
<div class="modal-content">
<div class="modal-header">
<h3>分析记录详情</h3>
<button class="modal-close" onclick="closeModal('history-modal')"></button>
</div>
<div class="modal-body" id="history-modal-body">
<!-- 动态生成 -->
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<script src="/static/futures_analysis.js?v=20260615001"></script>
</body>
</html>