From ade5610ba25f7359acd305313b9be899f62d3679 Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Thu, 24 Jul 2025 15:54:18 +0200 Subject: [PATCH] chore: update database after trade limit removal testing - Updated dev.db with latest automation runs without trade limits - Added page-temp.js for development reference - System now running unrestricted with unlimited daily trades --- page-temp.js | 711 +++++++++++++++++++++++++++++++++++++++++++ prisma/prisma/dev.db | Bin 1286144 -> 1302528 bytes 2 files changed, 711 insertions(+) create mode 100644 page-temp.js diff --git a/page-temp.js b/page-temp.js new file mode 100644 index 0000000..ac47575 --- /dev/null +++ b/page-temp.js @@ -0,0 +1,711 @@ +'use client' +import React, { useState, useEffect } from 'react' + +// Available timeframes for automation (matching analysis page format) +const timeframes = [ + { label: '5m', value: '5' }, + { label: '15m', value: '15' }, + { label: '30m', value: '30' }, + { label: '1h', value: '60' }, + { label: '2h', value: '120' }, + { label: '4h', value: '240' }, + { label: '1d', value: 'D' }, +] + +export default function AutomationPageV2() { + const [config, setConfig] = useState({ + mode: 'SIMULATION', + dexProvider: 'DRIFT', + symbol: 'SOLUSD', + timeframe: '1h', // Primary timeframe for backwards compatibility + selectedTimeframes: ['60'], // Multi-timeframe support + tradingAmount: 100, + balancePercentage: 50, // Default to 50% of available balance + // stopLossPercent and takeProfitPercent removed - AI calculates these automatically + }) + + const [status, setStatus] = useState(null) + const [balance, setBalance] = useState(null) + const [positions, setPositions] = useState([]) + const [loading, setLoading] = useState(false) + const [nextAnalysisCountdown, setNextAnalysisCountdown] = useState(0) + + useEffect(() => { + fetchStatus() + fetchBalance() + fetchPositions() + + const interval = setInterval(() => { + fetchStatus() + fetchBalance() + fetchPositions() + }, 30000) + return () => clearInterval(interval) + }, []) + + // Timer effect for countdown + useEffect(() => { + let countdownInterval = null + + if (status?.isActive && status?.nextAnalysisIn > 0) { + setNextAnalysisCountdown(status.nextAnalysisIn) + + countdownInterval = setInterval(() => { + setNextAnalysisCountdown(prev => { + if (prev <= 1) { + // Refresh status when timer reaches 0 + fetchStatus() + return 0 + } + return prev - 1 + }) + }, 1000) + } else { + setNextAnalysisCountdown(0) + } + + return () => { + if (countdownInterval) { + clearInterval(countdownInterval) + } + } + }, [status?.nextAnalysisIn, status?.isActive]) + + // Helper function to format countdown time + const formatCountdown = (seconds) => { + if (seconds <= 0) return 'Analyzing now...' + + const hours = Math.floor(seconds / 3600) + const minutes = Math.floor((seconds % 3600) / 60) + const secs = seconds % 60 + + if (hours > 0) { + return `${hours}h ${minutes}m ${secs}s` + } else if (minutes > 0) { + return `${minutes}m ${secs}s` + } else { + return `${secs}s` + } + } + + const toggleTimeframe = (timeframe) => { + setConfig(prev => ({ + ...prev, + selectedTimeframes: prev.selectedTimeframes.includes(timeframe) + ? prev.selectedTimeframes.filter(tf => tf !== timeframe) + : [...prev.selectedTimeframes, timeframe] + })) + } + + const fetchStatus = async () => { + 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) + } + } catch (error) { + console.error('Failed to fetch status:', error) + } + } + + const fetchBalance = async () => { + try { + const response = await fetch('/api/drift/balance') + const data = await response.json() + if (data.success) { + setBalance(data) + } + } catch (error) { + console.error('Failed to fetch balance:', error) + } + } + + const fetchPositions = async () => { + try { + const response = await fetch('/api/drift/positions') + const data = await response.json() + if (data.success) { + setPositions(data.positions || []) + } + } catch (error) { + console.error('Failed to fetch positions:', error) + } + } + + const handleStart = async () => { + console.log('Start button clicked') // Debug log + setLoading(true) + try { + // Ensure we have selectedTimeframes before starting + if (config.selectedTimeframes.length === 0) { + alert('Please select at least one timeframe for analysis') + setLoading(false) + return + } + + console.log('Starting automation with config:', { + ...config, + selectedTimeframes: config.selectedTimeframes + }) + + const response = await fetch('/api/automation/start', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(config) + }) + const data = await response.json() + if (data.success) { + fetchStatus() + } else { + alert('Failed to start automation: ' + data.error) + } + } catch (error) { + console.error('Failed to start automation:', error) + alert('Failed to start automation') + } finally { + setLoading(false) + } + } + + 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 { + alert('Failed to stop automation: ' + data.error) + } + } catch (error) { + console.error('Failed to stop automation:', error) + alert('Failed to stop automation') + } finally { + setLoading(false) + } + } + + return ( +
+
+ 🚀 NEW AUTOMATION V2 - MULTI-TIMEFRAME READY 🚀 +
+ +
+
+

