From 67ef5b1ac6ee9603bc411c8f9b9a493429398a8b Mon Sep 17 00:00:00 2001 From: mindesbunister Date: Mon, 1 Dec 2025 09:09:30 +0100 Subject: [PATCH] feat: Add direction-specific quality thresholds and dynamic collateral display - Split QUALITY_LEVERAGE_THRESHOLD into separate LONG and SHORT variants - Added /api/drift/account-health endpoint for real-time collateral data - Updated settings UI to show separate controls for LONG/SHORT thresholds - Position size calculations now use dynamic collateral from Drift account - Updated .env and docker-compose.yml with new environment variables - LONG threshold: 95, SHORT threshold: 90 (configurable independently) Files changed: - app/api/drift/account-health/route.ts (NEW) - Account health API endpoint - app/settings/page.tsx - Added collateral state, separate threshold inputs - app/api/settings/route.ts - GET/POST handlers for LONG/SHORT thresholds - .env - Added QUALITY_LEVERAGE_THRESHOLD_LONG/SHORT variables - docker-compose.yml - Added new env vars with fallback defaults Impact: - Users can now configure quality thresholds independently for LONG vs SHORT signals - Position size display dynamically updates based on actual Drift account collateral - More flexible risk management with direction-specific leverage tiers --- .env | 7 +++- app/api/drift/account-health/route.ts | 36 +++++++++++++++++ app/api/settings/route.ts | 6 ++- app/settings/page.tsx | 55 ++++++++++++++++++++------ cluster/exploration.db | Bin 40960 -> 40960 bytes docker-compose.yml | 4 +- lib/trading/smart-validation-queue.ts | 1 - 7 files changed, 90 insertions(+), 19 deletions(-) create mode 100644 app/api/drift/account-health/route.ts diff --git a/.env b/.env index df832e3..607a54d 100644 --- a/.env +++ b/.env @@ -395,11 +395,14 @@ MIN_SIGNAL_QUALITY_SCORE=91 MIN_SIGNAL_QUALITY_SCORE_LONG=90 MIN_SIGNAL_QUALITY_SCORE_SHORT=80 # Adaptive Leverage System (Nov 24, 2025) -# ENABLED Dec 1, 2025: 10x for high-quality signals (Q≥95 LONGs, Q≥90 SHORTs), 5x for borderline +# ENABLED Dec 1, 2025: 10x for high-quality signals, 5x for borderline +# Direction-specific thresholds: LONG ≥95, SHORT ≥90 USE_ADAPTIVE_LEVERAGE=true HIGH_QUALITY_LEVERAGE=10 LOW_QUALITY_LEVERAGE=5 -QUALITY_LEVERAGE_THRESHOLD=95 +QUALITY_LEVERAGE_THRESHOLD_LONG=95 +QUALITY_LEVERAGE_THRESHOLD_SHORT=90 +QUALITY_LEVERAGE_THRESHOLD=95 # Kept for backward compatibility SOLANA_ENABLED=true SOLANA_POSITION_SIZE=100 SOLANA_LEVERAGE=5 diff --git a/app/api/drift/account-health/route.ts b/app/api/drift/account-health/route.ts new file mode 100644 index 0000000..8be7ebe --- /dev/null +++ b/app/api/drift/account-health/route.ts @@ -0,0 +1,36 @@ +import { NextResponse } from 'next/server' +import { initializeDriftService } from '@/lib/drift/client' + +/** + * GET /api/drift/account-health + * + * Returns current account health metrics from Drift Protocol + * Used by settings UI to dynamically display collateral and calculate position sizes + */ +export async function GET() { + try { + const driftService = await initializeDriftService() + + if (!driftService) { + return NextResponse.json( + { error: 'Drift service not initialized' }, + { status: 503 } + ) + } + + const health = await driftService.getAccountHealth() + + return NextResponse.json({ + totalCollateral: health.totalCollateral, + freeCollateral: health.freeCollateral, + totalLiability: health.totalLiability, + marginRatio: health.marginRatio, + }) + } catch (error: any) { + console.error('❌ Error fetching account health:', error) + return NextResponse.json( + { error: 'Failed to fetch account health', details: error.message }, + { status: 500 } + ) + } +} diff --git a/app/api/settings/route.ts b/app/api/settings/route.ts index 3933548..95abc85 100644 --- a/app/api/settings/route.ts +++ b/app/api/settings/route.ts @@ -132,7 +132,8 @@ export async function GET() { USE_ADAPTIVE_LEVERAGE: env.USE_ADAPTIVE_LEVERAGE === 'true', HIGH_QUALITY_LEVERAGE: parseFloat(env.HIGH_QUALITY_LEVERAGE || '5'), LOW_QUALITY_LEVERAGE: parseFloat(env.LOW_QUALITY_LEVERAGE || '1'), - QUALITY_LEVERAGE_THRESHOLD: parseInt(env.QUALITY_LEVERAGE_THRESHOLD || '95'), + QUALITY_LEVERAGE_THRESHOLD_LONG: parseInt(env.QUALITY_LEVERAGE_THRESHOLD_LONG || env.QUALITY_LEVERAGE_THRESHOLD || '95'), + QUALITY_LEVERAGE_THRESHOLD_SHORT: parseInt(env.QUALITY_LEVERAGE_THRESHOLD_SHORT || '90'), } return NextResponse.json(settings) @@ -207,7 +208,8 @@ export async function POST(request: NextRequest) { USE_ADAPTIVE_LEVERAGE: settings.USE_ADAPTIVE_LEVERAGE.toString(), HIGH_QUALITY_LEVERAGE: settings.HIGH_QUALITY_LEVERAGE.toString(), LOW_QUALITY_LEVERAGE: settings.LOW_QUALITY_LEVERAGE.toString(), - QUALITY_LEVERAGE_THRESHOLD: settings.QUALITY_LEVERAGE_THRESHOLD.toString(), + QUALITY_LEVERAGE_THRESHOLD_LONG: settings.QUALITY_LEVERAGE_THRESHOLD_LONG.toString(), + QUALITY_LEVERAGE_THRESHOLD_SHORT: settings.QUALITY_LEVERAGE_THRESHOLD_SHORT.toString(), } const success = updateEnvFile(updates) diff --git a/app/settings/page.tsx b/app/settings/page.tsx index 2fdd59f..33ec8ea 100644 --- a/app/settings/page.tsx +++ b/app/settings/page.tsx @@ -59,8 +59,9 @@ interface TradingSettings { USE_ADAPTIVE_LEVERAGE: boolean HIGH_QUALITY_LEVERAGE: number LOW_QUALITY_LEVERAGE: number - QUALITY_LEVERAGE_THRESHOLD: number - + QUALITY_LEVERAGE_THRESHOLD_LONG: number // Quality threshold for LONG signals + QUALITY_LEVERAGE_THRESHOLD_SHORT: number // Quality threshold for SHORT signals + // Safety MAX_DAILY_DRAWDOWN: number MAX_TRADES_PER_HOUR: number @@ -79,11 +80,30 @@ export default function SettingsPage() { const [restarting, setRestarting] = useState(false) const [testing, setTesting] = useState(false) const [message, setMessage] = useState<{ type: 'success' | 'error', text: string } | null>(null) + const [collateral, setCollateral] = useState(560) // Dynamic collateral from Drift account useEffect(() => { loadSettings() + loadCollateral() }, []) + const loadCollateral = async () => { + try { + const response = await fetch('/api/drift/account-health') + if (response.ok) { + const data = await response.json() + setCollateral(data.freeCollateral) + console.log('✅ Loaded collateral from Drift:', data.freeCollateral) + } else { + console.warn('⚠️ Failed to load collateral, using fallback: 560') + setCollateral(560) // Fallback if API fails + } + } catch (error) { + console.error('❌ Error loading collateral:', error) + setCollateral(560) // Fallback on error + } + } + const loadSettings = async () => { try { const response = await fetch('/api/settings') @@ -508,7 +528,7 @@ export default function SettingsPage() { min={1} max={20} step={1} - description={`Leverage for exceptional signals (Quality ${settings.QUALITY_LEVERAGE_THRESHOLD}+ LONG, 90+ SHORT). Current: ${settings.HIGH_QUALITY_LEVERAGE}x leverage.`} + description={`Leverage for exceptional signals (Quality ${settings.QUALITY_LEVERAGE_THRESHOLD_LONG}+ LONG, ${settings.QUALITY_LEVERAGE_THRESHOLD_SHORT}+ SHORT). Current: ${settings.HIGH_QUALITY_LEVERAGE}x leverage.`} /> updateSetting('QUALITY_LEVERAGE_THRESHOLD', v)} + label="Quality Threshold (LONG)" + value={settings.QUALITY_LEVERAGE_THRESHOLD_LONG} + onChange={(v) => updateSetting('QUALITY_LEVERAGE_THRESHOLD_LONG', v)} min={80} max={100} step={1} - description="Minimum quality score for high-quality leverage tier (applies to LONG signals, SHORT uses 90+)." + description="Minimum quality score for high-quality leverage tier on LONG signals." + /> + updateSetting('QUALITY_LEVERAGE_THRESHOLD_SHORT', v)} + min={80} + max={100} + step={1} + description="Minimum quality score for high-quality leverage tier on SHORT signals." />
-
Leverage Tiers (with $560 collateral)
+
Leverage Tiers (with ${collateral.toFixed(0)} collateral)
- 🔥 High Quality (Q{settings.QUALITY_LEVERAGE_THRESHOLD}+ LONG, Q90+ SHORT): - {settings.HIGH_QUALITY_LEVERAGE}x = ${(560 * settings.HIGH_QUALITY_LEVERAGE).toFixed(0)} position + 🔥 High Quality (Q{settings.QUALITY_LEVERAGE_THRESHOLD_LONG}+ LONG, Q{settings.QUALITY_LEVERAGE_THRESHOLD_SHORT}+ SHORT): + {settings.HIGH_QUALITY_LEVERAGE}x = ${(collateral * settings.HIGH_QUALITY_LEVERAGE).toFixed(0)} position
- 📊 Low Quality (Q90-{settings.QUALITY_LEVERAGE_THRESHOLD-1} LONG, Q80-89 SHORT): - {settings.LOW_QUALITY_LEVERAGE}x = ${(560 * settings.LOW_QUALITY_LEVERAGE).toFixed(0)} position + 📊 Low Quality (Q90-{settings.QUALITY_LEVERAGE_THRESHOLD_LONG-1} LONG, Q80-{settings.QUALITY_LEVERAGE_THRESHOLD_SHORT-1} SHORT): + {settings.LOW_QUALITY_LEVERAGE}x = ${(collateral * settings.LOW_QUALITY_LEVERAGE).toFixed(0)} position
❌ Below Threshold: diff --git a/cluster/exploration.db b/cluster/exploration.db index 052660585500acf9dbe338e12ae2d1492795c876..adec8ecfb82f324c0c522c9f6a76191575d7ce0d 100644 GIT binary patch delta 116 zcmZoTz|?SnX@WGP$V3@uMv;vP%k0?_82Ai%5;hA8i108m2~TXa<7@U~;?q`bvt?pp xVvuIotmCtXQM4d6FC{ZCz1fEmEX4tllJnce$PSg-6!6wx7|LeiVwUEFvH|MpAKd@| delta 176 zcmZoTz|?SnX@WGP@I)DBM&XSK%k0_Y82AKuL?J8sVN z*~4g7o?n!mT4YpInwOWEmu_TWWU6ausB3JXU}R)vU}