From 931a3cde1df74a0bf4ba306cd3be8503cc93839a Mon Sep 17 00:00:00 2001 From: root Date: Thu, 7 May 2026 05:20:49 +0000 Subject: [PATCH] refactor(ui): tokenize trade profile metrics --- web/src/components/TradeProfileManager.tsx | 44 +++++++++++----------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/web/src/components/TradeProfileManager.tsx b/web/src/components/TradeProfileManager.tsx index 7701949..05dead2 100644 --- a/web/src/components/TradeProfileManager.tsx +++ b/web/src/components/TradeProfileManager.tsx @@ -80,13 +80,13 @@ export interface ProfileTradeStats { // --- CONSTANTS --- const AVAILABLE_RULES = [ - { id: 'TrendBiasRule', name: 'Trend Bias', desc: 'EMA50/200 direction check on 4H timeframe', icon: TrendingUp, color: '#3b82f6', defaultParams: { fastPeriod: 50, slowPeriod: 200 } }, - { id: 'MomentumRule', name: 'Momentum', desc: 'RSI overbought/oversold confirmation', icon: Activity, color: '#06b6d4', defaultParams: { rsiPeriod: 14, overbought: 70, oversold: 30 } }, - { id: 'ZoneRule', name: 'Zone Proximity', desc: 'Price relative to EMA value zones', icon: Target, color: '#a855f7', defaultParams: { zonePercent: 1.5 } }, - { id: 'SessionRule', name: 'Session Filter', desc: 'Trade only during major sessions', icon: Clock, color: '#f59e0b', defaultParams: { sessions: 'LDN,NY' } }, - { id: 'EntryTriggerRule', name: 'Entry Trigger', desc: 'Pattern-based precise entry logic', icon: Play, color: '#10b981', defaultParams: { showPatterns: true } }, - { id: 'RiskManagementRule', name: 'Risk Guard', desc: 'ATR-based stop loss & position sizing', icon: Shield, color: '#ef4444', defaultParams: { maxRisk: 2.0 } }, - { id: 'AIAnalysisRule', name: 'AI Sentiment', desc: 'LLM-powered market analysis', icon: Cpu, color: '#8b5cf6', defaultParams: { minConfidence: 70 } } + { id: 'TrendBiasRule', name: 'Trend Bias', desc: 'EMA50/200 direction check on 4H timeframe', icon: TrendingUp, color: 'var(--bl-info-strong)', defaultParams: { fastPeriod: 50, slowPeriod: 200 } }, + { id: 'MomentumRule', name: 'Momentum', desc: 'RSI overbought/oversold confirmation', icon: Activity, color: 'var(--bl-attention)', defaultParams: { rsiPeriod: 14, overbought: 70, oversold: 30 } }, + { id: 'ZoneRule', name: 'Zone Proximity', desc: 'Price relative to EMA value zones', icon: Target, color: 'var(--bl-emphasis)', defaultParams: { zonePercent: 1.5 } }, + { id: 'SessionRule', name: 'Session Filter', desc: 'Trade only during major sessions', icon: Clock, color: 'var(--bl-warning)', defaultParams: { sessions: 'LDN,NY' } }, + { id: 'EntryTriggerRule', name: 'Entry Trigger', desc: 'Pattern-based precise entry logic', icon: Play, color: 'var(--bl-success)', defaultParams: { showPatterns: true } }, + { id: 'RiskManagementRule', name: 'Risk Guard', desc: 'ATR-based stop loss & position sizing', icon: Shield, color: 'var(--bl-danger)', defaultParams: { maxRisk: 2.0 } }, + { id: 'AIAnalysisRule', name: 'AI Sentiment', desc: 'LLM-powered market analysis', icon: Cpu, color: 'var(--bl-emphasis)', defaultParams: { minConfidence: 70 } } ]; const SESSION_PRESET_OPTIONS = [ @@ -137,6 +137,8 @@ const panelClass = 'rounded-xl border border-[var(--border)] bg-[var(--card-elev const subtlePanelClass = 'rounded-xl border border-[var(--border)] bg-[var(--muted)]/35'; const iconButtonClass = 'h-8 w-8 rounded-xl'; const accentTextClass = 'text-[var(--accent)]'; +const statSuccessClass = 'text-emerald-600 dark:text-emerald-400'; +const statDangerClass = 'text-red-600 dark:text-red-400'; export const normalizeSessionPresetValue = (raw: unknown): string => { if (raw === undefined || raw === null) return 'LDN,NY'; @@ -580,10 +582,10 @@ export const TradeProfileManager = ({ botState = DEFAULT_BOT_STATE }: TradeProfi {/* Aggregate stats */}
- - - = 0 ? '+' : ''}$${totalPnl.toFixed(2)}`} color={totalPnl >= 0 ? '#00ff88' : '#ef4444'} /> - + + + = 0 ? '+' : ''}$${totalPnl.toFixed(2)}`} color={totalPnl >= 0 ? 'var(--bl-success)' : 'var(--bl-danger)'} /> +
@@ -724,15 +726,15 @@ export const TradeProfileManager = ({ botState = DEFAULT_BOT_STATE }: TradeProfi {/* Stats header row */}
{[ - { icon: DollarSign, label: 'Capital', val: `$${p.allocated_capital.toLocaleString()}`, color: '#3b82f6', valClass: 'text-[var(--foreground)]' }, - { icon: BarChart3, label: 'Realized', val: `${stats.totalPnl >= 0 ? '+' : ''}${stats.totalPnl.toFixed(2)}`, color: stats.totalPnl >= 0 ? '#16a34a' : '#dc2626', valClass: stats.totalPnl >= 0 ? 'text-emerald-600 dark:text-emerald-400' : 'text-red-600 dark:text-red-400' }, - { icon: AlertTriangle, label: 'Risk', val: `${p.risk_per_trade_percent}%`, color: '#f59e0b', valClass: 'text-[var(--foreground)]' }, + { icon: DollarSign, label: 'Capital', val: `$${p.allocated_capital.toLocaleString()}`, color: 'var(--bl-info-strong)', valClass: 'text-[var(--foreground)]' }, + { icon: BarChart3, label: 'Realized', val: `${stats.totalPnl >= 0 ? '+' : ''}${stats.totalPnl.toFixed(2)}`, color: stats.totalPnl >= 0 ? 'var(--bl-success)' : 'var(--bl-danger)', valClass: stats.totalPnl >= 0 ? statSuccessClass : statDangerClass }, + { icon: AlertTriangle, label: 'Risk', val: `${p.risk_per_trade_percent}%`, color: 'var(--bl-warning)', valClass: 'text-[var(--foreground)]' }, ].map((item, i) => (
@@ -768,10 +770,10 @@ export const TradeProfileManager = ({ botState = DEFAULT_BOT_STATE }: TradeProfi style={{ width: `${Math.max(stats.winRate, 2)}%`, background: stats.winRate >= 50 - ? '#16a34a' + ? 'var(--bl-success)' : stats.winRate >= 30 - ? '#f59e0b' - : '#dc2626', + ? 'var(--bl-warning)' + : 'var(--bl-danger)', }} />
@@ -1026,11 +1028,11 @@ export const TradeProfileManager = ({ botState = DEFAULT_BOT_STATE }: TradeProfi
- +