Automated Trading V2

+

Drift Protocol - Multi-Timeframe Analysis

+
+
+ + {status?.isActive ? ( + + ) : ( + + )} +
+
+ +
+ {/* Configuration Panel */} +
+
+

Configuration

+ + {/* Trading Mode */} +
+
+ +
+ + +
+
+ +
+ + {/* Symbol and Position Size */} +
+
+ + +
+ +
+ + { + const percentage = parseFloat(e.target.value); + const newAmount = balance ? (parseFloat(balance.availableBalance) * percentage / 100) : 100; + setConfig({ + ...config, + balancePercentage: percentage, + tradingAmount: Math.round(newAmount) + }); + }} + disabled={status?.isActive} + /> +
+ 10% + 50% + 100% +
+
+
+ + {/* MULTI-TIMEFRAME SELECTION */} +
+ + + {/* Timeframe Checkboxes */} +
+ {timeframes.map(tf => ( + + ))} +
+ + {/* Selected Timeframes Display */} + {config.selectedTimeframes.length > 0 && ( +
+
+ Selected: + {config.selectedTimeframes.map(tf => timeframes.find(t => t.value === tf)?.label).filter(Boolean).join(', ')} + +
+
+ 💡 Multiple timeframes provide more robust analysis +
+
+ )} + + {/* Quick Selection Buttons */} +
+ + + +
+
+ + {/* AI Risk Management Notice */} +
+
+ 🧠 +

AI-Powered Risk Management

+
+

+ Stop loss and take profit levels are automatically calculated by the AI based on: +

+
    +
  • • Multi-timeframe technical analysis
  • +
  • • Market volatility and support/resistance levels
  • +
  • • Real-time risk assessment and position sizing
  • +
  • • Learning from previous trade outcomes
  • +
+
+

+ ✅ Ultra-tight scalping enabled (0.5%+ stop losses proven effective) +

+
+
+
+
+ + {/* Status Panels */} +
+ {/* Account Status */} +
+
+

Account Status

