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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user