Fix automation v2 timeframe selection and SELL signal execution
- Fixed timeframe selection to use user-selected timeframes instead of hardcoded values - Added selectedTimeframes property to AutomationConfig interface - Added maxDailyTrades property to AutomationConfig interface - Removed Jupiter DEX blocking logic that prevented SELL signals from opening SHORT positions - Fixed SELL signals to properly execute SHORT positions on Drift Protocol - Updated automation test route with missing properties (selectedTimeframes, maxDailyTrades, dexProvider) - Added debug logging to automation v2 page for better troubleshooting - Added test click button for UI interaction debugging - Resolved TypeScript compilation errors in automation service - Ensured automation v2 interface is fully functional and responsive These changes enable: - Multi-timeframe analysis with user-selected timeframes - Proper SHORT position execution on SELL signals - Improved UI reliability and debugging capabilities - Full Drift Protocol perpetual futures trading support
This commit is contained in:
@@ -11,12 +11,14 @@ export async function GET(request: NextRequest) {
|
||||
mode: 'SIMULATION' as const,
|
||||
symbol: 'SOLUSD',
|
||||
timeframe: '1h',
|
||||
selectedTimeframes: ['1h'],
|
||||
tradingAmount: 10, // $10 for simulation
|
||||
maxLeverage: 2,
|
||||
stopLossPercent: 2,
|
||||
takeProfitPercent: 6,
|
||||
maxDailyTrades: 5,
|
||||
riskPercentage: 1
|
||||
riskPercentage: 1,
|
||||
dexProvider: 'DRIFT' as const
|
||||
}
|
||||
|
||||
console.log('📋 Config:', testConfig)
|
||||
|
||||
@@ -57,6 +57,7 @@ export default function AutomationPageV2() {
|
||||
try {
|
||||
const response = await fetch('/api/automation/status')
|
||||
const data = await response.json()
|
||||
console.log('Status fetched:', data) // Debug log
|
||||
if (data.success) {
|
||||
setStatus(data.status)
|
||||
}
|
||||
@@ -90,6 +91,7 @@ export default function AutomationPageV2() {
|
||||
}
|
||||
|
||||
const handleStart = async () => {
|
||||
console.log('Start button clicked') // Debug log
|
||||
setLoading(true)
|
||||
try {
|
||||
// Ensure we have selectedTimeframes before starting
|
||||
@@ -126,12 +128,14 @@ export default function AutomationPageV2() {
|
||||
}
|
||||
|
||||
const handleStop = async () => {
|
||||
console.log('Stop button clicked') // Debug log
|
||||
setLoading(true)
|
||||
try {
|
||||
const response = await fetch('/api/automation/stop', {
|
||||
method: 'POST'
|
||||
})
|
||||
const data = await response.json()
|
||||
console.log('Stop response:', data) // Debug log
|
||||
if (data.success) {
|
||||
fetchStatus()
|
||||
} else {
|
||||
@@ -157,6 +161,12 @@ export default function AutomationPageV2() {
|
||||
<p className="text-gray-400 mt-1">Drift Protocol - Multi-Timeframe Analysis</p>
|
||||
</div>
|
||||
<div className="flex space-x-4">
|
||||
<button
|
||||
onClick={() => console.log('TEST BUTTON CLICKED')}
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
|
||||
>
|
||||
Test Click
|
||||
</button>
|
||||
{status?.isActive ? (
|
||||
<button
|
||||
onClick={handleStop}
|
||||
|
||||
@@ -15,6 +15,7 @@ export interface AutomationConfig {
|
||||
mode: 'SIMULATION' | 'LIVE'
|
||||
symbol: string
|
||||
timeframe: string
|
||||
selectedTimeframes: string[] // Multi-timeframe support
|
||||
tradingAmount: number
|
||||
maxLeverage: number
|
||||
stopLossPercent: number
|
||||
@@ -62,6 +63,9 @@ export class AutomationService {
|
||||
this.isRunning = true
|
||||
|
||||
console.log(`🤖 Starting automation for ${config.symbol} ${config.timeframe} in ${config.mode} mode`)
|
||||
console.log(`📊 Using timeframes: ${config.selectedTimeframes?.join(", ") || "default fallback"}`)
|
||||
console.log(`📊 Timeframes array:`, config.selectedTimeframes)
|
||||
console.log(`🔧 Full config:`, JSON.stringify(config, null, 2))
|
||||
|
||||
// Ensure user exists in database
|
||||
await prisma.user.upsert({
|
||||
@@ -95,6 +99,7 @@ export class AutomationService {
|
||||
timeframe: config.timeframe,
|
||||
settings: {
|
||||
tradingAmount: config.tradingAmount,
|
||||
selectedTimeframes: config.selectedTimeframes,
|
||||
maxLeverage: config.maxLeverage,
|
||||
stopLossPercent: config.stopLossPercent,
|
||||
takeProfitPercent: config.takeProfitPercent,
|
||||
@@ -274,7 +279,7 @@ export class AutomationService {
|
||||
progressTracker.updateStep(sessionId, 'init', 'active', 'Starting multi-timeframe analysis...')
|
||||
|
||||
// Multi-timeframe analysis: 15m, 1h, 2h, 4h
|
||||
const timeframes = ['15', '1h', '2h', '4h']
|
||||
const timeframes = this.config!.selectedTimeframes && this.config!.selectedTimeframes.length > 0 ? this.config!.selectedTimeframes : ["15", "60", "120", "240"]
|
||||
const symbol = this.config!.symbol
|
||||
|
||||
console.log(`🔍 Analyzing ${symbol} across timeframes: ${timeframes.join(', ')} with AI + DIY layouts`)
|
||||
@@ -593,17 +598,12 @@ ${validResults.map(r => `• ${r.timeframe}: ${r.analysis?.recommendation} (${r.
|
||||
return null
|
||||
}
|
||||
|
||||
// ✅ ENHANCED: Support both BUY and SELL signals
|
||||
if (analysis.recommendation === 'SELL') {
|
||||
// Check if we have SOL position to sell
|
||||
const hasPosition = await this.checkCurrentPosition()
|
||||
if (!hasPosition) {
|
||||
console.log('📊 SELL signal but no SOL position to sell - skipping')
|
||||
return null
|
||||
}
|
||||
console.log('📉 SELL signal detected with existing SOL position')
|
||||
} else if (analysis.recommendation === 'BUY') {
|
||||
console.log('📈 BUY signal detected')
|
||||
|
||||
// Log the trading signal
|
||||
if (analysis.recommendation === "SELL") {
|
||||
console.log("📉 SELL signal detected - Opening SHORT position")
|
||||
} else if (analysis.recommendation === "BUY") {
|
||||
console.log("📈 BUY signal detected - Opening LONG position")
|
||||
}
|
||||
|
||||
// Calculate position size based on risk percentage
|
||||
@@ -625,40 +625,6 @@ ${validResults.map(r => `• ${r.timeframe}: ${r.analysis?.recommendation} (${r.
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ NEW: Check if we have SOL position available to sell
|
||||
private async checkCurrentPosition(): Promise<boolean> {
|
||||
try {
|
||||
// Check recent trades to see current position
|
||||
const recentTrades = await prisma.trade.findMany({
|
||||
where: {
|
||||
userId: this.config!.userId,
|
||||
symbol: this.config!.symbol,
|
||||
status: 'OPEN'
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 5
|
||||
})
|
||||
|
||||
// Count open positions
|
||||
let netPosition = 0
|
||||
for (const trade of recentTrades) {
|
||||
if (trade.side === 'BUY') {
|
||||
netPosition += trade.amount
|
||||
} else if (trade.side === 'SELL') {
|
||||
netPosition -= trade.amount
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`🔍 Current SOL position: ${netPosition.toFixed(4)} SOL`)
|
||||
return netPosition > 0.001 // Have at least 0.001 SOL to sell
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error checking current position:', error)
|
||||
// If we can't check, default to allowing the trade (fail-safe)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private async calculatePositionSize(analysis: any): Promise<number> {
|
||||
const baseAmount = this.config!.tradingAmount // This is the USD amount to invest
|
||||
const riskAdjustment = this.config!.riskPercentage / 100
|
||||
@@ -1106,6 +1072,7 @@ ${validResults.map(r => `• ${r.timeframe}: ${r.analysis?.recommendation} (${r.
|
||||
mode: session.mode,
|
||||
symbol: session.symbol,
|
||||
timeframe: session.timeframe,
|
||||
selectedTimeframes: settings.selectedTimeframes || ["60", "240"], // Default fallback
|
||||
tradingAmount: settings.tradingAmount || 100,
|
||||
maxLeverage: settings.maxLeverage || 3,
|
||||
stopLossPercent: settings.stopLossPercent || 2,
|
||||
|
||||
@@ -10,10 +10,12 @@ export interface AutomationConfig {
|
||||
mode: 'SIMULATION' | 'LIVE'
|
||||
symbol: string
|
||||
timeframe: string
|
||||
selectedTimeframes: string[] // Multi-timeframe support
|
||||
tradingAmount: number
|
||||
maxLeverage: number
|
||||
stopLossPercent: number
|
||||
takeProfitPercent: number
|
||||
maxDailyTrades: number
|
||||
riskPercentage: number
|
||||
dexProvider: 'JUPITER' | 'DRIFT'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user