Files
trading_bot_v3/components/TradeConfirmationModal.tsx
mindesbunister ab6c4fd861 🔥 OBLITERATE ALL MOCK DATA - System now uses 100% real data sources
- DESTROYED: AI analysis fake 5-second responses → Real TradingView screenshots (30-180s)
- DESTROYED: Mock trading execution → Real Drift Protocol only
- DESTROYED: Fake price data (44.11) → Live CoinGecko API (78.60)
- DESTROYED: Mock balance/portfolio → Real Drift account data
- DESTROYED: Fake screenshot capture → Real enhanced-screenshot service
 Live trading only
- DESTROYED: Hardcoded market data → Real CoinGecko validation
- DESTROYED: Mock chart generation → Real TradingView automation

CRITICAL FIXES:
 AI analysis now takes proper time and analyzes real charts
 Bearish SOL (-0.74%) will now recommend SHORT positions correctly
 All trades execute on real Drift account
 Real-time price feeds from CoinGecko
 Actual technical analysis from live chart patterns
 Database reset with fresh AI learning (18k+ entries cleared)
 Trade confirmation system with ChatGPT integration

NO MORE FAKE DATA - TRADING SYSTEM IS NOW REAL!
2025-07-30 19:10:25 +02:00

326 lines
12 KiB
TypeScript

