feat: Fix position calculator visibility and add auto-detection

- Fixed position calculator not showing when analysis entry price is 0
- Added auto-detection of Long/Short position type from AI analysis recommendation
- Implemented independent price fetching from CoinGecko API
- Added current market price display with AI recommendation
- Enhanced position calculator with fallback prices for testing
- Added API endpoint /api/price for real-time price data
- Position calculator now works even when analysis lacks specific entry prices
- Shows 'Auto-detected from analysis' label when position type is determined from AI

The position calculator is now always visible and uses:
1. Current market price from CoinGecko API
2. Auto-detected position type from analysis (Long/Short)
3. Fallback prices for testing when API is unavailable
4. Default stop loss/take profit levels when not specified in analysis
This commit is contained in:
mindesbunister
2025-07-18 13:33:34 +02:00
parent ba354c609d
commit bd49c65867
2 changed files with 137 additions and 6 deletions

View File

@@ -36,14 +36,52 @@ export default function PositionCalculator({
const [positionType, setPositionType] = useState<'long' | 'short'>('long')
const [calculation, setCalculation] = useState<PositionCalculation | null>(null)
const [showAdvanced, setShowAdvanced] = useState(false)
const [marketPrice, setMarketPrice] = useState<number>(currentPrice)
// Trading parameters
const [tradingFee, setTradingFee] = useState<number>(0.1) // 0.1% fee
const [maintenanceMargin, setMaintenanceMargin] = useState<number>(0.5) // 0.5% maintenance margin
// Auto-detect position type from analysis
useEffect(() => {
if (analysis?.recommendation) {
const rec = analysis.recommendation.toLowerCase()
if (rec.includes('buy') || rec.includes('long') || rec.includes('bullish')) {
setPositionType('long')
} else if (rec.includes('sell') || rec.includes('short') || rec.includes('bearish')) {
setPositionType('short')
}
}
}, [analysis])
// Fetch current market price if not provided
useEffect(() => {
const fetchPrice = async () => {
if (currentPrice > 0) {
setMarketPrice(currentPrice)
return
}
try {
const response = await fetch(`/api/price?symbol=${symbol}`)
const data = await response.json()
if (data.price) {
setMarketPrice(data.price)
}
} catch (error) {
console.error('Failed to fetch price:', error)
// Fallback to a reasonable default for testing
setMarketPrice(symbol.includes('BTC') ? 100000 : symbol.includes('ETH') ? 4000 : 100)
}
}
fetchPrice()
}, [currentPrice, symbol])
// Calculate position metrics
const calculatePosition = () => {
if (!currentPrice || currentPrice <= 0) return null
const priceToUse = marketPrice || currentPrice
if (!priceToUse || priceToUse <= 0) return null
const positionSize = investmentAmount * leverage
const marginRequired = investmentAmount
@@ -51,7 +89,7 @@ export default function PositionCalculator({
const netInvestment = investmentAmount + fee
// Get AI analysis targets if available
let entryPrice = currentPrice
let entryPrice = priceToUse
let stopLoss = 0
let takeProfit = 0
@@ -92,11 +130,11 @@ export default function PositionCalculator({
} else {
// Default targets if no analysis
stopLoss = positionType === 'long'
? currentPrice * 0.95
: currentPrice * 1.05
? priceToUse * 0.95
: priceToUse * 1.05
takeProfit = positionType === 'long'
? currentPrice * 1.10
: currentPrice * 0.90
? priceToUse * 1.10
: priceToUse * 0.90
}
// Calculate liquidation price
@@ -176,6 +214,21 @@ export default function PositionCalculator({
</button>
</div>
{/* Current Price Display */}
<div className="mb-6 p-4 bg-gray-800/30 rounded-lg border border-gray-600">
<div className="flex items-center justify-between">
<div className="text-sm text-gray-400">Current Market Price</div>
<div className="text-lg font-bold text-white">
{symbol}: ${formatPrice(marketPrice || currentPrice || 0)}
</div>
</div>
{analysis?.recommendation && (
<div className="mt-2 text-sm text-cyan-400">
AI Recommendation: {analysis.recommendation}
</div>
)}
</div>
{/* Input Controls */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
{/* Investment Amount */}
@@ -197,6 +250,9 @@ export default function PositionCalculator({
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Position Type
{analysis?.recommendation && (
<span className="ml-2 text-xs text-cyan-400">(Auto-detected from analysis)</span>
)}
</label>
<div className="flex space-x-2">
<button