diff --git a/src/components/trade/order/NewOrder.svelte b/src/components/trade/order/NewOrder.svelte index 664e09c..d13f327 100644 --- a/src/components/trade/order/NewOrder.svelte +++ b/src/components/trade/order/NewOrder.svelte @@ -106,7 +106,10 @@ // $: console.log('$size', $size); let tpProfitPercent, slLossPercent; - let tpPriceInputActive, tpPercentInputActive, slPriceInputActive, slPercentInputActive; + let tpProfitAmount, slLossAmount; + let highlightedTPButton, highlightedSLButton; + let tpPriceInputActive, tpPercentInputActive, tpAmountInputActive, slPriceInputActive, slPercentInputActive, slAmountInputActive; + const tpslPriceButtons = [1, 2, 5]; function setPrice(percentDiff) { if (!$prices[$selectedMarket]) return; @@ -114,6 +117,98 @@ highlightedPriceButton = percentDiff; } + function getReferencePrice() { + const referencePrice = $price * 1 > 0 ? $price * 1 : $prices[$selectedMarket] * 1; + return referencePrice > 0 ? referencePrice : undefined; + } + + function calculateTPPercent(targetPrice) { + const latestPrice = getReferencePrice(); + if (!(targetPrice > 0) || !(latestPrice > 0)) return; + let percent; + if ($isLong) { + percent = 100 * $leverage * (targetPrice - latestPrice) / targetPrice; + } else { + percent = 100 * $leverage * (latestPrice - targetPrice) / targetPrice; + } + return percent > 0 ? formatForDisplay(percent) : undefined; + } + + function calculateSLPercent(targetPrice) { + const latestPrice = getReferencePrice(); + if (!(targetPrice > 0) || !(latestPrice > 0)) return; + let percent; + if ($isLong) { + percent = 100 * $leverage * (latestPrice - targetPrice) / targetPrice; + } else { + percent = 100 * $leverage * (targetPrice - latestPrice) / targetPrice; + } + return percent > 0 ? formatForDisplay(percent) : undefined; + } + + function calculateAmountFromPercent(percent) { + if (!(percent > 0) || !($margin > 0)) return; + return formatForDisplay($margin * percent / 100); + } + + function calculatePercentFromAmount(amount) { + if (!(amount > 0) || !($margin > 0)) return; + return formatForDisplay(100 * amount / $margin); + } + + function calculateTPPriceFromPercent(percent) { + const latestPrice = getReferencePrice(); + if (!latestPrice || !(percent > 0)) return; + if ($isLong) { + return latestPrice + (latestPrice * ((percent / 100) / $leverage)) + } + return latestPrice - (latestPrice * ((percent / 100) / $leverage)) + } + + function calculateSLPriceFromPercent(percent) { + const latestPrice = getReferencePrice(); + if (!latestPrice || !(percent > 0)) return; + if ($isLong) { + return latestPrice - (latestPrice * ((percent / 100) / $leverage)) + } + return latestPrice + (latestPrice * ((percent / 100) / $leverage)) + } + + function updateTPFromPercent() { + const nextPrice = calculateTPPriceFromPercent(tpProfitPercent); + if (nextPrice) { + tpPrice.set(formatForDisplay(nextPrice)); + } + tpProfitAmount = calculateAmountFromPercent(tpProfitPercent); + } + + function updateSLFromPercent() { + const nextPrice = calculateSLPriceFromPercent(slLossPercent); + if (nextPrice) { + slPrice.set(formatForDisplay(nextPrice)); + } + slLossAmount = calculateAmountFromPercent(slLossPercent); + } + + 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); + tpProfitAmount = calculateAmountFromPercent(tpProfitPercent); + highlightedTPButton = percentDiff; + } else { + slPrice.set(formatForDisplay(nextPrice)); + slLossPercent = calculateSLPercent(nextPrice); + slLossAmount = calculateAmountFromPercent(slLossPercent); + highlightedSLButton = percentDiff; + } + } + function resetFieldsOnCheck() { if ($hasTP || $hasSL) { isReduceOnly.set(false); @@ -124,10 +219,14 @@ } if (!$hasTP || $isReduceOnly) { tpProfitPercent = undefined; + tpProfitAmount = undefined; + highlightedTPButton = null; tpPrice.set(); } if (!$hasSL || $isReduceOnly) { slLossPercent = undefined; + slLossAmount = undefined; + highlightedSLButton = null; slPrice.set(); } } @@ -141,6 +240,12 @@ size.set(); tpPrice.set(); slPrice.set(); + tpProfitPercent = undefined; + slLossPercent = undefined; + tpProfitAmount = undefined; + slLossAmount = undefined; + highlightedTPButton = null; + highlightedSLButton = null; showAdvanced = false; hasTrigger.set(false); hasTP.set(false); @@ -154,60 +259,57 @@ 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); + tpProfitAmount = calculateAmountFromPercent(tpProfitPercent); } 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); + slLossAmount = calculateAmountFromPercent(slLossPercent); } } function calculateTPSLFromPercent() { - const latestPrice = $price * 1 > 0 ? $price : $prices[$selectedMarket]; - - let _tpPrice, _slPrice; if (tpProfitPercent > 0 && tpPercentInputActive) { - if ($isLong) { - _tpPrice = latestPrice + (latestPrice * ((tpProfitPercent / 100) / $leverage)) - } else { - _tpPrice = latestPrice - (latestPrice * ((tpProfitPercent / 100) / $leverage)) - } - tpPrice.set(formatForDisplay(_tpPrice)); + highlightedTPButton = null; + updateTPFromPercent(); } if (slLossPercent > 0 && slPercentInputActive) { - if ($isLong) { - _slPrice = latestPrice - (latestPrice * ((slLossPercent / 100) / $leverage)) - } else { - _slPrice = latestPrice + (latestPrice * ((slLossPercent / 100) / $leverage)) - } - slPrice.set(formatForDisplay(_slPrice)); + highlightedSLButton = null; + updateSLFromPercent(); } } - $: calculateTPSLPercentFromPrices($tpPrice, $slPrice); - $: calculateTPSLFromPercent(tpProfitPercent, slLossPercent); + function calculateTPSLFromAmounts() { + if (tpProfitAmount > 0 && tpAmountInputActive) { + highlightedTPButton = null; + tpProfitPercent = calculatePercentFromAmount(tpProfitAmount); + updateTPFromPercent(); + } + if (slLossAmount > 0 && slAmountInputActive) { + highlightedSLButton = null; + slLossPercent = calculatePercentFromAmount(slLossAmount); + updateSLFromPercent(); + } + } + + function syncTPSLAmounts() { + if (!tpAmountInputActive) { + tpProfitAmount = calculateAmountFromPercent(tpProfitPercent); + } + if (!slAmountInputActive) { + slLossAmount = calculateAmountFromPercent(slLossPercent); + } + } + + $: calculateTPSLPercentFromPrices($tpPrice, $slPrice, $price, $prices[$selectedMarket], $leverage, $isLong, $margin); + $: calculateTPSLFromPercent(tpProfitPercent, slLossPercent, $price, $prices[$selectedMarket], $leverage, $isLong, $margin); + $: calculateTPSLFromAmounts(tpProfitAmount, slLossAmount, $margin); + $: syncTPSLAmounts(tpProfitPercent, slLossPercent, $margin); function _focusInput(name, isActive) { if (!isActive) return; @@ -334,6 +436,27 @@ .tpsl-help-button:hover { background-color: var(--layer200); } + .tpsl-buttons { + display: flex; + gap: 8px; + padding-bottom: 8px; + } + .tpsl-buttons button { + 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); + background: transparent; + color: inherit; + } + .tpsl-buttons button:hover, + .tpsl-buttons button.highlighted { + background-color: var(--layer100); + } @@ -392,10 +515,22 @@ {#if $hasTP}
+
+ {#each tpslPriceButtons as percentDiff} + + {/each} +
{tpPriceInputActive = true}} on:blur={() => {tpPriceInputActive = false}} />
- {tpPercentInputActive = true}} on:blur={() => {tpPercentInputActive = false}} /> +
+ {tpPercentInputActive = true}} on:blur={() => {tpPercentInputActive = false}} /> +
+ {tpAmountInputActive = true}} on:blur={() => {tpAmountInputActive = false}} />
@@ -408,10 +543,22 @@ {#if $hasSL}
+
+ {#each tpslPriceButtons as percentDiff} + + {/each} +
{slPriceInputActive = true}} on:blur={() => {slPriceInputActive = false}} />
- {slPercentInputActive = true}} on:blur={() => {slPercentInputActive = false}} /> +
+ {slPercentInputActive = true}} on:blur={() => {slPercentInputActive = false}} /> +
+ {slAmountInputActive = true}} on:blur={() => {slAmountInputActive = false}} />