- Interactive chat interface to ask questions about active trades - Automatic position detection and context-aware responses - Fresh screenshot capture with updated market analysis - Smart conversation flow with trade-specific insights - Quick action buttons for common trade management questions - TradeFollowUpPanel.tsx: Full-featured chat interface with position tracking - /api/trade-followup: GPT-4o mini integration with screenshot analysis - Enhanced AIAnalysisPanel with Follow-up button integration - 'Should I exit now?' - Real-time exit recommendations - 'Update my stop loss' - SL adjustment guidance based on current conditions - 'Move to break even' - Risk-free position management - 'Current market analysis' - Fresh chart analysis with updated screenshots - 'Risk assessment' - Position risk evaluation - 'Take profit strategy' - TP optimization recommendations - Enter trade based on AI analysis → Use Follow-up for ongoing management - Ask specific questions: 'Is this still a valid setup?' - Get updated analysis: 'What do the charts look like now?' - Risk management: 'Should I move my stop loss?' - Exit timing: 'Is this a good time to take profits?' The assistant provides context-aware guidance by: Tracking your current position details (entry, size, P&L) Capturing fresh screenshots when needed for updated analysis Combining position context with current market conditions Providing specific price levels and actionable advice Maintaining conversation history for continuity Perfect for traders who want ongoing AI guidance throughout their trades!
181 lines
5.5 KiB
JavaScript
181 lines
5.5 KiB
JavaScript
import { NextResponse } from 'next/server'
|
|
import OpenAI from 'openai'
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
|
|
const openai = new OpenAI({
|
|
apiKey: process.env.OPENAI_API_KEY
|
|
})
|
|
|
|
// Helper function to convert image file to base64
|
|
function imageToBase64(imagePath) {
|
|
try {
|
|
const fullPath = path.join(process.cwd(), 'screenshots', imagePath)
|
|
if (fs.existsSync(fullPath)) {
|
|
const imageBuffer = fs.readFileSync(fullPath)
|
|
return imageBuffer.toString('base64')
|
|
}
|
|
return null
|
|
} catch (error) {
|
|
console.error('Error converting image to base64:', error)
|
|
return null
|
|
}
|
|
}
|
|
|
|
export async function POST(request) {
|
|
try {
|
|
const { message, position, screenshots, chatHistory } = await request.json()
|
|
|
|
if (!message || !position) {
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: 'Message and position are required'
|
|
}, { status: 400 })
|
|
}
|
|
|
|
// Build context about the current position
|
|
const positionContext = `
|
|
CURRENT POSITION DETAILS:
|
|
- Symbol: ${position.symbol}
|
|
- Side: ${position.side}
|
|
- Entry Price: $${position.entryPrice}
|
|
- Current Price: $${position.currentPrice || 'Unknown'}
|
|
- Position Size: ${position.size}
|
|
- Current P&L: ${position.pnl > 0 ? '+' : ''}$${position.pnl?.toFixed(2) || 'Unknown'}
|
|
- Stop Loss: ${position.stopLoss ? `$${position.stopLoss}` : 'Not set'}
|
|
- Take Profit: ${position.takeProfit ? `$${position.takeProfit}` : 'Not set'}
|
|
- Entry Time: ${position.entryTime}
|
|
- Entry Analysis: ${position.entryAnalysis || 'Not available'}
|
|
`
|
|
|
|
// Build chat history context
|
|
const chatContext = chatHistory?.length > 0
|
|
? `\n\nRECENT CONVERSATION:\n${chatHistory.map((msg) =>
|
|
`${msg.type === 'user' ? 'TRADER' : 'ASSISTANT'}: ${msg.content}`
|
|
).join('\n')}`
|
|
: ''
|
|
|
|
// Analyze screenshots if provided
|
|
let screenshotAnalysis = ''
|
|
if (screenshots && screenshots.length > 0) {
|
|
console.log('📸 Processing screenshots for analysis:', screenshots.length)
|
|
|
|
const screenshotMessages = []
|
|
|
|
for (const screenshot of screenshots) {
|
|
// Extract filename from screenshot path/URL
|
|
const filename = screenshot.split('/').pop() || screenshot
|
|
console.log('🔍 Processing screenshot:', filename)
|
|
|
|
// Convert to base64
|
|
const base64Image = imageToBase64(filename)
|
|
if (base64Image) {
|
|
screenshotMessages.push({
|
|
type: "image_url",
|
|
image_url: {
|
|
url: `data:image/png;base64,${base64Image}`,
|
|
detail: "high"
|
|
}
|
|
})
|
|
} else {
|
|
console.warn('⚠️ Failed to convert screenshot to base64:', filename)
|
|
}
|
|
}
|
|
|
|
if (screenshotMessages.length > 0) {
|
|
console.log('🤖 Sending screenshots to OpenAI for analysis...')
|
|
const analysisResponse = await openai.chat.completions.create({
|
|
model: "gpt-4o-mini",
|
|
messages: [
|
|
{
|
|
role: "system",
|
|
content: `You are an expert trading analyst providing real-time trade management advice.
|
|
|
|
CURRENT POSITION: ${positionContext}
|
|
|
|
Analyze the provided chart screenshots and provide specific guidance on:
|
|
1. Current market structure and price action
|
|
2. Whether to hold, exit, or adjust the position
|
|
3. Stop loss and take profit recommendations
|
|
4. Risk assessment based on current conditions
|
|
5. Key levels to watch
|
|
|
|
Be specific with price levels and actionable advice. Focus on PRACTICAL trade management.`
|
|
},
|
|
{
|
|
role: "user",
|
|
content: [
|
|
{
|
|
type: "text",
|
|
text: `Analyze these current chart screenshots for my ${position.side} position in ${position.symbol}. What should I do now?`
|
|
},
|
|
...screenshotMessages
|
|
]
|
|
}
|
|
],
|
|
max_tokens: 1000,
|
|
temperature: 0.1
|
|
})
|
|
|
|
screenshotAnalysis = analysisResponse.choices[0]?.message?.content || ''
|
|
console.log('✅ Screenshot analysis completed')
|
|
}
|
|
}
|
|
|
|
// Generate conversational response
|
|
const systemPrompt = `You are an expert trading coach helping a trader manage their active position. You have access to:
|
|
|
|
${positionContext}
|
|
${chatContext}
|
|
|
|
${screenshotAnalysis ? `\nLATEST CHART ANALYSIS:\n${screenshotAnalysis}` : ''}
|
|
|
|
GUIDELINES:
|
|
- Be conversational and supportive
|
|
- Give specific, actionable advice
|
|
- Use exact price levels when possible
|
|
- Consider risk management principles
|
|
- Be honest about market uncertainty
|
|
- Use emojis appropriately
|
|
- Format important information clearly
|
|
|
|
The trader is asking: "${message}"
|
|
|
|
Provide helpful, specific guidance for their current position.`
|
|
|
|
const response = await openai.chat.completions.create({
|
|
model: "gpt-4o-mini",
|
|
messages: [
|
|
{
|
|
role: "system",
|
|
content: systemPrompt
|
|
},
|
|
{
|
|
role: "user",
|
|
content: message
|
|
}
|
|
],
|
|
max_tokens: 800,
|
|
temperature: 0.3
|
|
})
|
|
|
|
const assistantResponse = response.choices[0]?.message?.content
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
response: assistantResponse,
|
|
analysis: screenshotAnalysis ? {
|
|
timestamp: new Date().toISOString(),
|
|
content: screenshotAnalysis
|
|
} : null
|
|
})
|
|
|
|
} catch (error) {
|
|
console.error('Trade follow-up error:', error)
|
|
return NextResponse.json({
|
|
success: false,
|
|
error: 'Failed to process trade follow-up request'
|
|
}, { status: 500 })
|
|
}
|
|
}
|