diff --git a/src/web_dashboard.py b/src/web_dashboard.py
index 4b4fb6b..e1323ed 100644
--- a/src/web_dashboard.py
+++ b/src/web_dashboard.py
@@ -118,11 +118,9 @@ async def record_buy(pair: str, qty: float, price: float):
"""Record a buy trade"""
trading_state['current_trades'][pair] = {
'qty': qty,
- 'buy_price': price,
- 'buy_time': datetime.now().isoformat(),
- 'peak_profit': 0,
- 'trailing_stop': None,
- 'order_id': None
+ 'entry_price': price,
+ 'entry_time': datetime.now().isoformat(),
+ 'type': 'BUY'
}
trading_state['trades_today'] += 1
await broadcast_update()
@@ -210,196 +208,207 @@ html_content = """
Trading Bot Dashboard
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ background: linear-gradient(135deg, #0f0c29 0%, #302b63 100%);
+ color: #e0e0e0;
+ padding: 20px;
+ min-height: 100vh;
+ }
+
+ .container {
+ max-width: 1400px;
+ margin: 0 auto;
+ }
+
+ .header {
+ text-align: center;
+ margin-bottom: 30px;
+ border-bottom: 2px solid #6c63ff;
+ padding-bottom: 20px;
+ }
+
+ .header h1 {
+ font-size: 2.5em;
+ color: #6c63ff;
+ margin-bottom: 10px;
+ }
+
+ .status {
+ display: inline-block;
+ padding: 8px 16px;
+ background: #00c853;
+ color: white;
+ border-radius: 20px;
+ font-weight: bold;
+ font-size: 0.9em;
+ }
+
+ .grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 20px;
+ margin-bottom: 30px;
+ }
+
+ .card {
+ background: rgba(255, 255, 255, 0.1);
+ border: 1px solid #6c63ff;
+ border-radius: 10px;
+ padding: 20px;
+ backdrop-filter: blur(10px);
+ transition: all 0.3s ease;
+ }
+
+ .card:hover {
+ background: rgba(255, 255, 255, 0.15);
+ border-color: #00c853;
+ transform: translateY(-5px);
+ }
+
+ .card-title {
+ color: #6c63ff;
+ font-size: 0.9em;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ margin-bottom: 10px;
+ }
+
+ .card-value {
+ font-size: 2em;
+ font-weight: bold;
+ color: #e0e0e0;
+ margin-bottom: 5px;
+ }
+
+ .card-sub {
+ color: #a0a0a0;
+ font-size: 0.85em;
+ }
+
+ .positive {
+ color: #00c853;
+ }
+
+ .negative {
+ color: #ff3d00;
+ }
+
+ .section {
+ margin-bottom: 30px;
+ }
+
+ .section-title {
+ color: #6c63ff;
+ font-size: 1.5em;
+ margin-bottom: 15px;
+ border-bottom: 1px solid #6c63ff;
+ padding-bottom: 10px;
+ }
+
+ .trades-list {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 15px;
+ }
+
+ .trade-card {
+ background: rgba(255, 255, 255, 0.08);
+ border-left: 4px solid #6c63ff;
+ border-radius: 5px;
+ padding: 15px;
+ font-size: 0.9em;
+ }
+
+ .trade-card.open {
+ border-left-color: #6c63ff;
+ }
+
+ .trade-card.closed {
+ border-left-color: #00c853;
+ }
+
+ .trade-pair {
+ font-weight: bold;
+ color: #6c63ff;
+ margin-bottom: 8px;
+ }
+
+ .trade-info {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 10px;
+ font-size: 0.85em;
+ color: #a0a0a0;
+ }
+
+ .trade-info strong {
+ color: #e0e0e0;
+ }
+
+ .swap-item {
+ background: rgba(255, 255, 255, 0.05);
+ padding: 10px;
+ border-radius: 5px;
+ margin-bottom: 8px;
+ font-size: 0.85em;
+ }
+
+ .performance-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: 15px;
+ }
+
+ .stat-card {
+ background: rgba(108, 99, 255, 0.2);
+ border: 1px solid #6c63ff;
+ border-radius: 8px;
+ padding: 15px;
+ text-align: center;
+ }
+
+ .stat-label {
+ color: #a0a0a0;
+ font-size: 0.8em;
+ text-transform: uppercase;
+ margin-bottom: 8px;
+ }
+
+ .stat-value {
+ font-size: 1.8em;
+ font-weight: bold;
+ color: #00c853;
+ }
+
+ .stat-value.loss {
+ color: #ff3d00;
+ }
+
+ .update-time {
+ text-align: right;
+ color: #666;
+ font-size: 0.8em;
+ margin-top: 20px;
+ padding-top: 20px;
+ border-top: 1px solid #333;
+ }
+
+ @keyframes fadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
+ }
+
+ .fade-in {
+ animation: fadeIn 0.3s ease-in;
+ }
+
@@ -510,23 +519,23 @@ html_content = """
// Update key metrics - CHF PRIMARY, USD secondary
const usdt = data.balance.USDT || 0;
const usdt_chf = usdt * 0.84;
- document.getElementById('usdt').textContent = `$${usdt.toFixed(2)}`;
+ document.getElementById('usdt').textContent = `$${usdt.toFixed(2)} / CHF ${usdt_chf.toFixed(2)}`;
const portfolio_usd = data.portfolio_value_usd || 0;
const portfolio_chf = data.portfolio_value_chf || (portfolio_usd * 0.84);
- document.getElementById('portfolio').textContent = `$${portfolio_usd.toFixed(2)}`;
+ document.getElementById('portfolio').textContent = `$${portfolio_usd.toFixed(2)} / CHF ${portfolio_chf.toFixed(2)}`;
// Update P&L with color - CHF primary
const dailyPnl = data.daily_pnl || 0;
const dailyPnl_chf = dailyPnl * 0.84;
const dailyPnlEl = document.getElementById('daily-pnl');
- dailyPnlEl.textContent = `$${dailyPnl >= 0 ? '+' : ''}${dailyPnl.toFixed(2)}`;
+ dailyPnlEl.textContent = `$${dailyPnl >= 0 ? '+' : ''}${dailyPnl.toFixed(2)} / CHF ${dailyPnl_chf >= 0 ? '+' : ''}${dailyPnl_chf.toFixed(2)}`;
dailyPnlEl.className = 'card-value ' + (dailyPnl >= 0 ? 'positive' : 'negative');
const totalPnl = data.total_pnl || 0;
const totalPnl_chf = totalPnl * 0.84;
const totalPnlEl = document.getElementById('total-pnl');
- totalPnlEl.textContent = `$${totalPnl >= 0 ? '+' : ''}${totalPnl.toFixed(2)}`;
+ totalPnlEl.textContent = `$${totalPnl >= 0 ? '+' : ''}${totalPnl.toFixed(2)} / CHF ${totalPnl_chf >= 0 ? '+' : ''}${totalPnl_chf.toFixed(2)}`;
totalPnlEl.className = 'card-value ' + (totalPnl >= 0 ? 'positive' : 'negative');
// Update performance