fix: 四所统计日历显示每日盈亏与交易笔数

日历格子重置实例全局 button 样式,日期格展示 +X.XU 与 N 笔,标题栏汇总当月盈亏与总笔数。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-30 08:56:20 +08:00
parent 052dcf63bd
commit 4f784d09ac
8 changed files with 103 additions and 36 deletions
+4 -4
View File
@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<script src="/static/instance_theme.js?v=16"></script> <script src="/static/instance_theme.js?v=36"></script>
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4"> <link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4"> <link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
<script src="/static/account_risk_badge.js?v=4"></script> <script src="/static/account_risk_badge.js?v=4"></script>
@@ -243,8 +243,8 @@
.stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px} .stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px}
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4} .stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
</style> </style>
<link rel="stylesheet" href="/static/instance_theme.css?v=18"> <link rel="stylesheet" href="/static/instance_theme.css?v=38">
<link rel="stylesheet" href="/static/trade_stats_calendar.css?v=1"> <link rel="stylesheet" href="/static/trade_stats_calendar.css?v=3">
</head> </head>
<body <body
@@ -851,7 +851,7 @@
<script src="/static/form_submit_guard.js?v=2"></script> <script src="/static/form_submit_guard.js?v=2"></script>
<script src="/static/manual_order_rr_preview.js?v=5"></script> <script src="/static/manual_order_rr_preview.js?v=5"></script>
<script src="/static/strategy_roll.js?v=5"></script> <script src="/static/strategy_roll.js?v=5"></script>
<script src="/static/trade_stats_calendar.js?v=2"></script> <script src="/static/trade_stats_calendar.js?v=3"></script>
<script> <script>
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }}; const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }}; const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
+4 -4
View File
@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<script src="/static/instance_theme.js?v=16"></script> <script src="/static/instance_theme.js?v=36"></script>
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4"> <link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4"> <link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
<script src="/static/account_risk_badge.js?v=4"></script> <script src="/static/account_risk_badge.js?v=4"></script>
@@ -243,8 +243,8 @@
.stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px} .stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px}
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4} .stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
</style> </style>
<link rel="stylesheet" href="/static/instance_theme.css?v=18"> <link rel="stylesheet" href="/static/instance_theme.css?v=38">
<link rel="stylesheet" href="/static/trade_stats_calendar.css?v=1"> <link rel="stylesheet" href="/static/trade_stats_calendar.css?v=3">
</head> </head>
<body <body
@@ -818,7 +818,7 @@
<script src="/static/form_submit_guard.js?v=2"></script> <script src="/static/form_submit_guard.js?v=2"></script>
<script src="/static/manual_order_rr_preview.js?v=5"></script> <script src="/static/manual_order_rr_preview.js?v=5"></script>
<script src="/static/strategy_roll.js?v=5"></script> <script src="/static/strategy_roll.js?v=5"></script>
<script src="/static/trade_stats_calendar.js?v=2"></script> <script src="/static/trade_stats_calendar.js?v=3"></script>
<script> <script>
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }}; const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }}; const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
+4 -4
View File
@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<script src="/static/instance_theme.js?v=16"></script> <script src="/static/instance_theme.js?v=36"></script>
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4"> <link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4"> <link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
<script src="/static/account_risk_badge.js?v=4"></script> <script src="/static/account_risk_badge.js?v=4"></script>
@@ -243,8 +243,8 @@
.stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px} .stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px}
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4} .stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
</style> </style>
<link rel="stylesheet" href="/static/instance_theme.css?v=18"> <link rel="stylesheet" href="/static/instance_theme.css?v=38">
<link rel="stylesheet" href="/static/trade_stats_calendar.css?v=1"> <link rel="stylesheet" href="/static/trade_stats_calendar.css?v=3">
</head> </head>
<body <body
@@ -818,7 +818,7 @@
<script src="/static/form_submit_guard.js?v=2"></script> <script src="/static/form_submit_guard.js?v=2"></script>
<script src="/static/manual_order_rr_preview.js?v=5"></script> <script src="/static/manual_order_rr_preview.js?v=5"></script>
<script src="/static/strategy_roll.js?v=5"></script> <script src="/static/strategy_roll.js?v=5"></script>
<script src="/static/trade_stats_calendar.js?v=2"></script> <script src="/static/trade_stats_calendar.js?v=3"></script>
<script> <script>
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }}; const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }}; const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
+4 -4
View File
@@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<script src="/static/instance_theme.js?v=16"></script> <script src="/static/instance_theme.js?v=36"></script>
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4"> <link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4"> <link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
<script src="/static/account_risk_badge.js?v=4"></script> <script src="/static/account_risk_badge.js?v=4"></script>
@@ -243,8 +243,8 @@
.stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px} .stats-period-block h3{font-size:1rem;color:#dbe4ff;margin-bottom:4px}
.stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4} .stats-period-block .sub{font-size:.78rem;color:#8892b0;margin-bottom:10px;line-height:1.4}
</style> </style>
<link rel="stylesheet" href="/static/instance_theme.css?v=18"> <link rel="stylesheet" href="/static/instance_theme.css?v=38">
<link rel="stylesheet" href="/static/trade_stats_calendar.css?v=1"> <link rel="stylesheet" href="/static/trade_stats_calendar.css?v=3">
</head> </head>
<body <body
@@ -847,7 +847,7 @@
<script src="/static/form_submit_guard.js?v=2"></script> <script src="/static/form_submit_guard.js?v=2"></script>
<script src="/static/manual_order_rr_preview.js?v=5"></script> <script src="/static/manual_order_rr_preview.js?v=5"></script>
<script src="/static/strategy_roll.js?v=5"></script> <script src="/static/strategy_roll.js?v=5"></script>
<script src="/static/trade_stats_calendar.js?v=2"></script> <script src="/static/trade_stats_calendar.js?v=3"></script>
<script> <script>
const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }}; const JOURNAL_ENTRY_REASON_OPTIONS = {{ entry_reason_options | tojson }};
const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }}; const JOURNAL_ENTRY_REASON_OTHER = {{ entry_reason_other_value | tojson }};
+4 -4
View File
@@ -3,12 +3,12 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<script src="/static/instance_theme.js?v=17"></script> <script src="/static/instance_theme.js?v=37"></script>
<link rel="stylesheet" href="/static/instance_theme_early.css?v=4"> <link rel="stylesheet" href="/static/instance_theme_early.css?v=4">
<link rel="stylesheet" href="/static/account_risk_badge.css?v=4"> <link rel="stylesheet" href="/static/account_risk_badge.css?v=4">
<link rel="stylesheet" href="/static/instance_page.css?v=2"> <link rel="stylesheet" href="/static/instance_page.css?v=2">
<link rel="stylesheet" href="/static/instance_theme.css?v=18"> <link rel="stylesheet" href="/static/instance_theme.css?v=38">
<link rel="stylesheet" href="/static/trade_stats_calendar.css?v=1"> <link rel="stylesheet" href="/static/trade_stats_calendar.css?v=3">
<script src="/static/account_risk_badge.js?v=4"></script> <script src="/static/account_risk_badge.js?v=4"></script>
<meta name="theme-color" content="#0b0d14"> <meta name="theme-color" content="#0b0d14">
<title>{{ exchange_display }} · 加密货币 | 交易监控复盘系统</title> <title>{{ exchange_display }} · 加密货币 | 交易监控复盘系统</title>
@@ -121,7 +121,7 @@
<script src="/static/manual_order_rr_preview.js?v=5"></script> <script src="/static/manual_order_rr_preview.js?v=5"></script>
<script src="/static/strategy_roll.js?v=5"></script> <script src="/static/strategy_roll.js?v=5"></script>
<script src="/static/key_monitor_form.js?v=2"></script> <script src="/static/key_monitor_form.js?v=2"></script>
<script src="/static/trade_stats_calendar.js?v=2"></script> <script src="/static/trade_stats_calendar.js?v=3"></script>
{% include 'embed_boot_scripts.html' %} {% include 'embed_boot_scripts.html' %}
<script src="/static/instance_embed.js?v=5"></script> <script src="/static/instance_embed.js?v=5"></script>
</body> </body>
+2 -2
View File
@@ -16,7 +16,7 @@
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" /> <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" />
<noscript><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" /></noscript> <noscript><link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600&family=Orbitron:wght@500;600;700&display=swap" rel="stylesheet" /></noscript>
<link rel="stylesheet" href="/assets/app.css?v=20260614-plan-detail" /> <link rel="stylesheet" href="/assets/app.css?v=20260614-plan-detail" />
<link rel="stylesheet" href="/assets/trade_stats_calendar.css?v=1" /> <link rel="stylesheet" href="/assets/trade_stats_calendar.css?v=3" />
<link rel="stylesheet" href="/assets/account_risk_badge.css?v=4" /> <link rel="stylesheet" href="/assets/account_risk_badge.css?v=4" />
<script src="/assets/account_risk_badge.js?v=4"></script> <script src="/assets/account_risk_badge.js?v=4"></script>
<link rel="stylesheet" href="/assets/dashboard.css?v=20260612-dash-monitor-count" /> <link rel="stylesheet" href="/assets/dashboard.css?v=20260612-dash-monitor-count" />
@@ -1058,7 +1058,7 @@
<script src="/assets/chart.js?v=20260626-market-tail-patch"></script> <script src="/assets/chart.js?v=20260626-market-tail-patch"></script>
<script src="/assets/plan.js?v=20260614-plan-refresh"></script> <script src="/assets/plan.js?v=20260614-plan-refresh"></script>
<script src="/assets/calculator.js?v=3"></script> <script src="/assets/calculator.js?v=3"></script>
<script src="/assets/trade_stats_calendar.js?v=1"></script> <script src="/assets/trade_stats_calendar.js?v=3"></script>
<script src="/assets/archive.js?v=20260626-archive-layout"></script> <script src="/assets/archive.js?v=20260626-archive-layout"></script>
<script src="/assets/funds.js?v=20260609-hub-funds-fold"></script> <script src="/assets/funds.js?v=20260609-hub-funds-fold"></script>
<script src="/assets/dashboard.js?v=20260612-dash-monitor-count"></script> <script src="/assets/dashboard.js?v=20260612-dash-monitor-count"></script>
+34 -8
View File
@@ -23,6 +23,29 @@
.stats-calendar-wrap { .stats-calendar-wrap {
margin-bottom: 14px; margin-bottom: 14px;
} }
.trade-cal-wrap button.trade-cal-cell {
background: var(--trade-cal-cell-bg) !important;
background-image: none !important;
border: 1px solid transparent;
padding: 4px 3px;
min-height: 68px;
width: 100%;
box-shadow: none;
line-height: 1.15;
font-size: inherit;
text-align: center;
}
.trade-cal-wrap button.trade-cal-cell:disabled {
opacity: 1;
cursor: default;
}
.trade-cal-wrap .trade-cal-head .btn,
.trade-cal-wrap .trade-cal-head button {
min-height: 0;
min-width: 34px;
padding: 4px 12px;
line-height: 1.2;
}
.trade-cal-head { .trade-cal-head {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -71,9 +94,10 @@
.trade-cal-cell.has-trade { .trade-cal-cell.has-trade {
cursor: pointer; cursor: pointer;
} }
.trade-cal-cell.has-trade:hover { .trade-cal-wrap button.trade-cal-cell.has-trade:hover {
background: var(--trade-cal-cell-hover-bg) !important;
background-image: none !important;
border-color: var(--trade-cal-cell-hover-border); border-color: var(--trade-cal-cell-hover-border);
background: var(--trade-cal-cell-hover-bg);
} }
.trade-cal-cell.is-selected { .trade-cal-cell.is-selected {
border-color: var(--trade-cal-selected-border); border-color: var(--trade-cal-selected-border);
@@ -89,12 +113,6 @@
background: color-mix(in srgb, #3b82f6 14%, var(--trade-cal-sick-bg)); background: color-mix(in srgb, #3b82f6 14%, var(--trade-cal-sick-bg));
box-shadow: 0 0 0 2px var(--trade-cal-selected-shadow); box-shadow: 0 0 0 2px var(--trade-cal-selected-shadow);
} }
.trade-cal-cell.pnl-pos .trade-cal-pnl {
color: var(--trade-cal-pos);
}
.trade-cal-cell.pnl-neg .trade-cal-pnl {
color: var(--trade-cal-neg);
}
.trade-cal-day-num { .trade-cal-day-num {
font-size: 0.78rem; font-size: 0.78rem;
font-weight: 600; font-weight: 600;
@@ -104,10 +122,18 @@
font-size: 0.72rem; font-size: 0.72rem;
font-weight: 600; font-weight: 600;
line-height: 1.1; line-height: 1.1;
color: var(--text, #e8ecff);
}
.trade-cal-cell.pnl-pos .trade-cal-pnl {
color: var(--trade-cal-pos);
}
.trade-cal-cell.pnl-neg .trade-cal-pnl {
color: var(--trade-cal-neg);
} }
.trade-cal-cnt { .trade-cal-cnt {
font-size: 0.65rem; font-size: 0.65rem;
color: var(--muted, #8892b0); color: var(--muted, #8892b0);
font-weight: 500;
} }
.trade-cal-sick-tag { .trade-cal-sick-tag {
font-size: 0.62rem; font-size: 0.62rem;
+47 -6
View File
@@ -18,6 +18,29 @@
return y + "年" + m + "月"; return y + "年" + m + "月";
} }
function formatCalPnl(pnl) {
var n = Number(pnl);
if (!Number.isFinite(n)) n = 0;
return (n >= 0 ? "+" : "") + n.toFixed(1) + "U";
}
function dayHasTrade(info) {
if (!info) return false;
var cnt = Number(info.open_count);
if (Number.isFinite(cnt) && cnt > 0) return true;
var pnl = Number(info.pnl_total);
return Number.isFinite(pnl) && Math.abs(pnl) > 0.0001;
}
function dayOpenCount(info) {
var cnt = Number(info && info.open_count);
return Number.isFinite(cnt) && cnt > 0 ? cnt : 0;
}
function dayPnl(info) {
return Number(info && info.pnl_total) || 0;
}
function TradeStatsCalendar(config) { function TradeStatsCalendar(config) {
this.gridEl = config.gridEl; this.gridEl = config.gridEl;
this.titleEl = config.titleEl; this.titleEl = config.titleEl;
@@ -46,6 +69,8 @@
this.year = config.year || 0; this.year = config.year || 0;
this.month = config.month || 0; this.month = config.month || 0;
this.days = {}; this.days = {};
this.monthPnlTotal = 0;
this.monthOpenCount = 0;
this._navBound = false; this._navBound = false;
this._bindNav(); this._bindNav();
} }
@@ -72,7 +97,12 @@
TradeStatsCalendar.prototype.render = function () { TradeStatsCalendar.prototype.render = function () {
if (!this.gridEl || !this.titleEl) return; if (!this.gridEl || !this.titleEl) return;
if (this.year <= 0 || this.month <= 0) this.ensureMonth(new Date()); if (this.year <= 0 || this.month <= 0) this.ensureMonth(new Date());
this.titleEl.textContent = monthLabel(this.year, this.month); var title = monthLabel(this.year, this.month);
if (this.monthOpenCount > 0) {
title +=
" · " + formatCalPnl(this.monthPnlTotal) + " · " + this.monthOpenCount + "笔";
}
this.titleEl.textContent = title;
var first = new Date(this.year, this.month - 1, 1); var first = new Date(this.year, this.month - 1, 1);
var lastDay = new Date(this.year, this.month, 0).getDate(); var lastDay = new Date(this.year, this.month, 0).getDate();
var startWd = first.getDay(); var startWd = first.getDay();
@@ -94,10 +124,10 @@
"-" + "-" +
String(d).padStart(2, "0"); String(d).padStart(2, "0");
var info = this.days[dayStr]; var info = this.days[dayStr];
var hasTrade = info && info.open_count > 0; var hasTrade = dayHasTrade(info);
var sick = this.showSick && info && info.has_sick; var sick = this.showSick && info && info.has_sick;
var pnl = hasTrade ? Number(info.pnl_total) : null; var pnl = hasTrade ? dayPnl(info) : null;
var cnt = hasTrade ? info.open_count : 0; var cnt = hasTrade ? dayOpenCount(info) : 0;
var cls = var cls =
"trade-cal-cell" + "trade-cal-cell" +
(hasTrade ? " has-trade" : "") + (hasTrade ? " has-trade" : "") +
@@ -110,10 +140,9 @@
: ""); : "");
var body = '<span class="trade-cal-day-num">' + d + "</span>"; var body = '<span class="trade-cal-day-num">' + d + "</span>";
if (hasTrade) { if (hasTrade) {
var pnlTxt = (pnl >= 0 ? "+" : "") + pnl.toFixed(1);
body += body +=
'<span class="trade-cal-pnl">' + '<span class="trade-cal-pnl">' +
esc(pnlTxt) + esc(formatCalPnl(pnl)) +
"</span>" + "</span>" +
'<span class="trade-cal-cnt">' + '<span class="trade-cal-cnt">' +
cnt + cnt +
@@ -168,6 +197,18 @@
data = await resp.json(); data = await resp.json();
} }
this.days = this.parseResponse(data) || {}; this.days = this.parseResponse(data) || {};
this.monthPnlTotal = Number(data && data.month_pnl_total) || 0;
this.monthOpenCount = Number(data && data.month_open_count) || 0;
if (!this.monthOpenCount) {
var self = this;
Object.keys(this.days).forEach(function (k) {
if (dayHasTrade(self.days[k])) {
self.monthOpenCount += dayOpenCount(self.days[k]);
self.monthPnlTotal += dayPnl(self.days[k]);
}
});
this.monthPnlTotal = Math.round(this.monthPnlTotal * 10000) / 10000;
}
this.render(); this.render();
if (this.onMonthChange) this.onMonthChange(this.year, this.month, this.days); if (this.onMonthChange) this.onMonthChange(this.year, this.month, this.days);
} catch (e) { } catch (e) {