From b3a5ab022db86f5e5d2f7c5820e9bb55105858a7 Mon Sep 17 00:00:00 2001 From: Joe Tsang <30622993+jtsang586@users.noreply.github.com> Date: Tue, 26 Sep 2023 10:44:55 +0100 Subject: [PATCH 1/7] chore(ci): update genesis file (#4887) --- vegacapsule/genesis.tmpl | 1 + 1 file changed, 1 insertion(+) diff --git a/vegacapsule/genesis.tmpl b/vegacapsule/genesis.tmpl index 692bd7efc..c4a6e60e8 100644 --- a/vegacapsule/genesis.tmpl +++ b/vegacapsule/genesis.tmpl @@ -195,6 +195,7 @@ "market.fee.factors.makerFee": "0.004", "market.liquidity.stakeToCcyVolume": "0.3", "market.liquidity.targetstake.triggering.ratio": "0.7", + "market.liquidity.providersFeeCalculationTimeStep": "5s", "network.checkpoint.timeElapsedBetweenCheckpoints": "10s", "reward.asset": "{{.GetVegaContractID "VEGA"}}", "reward.staking.delegation.competitionLevel": "3.1", From cd5c73d3fdb906426a212a9088e7900ca2f36715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Szpiech?= Date: Tue, 26 Sep 2023 11:45:27 +0200 Subject: [PATCH 2/7] chore(trading): temporary disable console-test to unblock CI queue (#4885) --- .github/workflows/ci-cd-trigger.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci-cd-trigger.yml b/.github/workflows/ci-cd-trigger.yml index 565dceb8c..2fb441e24 100644 --- a/.github/workflows/ci-cd-trigger.yml +++ b/.github/workflows/ci-cd-trigger.yml @@ -175,14 +175,14 @@ jobs: preview_explorer: ${{ env.PREVIEW_EXPLORER }} preview_tools: ${{ env.PREVIEW_TOOLS }} - console-e2e: - needs: build-sources - name: '(CI) console python' - uses: ./.github/workflows/console-test-run.yml - secrets: inherit - if: ${{ contains(fromJSON(needs.build-sources.outputs.projects), 'trading') && github.event_name == 'pull_request' }} - with: - github-sha: ${{ github.event.pull_request.head.sha || github.sha }} + # console-e2e: + # needs: build-sources + # name: '(CI) console python' + # uses: ./.github/workflows/console-test-run.yml + # secrets: inherit + # if: ${{ contains(fromJSON(needs.build-sources.outputs.projects), 'trading') && github.event_name == 'pull_request' }} + # with: + # github-sha: ${{ github.event.pull_request.head.sha || github.sha }} cypress: needs: build-sources From 89b3c061071dce143f76c871cca3ffb3e0a82d6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20G=C5=82ownia?= Date: Tue, 26 Sep 2023 17:53:45 +0200 Subject: [PATCH 3/7] feat(deal-ticket): show worst case instead of ranges in estimated values (#4870) --- .../deal-ticket/deal-ticket-fee-details.tsx | 31 ++++++++++--------- .../components/deal-ticket/deal-ticket.tsx | 1 + 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx b/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx index 74289f8b8..e554b0c65 100644 --- a/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx +++ b/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx @@ -12,6 +12,7 @@ import { formatRange, formatValue } from '@vegaprotocol/utils'; import { marketMarginDataProvider } from '@vegaprotocol/accounts'; import { useDataProvider } from '@vegaprotocol/data-provider'; import * as AccordionPrimitive from '@radix-ui/react-accordion'; +import * as Schema from '@vegaprotocol/types'; import { MARGIN_DIFF_TOOLTIP_TEXT, @@ -87,6 +88,7 @@ export interface DealTicketMarginDetailsProps { onMarketClick?: (marketId: string, metaKey?: boolean) => void; assetSymbol: string; positionEstimate: EstimatePositionQuery['estimatePosition']; + side: Schema.Side; } export const DealTicketMarginDetails = ({ @@ -96,6 +98,7 @@ export const DealTicketMarginDetails = ({ market, onMarketClick, positionEstimate, + side, }: DealTicketMarginDetailsProps) => { const [breakdownDialog, setBreakdownDialog] = useState(false); const { pubKey: partyId } = useVegaWallet(); @@ -165,10 +168,7 @@ export const DealTicketMarginDetails = ({ : '0', assetDecimals )} - formattedValue={formatRange( - deductionFromCollateralBestCase > 0 - ? deductionFromCollateralBestCase.toString() - : '0', + formattedValue={formatValue( deductionFromCollateralWorstCase > 0 ? deductionFromCollateralWorstCase.toString() : '0', @@ -187,8 +187,7 @@ export const DealTicketMarginDetails = ({ marginEstimate?.worstCase.initialLevel, assetDecimals )} - formattedValue={formatRange( - marginEstimate?.bestCase.initialLevel, + formattedValue={formatValue( marginEstimate?.worstCase.initialLevel, assetDecimals, quantum @@ -200,6 +199,7 @@ export const DealTicketMarginDetails = ({ } let liquidationPriceEstimate = emptyValue; + let liquidationPriceEstimateRange = emptyValue; if (liquidationEstimate) { const liquidationEstimateBestCaseIncludingBuyOrders = BigInt( @@ -209,8 +209,7 @@ export const DealTicketMarginDetails = ({ liquidationEstimate.bestCase.including_sell_orders.replace(/\..*/, '') ); const liquidationEstimateBestCase = - liquidationEstimateBestCaseIncludingBuyOrders > - liquidationEstimateBestCaseIncludingSellOrders + side === Schema.Side.SIDE_BUY ? liquidationEstimateBestCaseIncludingBuyOrders : liquidationEstimateBestCaseIncludingSellOrders; @@ -221,14 +220,19 @@ export const DealTicketMarginDetails = ({ liquidationEstimate.worstCase.including_sell_orders.replace(/\..*/, '') ); const liquidationEstimateWorstCase = - liquidationEstimateWorstCaseIncludingBuyOrders > - liquidationEstimateWorstCaseIncludingSellOrders + side === Schema.Side.SIDE_BUY ? liquidationEstimateWorstCaseIncludingBuyOrders : liquidationEstimateWorstCaseIncludingSellOrders; // The estimate order query API gives us the liquidation price in formatted by asset decimals. // We need to calculate it with asset decimals, but display it with market decimals precision until the API changes. - liquidationPriceEstimate = formatRange( + liquidationPriceEstimate = formatValue( + liquidationEstimateWorstCase.toString(), + assetDecimals, + undefined, + market.decimalPlaces + ); + liquidationPriceEstimateRange = formatRange( (liquidationEstimateBestCase < liquidationEstimateWorstCase ? liquidationEstimateBestCase : liquidationEstimateWorstCase @@ -287,8 +291,7 @@ export const DealTicketMarginDetails = ({ noUnderline >
- {formatRange( - marginRequiredBestCase, + {formatValue( marginRequiredWorstCase, assetDecimals, quantum @@ -346,7 +349,7 @@ export const DealTicketMarginDetails = ({ {projectedMargin} Date: Tue, 26 Sep 2023 11:54:42 -0400 Subject: [PATCH 4/7] fix(market-depth): ensure scroll bar doesn't show on orderbook (#4882) --- libs/market-depth/src/lib/orderbook.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/market-depth/src/lib/orderbook.tsx b/libs/market-depth/src/lib/orderbook.tsx index 8d4878817..0691487d3 100644 --- a/libs/market-depth/src/lib/orderbook.tsx +++ b/libs/market-depth/src/lib/orderbook.tsx @@ -175,7 +175,7 @@ export const Orderbook = ({ ); return ( -
+
{({ width, height }) => { From 8a9b1c787412213f0488f846a19cdb6257911e8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20G=C5=82ownia?= Date: Tue, 26 Sep 2023 17:57:47 +0200 Subject: [PATCH 5/7] feat(deal-ticket): amend fee estimates for postOnly orders and when market is in auction (#4843) --- .../deal-ticket/deal-ticket-fee-details.tsx | 6 +- .../components/deal-ticket/deal-ticket.tsx | 8 +- .../src/hooks/use-estimate-fees.spec.tsx | 78 +++++++++++++++++++ .../src/hooks/use-estimate-fees.tsx | 36 +++++++-- .../fees-breakdown/fees-breakdown.tsx | 1 + libs/markets/src/lib/get-price.ts | 2 +- 6 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 libs/deal-ticket/src/hooks/use-estimate-fees.spec.tsx diff --git a/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx b/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx index e554b0c65..153882158 100644 --- a/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx +++ b/libs/deal-ticket/src/components/deal-ticket/deal-ticket-fee-details.tsx @@ -38,14 +38,16 @@ export interface DealTicketFeeDetailsProps { assetSymbol: string; order: OrderSubmissionBody['orderSubmission']; market: Market; + isMarketInAuction?: boolean; } export const DealTicketFeeDetails = ({ assetSymbol, order, market, + isMarketInAuction, }: DealTicketFeeDetailsProps) => { - const feeEstimate = useEstimateFees(order); + const feeEstimate = useEstimateFees(order, isMarketInAuction); const { settlementAsset: asset } = market.tradableInstrument.instrument.product; const { decimals: assetDecimals, quantum } = asset; @@ -65,7 +67,7 @@ export const DealTicketFeeDetails = ({ <> {t( - `An estimate of the most you would be expected to pay in fees, in the market's settlement asset ${assetSymbol}.` + `An estimate of the most you would be expected to pay in fees, in the market's settlement asset ${assetSymbol}. Fees estimated are "taker" fees and will only be payable if the order trades aggressively. Rebate equal to the maker portion will be paid to the trader if the order trades passively.` )} { const size = storedFormValues?.[dealTicketType]?.size; @@ -211,6 +212,7 @@ export const DealTicket = ({ size: rawSize, timeInForce, type, + postOnly, }, market.id, market.decimalPlaces, @@ -219,8 +221,7 @@ export const DealTicket = ({ const price = normalizedOrder && - marketPrice && - getDerivedPrice(normalizedOrder, marketPrice); + getDerivedPrice(normalizedOrder, marketPrice ?? undefined); const notionalSize = getNotionalSize( price, @@ -474,6 +475,7 @@ export const DealTicket = ({ } assetSymbol={assetSymbol} market={market} + isMarketInAuction={isMarketInAuction(marketData.marketTradingMode)} />
({ + data, +})); + +jest.mock('./__generated__/EstimateOrder', () => ({ + ...jest.requireActual('@vegaprotocol/data-provider'), + useEstimateFeesQuery: jest.fn((...args) => mockUseEstimateFeesQuery(...args)), +})); + +jest.mock('@vegaprotocol/wallet', () => ({ + useVegaWallet: () => ({ pubKey: 'pubKey' }), +})); + +describe('useEstimateFees', () => { + it('returns 0 as estimated values if order is postOnly', () => { + const { result } = renderHook(() => + useEstimateFees({ + marketId: 'marketId', + side: Side.SIDE_BUY, + size: '1', + price: '1', + timeInForce: OrderTimeInForce.TIME_IN_FORCE_FOK, + type: OrderType.TYPE_LIMIT, + postOnly: true, + }) + ); + expect(result.current).toEqual({ + totalFeeAmount: '0', + fees: { + infrastructureFee: '0', + liquidityFee: '0', + makerFee: '0', + }, + }); + expect(mockUseEstimateFeesQuery.mock.lastCall?.[0].skip).toBeTruthy(); + }); + + it('divide values by 2 if market is in auction', () => { + const { result } = renderHook(() => + useEstimateFees( + { + marketId: 'marketId', + side: Side.SIDE_BUY, + size: '1', + price: '1', + timeInForce: OrderTimeInForce.TIME_IN_FORCE_FOK, + type: OrderType.TYPE_LIMIT, + }, + true + ) + ); + expect(result.current).toEqual({ + totalFeeAmount: '6', + fees: { + infrastructureFee: '1', + liquidityFee: '2', + makerFee: '3', + }, + }); + }); +}); diff --git a/libs/deal-ticket/src/hooks/use-estimate-fees.tsx b/libs/deal-ticket/src/hooks/use-estimate-fees.tsx index 9ad2b0b5a..1d83415fd 100644 --- a/libs/deal-ticket/src/hooks/use-estimate-fees.tsx +++ b/libs/deal-ticket/src/hooks/use-estimate-fees.tsx @@ -1,13 +1,16 @@ import { useVegaWallet } from '@vegaprotocol/wallet'; import type { OrderSubmissionBody } from '@vegaprotocol/wallet'; +import type { EstimateFeesQuery } from './__generated__/EstimateOrder'; import { useEstimateFeesQuery } from './__generated__/EstimateOrder'; -export const useEstimateFees = ( - order?: OrderSubmissionBody['orderSubmission'] -) => { - const { pubKey } = useVegaWallet(); +const divideByTwo = (n: string) => (BigInt(n) / BigInt(2)).toString(); +export const useEstimateFees = ( + order?: OrderSubmissionBody['orderSubmission'], + isMarketInAuction?: boolean +): EstimateFeesQuery['estimateFees'] | undefined => { + const { pubKey } = useVegaWallet(); const { data } = useEstimateFeesQuery({ variables: order && { marketId: order.marketId, @@ -19,7 +22,28 @@ export const useEstimateFees = ( type: order.type, }, fetchPolicy: 'no-cache', - skip: !pubKey || !order?.size || !order?.price, + skip: !pubKey || !order?.size || !order?.price || order.postOnly, }); - return data?.estimateFees; + if (order?.postOnly) { + return { + totalFeeAmount: '0', + fees: { + infrastructureFee: '0', + liquidityFee: '0', + makerFee: '0', + }, + }; + } + return isMarketInAuction && data?.estimateFees + ? { + totalFeeAmount: divideByTwo(data.estimateFees.totalFeeAmount), + fees: { + infrastructureFee: divideByTwo( + data.estimateFees.fees.infrastructureFee + ), + liquidityFee: divideByTwo(data.estimateFees.fees.liquidityFee), + makerFee: divideByTwo(data.estimateFees.fees.makerFee), + }, + } + : data?.estimateFees; }; diff --git a/libs/markets/src/lib/components/fees-breakdown/fees-breakdown.tsx b/libs/markets/src/lib/components/fees-breakdown/fees-breakdown.tsx index 8b600db14..a7890a3fc 100644 --- a/libs/markets/src/lib/components/fees-breakdown/fees-breakdown.tsx +++ b/libs/markets/src/lib/components/fees-breakdown/fees-breakdown.tsx @@ -60,6 +60,7 @@ export const FeesBreakdown = ({ .plus(fees.infrastructureFee) .plus(fees.liquidityFee) .toString(); + if (totalFees === '0') return null; const formatValue = (value: string | number | null | undefined): string => { return value && !isNaN(Number(value)) ? addDecimalsFormatNumber(value, decimals) diff --git a/libs/markets/src/lib/get-price.ts b/libs/markets/src/lib/get-price.ts index 763acbfcf..e93b3e248 100644 --- a/libs/markets/src/lib/get-price.ts +++ b/libs/markets/src/lib/get-price.ts @@ -33,7 +33,7 @@ export const getDerivedPrice = ( type: Schema.OrderType; price?: string | undefined; }, - marketPrice: string + marketPrice?: string ) => { // If order type is market we should use either the mark price // or the uncrossing price. If order type is limit use the price From bb402c02f6f12a251329333e3811224010fa496b Mon Sep 17 00:00:00 2001 From: Matthew Russell Date: Tue, 26 Sep 2023 12:08:12 -0400 Subject: [PATCH 6/7] chore(trading): make volume bars color match candle color (#4881) --- apps/trading/pages/styles.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/trading/pages/styles.css b/apps/trading/pages/styles.css index 0a98f72aa..88db4c68f 100644 --- a/apps/trading/pages/styles.css +++ b/apps/trading/pages/styles.css @@ -110,8 +110,8 @@ html [data-theme='light'] { --pennant-color-depth-sell-fill: theme(colors.market.red.DEFAULT); --pennant-color-depth-sell-stroke: theme(colors.market.red.650); - --pennant-color-volume-buy: theme(colors.market.green.300); - --pennant-color-volume-sell: theme(colors.market.red.300); + --pennant-color-volume-buy: theme(colors.market.green.DEFAULT); + --pennant-color-volume-sell: theme(colors.market.red.DEFAULT); } html [data-theme='dark'] { @@ -132,7 +132,7 @@ html [data-theme='dark'] { --pennant-color-depth-sell-stroke: theme(colors.market.red.DEFAULT); --pennant-color-volume-buy: theme(colors.market.green.600); - --pennant-color-volume-sell: theme(colors.market.red.650); + --pennant-color-volume-sell: theme(colors.market.red.DEFAULT); } /** From d78de10855a93c1ebc985d84d70752d83c50392e Mon Sep 17 00:00:00 2001 From: Maciek Date: Tue, 26 Sep 2023 19:45:33 +0200 Subject: [PATCH 7/7] chore(trading): remove underlines on tooltips (#4884) --- apps/trading/components/header/header.tsx | 2 +- .../deal-ticket/deal-ticket-fee-details.tsx | 1 - .../src/components/deal-ticket/key-value.tsx | 2 +- .../src/components/tooltip/tooltip.tsx | 16 ++++++++-------- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/apps/trading/components/header/header.tsx b/apps/trading/components/header/header.tsx index 58207e1b5..6ff4d50ee 100644 --- a/apps/trading/components/header/header.tsx +++ b/apps/trading/components/header/header.tsx @@ -53,7 +53,7 @@ export const HeaderStat = ({
{heading}
- +
{formatValue( diff --git a/libs/deal-ticket/src/components/deal-ticket/key-value.tsx b/libs/deal-ticket/src/components/deal-ticket/key-value.tsx index 5d5e9c934..e287461f5 100644 --- a/libs/deal-ticket/src/components/deal-ticket/key-value.tsx +++ b/libs/deal-ticket/src/components/deal-ticket/key-value.tsx @@ -47,7 +47,7 @@ export const KeyValue = ({
{label}
- + {valueElement}
diff --git a/libs/ui-toolkit/src/components/tooltip/tooltip.tsx b/libs/ui-toolkit/src/components/tooltip/tooltip.tsx index 1b3d8f30c..769301c84 100644 --- a/libs/ui-toolkit/src/components/tooltip/tooltip.tsx +++ b/libs/ui-toolkit/src/components/tooltip/tooltip.tsx @@ -19,14 +19,14 @@ export interface TooltipProps { align?: 'start' | 'center' | 'end'; side?: 'top' | 'right' | 'bottom' | 'left'; sideOffset?: number; - noUnderline?: boolean; + underline?: boolean; } -export const TOOLTIP_TRIGGER_CLASS_NAME = (noUnderline?: boolean) => - classNames( - { 'underline underline-offset-2': !noUnderline }, - 'decoration-neutral-400 dark:decoration-neutral-400 decoration-dashed' - ); +export const TOOLTIP_TRIGGER_CLASS_NAME = (underline?: boolean) => + classNames({ + 'underline underline-offset-2 decoration-neutral-400 dark:decoration-neutral-400 decoration-dashed': + underline, + }); // Conditionally rendered tooltip if description content is provided. export const Tooltip = ({ @@ -36,12 +36,12 @@ export const Tooltip = ({ sideOffset, align = 'start', side = 'bottom', - noUnderline, + underline, }: TooltipProps) => description ? ( - + {children} {description && (