Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trade Panel Enhancements #2798

Merged
merged 4 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import InputTitle from 'components/Input/InputTitle'
import SLTPInputField, { SLTPInputFieldProps } from '../Trade/SLTPInputField'

const EditStopLossAndTakeProfitInput: React.FC<SLTPInputFieldProps> = memo(
({ type, currentPrice, ...props }) => {
({ type, price, ...props }) => {
const { t } = useTranslation()

return (
Expand All @@ -18,16 +18,16 @@ const EditStopLossAndTakeProfitInput: React.FC<SLTPInputFieldProps> = memo(
label={type === 'take-profit' ? 'Take Profit' : 'Stop Loss'}
rightElement={
<StyledInputTitle>
{t('futures.market.trade.edit-sl-tp.last-price')}:{' '}
<span>{formatDollars(currentPrice)}</span>
{t('futures.market.trade.edit-sl-tp.entry-price')}:{' '}
<span>{formatDollars(price)}</span>
</StyledInputTitle>
}
/>

<SLTPInputField
{...props}
type={type}
currentPrice={currentPrice}
price={price}
dataTestId={'trade-panel-stop-loss-input'}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default function EditStopLossAndTakeProfitModal() {
const { t } = useTranslation()
const dispatch = useAppDispatch()
const transactionState = useAppSelector(selectTransaction)
const { market, marketPrice, position } = useAppSelector(selectEditPositionModalInfo)
const { market, position } = useAppSelector(selectEditPositionModalInfo)
const exsistingSLTPOrders = useAppSelector(selectAllSLTPOrders)
const isSubmitting = useAppSelector(selectSubmittingFuturesTx)
const { takeProfitPrice, stopLossPrice } = useAppSelector(selectSlTpModalInputs)
Expand Down Expand Up @@ -114,6 +114,18 @@ export default function EditStopLossAndTakeProfitModal() {
]
)

const entryPriceWei = useMemo(() => {
return position?.activePosition?.details?.entryPrice ?? wei(0)
}, [position?.activePosition?.details?.entryPrice])

const calculateSizeWei = useMemo(() => {
if (!position?.activePosition.size || !entryPriceWei) {
0xlinus marked this conversation as resolved.
Show resolved Hide resolved
return wei(0)
}

return position.activePosition.size.mul(entryPriceWei)
}, [position?.activePosition.size, entryPriceWei])

useEffect(() => {
const existingSL = exsistingSLTPOrders.find(
(o) => o.marketKey === market?.marketKey && o.orderType === ConditionalOrderTypeEnum.STOP
Expand Down Expand Up @@ -147,13 +159,13 @@ export default function EditStopLossAndTakeProfitModal() {
const relativePercent = wei(percent).div(leverageWei)
const stopLoss =
position?.activePosition.side === 'short'
? marketPrice.add(marketPrice.mul(relativePercent))
: marketPrice.sub(marketPrice.mul(relativePercent))
? entryPriceWei.add(entryPriceWei.mul(relativePercent))
: entryPriceWei.sub(entryPriceWei.mul(relativePercent))
const dp = suggestedDecimals(stopLoss)
dispatch(setSLTPModalStopLoss(stopLoss.toString(dp)))
}
},
[marketPrice, dispatch, position?.activePosition.side, leverageWei]
[entryPriceWei, dispatch, position?.activePosition.side, leverageWei]
)

const onSelectTakeProfit = useCallback(
Expand All @@ -166,13 +178,13 @@ export default function EditStopLossAndTakeProfitModal() {
const relativePercent = wei(percent).div(leverageWei)
const takeProfit =
position?.activePosition.side === 'short'
? marketPrice.sub(marketPrice.mul(relativePercent))
: marketPrice.add(marketPrice.mul(relativePercent))
? entryPriceWei.sub(entryPriceWei.mul(relativePercent))
: entryPriceWei.add(entryPriceWei.mul(relativePercent))
const dp = suggestedDecimals(takeProfit)
dispatch(setSLTPModalTakeProfit(takeProfit.toString(dp)))
}
},
[marketPrice, dispatch, position?.activePosition.side, leverageWei]
[entryPriceWei, dispatch, position?.activePosition.side, leverageWei]
)

const onChangeStopLoss = useCallback(
Expand Down Expand Up @@ -220,10 +232,11 @@ export default function EditStopLossAndTakeProfitModal() {
<EditStopLossAndTakeProfitInput
type={'take-profit'}
invalidLabel={sltpValidity.takeProfit.invalidLabel}
currentPrice={marketPrice}
price={entryPriceWei}
value={takeProfitPrice}
positionSide={position?.activePosition.side || PositionSide.LONG}
leverage={position?.activePosition.leverage || wei(1)}
size={calculateSizeWei}
onChange={onChangeTakeProfit}
/>

Expand All @@ -240,8 +253,9 @@ export default function EditStopLossAndTakeProfitModal() {
positionSide={position?.activePosition.side || PositionSide.LONG}
leverage={position?.activePosition.leverage || wei(1)}
invalidLabel={sltpValidity.stopLoss.invalidLabel}
currentPrice={marketPrice}
price={entryPriceWei}
value={stopLossPrice}
size={calculateSizeWei}
onChange={onChangeStopLoss}
/>

Expand Down
9 changes: 6 additions & 3 deletions packages/app/src/sections/futures/Trade/SLTPInputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ export type SLTPInputFieldProps = {
type: 'take-profit' | 'stop-loss'
value: string
invalidLabel: string | undefined
currentPrice: Wei
price: Wei
leverage: Wei
size: Wei
minMaxPrice?: Wei
dataTestId?: string
positionSide: PositionSide
Expand All @@ -27,9 +28,10 @@ const SLTPInputField: React.FC<SLTPInputFieldProps> = memo(
type,
value,
invalidLabel,
currentPrice,
price,
positionSide,
leverage,
size,
dataTestId,
disabledReason,
disabled,
Expand Down Expand Up @@ -59,9 +61,10 @@ const SLTPInputField: React.FC<SLTPInputFieldProps> = memo(
<ShowPercentage
targetPrice={value}
isStopLoss={type === 'stop-loss'}
currentPrice={currentPrice}
price={price}
leverageSide={positionSide}
leverageWei={leverage}
sizeWei={size}
/>
)
}
Expand Down
40 changes: 31 additions & 9 deletions packages/app/src/sections/futures/Trade/SLTPInputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,17 @@ import {
selectLeverageInput,
selectLeverageSide,
selectTradePanelSLTPValidity,
selectTradeSizeInputs,
} from 'state/futures/selectors'
import {
setSmartMarginTradeStopLoss,
setSmartMarginTradeTakeProfit,
} from 'state/futures/smartMargin/reducer'
import { selectSlTpTradeInputs } from 'state/futures/smartMargin/selectors'
import {
selectOrderType,
selectSlTpTradeInputs,
selectSmartMarginOrderPrice,
} from 'state/futures/smartMargin/selectors'
import { useAppDispatch, useAppSelector } from 'state/hooks'

import OrderAcknowledgement from './OrderAcknowledgement'
Expand All @@ -39,6 +44,9 @@ export default function SLTPInputs() {
const leverage = useAppSelector(selectLeverageInput)
const hideWarning = useAppSelector(selectAckedOrdersWarning)
const sltpValidity = useSelector(selectTradePanelSLTPValidity)
const { susdSize } = useAppSelector(selectTradeSizeInputs)
const orderType = useAppSelector(selectOrderType)
const orderPrice = useAppSelector(selectSmartMarginOrderPrice)

const [showInputs, setShowInputs] = useState(false)
const [showOrderWarning, setShowOrderWarning] = useState(false)
Expand All @@ -56,19 +64,31 @@ export default function SLTPInputs() {
return leverage && Number(leverage) > 0 ? wei(leverage) : wei(1)
}, [leverage])

const price = useMemo(() => {
switch (orderType) {
case 'market':
return currentPrice
case 'limit':
case 'stop_market':
return orderPrice ? wei(orderPrice) : currentPrice
default:
return currentPrice
}
}, [orderPrice, orderType, currentPrice])

const onSelectStopLossPercent = useCallback(
(index: number) => {
const option = SL_OPTIONS[index]
const percent = Math.abs(Number(option.replace('%', ''))) / 100
const relativePercent = wei(percent).div(leverageWei)
const stopLoss =
leverageSide === 'short'
? currentPrice.add(currentPrice.mul(relativePercent))
: currentPrice.sub(currentPrice.mul(relativePercent))
? price.add(price.mul(relativePercent))
: price.sub(price.mul(relativePercent))
const dp = suggestedDecimals(stopLoss)
dispatch(setSmartMarginTradeStopLoss(stopLoss.toString(dp)))
},
[currentPrice, dispatch, leverageSide, leverageWei]
[dispatch, leverageSide, leverageWei, price]
)

const onSelectTakeProfit = useCallback(
Expand All @@ -78,12 +98,12 @@ export default function SLTPInputs() {
const relativePercent = wei(percent).div(leverageWei)
const takeProfit =
leverageSide === 'short'
? currentPrice.sub(currentPrice.mul(relativePercent))
: currentPrice.add(currentPrice.mul(relativePercent))
? price.sub(price.mul(relativePercent))
: price.add(price.mul(relativePercent))
const dp = suggestedDecimals(takeProfit)
dispatch(setSmartMarginTradeTakeProfit(takeProfit.toString(dp)))
},
[currentPrice, dispatch, leverageSide, leverageWei]
[dispatch, leverageSide, leverageWei, price]
)

const onChangeStopLoss = useCallback(
Expand Down Expand Up @@ -133,11 +153,12 @@ export default function SLTPInputs() {
invalidLabel={sltpValidity.takeProfit.invalidLabel}
value={takeProfitPrice}
type={'take-profit'}
currentPrice={currentPrice}
price={price}
positionSide={leverageSide}
leverage={leverageWei}
dataTestId={'trade-panel-take-profit-input'}
onChange={onChangeTakeProfit}
size={susdSize}
/>

<Spacer height={12} />
Expand All @@ -153,11 +174,12 @@ export default function SLTPInputs() {
invalidLabel={sltpValidity.stopLoss.invalidLabel}
value={stopLossPrice}
type={'stop-loss'}
currentPrice={currentPrice}
price={price}
positionSide={leverageSide}
leverage={leverageWei}
dataTestId={'trade-panel-stop-loss-input'}
onChange={onChangeStopLoss}
size={susdSize}
/>
</InputsContainer>
)
Expand Down
38 changes: 27 additions & 11 deletions packages/app/src/sections/futures/Trade/ShowPercentage.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,61 @@
import { PositionSide } from '@kwenta/sdk/types'
import { formatPercent } from '@kwenta/sdk/utils'
import { formatPercent, formatDollars } from '@kwenta/sdk/utils'
import Wei, { wei } from '@synthetixio/wei'
import { useMemo } from 'react'
import styled from 'styled-components'

import { Body } from 'components/Text'

type ShowPercentageProps = {
targetPrice: string
isStopLoss?: boolean
currentPrice: Wei
price: Wei
leverageSide: PositionSide | string | undefined
leverageWei: Wei
sizeWei: Wei
}

const ShowPercentage: React.FC<ShowPercentageProps> = ({
targetPrice,
isStopLoss = false,
currentPrice,
price,
leverageSide,
leverageWei,
sizeWei,
}) => {
const calculatePercentage = useMemo(() => {
if (!targetPrice || !currentPrice || !leverageSide) return ''
const [calculatePercentage, calculatePL] = useMemo(() => {
if (!targetPrice || !price || !leverageSide || !sizeWei) return ''
const priceWei = wei(targetPrice)

const diff =
leverageSide === 'short'
? isStopLoss
? priceWei.sub(currentPrice)
: currentPrice.sub(priceWei)
? priceWei.sub(price)
: price.sub(priceWei)
: isStopLoss
? currentPrice.sub(priceWei)
: priceWei.sub(currentPrice)
? price.sub(priceWei)
: priceWei.sub(price)

const percentage = diff.div(price).mul(leverageWei)
const profitLoss = sizeWei.mul(percentage.div(leverageWei)).mul(isStopLoss ? -1 : 1)

return formatPercent(diff.div(currentPrice).mul(leverageWei))
}, [currentPrice, isStopLoss, leverageSide, leverageWei, targetPrice])
return [formatPercent(percentage), formatDollars(profitLoss, { sign: isStopLoss ? '' : '+' })]
}, [price, isStopLoss, leverageSide, leverageWei, targetPrice, sizeWei])

return (
<Body size="large" mono>
<ProfitLoss isStopLoss={isStopLoss}>{calculatePL}</ProfitLoss>
{calculatePercentage}
</Body>
)
}

const ProfitLoss = styled.span<{ isStopLoss: boolean }>`
margin-right: 0.7rem;
color: ${({ theme, isStopLoss }) =>
isStopLoss
? theme.colors.selectedTheme.newTheme.text.negative
: theme.colors.selectedTheme.newTheme.text.positive};
`

export default ShowPercentage
2 changes: 1 addition & 1 deletion packages/app/src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,7 @@
"no-tp": "No TP",
"no-sl": "No SL",
"stop-loss": "Stop Loss",
"last-price": "Last Price",
"entry-price": "Entry Price",
"estimated-profit": "Estimated Profit",
"estimated-loss": "Estimated Loss",
"warning": "This setting applies to the entire position."
Expand Down