feat: Add 'Mark as Traded' functionality for manual trade tracking
- Add markAsTraded() function to create virtual positions for follow-up analysis - Enable follow-up assistant for manually executed trades on external platforms - Add blue 'Mark Traded' buttons next to existing green 'Trade' buttons - Prompt for trade amount and confirm entry price before creating position - Automatically store analysis data (entry, SL, TP) with virtual position - Optional direct access to Trade Follow-up Assistant after marking - Solves issue where manual Drift trades couldn't use follow-up analysis - Maintains existing automated trade execution functionality
This commit is contained in:
@@ -504,6 +504,72 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP
|
||||
setTradeModalOpen(true)
|
||||
}
|
||||
|
||||
// Manual trade marking for follow-up (when trading manually on external platforms)
|
||||
const markAsTraded = async (analysisData: any) => {
|
||||
try {
|
||||
console.log('📋 Marking analysis as manually traded for follow-up:', analysisData)
|
||||
|
||||
// Extract trade data from analysis
|
||||
const analysis = analysisData.result?.analysis || analysisData.analysis
|
||||
if (!analysis) {
|
||||
alert('❌ No analysis data found to mark as traded')
|
||||
return
|
||||
}
|
||||
|
||||
// Create virtual position for follow-up tracking
|
||||
const entryPrice = analysis.entry?.price || 0
|
||||
const stopLoss = analysis.stopLoss?.price || null
|
||||
const takeProfit = analysis.takeProfits?.tp1?.price || null
|
||||
const side = analysis.recommendation === 'BUY' ? 'LONG' : analysis.recommendation === 'SELL' ? 'SHORT' : 'LONG'
|
||||
|
||||
if (!entryPrice) {
|
||||
alert('❌ No entry price found in analysis')
|
||||
return
|
||||
}
|
||||
|
||||
// Prompt for trade details
|
||||
const amount = prompt('Enter trade amount (size):')
|
||||
if (!amount || parseFloat(amount) <= 0) return
|
||||
|
||||
const actualEntryPrice = prompt(`Confirm entry price (from analysis: $${entryPrice}):`, entryPrice.toString())
|
||||
if (!actualEntryPrice) return
|
||||
|
||||
const response = await fetch('/api/trading/positions', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
action: 'add',
|
||||
symbol: symbol,
|
||||
side: side,
|
||||
amount: parseFloat(amount),
|
||||
entryPrice: parseFloat(actualEntryPrice),
|
||||
leverage: 1,
|
||||
stopLoss: stopLoss,
|
||||
takeProfit: takeProfit,
|
||||
txId: `manual_${Date.now()}`,
|
||||
notes: `Manual trade marked from AI analysis - ${analysis.summary?.substring(0, 100) || 'AI trading setup'}`
|
||||
})
|
||||
})
|
||||
|
||||
const result = await response.json()
|
||||
|
||||
if (result.success) {
|
||||
alert(`✅ Position marked as traded!\n\n• ${side} ${amount} ${symbol}\n• Entry: $${actualEntryPrice}\n• Follow-up assistant now available`)
|
||||
|
||||
// Optional: Show follow-up panel
|
||||
if (confirm('Open Trade Follow-up Assistant now?')) {
|
||||
setFollowUpPanelOpen(true)
|
||||
}
|
||||
} else {
|
||||
throw new Error(result.error || 'Failed to mark trade')
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error marking trade:', error)
|
||||
alert(`❌ Failed to mark trade: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
||||
}
|
||||
}
|
||||
|
||||
// Trade execution API call
|
||||
const executeTrade = async (tradeData: any) => {
|
||||
try {
|
||||
@@ -1022,12 +1088,21 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP
|
||||
</h5>
|
||||
<div className="flex items-center space-x-2">
|
||||
{timeframeResult.success && timeframeResult.result.analysis && (
|
||||
<button
|
||||
onClick={() => handleTradeClick(timeframeResult)}
|
||||
className="px-3 py-1 bg-gradient-to-r from-green-500 to-green-600 text-white text-xs font-medium rounded hover:from-green-600 hover:to-green-700 transition-all transform hover:scale-105"
|
||||
>
|
||||
💰 Trade
|
||||
</button>
|
||||
<>
|
||||
<button
|
||||
onClick={() => handleTradeClick(timeframeResult)}
|
||||
className="px-3 py-1 bg-gradient-to-r from-green-500 to-green-600 text-white text-xs font-medium rounded hover:from-green-600 hover:to-green-700 transition-all transform hover:scale-105"
|
||||
>
|
||||
💰 Trade
|
||||
</button>
|
||||
<button
|
||||
onClick={() => markAsTraded(timeframeResult)}
|
||||
className="px-3 py-1 bg-gradient-to-r from-blue-500 to-blue-600 text-white text-xs font-medium rounded hover:from-blue-600 hover:to-blue-700 transition-all transform hover:scale-105"
|
||||
title="Mark as manually traded for follow-up analysis"
|
||||
>
|
||||
📋 Mark Traded
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
<span className="text-xs text-gray-400">
|
||||
{timeframeResult.success ? 'Analysis Complete' : 'Failed'}
|
||||
@@ -1125,12 +1200,21 @@ export default function AIAnalysisPanel({ onAnalysisComplete }: AIAnalysisPanelP
|
||||
</h3>
|
||||
<div className="flex items-center space-x-3">
|
||||
{result.analysis && (
|
||||
<button
|
||||
onClick={() => handleTradeClick({ result, timeframeLabel: selectedTimeframes.map(tf => timeframes.find(t => t.value === tf)?.label).join(', ') })}
|
||||
className="px-4 py-2 bg-gradient-to-r from-green-500 to-green-600 text-white text-sm font-medium rounded-lg hover:from-green-600 hover:to-green-700 transition-all transform hover:scale-105"
|
||||
>
|
||||
💰 Execute Trade
|
||||
</button>
|
||||
<>
|
||||
<button
|
||||
onClick={() => handleTradeClick({ result, timeframeLabel: selectedTimeframes.map(tf => timeframes.find(t => t.value === tf)?.label).join(', ') })}
|
||||
className="px-4 py-2 bg-gradient-to-r from-green-500 to-green-600 text-white text-sm font-medium rounded-lg hover:from-green-600 hover:to-green-700 transition-all transform hover:scale-105"
|
||||
>
|
||||
💰 Execute Trade
|
||||
</button>
|
||||
<button
|
||||
onClick={() => markAsTraded({ result, timeframeLabel: selectedTimeframes.map(tf => timeframes.find(t => t.value === tf)?.label).join(', ') })}
|
||||
className="px-4 py-2 bg-gradient-to-r from-blue-500 to-blue-600 text-white text-sm font-medium rounded-lg hover:from-blue-600 hover:to-blue-700 transition-all transform hover:scale-105"
|
||||
title="Mark as manually traded for follow-up analysis"
|
||||
>
|
||||
📋 Mark as Traded
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
{result.screenshots && (
|
||||
<div className="text-xs text-gray-400">
|
||||
|
||||
Reference in New Issue
Block a user