diff --git a/apps/simple-trading-app-e2e/src/integration/market-trade.test.ts b/apps/simple-trading-app-e2e/src/integration/market-trade.test.ts index 08defc3fa..f121ece58 100644 --- a/apps/simple-trading-app-e2e/src/integration/market-trade.test.ts +++ b/apps/simple-trading-app-e2e/src/integration/market-trade.test.ts @@ -152,26 +152,68 @@ describe('Market trade', () => { } }); + it('notional position size should be present', () => { + if (markets?.length) { + cy.visit(`/trading/${markets[1].id}`); + connectVegaWallet(); + cy.get('#step-1-control [aria-label^="Selected value"]').click(); + cy.get('button[aria-label="Open short position"]').click(); + cy.get('#step-2-control').click(); + cy.get('#step-2-panel') + .find('dd') + .eq(0) + .find('button') + .should('have.text', '1'); + cy.get('#step-2-panel').find('dd').eq(0).find('button').click(); + cy.get('#step-2-panel') + .find('dd') + .eq(0) + .find('input') + .type('{backspace}2'); + cy.get('#step-2-panel').find('dd').eq(0).find('button').click(); + cy.get('#step-2-panel') + .find('dt') + .eq(2) + .should('have.text', 'Est. Position Size (tDAI)'); + cy.get('#step-2-panel').find('dd').eq(2).should('have.text', '197.86012'); + } + }); + + it('total fees should be displayed', () => { + if (markets?.length) { + cy.visit(`/trading/${markets[1].id}`); + connectVegaWallet(); + cy.get('#step-1-control [aria-label^="Selected value"]').click(); + cy.get('button[aria-label="Open short position"]').click(); + cy.get('#step-2-control').click(); + cy.get('#step-2-panel') + .find('dt') + .eq(3) + .should('have.text', 'Est. Fees (tDAI)'); + cy.get('#step-2-panel') + .find('dd') + .eq(3) + .should('have.text', '3.00000 (3.03%)'); + } + }); + it('order review should display proper calculations', () => { if (markets?.length) { cy.visit(`/trading/${markets[0].id}`); connectVegaWallet(); cy.get('h3').contains('Review Trade').click(); - cy.getByTestId('key-value-table') - .find('dl') - .eq(1) - .find('dd div') - .should('have.text', '25.78726'); - cy.getByTestId('key-value-table') - .find('dl') - .eq(2) - .find('dd div') - .should('have.text', '1.00000'); - cy.getByTestId('key-value-table') - .find('dl') + + cy.get('#step-3-panel').find('dd').eq(1).should('have.text', '1'); + + cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006'); + + cy.get('#step-3-panel') + .find('dd') .eq(3) - .find('dd div') - .should('have.text', ' - '); + .should('have.text', '3.00000 (3.03%)'); + + cy.get('#step-3-panel').find('dd').eq(4).should('have.text', ' - '); + cy.getByTestId('place-order').click(); cy.getByTestId('dialog-title').should( 'have.text', diff --git a/apps/simple-trading-app-e2e/src/support/mocks/generate-estimate-order.ts b/apps/simple-trading-app-e2e/src/support/mocks/generate-estimate-order.ts index f7ee51bc1..e0dfd0d23 100644 --- a/apps/simple-trading-app-e2e/src/support/mocks/generate-estimate-order.ts +++ b/apps/simple-trading-app-e2e/src/support/mocks/generate-estimate-order.ts @@ -1,7 +1,12 @@ export const generateEstimateOrder = () => { return { estimateOrder: { - totalFeeAmount: '16085.09240212.7380425.46', + fee: { + __typename: 'TradeFee', + makerFee: '100000', + liquidityFee: '100000', + infrastructureFee: '100000', + }, marginLevels: { initialLevel: '2844054.80937741220203', __typename: 'MarginLevels', diff --git a/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-estimates.tsx b/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-estimates.tsx new file mode 100644 index 000000000..2453ed869 --- /dev/null +++ b/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-estimates.tsx @@ -0,0 +1,78 @@ +import React from 'react'; +import type { ReactNode } from 'react'; +import { t } from '@vegaprotocol/react-helpers'; + +interface DealTicketEstimatesProps { + quoteName?: string; + price?: string; + estCloseOut?: string; + estMargin?: string; + fees?: string; + notionalSize?: string; + size?: string; +} + +interface DataTitleProps { + children: ReactNode; + quoteName?: string; +} + +const DataTitle = ({ children, quoteName = '' }: DataTitleProps) => ( +
+ {children} + {quoteName && ({quoteName})} +
+); + +export const DealTicketEstimates = ({ + price, + quoteName, + estCloseOut, + estMargin, + fees, + notionalSize, + size, +}: DealTicketEstimatesProps) => ( +
+ {size && ( +
+ {t('No. of Contracts')} +
{size}
+
+ )} + {price && ( +
+ {t('Est. Price')} +
{price}
+
+ )} + {notionalSize && ( +
+ {t('Est. Position Size')} +
{notionalSize}
+
+ )} + {fees && ( +
+ {t('Est. Fees')} +
{fees}
+
+ )} + {estMargin && ( +
+ {t('Est. Margin')} +
{estMargin}
+
+ )} + {estCloseOut && ( +
+
+ {t('Est. Close out')} +   + ({quoteName}) +
+
{estCloseOut}
+
+ )} +
+); diff --git a/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-size.tsx b/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-size.tsx index cc5c9ce64..35a2171fb 100644 --- a/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-size.tsx +++ b/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-size.tsx @@ -10,6 +10,7 @@ import { FormGroup, } from '@vegaprotocol/ui-toolkit'; import { BigNumber } from 'bignumber.js'; +import { DealTicketEstimates } from './deal-ticket-estimates'; interface DealTicketSizeProps { step: number; @@ -22,7 +23,9 @@ interface DealTicketSizeProps { price: string; estCloseOut: string; estMargin: string; + fees: string; positionDecimalPlaces: number; + notionalSize: string; } const getSizeLabel = (value: number): string => { @@ -47,6 +50,8 @@ export const DealTicketSize = ({ onValueChange, estCloseOut, positionDecimalPlaces, + fees, + notionalSize, }: DealTicketSizeProps) => { const sizeRatios = [0, 25, 50, 75, 100]; const [inputValue, setInputValue] = useState(value); @@ -142,11 +147,7 @@ export const DealTicketSize = ({
-
- {t('Size')} -   - ({quoteName}) -
+
{t('Contracts')}
-
-
{t('Est. price')}
-
{price}
-
-
-
{t('Est. close out')}
-
{estCloseOut}
-
+ ); }; diff --git a/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-steps.tsx b/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-steps.tsx index 80c3cfd57..452c83a31 100644 --- a/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-steps.tsx +++ b/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-steps.tsx @@ -72,6 +72,14 @@ export const DealTicketSteps = ({ market, partyId: keypair?.pub || '', }); + const value = new BigNumber(orderSize).toNumber(); + const price = + market.depth.lastTrade && + addDecimal(market.depth.lastTrade.price, market.decimalPlaces); + const emptyString = ' - '; + + const [notionalSize, setNotionalSize] = useState(null); + const [fees, setFees] = useState(null); const maxTrade = useMaximumPositionSize({ partyId: keypair?.pub || '', @@ -112,6 +120,28 @@ export const DealTicketSteps = ({ } }; + useEffect(() => { + if (market?.depth?.lastTrade?.price) { + const size = new BigNumber(market.depth.lastTrade.price) + .multipliedBy(value) + .toNumber(); + + setNotionalSize(addDecimal(size, market.decimalPlaces)); + } + }, [market, value]); + + useEffect(() => { + if (estMargin?.fees && notionalSize) { + const percentage = new BigNumber(estMargin?.fees) + .dividedBy(notionalSize) + .multipliedBy(100) + .decimalPlaces(2) + .toString(); + + setFees(`${estMargin.fees} (${percentage}%)`); + } + }, [estMargin, notionalSize]); + const transactionStatus = transaction.status === VegaTxStatus.Requested || transaction.status === VegaTxStatus.Pending @@ -163,15 +193,16 @@ export const DealTicketSteps = ({ onValueChange={onSizeChange} value={new BigNumber(orderSize).toNumber()} name="size" - price={ - market.depth.lastTrade - ? addDecimal(market.depth.lastTrade.price, market.decimalPlaces) - : '' - } + price={price || emptyString} positionDecimalPlaces={market.positionDecimalPlaces} - quoteName={market.tradableInstrument.instrument.product.quoteName} + quoteName={ + market.tradableInstrument.instrument.product.settlementAsset + .symbol + } + notionalSize={notionalSize || emptyString} estCloseOut={estCloseOut} - estMargin={estMargin || ' - '} + fees={fees || emptyString} + estMargin={estMargin?.margin || emptyString} /> ) : ( 'loading...' @@ -193,7 +224,14 @@ export const DealTicketSteps = ({ transactionStatus={transactionStatus} order={order} estCloseOut={estCloseOut} - estMargin={estMargin || ' - '} + estMargin={estMargin?.margin || emptyString} + price={price || emptyString} + quoteName={ + market.tradableInstrument.instrument.product.settlementAsset + .symbol + } + notionalSize={notionalSize || emptyString} + fees={fees || emptyString} /> { const { data: tagsData } = useQuery( MARKET_TAGS_QUERY, @@ -88,41 +94,20 @@ export default ({
- @{' '} - {market.depth.lastTrade - ? addDecimal(market.depth.lastTrade.price, market.decimalPlaces) - : ' - '}{' '} + {`@ ${price} `} (EST)
- - <>{t('Est. margin')} -
- {estMargin} - -
-
- - <> - {t('Size')}{' '} -
- ({market.tradableInstrument.instrument.product.quoteName}) -
- -
- {formatNumber(order.size, market.decimalPlaces)} - -
-
- - <>{t('Est. close out')} -
- {estCloseOut} - -
-
+ +