Files
trading_bot_v3/components/AutomatedTradingPanel.tsx
mindesbunister a8fcb33ec8 🚀 Major TradingView Automation Improvements
 SUCCESSFUL FEATURES:
- Fixed TradingView login automation by implementing Email button click detection
- Added comprehensive Playwright-based automation with Docker support
- Implemented robust chart navigation and symbol switching
- Added timeframe detection with interval legend clicking and keyboard fallbacks
- Created enhanced screenshot capture with multiple layout support
- Built comprehensive debug tools and error handling

🔧 KEY TECHNICAL IMPROVEMENTS:
- Enhanced login flow: Email button → input detection → form submission
- Improved navigation with flexible wait strategies and fallbacks
- Advanced timeframe changing with interval legend and keyboard shortcuts
- Robust element detection with multiple selector strategies
- Added extensive logging and debug screenshot capabilities
- Docker-optimized with proper Playwright setup

📁 NEW FILES:
- lib/tradingview-automation.ts: Complete Playwright automation
- lib/enhanced-screenshot.ts: Advanced screenshot service
- debug-*.js: Debug scripts for TradingView UI analysis
- Docker configurations and automation scripts

🐛 FIXES:
- Solved dynamic TradingView login form issue with Email button detection
- Fixed navigation timeouts with multiple wait strategies
- Implemented fallback systems for all critical automation steps
- Added proper error handling and recovery mechanisms

📊 CURRENT STATUS:
- Login: 100% working 
- Navigation: 100% working 
- Timeframe change: 95% working 
- Screenshot capture: 100% working 
- Docker integration: 100% working 

Next: Fix AI analysis JSON response format
2025-07-12 14:50:24 +02:00

250 lines
8.5 KiB
TypeScript

