feat: Add adaptive leverage controls to settings UI

Complete implementation of adaptive leverage configuration via web interface:

Frontend (app/settings/page.tsx):
- Added 4 fields to TradingSettings interface:
  * USE_ADAPTIVE_LEVERAGE: boolean
  * HIGH_QUALITY_LEVERAGE: number
  * LOW_QUALITY_LEVERAGE: number
  * QUALITY_LEVERAGE_THRESHOLD: number

- Added complete Adaptive Leverage section with:
  * Purple-themed informational box explaining quality-based leverage
  * Toggle switch for enabling/disabling (🎯 Enable Adaptive Leverage)
  * Number inputs for high leverage (1-20), low leverage (1-20), threshold (80-100)
  * Visual tier display showing leverage multipliers and position sizes
  * Dynamic calculation based on $560 free collateral

Backend (app/api/settings/route.ts):
- GET handler: Load 4 adaptive leverage fields from environment variables
- POST handler: Save 4 adaptive leverage fields to .env file
- Proper type conversion (boolean from 'true', numbers from parseInt/parseFloat)

Visual Tier Display Example:
 Below Threshold: Blocked (no trade)

Changes enable users to adjust leverage settings via web UI instead of
manually editing .env file and restarting container.
This commit is contained in:
mindesbunister
2025-12-01 08:47:38 +01:00
parent 2e511ceddc
commit 21c13b915a
2 changed files with 91 additions and 0 deletions

View File

@@ -127,6 +127,12 @@ export async function GET() {
MIN_SIGNAL_QUALITY_SCORE_SHORT: parseInt(env.MIN_SIGNAL_QUALITY_SCORE_SHORT || env.MIN_SIGNAL_QUALITY_SCORE || '60'), MIN_SIGNAL_QUALITY_SCORE_SHORT: parseInt(env.MIN_SIGNAL_QUALITY_SCORE_SHORT || env.MIN_SIGNAL_QUALITY_SCORE || '60'),
SLIPPAGE_TOLERANCE: parseFloat(env.SLIPPAGE_TOLERANCE || '1.0'), SLIPPAGE_TOLERANCE: parseFloat(env.SLIPPAGE_TOLERANCE || '1.0'),
DRY_RUN: env.DRY_RUN === 'true', DRY_RUN: env.DRY_RUN === 'true',
// Adaptive Leverage (Dec 1, 2025)
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'),
} }
return NextResponse.json(settings) return NextResponse.json(settings)
@@ -196,6 +202,12 @@ export async function POST(request: NextRequest) {
MIN_SIGNAL_QUALITY_SCORE_SHORT: settings.MIN_SIGNAL_QUALITY_SCORE_SHORT.toString(), MIN_SIGNAL_QUALITY_SCORE_SHORT: settings.MIN_SIGNAL_QUALITY_SCORE_SHORT.toString(),
SLIPPAGE_TOLERANCE: settings.SLIPPAGE_TOLERANCE.toString(), SLIPPAGE_TOLERANCE: settings.SLIPPAGE_TOLERANCE.toString(),
DRY_RUN: settings.DRY_RUN.toString(), DRY_RUN: settings.DRY_RUN.toString(),
// Adaptive Leverage (Dec 1, 2025)
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(),
} }
const success = updateEnvFile(updates) const success = updateEnvFile(updates)

View File

@@ -55,6 +55,12 @@ interface TradingSettings {
MIN_ADX_INCREASE: number MIN_ADX_INCREASE: number
MAX_PRICE_POSITION_FOR_SCALE: number MAX_PRICE_POSITION_FOR_SCALE: number
// Adaptive Leverage (Quality-based)
USE_ADAPTIVE_LEVERAGE: boolean
HIGH_QUALITY_LEVERAGE: number
LOW_QUALITY_LEVERAGE: number
QUALITY_LEVERAGE_THRESHOLD: number
// Safety // Safety
MAX_DAILY_DRAWDOWN: number MAX_DAILY_DRAWDOWN: number
MAX_TRADES_PER_HOUR: number MAX_TRADES_PER_HOUR: number
@@ -468,6 +474,79 @@ export default function SettingsPage() {
/> />
</Section> </Section>
{/* Adaptive Leverage */}
<Section title="⚡ Adaptive Leverage" description="Quality-based dynamic leverage adjustment">
<div className="mb-4 p-3 bg-purple-500/10 border border-purple-500/30 rounded-lg">
<p className="text-sm text-purple-400">
Automatically adjust leverage based on signal quality score. High-quality signals get more leverage for maximum profit, borderline signals use lower leverage for risk management.
</p>
</div>
<div className="flex items-center justify-between p-4 bg-slate-700/30 rounded-lg mb-4">
<div className="flex-1">
<div className="text-white font-medium mb-1">🎯 Enable Adaptive Leverage</div>
<div className="text-slate-400 text-sm">
Dynamically adjust leverage based on signal quality
</div>
</div>
<button
onClick={() => updateSetting('USE_ADAPTIVE_LEVERAGE', !settings.USE_ADAPTIVE_LEVERAGE)}
className={`relative inline-flex h-8 w-14 items-center rounded-full transition-colors ${
settings.USE_ADAPTIVE_LEVERAGE ? 'bg-green-500' : 'bg-slate-600'
}`}
>
<span
className={`inline-block h-6 w-6 transform rounded-full bg-white transition-transform ${
settings.USE_ADAPTIVE_LEVERAGE ? 'translate-x-7' : 'translate-x-1'
}`}
/>
</button>
</div>
<Setting
label="High Quality Leverage"
value={settings.HIGH_QUALITY_LEVERAGE}
onChange={(v) => updateSetting('HIGH_QUALITY_LEVERAGE', v)}
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.`}
/>
<Setting
label="Low Quality Leverage"
value={settings.LOW_QUALITY_LEVERAGE}
onChange={(v) => updateSetting('LOW_QUALITY_LEVERAGE', v)}
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.`}
/>
<Setting
label="Quality Threshold"
value={settings.QUALITY_LEVERAGE_THRESHOLD}
onChange={(v) => updateSetting('QUALITY_LEVERAGE_THRESHOLD', v)}
min={80}
max={100}
step={1}
description="Minimum quality score for high-quality leverage tier (applies to LONG signals, SHORT uses 90+)."
/>
<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="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>
</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>
</div>
<div className="flex justify-between">
<span className="text-slate-400">❌ Below Threshold:</span>
<span className="text-red-400 font-bold">Blocked (no trade)</span>
</div>
</div>
</div>
</Section>
{/* Risk Management */} {/* Risk Management */}
<Section title="🛡️ Risk Management" description="Stop loss and take profit levels"> <Section title="🛡️ Risk Management" description="Stop loss and take profit levels">
<Setting <Setting