🔥 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!
This commit is contained in:
325
components/TradeConfirmationModal.tsx
Normal file
325
components/TradeConfirmationModal.tsx
Normal file
@@ -0,0 +1,325 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user