From adaf1ca9f0bb5336a3b1c46c83c67d7dd9227e71 Mon Sep 17 00:00:00 2001 From: qq33357486 Date: Tue, 12 May 2026 12:54:55 +0800 Subject: [PATCH] Enhance TP/SL order inputs --- src/components/trade/order/NewOrder.svelte | 130 +++++++++++++++++---- 1 file changed, 107 insertions(+), 23 deletions(-) diff --git a/src/components/trade/order/NewOrder.svelte b/src/components/trade/order/NewOrder.svelte index 664e09c..b49fcc5 100644 --- a/src/components/trade/order/NewOrder.svelte +++ b/src/components/trade/order/NewOrder.svelte @@ -106,7 +106,9 @@ // $: console.log('$size', $size); let tpProfitPercent, slLossPercent; + let highlightedTPButton, highlightedSLButton; let tpPriceInputActive, tpPercentInputActive, slPriceInputActive, slPercentInputActive; + const tpslPriceButtons = [1, 2, 5]; function setPrice(percentDiff) { if (!$prices[$selectedMarket]) return; @@ -114,6 +116,56 @@ highlightedPriceButton = percentDiff; } + function getReferencePrice() { + return $price * 1 > 0 ? $price * 1 : $prices[$selectedMarket] * 1; + } + + function calculateTPPercent(targetPrice) { + const latestPrice = getReferencePrice(); + if (!targetPrice || !latestPrice) return; + const percent = $isLong + ? 100 * $leverage * (targetPrice - latestPrice) / targetPrice + : 100 * $leverage * (latestPrice - targetPrice) / targetPrice; + return percent > 0 ? formatForDisplay(percent) : undefined; + } + + function calculateSLPercent(targetPrice) { + const latestPrice = getReferencePrice(); + if (!targetPrice || !latestPrice) return; + const percent = $isLong + ? 100 * $leverage * (latestPrice - targetPrice) / targetPrice + : 100 * $leverage * (targetPrice - latestPrice) / targetPrice; + return percent > 0 ? formatForDisplay(percent) : undefined; + } + + function setTPSLPrice(kind, percentDiff) { + const latestPrice = getReferencePrice(); + if (!latestPrice) return; + const isTakeProfit = kind == 'tp'; + const direction = isTakeProfit == $isLong ? 1 : -1; + const nextPrice = latestPrice * (1 + direction * percentDiff / 100); + if (isTakeProfit) { + tpPrice.set(formatForDisplay(nextPrice)); + tpProfitPercent = calculateTPPercent(nextPrice); + highlightedTPButton = percentDiff; + } else { + slPrice.set(formatForDisplay(nextPrice)); + slLossPercent = calculateSLPercent(nextPrice); + highlightedSLButton = percentDiff; + } + } + + function formatTPSLAmount(percent, isLoss) { + if (!percent || !$margin) return '0'; + const amount = $margin * percent / 100; + return `${isLoss ? '-' : '+'}${formatForDisplay(amount)} ${$selectedAsset}`; + } + + function formatTPSLPercent(percent, isLoss) { + if (!percent) return '0%'; + return `${isLoss ? '-' : ''}${formatForDisplay(percent)}%`; + } + function resetFieldsOnCheck() { if ($hasTP || $hasSL) { isReduceOnly.set(false); @@ -124,10 +176,12 @@ } if (!$hasTP || $isReduceOnly) { tpProfitPercent = undefined; + highlightedTPButton = null; tpPrice.set(); } if (!$hasSL || $isReduceOnly) { slLossPercent = undefined; + highlightedSLButton = null; slPrice.set(); } } @@ -141,6 +195,8 @@ size.set(); tpPrice.set(); slPrice.set(); + highlightedTPButton = null; + highlightedSLButton = null; showAdvanced = false; hasTrigger.set(false); hasTP.set(false); @@ -154,40 +210,23 @@ function calculateTPSLPercentFromPrices() { - const latestPrice = $price * 1 > 0 ? $price : $prices[$selectedMarket]; - if ($tpPrice > 0 && tpPriceInputActive) { - if ($isLong) { - tpProfitPercent = 100 * $leverage * ($tpPrice * 1 - latestPrice * 1) / $tpPrice; - } else { - tpProfitPercent = 100 * $leverage * (latestPrice * 1 - $tpPrice * 1) / $tpPrice; - } - if (tpProfitPercent <= 0) { - tpProfitPercent = undefined; - return; - } - tpProfitPercent = formatForDisplay(tpProfitPercent); + highlightedTPButton = null; + tpProfitPercent = calculateTPPercent($tpPrice * 1); } if ($slPrice > 0 && slPriceInputActive) { - if ($isLong) { - slLossPercent = 100 * $leverage * (latestPrice * 1 - $slPrice * 1) / $slPrice; - } else { - slLossPercent = 100 * $leverage * ($slPrice * 1 - latestPrice * 1) / $slPrice; - } - if (slLossPercent <= 0) { - slLossPercent = undefined; - return; - } - slLossPercent = formatForDisplay(slLossPercent); + highlightedSLButton = null; + slLossPercent = calculateSLPercent($slPrice * 1); } } function calculateTPSLFromPercent() { - const latestPrice = $price * 1 > 0 ? $price : $prices[$selectedMarket]; + const latestPrice = getReferencePrice(); let _tpPrice, _slPrice; if (tpProfitPercent > 0 && tpPercentInputActive) { + highlightedTPButton = null; if ($isLong) { _tpPrice = latestPrice + (latestPrice * ((tpProfitPercent / 100) / $leverage)) } else { @@ -196,6 +235,7 @@ tpPrice.set(formatForDisplay(_tpPrice)); } if (slLossPercent > 0 && slPercentInputActive) { + highlightedSLButton = null; if ($isLong) { _slPrice = latestPrice - (latestPrice * ((slLossPercent / 100) / $leverage)) } else { @@ -334,6 +374,28 @@ .tpsl-help-button:hover { background-color: var(--layer200); } + .tpsl-buttons { + display: flex; + gap: 8px; + padding-bottom: 8px; + } + .tpsl-buttons a { + flex: 1; + text-align: center; + border: 1px solid var(--layer200); + padding: 8px 0; + cursor: pointer; + font-size: 80%; + font-weight: 600; + border-radius: var(--base-radius); + } + .tpsl-buttons a:hover, + .tpsl-buttons a.highlighted { + background-color: var(--layer100); + } + .tpsl-summary { + padding-top: 8px; + } @@ -392,10 +454,21 @@ {#if $hasTP}
+
+ {#each tpslPriceButtons as percentDiff} + setTPSLPrice('tp', percentDiff)} + >+{percentDiff}% + {/each} +
{tpPriceInputActive = true}} on:blur={() => {tpPriceInputActive = false}} />
{tpPercentInputActive = true}} on:blur={() => {tpPercentInputActive = false}} /> +
+ +
@@ -408,10 +481,21 @@ {#if $hasSL}
+
+ {#each tpslPriceButtons as percentDiff} + setTPSLPrice('sl', percentDiff)} + >-{percentDiff}% + {/each} +
{slPriceInputActive = true}} on:blur={() => {slPriceInputActive = false}} />
{slPercentInputActive = true}} on:blur={() => {slPercentInputActive = false}} /> +
+ +