- Restructure tabs to analysis-focused workflow: * Analysis Hub: AI analysis, risk management, manual trade logger * Daily Prep: Market summary, alerts, checklist, news, trading plan * Journal & Review: Trading journal, habit tracker, advanced analytics * Live Charts: Technical analysis with streaming charts - Add ManualTradeLogger component for logging trades from MT5/TradingView/cTrader - Remove execution-focused components (TradeControls, PortfolioTracker) - Update XAU/USD price to realistic ,084.99 - Add indicator preferences and AI plan service - Add comprehensive documentation on decision coverage and implementation
270 lines
9.2 KiB
TypeScript
270 lines
9.2 KiB
TypeScript
import { useState } from 'react';
|
|
import { Plus, TrendingUp, TrendingDown, Save, X } from 'lucide-react';
|
|
|
|
interface ManualTradeLoggerProps {
|
|
onTradeLogged?: (trade: any) => void;
|
|
}
|
|
|
|
export default function ManualTradeLogger({ onTradeLogged }: ManualTradeLoggerProps) {
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const [trade, setTrade] = useState({
|
|
symbol: 'XAU/USD',
|
|
action: 'BUY' as 'BUY' | 'SELL',
|
|
entryPrice: '',
|
|
quantity: '',
|
|
stopLoss: '',
|
|
takeProfit: '',
|
|
entryTime: new Date().toISOString().slice(0, 16),
|
|
platform: 'MT5',
|
|
notes: ''
|
|
});
|
|
|
|
const handleSubmit = () => {
|
|
if (!trade.entryPrice || !trade.quantity) {
|
|
alert('Please enter at least entry price and quantity');
|
|
return;
|
|
}
|
|
|
|
const loggedTrade = {
|
|
...trade,
|
|
id: Date.now(),
|
|
entryPrice: parseFloat(trade.entryPrice),
|
|
quantity: parseFloat(trade.quantity),
|
|
stopLoss: trade.stopLoss ? parseFloat(trade.stopLoss) : null,
|
|
takeProfit: trade.takeProfit ? parseFloat(trade.takeProfit) : null,
|
|
status: 'OPEN',
|
|
loggedAt: new Date().toISOString()
|
|
};
|
|
|
|
// Save to localStorage
|
|
const existingTrades = JSON.parse(localStorage.getItem('logged-trades') || '[]');
|
|
existingTrades.push(loggedTrade);
|
|
localStorage.setItem('logged-trades', JSON.stringify(existingTrades));
|
|
|
|
if (onTradeLogged) {
|
|
onTradeLogged(loggedTrade);
|
|
}
|
|
|
|
// Reset form
|
|
setTrade({
|
|
symbol: 'XAU/USD',
|
|
action: 'BUY',
|
|
entryPrice: '',
|
|
quantity: '',
|
|
stopLoss: '',
|
|
takeProfit: '',
|
|
entryTime: new Date().toISOString().slice(0, 16),
|
|
platform: 'MT5',
|
|
notes: ''
|
|
});
|
|
setIsOpen(false);
|
|
alert('Trade logged successfully!');
|
|
};
|
|
|
|
return (
|
|
<div className="card">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<h3 className="text-lg font-semibold">📝 Log External Trade</h3>
|
|
<button
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
className="btn-primary flex items-center gap-2"
|
|
>
|
|
<Plus className="w-4 h-4" />
|
|
Log Trade
|
|
</button>
|
|
</div>
|
|
|
|
{isOpen && (
|
|
<div className="bg-dark-bg rounded-lg p-6 border-2 border-blue-500">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<h4 className="font-semibold text-lg">Log Trade from External Platform</h4>
|
|
<button onClick={() => setIsOpen(false)} className="text-gray-400 hover:text-white">
|
|
<X className="w-5 h-5" />
|
|
</button>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-2 gap-4">
|
|
{/* Symbol */}
|
|
<div>
|
|
<label className="block text-sm text-gray-400 mb-2">Symbol</label>
|
|
<select
|
|
value={trade.symbol}
|
|
onChange={(e) => setTrade({ ...trade, symbol: e.target.value })}
|
|
className="input w-full"
|
|
>
|
|
<option value="XAU/USD">XAU/USD (Gold)</option>
|
|
<option value="EUR/USD">EUR/USD</option>
|
|
<option value="GBP/USD">GBP/USD</option>
|
|
<option value="BTC/USD">BTC/USD</option>
|
|
<option value="Other">Other</option>
|
|
</select>
|
|
</div>
|
|
|
|
{/* Action */}
|
|
<div>
|
|
<label className="block text-sm text-gray-400 mb-2">Action</label>
|
|
<div className="grid grid-cols-2 gap-2">
|
|
<button
|
|
onClick={() => setTrade({ ...trade, action: 'BUY' })}
|
|
className={`py-2 px-4 rounded font-medium ${
|
|
trade.action === 'BUY'
|
|
? 'bg-green-500 text-white'
|
|
: 'bg-dark-surface text-gray-400'
|
|
}`}
|
|
>
|
|
<TrendingUp className="w-4 h-4 inline mr-1" />
|
|
BUY
|
|
</button>
|
|
<button
|
|
onClick={() => setTrade({ ...trade, action: 'SELL' })}
|
|
className={`py-2 px-4 rounded font-medium ${
|
|
trade.action === 'SELL'
|
|
? 'bg-red-500 text-white'
|
|
: 'bg-dark-surface text-gray-400'
|
|
}`}
|
|
>
|
|
<TrendingDown className="w-4 h-4 inline mr-1" />
|
|
SELL
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Entry Price */}
|
|
<div>
|
|
<label className="block text-sm text-gray-400 mb-2">Entry Price *</label>
|
|
<input
|
|
type="number"
|
|
step="0.01"
|
|
value={trade.entryPrice}
|
|
onChange={(e) => setTrade({ ...trade, entryPrice: e.target.value })}
|
|
className="input w-full"
|
|
placeholder="2030.50"
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
{/* Quantity */}
|
|
<div>
|
|
<label className="block text-sm text-gray-400 mb-2">Quantity (lots/oz) *</label>
|
|
<input
|
|
type="number"
|
|
step="0.01"
|
|
value={trade.quantity}
|
|
onChange={(e) => setTrade({ ...trade, quantity: e.target.value })}
|
|
className="input w-full"
|
|
placeholder="1.0"
|
|
required
|
|
/>
|
|
</div>
|
|
|
|
{/* Stop Loss */}
|
|
<div>
|
|
<label className="block text-sm text-gray-400 mb-2">Stop Loss</label>
|
|
<input
|
|
type="number"
|
|
step="0.01"
|
|
value={trade.stopLoss}
|
|
onChange={(e) => setTrade({ ...trade, stopLoss: e.target.value })}
|
|
className="input w-full"
|
|
placeholder="2020.00"
|
|
/>
|
|
</div>
|
|
|
|
{/* Take Profit */}
|
|
<div>
|
|
<label className="block text-sm text-gray-400 mb-2">Take Profit</label>
|
|
<input
|
|
type="number"
|
|
step="0.01"
|
|
value={trade.takeProfit}
|
|
onChange={(e) => setTrade({ ...trade, takeProfit: e.target.value })}
|
|
className="input w-full"
|
|
placeholder="2050.00"
|
|
/>
|
|
</div>
|
|
|
|
{/* Entry Time */}
|
|
<div>
|
|
<label className="block text-sm text-gray-400 mb-2">Entry Time</label>
|
|
<input
|
|
type="datetime-local"
|
|
value={trade.entryTime}
|
|
onChange={(e) => setTrade({ ...trade, entryTime: e.target.value })}
|
|
className="input w-full"
|
|
/>
|
|
</div>
|
|
|
|
{/* Platform */}
|
|
<div>
|
|
<label className="block text-sm text-gray-400 mb-2">Platform</label>
|
|
<select
|
|
value={trade.platform}
|
|
onChange={(e) => setTrade({ ...trade, platform: e.target.value })}
|
|
className="input w-full"
|
|
>
|
|
<option value="MT4">MetaTrader 4</option>
|
|
<option value="MT5">MetaTrader 5</option>
|
|
<option value="TradingView">TradingView</option>
|
|
<option value="cTrader">cTrader</option>
|
|
<option value="Broker Platform">Broker Platform</option>
|
|
<option value="Other">Other</option>
|
|
</select>
|
|
</div>
|
|
|
|
{/* Notes */}
|
|
<div className="col-span-2">
|
|
<label className="block text-sm text-gray-400 mb-2">Trade Notes</label>
|
|
<textarea
|
|
value={trade.notes}
|
|
onChange={(e) => setTrade({ ...trade, notes: e.target.value })}
|
|
className="input w-full"
|
|
rows={3}
|
|
placeholder="Why did you enter this trade? What's your plan?"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex gap-3 mt-6">
|
|
<button
|
|
onClick={handleSubmit}
|
|
className="btn-primary flex items-center gap-2 flex-1"
|
|
>
|
|
<Save className="w-4 h-4" />
|
|
Log Trade
|
|
</button>
|
|
<button
|
|
onClick={() => setIsOpen(false)}
|
|
className="btn bg-dark-surface text-gray-300 hover:bg-dark-hover"
|
|
>
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Quick Stats */}
|
|
<div className="mt-4 grid grid-cols-3 gap-3">
|
|
<div className="bg-dark-bg rounded p-3">
|
|
<div className="text-xs text-gray-400">Today's Trades</div>
|
|
<div className="text-xl font-bold">0</div>
|
|
</div>
|
|
<div className="bg-dark-bg rounded p-3">
|
|
<div className="text-xs text-gray-400">Open Positions</div>
|
|
<div className="text-xl font-bold text-blue-500">0</div>
|
|
</div>
|
|
<div className="bg-dark-bg rounded p-3">
|
|
<div className="text-xs text-gray-400">Win Rate</div>
|
|
<div className="text-xl font-bold text-green-500">--</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-4 p-3 bg-blue-500/10 border border-blue-500/30 rounded">
|
|
<p className="text-sm text-blue-300">
|
|
💡 <strong>Tip:</strong> Log your trades from MT5/TradingView/Broker platform here for
|
|
continuous analysis and journaling.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|