diff --git a/components/mission-control/TradingPanel.tsx b/components/mission-control/TradingPanel.tsx index 46911a0..0c4ad5b 100644 --- a/components/mission-control/TradingPanel.tsx +++ b/components/mission-control/TradingPanel.tsx @@ -34,6 +34,7 @@ interface Trade { closedAt?: string notes: string isDemo: boolean + traderStyle?: string // NEW: tracks which trader style was used } const defaultTraders: Trader[] = [ @@ -61,11 +62,183 @@ const defaultTraders: Trader[] = [ } ] +// Execute Trade Modal Component +function ExecuteTradeModal({ + traders, + selectedTrader, + onClose, + onTradeExecuted +}: { + traders: Trader[] + selectedTrader: string + onClose: () => void + onTradeExecuted: (trade: Trade) => void +}) { + const [form, setForm] = useState({ + pair: 'BTC/USD', + direction: 'long' as 'long' | 'short', + isDemo: true, + entryPrice: '', + timeframe: '4H', + setup: '' + }) + + const submitTrade = () => { + const trader = traders.find(t => t.id === selectedTrader) + const trade: Trade = { + id: Date.now().toString(), + trader: trader?.name || 'Unknown', + pair: form.pair, + direction: form.direction, + entryPrice: parseFloat(form.entryPrice) || 0, + status: 'open', + isDemo: form.isDemo, + openedAt: new Date().toISOString(), + setup: form.setup || `${trader?.name} setup`, + timeframe: form.timeframe, + reason: '', + notes: '', + traderStyle: selectedTrader + } + + // Save to API + fetch('/api/trading/trades', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(trade) + }).then(() => { + onTradeExecuted(trade) + }) + } + + const trader = traders.find(t => t.id === selectedTrader) + + return ( +
+
+

Execute Trade

+ +
+ +
+ {/* Trader Style Badge */} +
+

Trading Style

+

{trader?.name}

+
+ + {/* Pair */} +
+ + +
+ + {/* Direction */} +
+ + +
+ + {/* Entry Price */} +
+ + setForm({...form, entryPrice: e.target.value})} + placeholder="0.00" + className="w-full bg-white/10 border border-white/20 rounded-lg px-3 py-2 text-white" + /> +
+ + {/* Timeframe */} +
+ + +
+ + {/* Demo/Real */} +
+ + +
+ + {/* Setup Note */} +
+ + setForm({...form, setup: e.target.value})} + placeholder="What setup is this?" + className="w-full bg-white/10 border border-white/20 rounded-lg px-3 py-2 text-white" + /> +
+ + +
+
+ ) +} + export function TradingPanel() { const [activeTab, setActiveTab] = useState('research') const [traders, setTraders] = useState(defaultTraders) const [selectedTrader, setSelectedTrader] = useState('dopetrades') const [showFullAnalysis, setShowFullAnalysis] = useState(null) + const [showExecuteTrade, setShowExecuteTrade] = useState(false) const [trades, setTrades] = useState([]) const [journalFilter, setJournalFilter] = useState<'all' | 'demo' | 'real'>('all') @@ -254,7 +427,9 @@ export function TradingPanel() { - @@ -272,7 +447,38 @@ export function TradingPanel() {

📔 Trading Journal

- {/* Stats */} + {/* Per-Trader Stats */} +
+

📊 Performance by Trader Style

+
+ {traders.filter(t => t.status !== 'paused').map(trader => { + const traderTrades = trades.filter(t => t.traderStyle === trader.id) + const closedTrades = traderTrades.filter(t => t.status === 'closed' && !t.isDemo) + const wins = closedTrades.filter(t => (t.pnl || 0) > 0).length + const totalPnl = closedTrades.reduce((sum, t) => sum + (t.pnl || 0), 0) + const winRate = closedTrades.length > 0 ? Math.round((wins / closedTrades.length) * 100) : 0 + + return ( +
+
+
+ {trader.name} + ({traderTrades.length} trades) +
+
+ = 0 ? 'text-green-400' : 'text-red-400'}`}> + ${totalPnl.toFixed(2)} + + | {winRate}% WR +
+
+
+ ) + })} +
+
+ + {/* Overall Stats */}

${totalPnl.toFixed(2)}

@@ -472,6 +678,21 @@ export function TradingPanel() {
)} + + {/* Execute Trade Modal */} + {showExecuteTrade && ( +
+ setShowExecuteTrade(false)} + onTradeExecuted={(trade) => { + setTrades([trade, ...trades]) + setShowExecuteTrade(false) + }} + /> +
+ )}
) }