From 4f784d09ac66a1fa4512ee7d9dcdc3d5a4adff9b Mon Sep 17 00:00:00 2001 From: dekun Date: Tue, 30 Jun 2026 08:56:20 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=9B=9B=E6=89=80=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E6=97=A5=E5=8E=86=E6=98=BE=E7=A4=BA=E6=AF=8F=E6=97=A5=E7=9B=88?= =?UTF-8?q?=E4=BA=8F=E4=B8=8E=E4=BA=A4=E6=98=93=E7=AC=94=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 日历格子重置实例全局 button 样式,日期格展示 +X.XU 与 N 笔,标题栏汇总当月盈亏与总笔数。 Co-authored-by: Cursor --- crypto_monitor_binance/templates/index.html | 8 +-- crypto_monitor_gate/templates/index.html | 8 +-- crypto_monitor_gate_bot/templates/index.html | 8 +-- crypto_monitor_okx/templates/index.html | 8 +-- embed_templates/embed_shell.html | 8 +-- manual_trading_hub/static/index.html | 4 +- static/trade_stats_calendar.css | 42 +++++++++++++--- static/trade_stats_calendar.js | 53 +++++++++++++++++--- 8 files changed, 103 insertions(+), 36 deletions(-) diff --git a/crypto_monitor_binance/templates/index.html b/crypto_monitor_binance/templates/index.html index 90d5b9f..443c22f 100644 --- a/crypto_monitor_binance/templates/index.html +++ b/crypto_monitor_binance/templates/index.html @@ -3,7 +3,7 @@ - + @@ -243,8 +243,8 @@ .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} - - + + - + + @@ -243,8 +243,8 @@ .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} - - + + - + + @@ -243,8 +243,8 @@ .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} - - + + - + + @@ -243,8 +243,8 @@ .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} - - + + - + + - - + + {{ exchange_display }} · 加密货币 | 交易监控复盘系统 @@ -121,7 +121,7 @@ - + {% include 'embed_boot_scripts.html' %} diff --git a/manual_trading_hub/static/index.html b/manual_trading_hub/static/index.html index 27c2eef..4c43577 100644 --- a/manual_trading_hub/static/index.html +++ b/manual_trading_hub/static/index.html @@ -16,7 +16,7 @@ - + @@ -1058,7 +1058,7 @@ - + diff --git a/static/trade_stats_calendar.css b/static/trade_stats_calendar.css index 30bd526..f928e3c 100644 --- a/static/trade_stats_calendar.css +++ b/static/trade_stats_calendar.css @@ -23,6 +23,29 @@ .stats-calendar-wrap { 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 { display: flex; align-items: center; @@ -71,9 +94,10 @@ .trade-cal-cell.has-trade { 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); - background: var(--trade-cal-cell-hover-bg); } .trade-cal-cell.is-selected { border-color: var(--trade-cal-selected-border); @@ -89,12 +113,6 @@ background: color-mix(in srgb, #3b82f6 14%, var(--trade-cal-sick-bg)); 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 { font-size: 0.78rem; font-weight: 600; @@ -104,10 +122,18 @@ font-size: 0.72rem; font-weight: 600; 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 { font-size: 0.65rem; color: var(--muted, #8892b0); + font-weight: 500; } .trade-cal-sick-tag { font-size: 0.62rem; diff --git a/static/trade_stats_calendar.js b/static/trade_stats_calendar.js index 1c352dc..95f641c 100644 --- a/static/trade_stats_calendar.js +++ b/static/trade_stats_calendar.js @@ -18,6 +18,29 @@ 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) { this.gridEl = config.gridEl; this.titleEl = config.titleEl; @@ -46,6 +69,8 @@ this.year = config.year || 0; this.month = config.month || 0; this.days = {}; + this.monthPnlTotal = 0; + this.monthOpenCount = 0; this._navBound = false; this._bindNav(); } @@ -72,7 +97,12 @@ TradeStatsCalendar.prototype.render = function () { if (!this.gridEl || !this.titleEl) return; 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 lastDay = new Date(this.year, this.month, 0).getDate(); var startWd = first.getDay(); @@ -94,10 +124,10 @@ "-" + String(d).padStart(2, "0"); 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 pnl = hasTrade ? Number(info.pnl_total) : null; - var cnt = hasTrade ? info.open_count : 0; + var pnl = hasTrade ? dayPnl(info) : null; + var cnt = hasTrade ? dayOpenCount(info) : 0; var cls = "trade-cal-cell" + (hasTrade ? " has-trade" : "") + @@ -110,10 +140,9 @@ : ""); var body = '' + d + ""; if (hasTrade) { - var pnlTxt = (pnl >= 0 ? "+" : "") + pnl.toFixed(1); body += '' + - esc(pnlTxt) + + esc(formatCalPnl(pnl)) + "" + '' + cnt + @@ -168,6 +197,18 @@ data = await resp.json(); } 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(); if (this.onMonthChange) this.onMonthChange(this.year, this.month, this.days); } catch (e) {