- 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!
326 lines
12 KiB
TypeScript
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;
|