feat: Add customizable TP size percentages and fix settings save
**New Features:** - Added TAKE_PROFIT_1_SIZE_PERCENT (default: 50%) - Added TAKE_PROFIT_2_SIZE_PERCENT (default: 50%) - Users can now control WHAT % to close at each TP level - Risk calculator now shows actual TP sizes dynamically **Bug Fixes:** - Fixed settings save failure by mounting .env file to container - Added .env volume mount in docker-compose.yml - Fixed permission issues (.env must be chmod 666) **UI Changes:** - Split TP controls into Price % and Size % - TP1 Price: When to exit first partial - TP1 Size: What % of position to close (1-100%) - TP2 Price: When to exit second partial - TP2 Size: What % of remaining to close (1-100%) - Risk calculator displays dynamic percentages **Example:** - TP1 at +1% price, close 60% of position - TP2 at +2% price, close 40% of remaining (24% of original) - Total exit: 84% of position at TP levels
This commit is contained in:
@@ -13,7 +13,9 @@ interface TradingSettings {
|
||||
LEVERAGE: number
|
||||
STOP_LOSS_PERCENT: number
|
||||
TAKE_PROFIT_1_PERCENT: number
|
||||
TAKE_PROFIT_1_SIZE_PERCENT: number
|
||||
TAKE_PROFIT_2_PERCENT: number
|
||||
TAKE_PROFIT_2_SIZE_PERCENT: number
|
||||
EMERGENCY_STOP_PERCENT: number
|
||||
BREAKEVEN_TRIGGER_PERCENT: number
|
||||
PROFIT_LOCK_TRIGGER_PERCENT: number
|
||||
@@ -96,9 +98,9 @@ export default function SettingsPage() {
|
||||
const calculateRisk = () => {
|
||||
if (!settings) return null
|
||||
const maxLoss = settings.MAX_POSITION_SIZE_USD * settings.LEVERAGE * (Math.abs(settings.STOP_LOSS_PERCENT) / 100)
|
||||
const tp1Gain = settings.MAX_POSITION_SIZE_USD * settings.LEVERAGE * (settings.TAKE_PROFIT_1_PERCENT / 100)
|
||||
const tp2Gain = settings.MAX_POSITION_SIZE_USD * settings.LEVERAGE * (settings.TAKE_PROFIT_2_PERCENT / 100)
|
||||
const fullWin = tp1Gain / 2 + tp2Gain / 2 // 50% at each TP
|
||||
const tp1Gain = settings.MAX_POSITION_SIZE_USD * settings.LEVERAGE * (settings.TAKE_PROFIT_1_PERCENT / 100) * (settings.TAKE_PROFIT_1_SIZE_PERCENT / 100)
|
||||
const tp2Gain = settings.MAX_POSITION_SIZE_USD * settings.LEVERAGE * (settings.TAKE_PROFIT_2_PERCENT / 100) * (settings.TAKE_PROFIT_2_SIZE_PERCENT / 100)
|
||||
const fullWin = tp1Gain + tp2Gain
|
||||
|
||||
return { maxLoss, tp1Gain, tp2Gain, fullWin }
|
||||
}
|
||||
@@ -143,12 +145,12 @@ export default function SettingsPage() {
|
||||
<div className="text-white text-2xl font-bold">-${risk.maxLoss.toFixed(2)}</div>
|
||||
</div>
|
||||
<div className="bg-blue-500/10 border border-blue-500/50 rounded-lg p-4">
|
||||
<div className="text-blue-400 text-sm mb-1">TP1 Gain (50%)</div>
|
||||
<div className="text-white text-2xl font-bold">+${(risk.tp1Gain / 2).toFixed(2)}</div>
|
||||
<div className="text-blue-400 text-sm mb-1">TP1 Gain ({settings.TAKE_PROFIT_1_SIZE_PERCENT}%)</div>
|
||||
<div className="text-white text-2xl font-bold">+${risk.tp1Gain.toFixed(2)}</div>
|
||||
</div>
|
||||
<div className="bg-green-500/10 border border-green-500/50 rounded-lg p-4">
|
||||
<div className="text-green-400 text-sm mb-1">TP2 Gain (50%)</div>
|
||||
<div className="text-white text-2xl font-bold">+${(risk.tp2Gain / 2).toFixed(2)}</div>
|
||||
<div className="text-green-400 text-sm mb-1">TP2 Gain ({settings.TAKE_PROFIT_2_SIZE_PERCENT}%)</div>
|
||||
<div className="text-white text-2xl font-bold">+${risk.tp2Gain.toFixed(2)}</div>
|
||||
</div>
|
||||
<div className="bg-purple-500/10 border border-purple-500/50 rounded-lg p-4">
|
||||
<div className="text-purple-400 text-sm mb-1">Full Win</div>
|
||||
@@ -197,22 +199,40 @@ export default function SettingsPage() {
|
||||
description="Close 100% of position when price drops this much. Protects from large losses."
|
||||
/>
|
||||
<Setting
|
||||
label="Take Profit 1 (%)"
|
||||
label="Take Profit 1 Price (%)"
|
||||
value={settings.TAKE_PROFIT_1_PERCENT}
|
||||
onChange={(v) => updateSetting('TAKE_PROFIT_1_PERCENT', v)}
|
||||
min={0.1}
|
||||
max={10}
|
||||
step={0.1}
|
||||
description="Close 50% of position at this profit level. Locks in early gains."
|
||||
description="Price level for first take profit exit."
|
||||
/>
|
||||
<Setting
|
||||
label="Take Profit 2 (%)"
|
||||
label="Take Profit 1 Size (%)"
|
||||
value={settings.TAKE_PROFIT_1_SIZE_PERCENT}
|
||||
onChange={(v) => updateSetting('TAKE_PROFIT_1_SIZE_PERCENT', v)}
|
||||
min={1}
|
||||
max={100}
|
||||
step={1}
|
||||
description="What % of position to close at TP1. Example: 50 = close half."
|
||||
/>
|
||||
<Setting
|
||||
label="Take Profit 2 Price (%)"
|
||||
value={settings.TAKE_PROFIT_2_PERCENT}
|
||||
onChange={(v) => updateSetting('TAKE_PROFIT_2_PERCENT', v)}
|
||||
min={0.1}
|
||||
max={20}
|
||||
step={0.1}
|
||||
description="Close remaining 50% at this profit level. Captures larger moves."
|
||||
description="Price level for second take profit exit."
|
||||
/>
|
||||
<Setting
|
||||
label="Take Profit 2 Size (%)"
|
||||
value={settings.TAKE_PROFIT_2_SIZE_PERCENT}
|
||||
onChange={(v) => updateSetting('TAKE_PROFIT_2_SIZE_PERCENT', v)}
|
||||
min={1}
|
||||
max={100}
|
||||
step={1}
|
||||
description="What % of remaining position to close at TP2. Example: 100 = close rest."
|
||||
/>
|
||||
<Setting
|
||||
label="Emergency Stop (%)"
|
||||
|
||||
Reference in New Issue
Block a user