From 8ce51dddbc8a259f44eb54c5b79555bc854b4fb8 Mon Sep 17 00:00:00 2001 From: "m.ray" <16125548+MadalinaRaicu@users.noreply.github.com> Date: Thu, 21 Jul 2022 11:57:30 +0200 Subject: [PATCH] Feat/625 market info more details - open interest, liquidity info, market and instrument ids, price and settlement asset in the header - Part 1 (#823) * fix: #625 update the info market query with new fields * fix: #625 generate code for info market query and fix pagination being removed from globalTypes * fix: add id and filter no trading auctions * fix: add id and format labels * fix: add name and code to instrument * fix: add name and code to instrument * fix: format check * feat: add settlement asset and mark price * feat: add liquidity parameters * fix: remove settings.json * fix: price instead of mark price label * fix: add instrument metadata * fix: remove unused set lodash * fix: move Liquidity monitoring parameters after price monitoring * fix: rename instrument metadata to metadata * fix: settlement asset could be undefined * Merge branch 'master' of github.com:vegaprotocol/frontend-monorepo into feat/625-market-info-more-details-open-interest-liquidity-ids-risk * fix: format market id and trading mode label in key details * fix: display settlement asset if defined * fix: format trade-grid.tsx --- .../trading/pages/markets/[marketId].page.tsx | 10 ++ .../pages/markets/__generated__/Market.ts | 32 +++++ apps/trading/pages/markets/trade-grid.tsx | 31 ++++- .../__generated__/MarketInfoQuery.ts | 124 +++++++++++++++++- .../src/components/info-market.tsx | 109 ++++++++++++--- .../__generated__/MarketList.ts | 6 +- .../markets-data-provider.ts | 1 + .../src/lib/utils/market-list.utils.ts | 8 +- .../components/order-list/order-list.spec.tsx | 8 +- .../lib/components/order-list/order-list.tsx | 9 +- libs/types/src/__generated__/index.ts | 1 + libs/types/src/index.ts | 2 +- .../vega-transaction-dialog.tsx | 9 +- 13 files changed, 317 insertions(+), 33 deletions(-) create mode 100644 libs/types/src/__generated__/index.ts diff --git a/apps/trading/pages/markets/[marketId].page.tsx b/apps/trading/pages/markets/[marketId].page.tsx index 9b27255ea..7f56ad4b8 100644 --- a/apps/trading/pages/markets/[marketId].page.tsx +++ b/apps/trading/pages/markets/[marketId].page.tsx @@ -41,6 +41,16 @@ const MARKET_QUERY = gql` metadata { tags } + product { + ... on Future { + quoteName + settlementAsset { + id + symbol + name + } + } + } } } marketTimestamps { diff --git a/apps/trading/pages/markets/__generated__/Market.ts b/apps/trading/pages/markets/__generated__/Market.ts index 8394d1307..cf1a57310 100644 --- a/apps/trading/pages/markets/__generated__/Market.ts +++ b/apps/trading/pages/markets/__generated__/Market.ts @@ -61,6 +61,34 @@ export interface Market_market_tradableInstrument_instrument_metadata { tags: string[] | null; } +export interface Market_market_tradableInstrument_instrument_product_settlementAsset { + __typename: "Asset"; + /** + * The id of the asset + */ + id: string; + /** + * The symbol of the asset (e.g: GBP) + */ + symbol: string; + /** + * The full name of the asset (e.g: Great British Pound) + */ + name: string; +} + +export interface Market_market_tradableInstrument_instrument_product { + __typename: "Future"; + /** + * String representing the quote (e.g. BTCUSD -> USD is quote) + */ + quoteName: string; + /** + * The name of the asset (string) + */ + settlementAsset: Market_market_tradableInstrument_instrument_product_settlementAsset; +} + export interface Market_market_tradableInstrument_instrument { __typename: "Instrument"; /** @@ -75,6 +103,10 @@ export interface Market_market_tradableInstrument_instrument { * Metadata for this instrument */ metadata: Market_market_tradableInstrument_instrument_metadata; + /** + * A reference to or instance of a fully specified product, including all required product parameters for that product (Product union) + */ + product: Market_market_tradableInstrument_instrument_product; } export interface Market_market_tradableInstrument { diff --git a/apps/trading/pages/markets/trade-grid.tsx b/apps/trading/pages/markets/trade-grid.tsx index ec9c38be0..adf274aa9 100644 --- a/apps/trading/pages/markets/trade-grid.tsx +++ b/apps/trading/pages/markets/trade-grid.tsx @@ -85,14 +85,14 @@ export const TradeMarketHeader = ({ className="flex flex-auto items-start gap-64 overflow-x-auto whitespace-nowrap" >
- Change (24h) + {t('Change (24h)')}
- Volume + {t('Volume')} {market.data && market.data.indicativeVolume !== '0' ? addDecimalsFormatNumber( @@ -103,7 +103,7 @@ export const TradeMarketHeader = ({
- Trading mode + {t('Trading mode')} {market.tradingMode === MarketTradingMode.MonitoringAuction && market.data?.trigger && @@ -114,6 +114,29 @@ export const TradeMarketHeader = ({ : formatLabel(market.tradingMode)}
+
+ {t('Price')} + + {market.data && market.data.markPrice !== '0' + ? addDecimalsFormatNumber( + market.data.markPrice, + market.decimalPlaces + ) + : '-'} + +
+ {market.tradableInstrument.instrument.product?.settlementAsset + ?.symbol && ( +
+ {t('Settlement asset')} + + { + market.tradableInstrument.instrument.product?.settlementAsset + ?.symbol + } + +
+ )} @@ -159,7 +182,7 @@ export const TradeGrid = ({ market }: TradeGridProps) => { - + diff --git a/libs/deal-ticket/src/components/__generated__/MarketInfoQuery.ts b/libs/deal-ticket/src/components/__generated__/MarketInfoQuery.ts index c45bd414a..a029d366f 100644 --- a/libs/deal-ticket/src/components/__generated__/MarketInfoQuery.ts +++ b/libs/deal-ticket/src/components/__generated__/MarketInfoQuery.ts @@ -3,12 +3,36 @@ // @generated // This file was automatically generated and should not be edited. -import { MarketState, MarketTradingMode } from "@vegaprotocol/types"; +import { MarketState, MarketTradingMode, AccountType } from "@vegaprotocol/types"; // ==================================================== // GraphQL query operation: MarketInfoQuery // ==================================================== +export interface MarketInfoQuery_market_accounts_asset { + __typename: "Asset"; + /** + * The id of the asset + */ + id: string; +} + +export interface MarketInfoQuery_market_accounts { + __typename: "Account"; + /** + * Account type (General, Margin, etc) + */ + type: AccountType; + /** + * Asset, the 'currency' + */ + asset: MarketInfoQuery_market_accounts_asset; + /** + * Balance as string - current account balance (approx. as balances can be updated several times per second) + */ + balance: string; +} + export interface MarketInfoQuery_market_fees_factors { __typename: "FeeFactors"; /** @@ -125,6 +149,42 @@ export interface MarketInfoQuery_market_data { * the aggregated volume being offered at the best static offer price, excluding pegged orders. */ bestStaticOfferVolume: string; + /** + * the sum of the size of all positions greater than 0. + */ + openInterest: string; +} + +export interface MarketInfoQuery_market_liquidityMonitoringParameters_targetStakeParameters { + __typename: "TargetStakeParameters"; + /** + * Specifies length of time window expressed in seconds for target stake calculation + */ + timeWindow: number; + /** + * Specifies scaling factors used in target stake calculation + */ + scalingFactor: number; +} + +export interface MarketInfoQuery_market_liquidityMonitoringParameters { + __typename: "LiquidityMonitoringParameters"; + /** + * Specifies the triggering ratio for entering liquidity auction + */ + triggeringRatio: number; + /** + * Specifies parameters related to target stake calculation + */ + targetStakeParameters: MarketInfoQuery_market_liquidityMonitoringParameters_targetStakeParameters; +} + +export interface MarketInfoQuery_market_tradableInstrument_instrument_metadata { + __typename: "InstrumentMetadata"; + /** + * An arbitrary list of tags to associated to associate to the Instrument (string list) + */ + tags: string[] | null; } export interface MarketInfoQuery_market_tradableInstrument_instrument_product_settlementAsset { @@ -143,6 +203,28 @@ export interface MarketInfoQuery_market_tradableInstrument_instrument_product_se name: string; } +export interface MarketInfoQuery_market_tradableInstrument_instrument_product_oracleSpecForSettlementPrice { + __typename: "OracleSpec"; + /** + * id is a hash generated from the OracleSpec data. + */ + id: string; +} + +export interface MarketInfoQuery_market_tradableInstrument_instrument_product_oracleSpecForTradingTermination { + __typename: "OracleSpec"; + /** + * id is a hash generated from the OracleSpec data. + */ + id: string; +} + +export interface MarketInfoQuery_market_tradableInstrument_instrument_product_oracleSpecBinding { + __typename: "OracleSpecToFutureBinding"; + settlementPriceProperty: string; + tradingTerminationProperty: string; +} + export interface MarketInfoQuery_market_tradableInstrument_instrument_product { __typename: "Future"; /** @@ -153,10 +235,38 @@ export interface MarketInfoQuery_market_tradableInstrument_instrument_product { * The name of the asset (string) */ settlementAsset: MarketInfoQuery_market_tradableInstrument_instrument_product_settlementAsset; + /** + * The oracle spec describing the oracle data of interest for settlement price. + */ + oracleSpecForSettlementPrice: MarketInfoQuery_market_tradableInstrument_instrument_product_oracleSpecForSettlementPrice; + /** + * The oracle spec describing the oracle data of interest for trading termination. + */ + oracleSpecForTradingTermination: MarketInfoQuery_market_tradableInstrument_instrument_product_oracleSpecForTradingTermination; + /** + * The binding between the oracle spec and the settlement price + */ + oracleSpecBinding: MarketInfoQuery_market_tradableInstrument_instrument_product_oracleSpecBinding; } export interface MarketInfoQuery_market_tradableInstrument_instrument { __typename: "Instrument"; + /** + * Uniquely identify an instrument across all instruments available on Vega (string) + */ + id: string; + /** + * Full and fairly descriptive name for the instrument + */ + name: string; + /** + * A short non necessarily unique code used to easily describe the instrument (e.g: FX:BTCUSD/DEC18) (string) + */ + code: string; + /** + * Metadata for this instrument + */ + metadata: MarketInfoQuery_market_tradableInstrument_instrument_metadata; /** * A reference to or instance of a fully specified product, including all required product parameters for that product (Product union) */ @@ -258,14 +368,14 @@ export interface MarketInfoQuery_market { /** * decimalPlaces indicates the number of decimal places that an integer must be shifted by in order to get a correct * number denominated in the currency of the Market. (uint64) - * + * * Examples: * Currency Balance decimalPlaces Real Balance * GBP 100 0 GBP 100 * GBP 100 2 GBP 1.00 * GBP 100 4 GBP 0.01 * GBP 1 4 GBP 0.0001 ( 0.01p ) - * + * * GBX (pence) 100 0 GBP 1.00 (100p ) * GBX (pence) 100 2 GBP 0.01 ( 1p ) * GBX (pence) 100 4 GBP 0.0001 ( 0.01p ) @@ -286,6 +396,10 @@ export interface MarketInfoQuery_market { * Current mode of execution of the market */ tradingMode: MarketTradingMode; + /** + * Get account for a party or market + */ + accounts: MarketInfoQuery_market_accounts[] | null; /** * Fees related data */ @@ -302,6 +416,10 @@ export interface MarketInfoQuery_market { * marketData for the given market */ data: MarketInfoQuery_market_data | null; + /** + * Liquidity monitoring parameters for the market + */ + liquidityMonitoringParameters: MarketInfoQuery_market_liquidityMonitoringParameters; /** * An instance of or reference to a tradable instrument. */ diff --git a/libs/deal-ticket/src/components/info-market.tsx b/libs/deal-ticket/src/components/info-market.tsx index e749fd630..45cabc56c 100644 --- a/libs/deal-ticket/src/components/info-market.tsx +++ b/libs/deal-ticket/src/components/info-market.tsx @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { addDecimalsFormatNumber, + formatLabel, formatNumber, formatNumberPercentage, t, @@ -15,10 +16,7 @@ import { import startCase from 'lodash/startCase'; import pick from 'lodash/pick'; import omit from 'lodash/omit'; -import type { - MarketInfoQuery, - MarketInfoQuery_market, -} from './__generated__/MarketInfoQuery'; +import type { MarketInfoQuery, MarketInfoQuery_market } from './__generated__'; import BigNumber from 'bignumber.js'; import { gql, useQuery } from '@apollo/client'; @@ -31,6 +29,13 @@ const MARKET_INFO_QUERY = gql` positionDecimalPlaces state tradingMode + accounts { + type + asset { + id + } + balance + } fees { factors { makerFee @@ -53,6 +58,13 @@ const MARKET_INFO_QUERY = gql` short long } + accounts { + type + asset { + id + } + balance + } data { market { id @@ -64,9 +76,23 @@ const MARKET_INFO_QUERY = gql` bestStaticBidVolume bestStaticOfferVolume indicativeVolume + openInterest + } + liquidityMonitoringParameters { + triggeringRatio + targetStakeParameters { + timeWindow + scalingFactor + } } tradableInstrument { instrument { + id + name + code + metadata { + tags + } product { ... on Future { quoteName @@ -75,6 +101,16 @@ const MARKET_INFO_QUERY = gql` symbol name } + oracleSpecForSettlementPrice { + id + } + oracleSpecForTradingTermination { + id + } + oracleSpecBinding { + settlementPriceProperty + tradingTerminationProperty + } } } } @@ -159,19 +195,28 @@ export const Info = ({ market }: InfoProps) => { ), }, ]; + + const keyDetails = pick( + market, + 'name', + 'decimalPlaces', + 'positionDecimalPlaces', + 'tradingMode', + 'state', + 'id' as 'marketId' + ); const marketSpecPanels = [ { title: t('Key details'), content: ( ), }, @@ -180,8 +225,28 @@ export const Info = ({ market }: InfoProps) => { content: ( + ), + }, + { + title: t('Metadata'), + content: ( + { + const [key, value] = tag.split(':'); + return { [key]: value }; + }) + .reduce((acc, curr) => ({ ...acc, ...curr }), {}), }} /> ), @@ -212,6 +277,18 @@ export const Info = ({ market }: InfoProps) => { content: , }) ), + { + title: t('Liquidity monitoring parameters'), + content: ( + + ), + }, ]; return ( @@ -261,7 +338,7 @@ const Row = ({ ? decimalPlaces ? addDecimalsFormatNumber(value, decimalPlaces) : asPercentage - ? formatNumberPercentage(new BigNumber(value)) + ? formatNumberPercentage(new BigNumber(value * 100)) : formatNumber(Number(value)) : value} @@ -283,7 +360,7 @@ export const MarketInfoTable = ({ decimalPlaces, asPercentage, unformatted, - omits = ['id', '__typename'], + omits = ['__typename'], }: MarketInfoTableProps) => { return ( diff --git a/libs/market-list/src/lib/components/markets-container/__generated__/MarketList.ts b/libs/market-list/src/lib/components/markets-container/__generated__/MarketList.ts index e5bdaaee7..ba2894224 100644 --- a/libs/market-list/src/lib/components/markets-container/__generated__/MarketList.ts +++ b/libs/market-list/src/lib/components/markets-container/__generated__/MarketList.ts @@ -3,7 +3,7 @@ // @generated // This file was automatically generated and should not be edited. -import { Interval, MarketState } from "@vegaprotocol/types"; +import { Interval, MarketState, MarketTradingMode } from "@vegaprotocol/types"; // ==================================================== // GraphQL query operation: MarketList @@ -112,6 +112,10 @@ export interface MarketList_markets { * Current state of the market */ state: MarketState; + /** + * Current mode of execution of the market + */ + tradingMode: MarketTradingMode; /** * marketData for the given market */ diff --git a/libs/market-list/src/lib/components/markets-container/markets-data-provider.ts b/libs/market-list/src/lib/components/markets-container/markets-data-provider.ts index 32121c091..b8ac8c99f 100644 --- a/libs/market-list/src/lib/components/markets-container/markets-data-provider.ts +++ b/libs/market-list/src/lib/components/markets-container/markets-data-provider.ts @@ -54,6 +54,7 @@ export const MARKET_LIST_QUERY = gql` id decimalPlaces state + tradingMode data { market { id diff --git a/libs/market-list/src/lib/utils/market-list.utils.ts b/libs/market-list/src/lib/utils/market-list.utils.ts index 7a04d36d1..7b3ce4790 100644 --- a/libs/market-list/src/lib/utils/market-list.utils.ts +++ b/libs/market-list/src/lib/utils/market-list.utils.ts @@ -1,4 +1,4 @@ -import { MarketState } from '@vegaprotocol/types'; +import { MarketState, MarketTradingMode } from '@vegaprotocol/types'; import orderBy from 'lodash/orderBy'; import type { MarketList, @@ -13,7 +13,11 @@ export const lastPrice = ({ candles }: MarketList_markets) => export const mapDataToMarketList = ({ markets }: MarketList) => orderBy( markets - ?.filter((m) => m.state !== MarketState.Rejected) + ?.filter( + (m) => + m.state !== MarketState.Rejected && + m.tradingMode !== MarketTradingMode.NoTrading + ) .map((m) => { return { id: m.id, diff --git a/libs/orders/src/lib/components/order-list/order-list.spec.tsx b/libs/orders/src/lib/components/order-list/order-list.spec.tsx index 8a3635c72..4ab543b4f 100644 --- a/libs/orders/src/lib/components/order-list/order-list.spec.tsx +++ b/libs/orders/src/lib/components/order-list/order-list.spec.tsx @@ -1,5 +1,9 @@ import { act, render, screen } from '@testing-library/react'; -import { addDecimal, getDateTimeFormat } from '@vegaprotocol/react-helpers'; +import { + addDecimal, + formatLabel, + getDateTimeFormat, +} from '@vegaprotocol/react-helpers'; import type { Orders_party_orders } from '../__generated__/Orders'; import { OrderStatus, OrderRejectionReason } from '@vegaprotocol/types'; import { OrderListTable } from './order-list'; @@ -118,7 +122,7 @@ describe('OrderListTable', () => { }); const cells = screen.getAllByRole('gridcell'); expect(cells[3]).toHaveTextContent( - `${rejectedOrder.status}: ${rejectedOrder.rejectionReason}` + `${rejectedOrder.status}: ${formatLabel(rejectedOrder.rejectionReason)}` ); }); }); diff --git a/libs/orders/src/lib/components/order-list/order-list.tsx b/libs/orders/src/lib/components/order-list/order-list.tsx index 4af3e103f..6cc16a331 100644 --- a/libs/orders/src/lib/components/order-list/order-list.tsx +++ b/libs/orders/src/lib/components/order-list/order-list.tsx @@ -1,6 +1,11 @@ import { OrderTimeInForce, OrderStatus, Side } from '@vegaprotocol/types'; import type { Orders_party_orders } from '../__generated__/Orders'; -import { addDecimal, getDateTimeFormat, t } from '@vegaprotocol/react-helpers'; +import { + addDecimal, + formatLabel, + getDateTimeFormat, + t, +} from '@vegaprotocol/react-helpers'; import { AgGridDynamic as AgGrid, Button } from '@vegaprotocol/ui-toolkit'; import type { ICellRendererParams, @@ -139,7 +144,7 @@ export const OrderListTable = forwardRef( field="status" valueFormatter={({ value, data }: ValueFormatterParams) => { if (value === OrderStatus.Rejected) { - return `${value}: ${data.rejectionReason}`; + return `${value}: ${formatLabel(data.rejectionReason)}`; } return value; diff --git a/libs/types/src/__generated__/index.ts b/libs/types/src/__generated__/index.ts new file mode 100644 index 000000000..1eba4846b --- /dev/null +++ b/libs/types/src/__generated__/index.ts @@ -0,0 +1 @@ +export * from './globalTypes'; diff --git a/libs/types/src/index.ts b/libs/types/src/index.ts index e13521c83..f01cb9e4c 100644 --- a/libs/types/src/index.ts +++ b/libs/types/src/index.ts @@ -1,3 +1,3 @@ -export * from './__generated__/globalTypes'; +export * from './__generated__'; export * from './candle'; export * from './pagination'; diff --git a/libs/wallet/src/vega-transaction-dialog/vega-transaction-dialog.tsx b/libs/wallet/src/vega-transaction-dialog/vega-transaction-dialog.tsx index c9298b102..7f142d263 100644 --- a/libs/wallet/src/vega-transaction-dialog/vega-transaction-dialog.tsx +++ b/libs/wallet/src/vega-transaction-dialog/vega-transaction-dialog.tsx @@ -4,7 +4,11 @@ import type { VegaTxState } from '../use-vega-transaction'; import { VegaTxStatus } from '../use-vega-transaction'; import { Icon, Loader } from '@vegaprotocol/ui-toolkit'; import type { ReactNode } from 'react'; -import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers'; +import { + addDecimalsFormatNumber, + formatLabel, + t, +} from '@vegaprotocol/react-helpers'; import { useEnvironment } from '@vegaprotocol/environment'; import { OrderType } from '@vegaprotocol/types'; import type { Order } from '../wallet-types'; @@ -169,7 +173,8 @@ export const VegaDialog = ({ icon={} >

- {t(`Reason: ${finalizedOrder.rejectionReason}`)} + {finalizedOrder.rejectionReason && + t(`Reason: ${formatLabel(finalizedOrder.rejectionReason)}`)}

);