+ +
+ {balance ? ( +
+
+ Available Balance: + ${parseFloat(balance.availableBalance).toFixed(2)} +
+
+ Account Value: + ${parseFloat(balance.accountValue || balance.availableBalance).toFixed(2)} +
+
+ Unrealized P&L: + 0 ? 'text-green-400' : balance.unrealizedPnl < 0 ? 'text-red-400' : 'text-gray-400'}`}> + ${parseFloat(balance.unrealizedPnl || 0).toFixed(2)} + +
+
+ Open Positions: + {positions.length} +
+
+ ) : ( +
+
Loading account data...
+
+ )} +
+ + {/* Bot Status */} +
+

Bot Status

+ {status ? ( +
+
+ Status: + + {status.isActive ? 'ACTIVE' : 'STOPPED'} + +
+
+ Mode: + + {status.mode} + +
+
+ Protocol: + DRIFT +
+
+ Symbol: + {status.symbol} +
+
+ Timeframes: + + {config.selectedTimeframes.map(tf => timeframes.find(t => t.value === tf)?.label).filter(Boolean).join(', ')} + +
+
+ ) : ( +

Loading bot status...

+ )} +
+ + {/* Analysis Progress */} + {status?.analysisProgress && ( +
+
+

Analysis Progress

+
+ Session: {status.analysisProgress.sessionId.split('-').pop()} +
+
+
+ {/* Overall Progress */} +
+ Step {status.analysisProgress.currentStep} of {status.analysisProgress.totalSteps} + + {Math.round((status.analysisProgress.currentStep / status.analysisProgress.totalSteps) * 100)}% + +
+
+
+
+ + {/* Timeframe Progress */} + {status.analysisProgress.timeframeProgress && ( +
+
+ + Analyzing {status.analysisProgress.timeframeProgress.currentTimeframe || 'timeframes'} + + + {status.analysisProgress.timeframeProgress.current}/{status.analysisProgress.timeframeProgress.total} + +
+
+ )} + + {/* Detailed Steps */} +
+ {status.analysisProgress.steps.map((step, index) => ( +
+ {/* Status Icon */} +
+ {step.status === 'active' ? '⏳' : + step.status === 'completed' ? '✓' : + step.status === 'error' ? '✗' : + index + 1} +
+ + {/* Step Info */} +
+
+ {step.title} +
+
+ {step.details || step.description} +
+
+ + {/* Duration */} + {step.duration && ( +
+ {(step.duration / 1000).toFixed(1)}s +
+ )} +
+ ))} +
+
+
+ )} + + {/* Analysis Timer */} + {status?.isActive && !status?.analysisProgress && ( +
+
+

Analysis Timer

+
+ Cycle #{status.currentCycle || 0} +
+
+
+
+
+ {formatCountdown(nextAnalysisCountdown)} +
+
+ {nextAnalysisCountdown > 0 ? 'Next Analysis In' : 'Analysis Starting Soon'} +
+
+
+
0 ? + `${Math.max(0, 100 - (nextAnalysisCountdown / status.analysisInterval) * 100)}%` : + '0%' + }} + >
+
+
+ Analysis Interval: {Math.floor((status.analysisInterval || 0) / 60)}m +
+
+
+ )} + + {/* Individual Timeframe Results */} + {status?.individualTimeframeResults && status.individualTimeframeResults.length > 0 && ( +
+

Timeframe Analysis

+
+ {status.individualTimeframeResults.map((result, index) => ( +
+
+ + {timeframes.find(tf => tf.value === result.timeframe)?.label || result.timeframe} + + + {result.recommendation} + +
+
+
+ {result.confidence}% +
+
+ confidence +
+
+
+ ))} +
+
+
+ ✅ Last Updated: {status.individualTimeframeResults[0]?.timestamp ? + new Date(status.individualTimeframeResults[0].timestamp).toLocaleTimeString() : + 'N/A' + } +
+
+
+ )} + + {/* Trading Metrics */} +
+

Trading Metrics

+
+
+
+ ${balance ? parseFloat(balance.accountValue || balance.availableBalance).toFixed(2) : '0.00'} +
+
Portfolio
+
+
+
+ {balance ? parseFloat(balance.leverage || 0).toFixed(1) : '0.0'}% +
+
Leverage Used
+
+
+
+ ${balance ? parseFloat(balance.unrealizedPnl || 0).toFixed(2) : '0.00'} +
+
Unrealized P&L
+
+
+
+ {positions.length} +
+
Open Positions
+
+
+
+
+
+
+ ) +} diff --git a/prisma/prisma/dev.db b/prisma/prisma/dev.db index cb0f180f0c45e49d7c1ffd0963633018cc0600e6..d4675a6061b86781eb98e082339ef99c940d2012 100644 GIT binary patch delta 1635 zcmaizZERCz7>0Y!>DTGU`6`{VmQi7DFrb{a>(RQ*U>49G-QM?~zr6 zeTKx`(c#%8N@bWT7p-%>+=y4Zsr`Bzdqb5;STXfbPFl}Svs3I(?2U`!nzwX$)T+3h zh?Q|0iOjqoPp6yr}Mn zE-9w;>Oa*t)SsyP$(!R$cL7sHH?;;r&4CV|msBg1tyWve)6%@Blv?mWE^FLJF+Xuj*-)>Y^_GN=8$O^F@_LlTF$`$Gxbd z`HPsgi1kYCP0q>SYLQOB^mmM2nf!(6r_j4aorkZlsS7c7LTALeE!q<}He}$j|FY=D z!CRakkuHq}zpO18xh_^7h>|dz6fK>bn9WLr@PTxueKv?qSbhBKU^!=k{!na}mc{tjHk6gLL zeNNdgXA^IDIPuZ(OyZ;0vrT8TDn?71K1;h!?u*-VCh87bA2kt}V-#`7Z9b35CSJ#Q zoj!cJRw$rk9Dm2?P~@1DViKK<4(Se#OH2vRDgKb~8HF^t)ra_vW_kU z4{QE)#Q!(ObM0Pcj1`2dB&*uD+~v=Cas15BqcNkA79;t&ke9e8p2Jv~B;%Bp{}^jv zF{1K_StxAW+tRWt8VU!aQAgw6n4_gF+`J+dY;Scm26wdQ6uh0sSdr`yi_kko88P;Q z*}%33qr0N99pNT?Fr>9Yn9>yB`=e$7_H~9Aa5cm!Sm_rzB!?Il4J^L`y+bAmle@U5 zAY9=}Al%L@+bzk88NVoEe1l*>%WD=pBD*xn+rki)5xgp;~&|a5?t73 zs)R60Td=%RWKmdSS&fFT%x@;PYt5K8nI|x@-6SW%Ob|T`tqF{|X^e5x&!sUci>6g&SY{X)7#J5M8C2yM zn&g{QmgG-gn93+O{YEaMKj)gRLdF?3>p0d;|CqyAz-6=gsVb1armJZCw{*t!tc3K7 zt}%WG(GMh{dX3+2x5;BP7sR2rqn@#bL!9#q1IWqSc^Vk?m^KSKtYx46Jd#nM{d*@P z5HkTWGZ3=?F)I+W0Wmuea{w_X5OV=BHxTmxF)tAF0Wm)i3vB=1DafnF9K|X%oqdDg fR-nOgEYs(05#*d+GD%pZ-F&OycJr-5Ctm>o!CQDp