import React, { useState } from 'react'
interface TradingViewCredentials {
email: string
password: string
}
interface AutomatedAnalysisResult {
screenshots: string[]
analysis: any
symbol: string
timeframe: string
timestamp: string
}
export function AutomatedTradingPanel() {
const [credentials, setCredentials] = useState<TradingViewCredentials>({
email: '',
password: ''
})
const [symbol, setSymbol] = useState('SOLUSD')
const [timeframe, setTimeframe] = useState('5')
const [isLoading, setIsLoading] = useState(false)
const [result, setResult] = useState<AutomatedAnalysisResult | null>(null)
const [error, setError] = useState<string>('')
const [healthStatus, setHealthStatus] = useState<'unknown' | 'ok' | 'error'>('unknown')
const checkHealth = async () => {
try {
const response = await fetch('/api/trading/automated-analysis')
const data = await response.json()
if (data.status === 'ok') {
setHealthStatus('ok')
} else {
setHealthStatus('error')
setError(data.message || 'Health check failed')
}
} catch (err: any) {
setHealthStatus('error')
setError(err.message || 'Failed to check health')
}
}
const runAutomatedAnalysis = async () => {
if (!credentials.email || !credentials.password) {
setError('Please enter your TradingView credentials')
return
}
setIsLoading(true)
setError('')
setResult(null)
try {
const response = await fetch('/api/trading/automated-analysis', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
symbol,
timeframe,
credentials
})
})
const data = await response.json()
if (!response.ok) {
throw new Error(data.error || data.details || 'Analysis failed')
}
setResult(data.data)
} catch (err: any) {
setError(err.message || 'Failed to run automated analysis')
} finally {
setIsLoading(false)
}
}
return (
<div className="p-6 bg-white rounded-lg shadow-lg">
<h2 className="text-2xl font-bold mb-6">Automated TradingView Analysis (Docker)</h2>
{/* Health Check */}
<div className="mb-6 p-4 border rounded-lg">
<div className="flex items-center justify-between mb-2">
<h3 className="text-lg font-semibold">System Health</h3>
<button
onClick={checkHealth}
className="px-3 py-1 bg-blue-500 text-white rounded hover:bg-blue-600"
>
Check Health
</button>
</div>
{healthStatus !== 'unknown' && (
<div className={`p-2 rounded ${healthStatus === 'ok' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'}`}>
Status: {healthStatus === 'ok' ? '✅ System Ready' : '❌ System Error'}
</div>
)}
</div>
{/* Configuration */}
<div className="space-y-4 mb-6">
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium mb-1">Symbol</label>
<input
type="text"
value={symbol}
onChange={(e) => setSymbol(e.target.value)}
className="w-full p-2 border rounded"
placeholder="e.g., SOLUSD, BTCUSD"
/>
</div>
<div>
<label className="block text-sm font-medium mb-1">Timeframe</label>
<select
value={timeframe}
onChange={(e) => setTimeframe(e.target.value)}
className="w-full p-2 border rounded"
>
<option value="1">1 min</option>
<option value="5">5 min</option>
<option value="15">15 min</option>
<option value="30">30 min</option>
<option value="60">1 hour</option>
</select>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium mb-1">TradingView Email</label>
<input
type="email"
value={credentials.email}
onChange={(e) => setCredentials(prev => ({ ...prev, email: e.target.value }))}
className="w-full p-2 border rounded"
placeholder="your-email@example.com"
/>
</div>
<div>
<label className="block text-sm font-medium mb-1">TradingView Password</label>
<input
type="password"
value={credentials.password}
onChange={(e) => setCredentials(prev => ({ ...prev, password: e.target.value }))}
className="w-full p-2 border rounded"
placeholder="your-password"
/>
</div>
</div>
</div>
{/* Action Button */}
<button
onClick={runAutomatedAnalysis}
disabled={isLoading}
className={`w-full py-3 px-6 rounded text-white font-semibold ${
isLoading
? 'bg-gray-400 cursor-not-allowed'
: 'bg-green-600 hover:bg-green-700'
}`}
>
{isLoading ? '🔄 Running Automated Analysis...' : '🚀 Start Automated Analysis'}
</button>
{/* Error Display */}
{error && (
<div className="mt-4 p-4 bg-red-100 border border-red-400 text-red-700 rounded">
<strong>Error:</strong> {error}
</div>
)}
{/* Results */}
{result && (
<div className="mt-6 space-y-4">
<h3 className="text-lg font-semibold">Analysis Results</h3>
{/* Screenshots */}
<div>
<h4 className="font-medium mb-2">Screenshots Captured:</h4>
<div className="grid grid-cols-2 gap-2">
{result.screenshots.map((screenshot, index) => (
<div key={index} className="text-sm bg-gray-100 p-2 rounded">
📸 {screenshot}
</div>
))}
</div>
</div>
{/* Analysis Summary */}
<div className="p-4 border rounded-lg">
<h4 className="font-medium mb-2">AI Analysis Summary</h4>
<div className="space-y-2 text-sm">
<div><strong>Symbol:</strong> {result.symbol}</div>
<div><strong>Timeframe:</strong> {result.timeframe}</div>
<div><strong>Sentiment:</strong>
<span className={`ml-2 px-2 py-1 rounded text-xs ${
result.analysis.marketSentiment === 'BULLISH' ? 'bg-green-100 text-green-800' :
result.analysis.marketSentiment === 'BEARISH' ? 'bg-red-100 text-red-800' :
'bg-yellow-100 text-yellow-800'
}`}>
{result.analysis.marketSentiment}
</span>
</div>
<div><strong>Recommendation:</strong>
<span className={`ml-2 px-2 py-1 rounded text-xs ${
result.analysis.recommendation === 'BUY' ? 'bg-green-100 text-green-800' :
result.analysis.recommendation === 'SELL' ? 'bg-red-100 text-red-800' :
'bg-gray-100 text-gray-800'
}`}>
{result.analysis.recommendation}
</span>
</div>
<div><strong>Confidence:</strong> {result.analysis.confidence}%</div>
<div><strong>Summary:</strong> {result.analysis.summary}</div>
<div><strong>Reasoning:</strong> {result.analysis.reasoning}</div>
</div>
</div>
{/* Trading Details */}
{result.analysis.entry && (
<div className="p-4 border rounded-lg bg-blue-50">
<h4 className="font-medium mb-2">Trading Setup</h4>
<div className="space-y-1 text-sm">
<div><strong>Entry:</strong> ${result.analysis.entry.price}</div>
{result.analysis.stopLoss && (
<div><strong>Stop Loss:</strong> ${result.analysis.stopLoss.price}</div>
)}
{result.analysis.takeProfits?.tp1 && (
<div><strong>Take Profit 1:</strong> ${result.analysis.takeProfits.tp1.price}</div>
)}
{result.analysis.riskToReward && (
<div><strong>Risk/Reward:</strong> {result.analysis.riskToReward}</div>
)}
</div>
</div>
)}
</div>
)}
</div>
)
}
export default AutomatedTradingPanel