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
This commit is contained in:
mindesbunister
2025-12-01 09:09:30 +01:00
parent a294f44a06
commit 67ef5b1ac6
7 changed files with 90 additions and 19 deletions

View File

@@ -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<number>(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.`}
/>
<Setting
label="Low Quality Leverage"
@@ -517,27 +537,36 @@ export default function SettingsPage() {
min={1}
max={20}
step={1}
description={`Leverage for borderline signals (Quality 90-${settings.QUALITY_LEVERAGE_THRESHOLD-1} LONG, 80-89 SHORT). Current: ${settings.LOW_QUALITY_LEVERAGE}x leverage.`}
description={`Leverage for borderline signals (Quality 90-${settings.QUALITY_LEVERAGE_THRESHOLD_LONG-1} LONG, 80-${settings.QUALITY_LEVERAGE_THRESHOLD_SHORT-1} SHORT). Current: ${settings.LOW_QUALITY_LEVERAGE}x leverage.`}
/>
<Setting
label="Quality Threshold"
value={settings.QUALITY_LEVERAGE_THRESHOLD}
onChange={(v) => 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."
/>
<Setting
label="Quality Threshold (SHORT)"
value={settings.QUALITY_LEVERAGE_THRESHOLD_SHORT}
onChange={(v) => updateSetting('QUALITY_LEVERAGE_THRESHOLD_SHORT', v)}
min={80}
max={100}
step={1}
description="Minimum quality score for high-quality leverage tier on SHORT signals."
/>
<div className="p-4 bg-slate-700/50 rounded-lg">
<div className="text-sm text-slate-300 mb-2">Leverage Tiers (with $560 collateral)</div>
<div className="text-sm text-slate-300 mb-2">Leverage Tiers (with ${collateral.toFixed(0)} collateral)</div>
<div className="space-y-2 text-xs">
<div className="flex justify-between">
<span className="text-slate-400">🔥 High Quality (Q{settings.QUALITY_LEVERAGE_THRESHOLD}+ LONG, Q90+ SHORT):</span>
<span className="text-green-400 font-bold">{settings.HIGH_QUALITY_LEVERAGE}x = ${(560 * settings.HIGH_QUALITY_LEVERAGE).toFixed(0)} position</span>
<span className="text-slate-400">🔥 High Quality (Q{settings.QUALITY_LEVERAGE_THRESHOLD_LONG}+ LONG, Q{settings.QUALITY_LEVERAGE_THRESHOLD_SHORT}+ SHORT):</span>
<span className="text-green-400 font-bold">{settings.HIGH_QUALITY_LEVERAGE}x = ${(collateral * settings.HIGH_QUALITY_LEVERAGE).toFixed(0)} position</span>
</div>
<div className="flex justify-between">
<span className="text-slate-400">📊 Low Quality (Q90-{settings.QUALITY_LEVERAGE_THRESHOLD-1} LONG, Q80-89 SHORT):</span>
<span className="text-yellow-400 font-bold">{settings.LOW_QUALITY_LEVERAGE}x = ${(560 * settings.LOW_QUALITY_LEVERAGE).toFixed(0)} position</span>
<span className="text-slate-400">📊 Low Quality (Q90-{settings.QUALITY_LEVERAGE_THRESHOLD_LONG-1} LONG, Q80-{settings.QUALITY_LEVERAGE_THRESHOLD_SHORT-1} SHORT):</span>
<span className="text-yellow-400 font-bold">{settings.LOW_QUALITY_LEVERAGE}x = ${(collateral * settings.LOW_QUALITY_LEVERAGE).toFixed(0)} position</span>
</div>
<div className="flex justify-between">
<span className="text-slate-400">❌ Below Threshold:</span>