import React, { useState } from 'react';
const TradeConfirmationModal = ({
isOpen,
onClose,
analysis,
symbol,
timeframe,
onConfirm,
onAbort
}) => {
const [chatInput, setChatInput] = useState('');
const [chatHistory, setChatHistory] = useState([]);
const [loading, setLoading] = useState(false);
const [recommendation, setRecommendation] = useState(null);
const [abortReason, setAbortReason] = useState('');
const [showAbortInput, setShowAbortInput] = useState(false);
// Get AI recommendation when modal opens
React.useEffect(() => {
if (isOpen && analysis && !recommendation) {
getAIRecommendation();
}
}, [isOpen, analysis]);
const getAIRecommendation = async () => {
setLoading(true);
try {
const response = await fetch('/api/trade-confirmation', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'analyze',
analysis,
symbol,
timeframe
})
});
const data = await response.json();
if (data.success) {
setRecommendation(data.recommendation);
}
} catch (error) {
console.error('Error getting AI recommendation:', error);
}
setLoading(false);
};
const handleChat = async () => {
if (!chatInput.trim()) return;
const userMessage = chatInput;
setChatHistory(prev => [...prev, { role: 'user', content: userMessage }]);
setChatInput('');
setLoading(true);
try {
const response = await fetch('/api/trade-confirmation', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'chat',
userInput: userMessage
})
});
const data = await response.json();
if (data.success) {
setChatHistory(prev => [...prev, { role: 'assistant', content: data.response }]);
}
} catch (error) {
console.error('Error in chat:', error);
}
setLoading(false);
};
const handleConfirm = async () => {
try {
const response = await fetch('/api/trade-confirmation', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'confirm',
analysis,
symbol,
timeframe
})
});
const data = await response.json();
if (data.success) {
onConfirm(data);
onClose();
}
} catch (error) {
console.error('Error confirming trade:', error);
}
};
const handleAbort = async () => {
if (!abortReason.trim()) {
alert('Please provide a reason for aborting the trade');
return;
}
try {
const response = await fetch('/api/trade-confirmation', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'abort',
userInput: abortReason,
analysis,
symbol,
timeframe
})
});
const data = await response.json();
if (data.success) {
onAbort(data, abortReason);
onClose();
}
} catch (error) {
console.error('Error aborting trade:', error);
}
};
if (!isOpen) return null;
return (
<div className="fixed inset-0 bg-black/80 backdrop-blur-sm z-50 flex items-center justify-center p-4">
<div className="bg-gray-900 rounded-2xl border border-purple-500/30 shadow-2xl w-full max-w-6xl max-h-[90vh] overflow-y-auto">
{/* Header */}
<div className="bg-gradient-to-r from-purple-900/50 to-blue-900/50 p-6 border-b border-purple-500/30">
<div className="flex justify-between items-center">
<h2 className="text-2xl font-bold text-white">
🎯 Trade Confirmation Required
</h2>
<button
onClick={onClose}
className="text-gray-400 hover:text-white transition-colors text-2xl"
>
</button>
</div>
<p className="text-purple-300 mt-2">
{symbol} {timeframe}m timeframe Review analysis and confirm execution
</p>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 p-6">
{/* Left Column - Analysis & Recommendation */}
<div className="space-y-6">
{/* Current Analysis */}
<div className="bg-black/30 rounded-xl p-6 border border-purple-500/20">
<h3 className="text-xl font-bold text-purple-300 mb-4">📊 Current Analysis</h3>
{analysis && (
<div className="space-y-4 text-sm">
<div className="grid grid-cols-2 gap-4">
<div className="bg-gray-800/50 p-3 rounded-lg">
<div className="text-gray-300">Trend</div>
<div className="text-white font-medium">
{analysis.trend} ({Math.round((analysis.strength || 0) * 100)}%)
</div>
</div>
<div className="bg-gray-800/50 p-3 rounded-lg">
<div className="text-gray-300">Confidence</div>
<div className="text-white font-medium">{analysis.confidence}%</div>
</div>
</div>
<div className="bg-gray-800/50 p-3 rounded-lg">
<div className="text-gray-300 mb-2">Support/Resistance</div>
<div className="text-green-300">Support: {analysis.support?.join(', ')}</div>
<div className="text-red-300">Resistance: {analysis.resistance?.join(', ')}</div>
</div>
<div className="bg-gray-800/50 p-3 rounded-lg">
<div className="text-gray-300 mb-2">Technical Indicators</div>
<div className="text-cyan-300 text-xs space-y-1">
{analysis.indicators?.rsi && <div>RSI: {analysis.indicators.rsi}</div>}
{analysis.indicators?.macd && <div>MACD: {analysis.indicators.macd}</div>}
{analysis.indicators?.volume && <div>Volume: {analysis.indicators.volume}</div>}
</div>
</div>
</div>
)}
</div>
{/* AI Recommendation */}
<div className="bg-black/30 rounded-xl p-6 border border-green-500/20">
<h3 className="text-xl font-bold text-green-300 mb-4">🤖 AI Recommendation</h3>
{loading && !recommendation ? (
<div className="text-center py-8">
<div className="animate-spin text-4xl mb-4">🔄</div>
<div className="text-gray-300">Analyzing market conditions...</div>
</div>
) : recommendation ? (
<div className="bg-gray-800/50 p-4 rounded-lg">
<pre className="text-gray-200 whitespace-pre-wrap text-sm leading-relaxed">
{recommendation}
</pre>
</div>
) : (
<div className="text-gray-400">No recommendation available</div>
)}
</div>
</div>
{/* Right Column - Chat & Actions */}
<div className="space-y-6">
{/* Chat with AI */}
<div className="bg-black/30 rounded-xl border border-blue-500/20">
<div className="p-4 border-b border-blue-500/20">
<h3 className="text-xl font-bold text-blue-300">💬 Ask AI Assistant</h3>
</div>
{/* Chat History */}
<div className="h-64 overflow-y-auto p-4 space-y-3">
{chatHistory.length === 0 ? (
<div className="text-gray-400 text-center py-8">
Ask questions about this trade analysis...
</div>
) : (
chatHistory.map((message, index) => (
<div
key={index}
className={`p-3 rounded-lg ${
message.role === 'user'
? 'bg-purple-900/30 ml-4 text-purple-100'
: 'bg-blue-900/30 mr-4 text-blue-100'
}`}
>
<div className="text-xs opacity-70 mb-1">
{message.role === 'user' ? 'You' : 'AI Assistant'}
</div>
<div className="text-sm">{message.content}</div>
</div>
))
)}
</div>
{/* Chat Input */}
<div className="p-4 border-t border-blue-500/20">
<div className="flex gap-2">
<input
type="text"
value={chatInput}
onChange={(e) => setChatInput(e.target.value)}
placeholder="Ask about the analysis..."
className="flex-1 bg-gray-800 border border-gray-600 rounded-lg px-3 py-2 text-white text-sm"
onKeyPress={(e) => e.key === 'Enter' && handleChat()}
/>
<button
onClick={handleChat}
disabled={loading || !chatInput.trim()}
className="bg-blue-600 hover:bg-blue-700 disabled:bg-gray-600 text-white px-4 py-2 rounded-lg text-sm transition-colors"
>
Send
</button>
</div>
</div>
</div>
{/* Decision Actions */}
<div className="bg-black/30 rounded-xl p-6 border border-yellow-500/20">
<h3 className="text-xl font-bold text-yellow-300 mb-6"> Execute Decision</h3>
{!showAbortInput ? (
<div className="space-y-4">
<button
onClick={handleConfirm}
className="w-full bg-green-600 hover:bg-green-700 text-white font-bold py-4 px-6 rounded-xl transition-colors text-lg"
>
EXECUTE TRADE
</button>
<button
onClick={() => setShowAbortInput(true)}
className="w-full bg-red-600 hover:bg-red-700 text-white font-bold py-4 px-6 rounded-xl transition-colors text-lg"
>
ABORT TRADE
</button>
</div>
) : (
<div className="space-y-4">
<textarea
value={abortReason}
onChange={(e) => setAbortReason(e.target.value)}
placeholder="Why are you aborting this trade? (This helps the AI learn)"
className="w-full bg-gray-800 border border-gray-600 rounded-lg px-4 py-3 text-white text-sm h-24"
/>
<div className="flex gap-3">
<button
onClick={handleAbort}
disabled={!abortReason.trim()}
className="flex-1 bg-red-600 hover:bg-red-700 disabled:bg-gray-600 text-white font-bold py-3 px-4 rounded-lg transition-colors"
>
Confirm Abort
</button>
<button
onClick={() => setShowAbortInput(false)}
className="flex-1 bg-gray-600 hover:bg-gray-700 text-white font-bold py-3 px-4 rounded-lg transition-colors"
>
Cancel
</button>
</div>
</div>
)}
</div>
</div>
</div>
</div>
</div>
);
};
export default TradeConfirmationModal;