From 8e025adba92b4dceb77119de5ad29f84494fb09e Mon Sep 17 00:00:00 2001
From: aaron <>
Date: Sun, 29 Mar 2026 12:27:25 +0800
Subject: [PATCH] 1
---
frontend/trading.html | 207 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 205 insertions(+), 2 deletions(-)
diff --git a/frontend/trading.html b/frontend/trading.html
index 6210708..cf164fe 100644
--- a/frontend/trading.html
+++ b/frontend/trading.html
@@ -145,8 +145,81 @@
color: var(--error);
}
+ /* Real-time Prices */
+ .price-section {
+ margin-bottom: 24px;
+ padding: 16px;
+ background: var(--bg-secondary);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-md);
+ }
+
+ .price-list {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
+ gap: 12px;
+ }
+
+ .price-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 12px;
+ background: var(--bg-primary);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-sm);
+ }
+
+ .price-item .symbol {
+ font-weight: 600;
+ color: var(--text-primary);
+ }
+
+ .price-item .price {
+ font-size: 16px;
+ font-weight: 700;
+ color: var(--primary);
+ }
+
+ /* Core Metrics Grid */
+ .core-metrics-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+ gap: 16px;
+ margin-bottom: 24px;
+ }
+
+ .core-metric-card {
+ background: var(--bg-primary);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-md);
+ padding: 24px;
+ text-align: center;
+ }
+
+ .core-metric-label {
+ font-size: 13px;
+ font-weight: 500;
+ color: var(--text-secondary);
+ margin-bottom: 8px;
+ }
+
+ .core-metric-value {
+ font-size: 28px;
+ font-weight: 700;
+ color: var(--text-primary);
+ }
+
+ .core-metric-value.positive {
+ color: var(--success);
+ }
+
+ .core-metric-value.negative {
+ color: var(--error);
+ }
+
@media (max-width: 768px) {
- .metrics-grid, .stat-grid, .grade-stats {
+ .metrics-grid, .stat-grid, .grade-stats, .core-metrics-grid, .price-list {
grid-template-columns: 1fr;
}
}
@@ -273,6 +346,17 @@
+
+
+
实时价格
+
+
+ {{ symbol }}
+ ${{ price.toLocaleString() }}
+
+
+
+
@@ -483,6 +570,94 @@
+
+
+
+
+
+
+
累计收益率
+
+ {{ stats.total_pnl_percent >= 0 ? '+' : '' }}{{ stats.total_pnl_percent ? stats.total_pnl_percent.toFixed(2) : '0.00' }}%
+
+
+
+
总盈亏
+
+ {{ stats.total_pnl >= 0 ? '+' : '' }}${{ stats.total_pnl ? stats.total_pnl.toFixed(2) : '0.00' }}
+
+
+
+
胜率
+
+ {{ stats.win_rate ? stats.win_rate.toFixed(1) : '0.0' }}%
+
+
+
+
盈亏比
+
+ {{ stats.profit_factor === Infinity ? '∞' : (stats.profit_factor ? stats.profit_factor.toFixed(2) : '0.00') }}
+
+
+
+
+
+
+
+
+
+
+ 总交易数
+ {{ stats.total_trades || 0 }}
+
+
+ 盈利交易
+ {{ stats.winning_trades || 0 }}
+
+
+ 亏损交易
+ {{ stats.losing_trades || 0 }}
+
+
+ 最佳交易
+ {{ stats.best_trade ? stats.best_trade.toFixed(2) : '0.00' }}%
+
+
+ 最差交易
+ {{ stats.worst_trade ? stats.worst_trade.toFixed(2) : '0.00' }}%
+
+
+
+
+
+
+
+
+ 平均盈利
+ ${{ stats.average_win ? stats.average_win.toFixed(2) : '0.00' }}
+
+
+ 平均亏损
+ ${{ stats.average_loss ? stats.average_loss.toFixed(2) : '0.00' }}
+
+
+ 最大回撤
+ {{ stats.max_drawdown ? stats.max_drawdown.toFixed(2) : '0.00' }}%
+
+
+ 收益率
+
+ {{ stats.return_percent >= 0 ? '+' : '' }}{{ stats.return_percent ? stats.return_percent.toFixed(2) : '0.00' }}%
+
+
+
+
+
+
@@ -534,7 +709,9 @@
showAdminMenu: false,
adminPassword: '223388',
titleClickCount: 0,
- titleClickTimer: null
+ titleClickTimer: null,
+ refreshInterval: null,
+ latestPrices: {}
};
},
computed: {
@@ -571,6 +748,18 @@
}
},
+ async silentRefresh() {
+ try {
+ await Promise.all([
+ this.fetchAccountStatus(),
+ this.fetchStatistics(),
+ this.fetchOrders()
+ ]);
+ } catch (e) {
+ console.error('静默刷新失败:', e);
+ }
+ },
+
async fetchAccountStatus() {
try {
const response = await axios.get('/api/trading/account');
@@ -599,6 +788,10 @@
console.log('API Response:', response.data);
if (response.data.success) {
this.orders = response.data.orders || [];
+ // 获取实时价格
+ if (response.data.latest_prices) {
+ this.latestPrices = response.data.latest_prices;
+ }
console.log('Orders loaded:', this.orders.length);
console.log('Orders data:', this.orders);
console.log('Open positions:', this.orders.filter(o => o.status === 'open'));
@@ -768,12 +961,22 @@
mounted() {
this.refreshData();
+ // 每3秒自动刷新(静默刷新,不显示 loading)
+ this.refreshInterval = setInterval(() => {
+ this.silentRefresh();
+ }, 3000);
+
// 点击外部关闭管理菜单
document.addEventListener('click', (e) => {
if (this.showAdminMenu && !e.target.closest('.admin-dropdown')) {
this.showAdminMenu = false;
}
});
+ },
+ beforeUnmount() {
+ if (this.refreshInterval) {
+ clearInterval(this.refreshInterval);
+ }
}
}).mount('#app');