diff --git a/apps/trading-e2e/src/integration/closed-markets.cy.ts b/apps/trading-e2e/src/integration/closed-markets.cy.ts index 38c06d951..c5f913f6b 100644 --- a/apps/trading-e2e/src/integration/closed-markets.cy.ts +++ b/apps/trading-e2e/src/integration/closed-markets.cy.ts @@ -5,10 +5,12 @@ import { assetsQuery, chainIdQuery, statisticsQuery, - closedMarketsQuery, - createClosedMarket, createDataConnection, oracleSpecDataConnectionQuery, + createMarketFragment, + marketsQuery, + marketsDataQuery, + createMarketsDataFragment, } from '@vegaprotocol/mock'; import { networkParamsQuery } from '@vegaprotocol/mock'; import { @@ -24,8 +26,9 @@ describe('Closed markets', { tags: '@smoke' }, () => { // @ts-ignore asset definitely exists const settlementAsset = assetsResult.assetsConnection.edges[0].node; - const settledMarket = createClosedMarket({ + const settledMarket = createMarketFragment({ id: '0', + state: MarketState.STATE_SETTLED, marketTimestamps: { open: subDays(new Date(), 10).toISOString(), close: subDays(new Date(), 4).toISOString(), @@ -45,7 +48,7 @@ describe('Closed markets', { tags: '@smoke' }, () => { }, }); - const terminatedMarket = createClosedMarket({ + const terminatedMarket = createMarketFragment({ id: '1', state: MarketState.STATE_TRADING_TERMINATED, marketTimestamps: { @@ -63,7 +66,7 @@ describe('Closed markets', { tags: '@smoke' }, () => { }, }); - const delayedSettledMarket = createClosedMarket({ + const delayedSettledMarket = createMarketFragment({ id: '2', state: MarketState.STATE_TRADING_TERMINATED, marketTimestamps: { @@ -81,7 +84,10 @@ describe('Closed markets', { tags: '@smoke' }, () => { }, }); - const unknownMarket = createClosedMarket({ id: '3' }); + const unknownMarket = createMarketFragment({ + id: '3', + state: MarketState.STATE_SETTLED, + }); const closedMarketsResult = [ { @@ -94,8 +100,56 @@ describe('Closed markets', { tags: '@smoke' }, () => { node: delayedSettledMarket, }, { node: unknownMarket }, - { node: createClosedMarket({ id: '4', state: MarketState.STATE_PENDING }) }, - { node: createClosedMarket({ id: '5', state: MarketState.STATE_ACTIVE }) }, + { + node: createMarketFragment({ id: '4', state: MarketState.STATE_PENDING }), + }, + { + node: createMarketFragment({ id: '5', state: MarketState.STATE_ACTIVE }), + }, + ]; + + const settledMarketData = createMarketsDataFragment({ + market: { + id: settledMarket.id, + }, + bestBidPrice: '1000', + bestOfferPrice: '2000', + markPrice: '1500', + }); + + const closedMarketsDataResult = [ + { + node: { + data: settledMarketData, + }, + }, + { + node: { + data: createMarketsDataFragment({ + market: { + id: terminatedMarket.id, + }, + }), + }, + }, + { + node: { + data: createMarketsDataFragment({ + market: { + id: delayedSettledMarket.id, + }, + }), + }, + }, + { + node: { + data: createMarketsDataFragment({ + market: { + id: unknownMarket.id, + }, + }), + }, + }, ]; const specDataConnection = createDataConnection(); @@ -108,13 +162,22 @@ describe('Closed markets', { tags: '@smoke' }, () => { aliasGQLQuery(req, 'Assets', assetsResult); aliasGQLQuery( req, - 'ClosedMarkets', - closedMarketsQuery({ + 'Markets', + marketsQuery({ marketsConnection: { edges: closedMarketsResult, }, }) ); + aliasGQLQuery( + req, + 'MarketsData', + marketsDataQuery({ + marketsConnection: { + edges: closedMarketsDataResult, + }, + }) + ); aliasGQLQuery( req, 'OracleSpecDataConnection', @@ -192,7 +255,7 @@ describe('Closed markets', { tags: '@smoke' }, () => { .should( 'have.text', addDecimalsFormatNumber( - settledMarket.data.bestBidPrice, + settledMarketData.bestBidPrice, settledMarket.decimalPlaces ) ); @@ -204,7 +267,7 @@ describe('Closed markets', { tags: '@smoke' }, () => { .should( 'have.text', addDecimalsFormatNumber( - settledMarket.data.bestOfferPrice, + settledMarketData.bestOfferPrice, settledMarket.decimalPlaces ) ); @@ -214,7 +277,7 @@ describe('Closed markets', { tags: '@smoke' }, () => { 'have.text', addDecimalsFormatNumber( - settledMarket.data.markPrice, + settledMarketData.markPrice, settledMarket.decimalPlaces ) ); diff --git a/apps/trading/client-pages/markets/closed.tsx b/apps/trading/client-pages/markets/closed.tsx index ead629f6b..c22a39dd5 100644 --- a/apps/trading/client-pages/markets/closed.tsx +++ b/apps/trading/client-pages/markets/closed.tsx @@ -13,13 +13,17 @@ import { getMarketExpiryDate, } from '@vegaprotocol/utils'; import { usePositionsQuery } from '@vegaprotocol/positions'; -import type { ClosedMarketFragment } from '@vegaprotocol/market-list'; -import { useClosedMarketsQuery } from '@vegaprotocol/market-list'; +import type { MarketMaybeWithData } from '@vegaprotocol/market-list'; +import { closedMarketsWithDataProvider } from '@vegaprotocol/market-list'; import { useVegaWallet } from '@vegaprotocol/wallet'; import { useAssetDetailsDialogStore } from '@vegaprotocol/assets'; import type { ColDef } from 'ag-grid-community'; import { SettlementDateCell } from './settlement-date-cell'; import { SettlementPriceCell } from './settlement-price-cell'; +import { useDataProvider } from '@vegaprotocol/react-helpers'; + +type SettlementAsset = + MarketMaybeWithData['tradableInstrument']['instrument']['product']['settlementAsset']; interface Row { id: string; @@ -35,13 +39,16 @@ interface Row { settlementDataOracleId: string; settlementDataSpecBinding: string; tradingTerminationOracleId: string; - settlementAsset: ClosedMarketFragment['tradableInstrument']['instrument']['product']['settlementAsset']; + settlementAsset: SettlementAsset; realisedPNL: string | undefined; } export const Closed = () => { const { pubKey } = useVegaWallet(); - const { data: marketData } = useClosedMarketsQuery(); + const { data: marketData } = useDataProvider({ + dataProvider: closedMarketsWithDataProvider, + variables: undefined, + }); const { data: positionData } = usePositionsQuery({ variables: { partyId: pubKey || '', @@ -51,48 +58,40 @@ export const Closed = () => { // find a position for each market and add the realised pnl to // a normalized object - const rowData = compact(marketData?.marketsConnection?.edges) - .map((edge) => edge.node) - .map((market) => { - const position = positionData?.party?.positionsConnection?.edges?.find( - (edge) => { - return edge.node.market.id === market.id; - } - ); + const rowData = compact(marketData).map((market) => { + const position = positionData?.party?.positionsConnection?.edges?.find( + (edge) => { + return edge.node.market.id === market.id; + } + ); - const row: Row = { - id: market.id, - code: market.tradableInstrument.instrument.code, - name: market.tradableInstrument.instrument.name, - decimalPlaces: market.decimalPlaces, - state: market.state, - metadata: market.tradableInstrument.instrument.metadata.tags ?? [], - closeTimestamp: market.marketTimestamps.close, - bestBidPrice: market.data?.bestBidPrice, - bestOfferPrice: market.data?.bestOfferPrice, - markPrice: market.data?.markPrice, - settlementDataOracleId: - market.tradableInstrument.instrument.product - .dataSourceSpecForSettlementData.id, - settlementDataSpecBinding: - market.tradableInstrument.instrument.product.dataSourceSpecBinding - .settlementDataProperty, - tradingTerminationOracleId: - market.tradableInstrument.instrument.product - .dataSourceSpecForTradingTermination.id, - settlementAsset: - market.tradableInstrument.instrument.product.settlementAsset, - realisedPNL: position?.node.realisedPNL, - }; + const row: Row = { + id: market.id, + code: market.tradableInstrument.instrument.code, + name: market.tradableInstrument.instrument.name, + decimalPlaces: market.decimalPlaces, + state: market.state, + metadata: market.tradableInstrument.instrument.metadata.tags ?? [], + closeTimestamp: market.marketTimestamps.close, + bestBidPrice: market.data?.bestBidPrice, + bestOfferPrice: market.data?.bestOfferPrice, + markPrice: market.data?.markPrice, + settlementDataOracleId: + market.tradableInstrument.instrument.product + .dataSourceSpecForSettlementData.id, + settlementDataSpecBinding: + market.tradableInstrument.instrument.product.dataSourceSpecBinding + .settlementDataProperty, + tradingTerminationOracleId: + market.tradableInstrument.instrument.product + .dataSourceSpecForTradingTermination.id, + settlementAsset: + market.tradableInstrument.instrument.product.settlementAsset, + realisedPNL: position?.node.realisedPNL, + }; - return row; - }) - .filter((m) => { - return [ - MarketState.STATE_SETTLED, - MarketState.STATE_TRADING_TERMINATED, - ].includes(m.state); - }); + return row; + }); return ; }; @@ -257,6 +256,7 @@ const ClosedMarketsDataGrid = ({ rowData }: { rowData: Row[] }) => { style={{ width: '100%', height: '100%' }} rowData={rowData} columnDefs={colDefs} + getRowId={({ data }) => data.id} defaultColDef={{ flex: 1, resizable: true, diff --git a/libs/market-list/src/lib/ClosedMarkets.graphql b/libs/market-list/src/lib/ClosedMarkets.graphql deleted file mode 100644 index bd15450f5..000000000 --- a/libs/market-list/src/lib/ClosedMarkets.graphql +++ /dev/null @@ -1,60 +0,0 @@ -fragment ClosedMarket on Market { - id - decimalPlaces - positionDecimalPlaces - state - tradingMode - data { - market { - id - } - bestBidPrice - bestOfferPrice - markPrice - } - tradableInstrument { - instrument { - id - name - code - metadata { - tags - } - product { - ... on Future { - settlementAsset { - id - symbol - name - decimals - } - quoteName - dataSourceSpecForTradingTermination { - id - } - dataSourceSpecForSettlementData { - id - } - dataSourceSpecBinding { - settlementDataProperty - tradingTerminationProperty - } - } - } - } - } - marketTimestamps { - open - close - } -} - -query ClosedMarkets { - marketsConnection { - edges { - node { - ...ClosedMarket - } - } - } -} diff --git a/libs/market-list/src/lib/__generated__/ClosedMarkets.ts b/libs/market-list/src/lib/__generated__/ClosedMarkets.ts deleted file mode 100644 index 46c72a7c2..000000000 --- a/libs/market-list/src/lib/__generated__/ClosedMarkets.ts +++ /dev/null @@ -1,102 +0,0 @@ -import * as Types from '@vegaprotocol/types'; - -import { gql } from '@apollo/client'; -import * as Apollo from '@apollo/client'; -const defaultOptions = {} as const; -export type ClosedMarketFragment = { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, data?: { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, market: { __typename?: 'Market', id: string } } | null, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } }; - -export type ClosedMarketsQueryVariables = Types.Exact<{ [key: string]: never; }>; - - -export type ClosedMarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, data?: { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, market: { __typename?: 'Market', id: string } } | null, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } } }> } | null }; - -export const ClosedMarketFragmentDoc = gql` - fragment ClosedMarket on Market { - id - decimalPlaces - positionDecimalPlaces - state - tradingMode - data { - market { - id - } - bestBidPrice - bestOfferPrice - markPrice - } - tradableInstrument { - instrument { - id - name - code - metadata { - tags - } - product { - ... on Future { - settlementAsset { - id - symbol - name - decimals - } - quoteName - dataSourceSpecForTradingTermination { - id - } - dataSourceSpecForSettlementData { - id - } - dataSourceSpecBinding { - settlementDataProperty - tradingTerminationProperty - } - } - } - } - } - marketTimestamps { - open - close - } -} - `; -export const ClosedMarketsDocument = gql` - query ClosedMarkets { - marketsConnection { - edges { - node { - ...ClosedMarket - } - } - } -} - ${ClosedMarketFragmentDoc}`; - -/** - * __useClosedMarketsQuery__ - * - * To run a query within a React component, call `useClosedMarketsQuery` and pass it any options that fit your needs. - * When your component renders, `useClosedMarketsQuery` returns an object from Apollo Client that contains loading, error, and data properties - * you can use to render your UI. - * - * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; - * - * @example - * const { data, loading, error } = useClosedMarketsQuery({ - * variables: { - * }, - * }); - */ -export function useClosedMarketsQuery(baseOptions?: Apollo.QueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(ClosedMarketsDocument, options); - } -export function useClosedMarketsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(ClosedMarketsDocument, options); - } -export type ClosedMarketsQueryHookResult = ReturnType; -export type ClosedMarketsLazyQueryHookResult = ReturnType; -export type ClosedMarketsQueryResult = Apollo.QueryResult; \ No newline at end of file diff --git a/libs/market-list/src/lib/__generated__/markets.ts b/libs/market-list/src/lib/__generated__/markets.ts index 58a8df387..e238c6f4b 100644 --- a/libs/market-list/src/lib/__generated__/markets.ts +++ b/libs/market-list/src/lib/__generated__/markets.ts @@ -3,12 +3,12 @@ import * as Types from '@vegaprotocol/types'; import { gql } from '@apollo/client'; import * as Apollo from '@apollo/client'; const defaultOptions = {} as const; -export type MarketFieldsFragment = { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } }; +export type MarketFieldsFragment = { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } }; export type MarketsQueryVariables = Types.Exact<{ [key: string]: never; }>; -export type MarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } } }> } | null }; +export type MarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string }, dataSourceSpecBinding: { __typename?: 'DataSourceSpecToFutureBinding', settlementDataProperty: string, tradingTerminationProperty: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } } }> } | null }; export const MarketFieldsFragmentDoc = gql` fragment MarketFields on Market { @@ -44,6 +44,13 @@ export const MarketFieldsFragmentDoc = gql` dataSourceSpecForTradingTermination { id } + dataSourceSpecForSettlementData { + id + } + dataSourceSpecBinding { + settlementDataProperty + tradingTerminationProperty + } } } } diff --git a/libs/market-list/src/lib/index.ts b/libs/market-list/src/lib/index.ts index 7360db793..455afc63b 100644 --- a/libs/market-list/src/lib/index.ts +++ b/libs/market-list/src/lib/index.ts @@ -6,7 +6,6 @@ export * from './market-data-provider'; export * from './markets-candles-provider'; export * from './markets-data-provider'; export * from './markets-provider'; -export * from './__generated__/ClosedMarkets'; export * from './__generated__/market-candles'; export * from './__generated__/market-data'; export * from './__generated__/markets'; diff --git a/libs/market-list/src/lib/markets-data.mock.ts b/libs/market-list/src/lib/markets-data.mock.ts index 99df096b3..39aab494e 100644 --- a/libs/market-list/src/lib/markets-data.mock.ts +++ b/libs/market-list/src/lib/markets-data.mock.ts @@ -25,8 +25,10 @@ export const marketsDataQuery = ( return merge(defaultResult, override); }; -const marketsDataFieldsFragments: MarketsDataFieldsFragment[] = [ - { +export const createMarketsDataFragment = ( + override?: PartialDeep +): MarketsDataFieldsFragment => { + const defaultResult = { market: { id: 'market-0', __typename: 'Market', @@ -42,56 +44,28 @@ const marketsDataFieldsFragments: MarketsDataFieldsFragment[] = [ markPrice: '4612690058', trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED, __typename: 'MarketData', - }, - { + }; + return merge(defaultResult, override); +}; + +const marketsDataFieldsFragments: MarketsDataFieldsFragment[] = [ + createMarketsDataFragment(), + createMarketsDataFragment({ market: { id: 'market-1', - __typename: 'Market', }, - marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS, - staticMidPrice: '0', - indicativePrice: '0', - bestStaticBidPrice: '0', - bestStaticOfferPrice: '0', - indicativeVolume: '0', - bestBidPrice: '0', - bestOfferPrice: '0', markPrice: '8441', - trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED, - __typename: 'MarketData', - }, - { + }), + createMarketsDataFragment({ market: { id: 'market-2', - __typename: 'Market', }, - marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS, - staticMidPrice: '0', - indicativePrice: '0', - bestStaticBidPrice: '0', - bestStaticOfferPrice: '0', - indicativeVolume: '0', - bestBidPrice: '0', - bestOfferPrice: '0', - markPrice: '4612690058', trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY_TARGET_NOT_MET, - __typename: 'MarketData', - }, - { + }), + createMarketsDataFragment({ market: { id: 'market-3', - __typename: 'Market', }, - marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS, - staticMidPrice: '0', - indicativePrice: '0', - bestStaticBidPrice: '0', - bestStaticOfferPrice: '0', - indicativeVolume: '0', - bestBidPrice: '0', - bestOfferPrice: '0', - markPrice: '4612690058', trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY_TARGET_NOT_MET, - __typename: 'MarketData', - }, + }), ]; diff --git a/libs/market-list/src/lib/markets-provider.ts b/libs/market-list/src/lib/markets-provider.ts index 253d973ec..ebe2845a4 100644 --- a/libs/market-list/src/lib/markets-provider.ts +++ b/libs/market-list/src/lib/markets-provider.ts @@ -13,7 +13,7 @@ import type { MarketData } from './market-data-provider'; import type { MarketCandles } from './markets-candles-provider'; import { useMemo } from 'react'; import * as Schema from '@vegaprotocol/types'; -import { filterAndSortMarkets } from './utils'; +import { filterAndSortClosedMarkets, filterAndSortMarkets } from './utils'; import { MarketsDocument } from './__generated__/markets'; import type { Candle } from './market-candles-provider'; @@ -72,6 +72,11 @@ export const activeMarketsProvider = makeDerivedDataProvider( ([markets]) => filterAndSortMarkets(markets) ); +export const closedMarketsProvider = makeDerivedDataProvider( + [marketsProvider], + ([markets]) => filterAndSortClosedMarkets(markets) +); + export type MarketMaybeWithCandles = Market & { candles?: Candle[] }; const addCandles = ( @@ -111,6 +116,13 @@ export const marketsWithDataProvider = makeDerivedDataProvider< addData(parts[0] as Market[], parts[1] as MarketData[]) ); +export const closedMarketsWithDataProvider = makeDerivedDataProvider< + MarketMaybeWithData[], + never +>([closedMarketsProvider, marketsDataProvider], (parts) => + addData(parts[0] as Market[], parts[1] as MarketData[]) +); + export type MarketMaybeWithDataAndCandles = MarketMaybeWithData & MarketMaybeWithCandles; diff --git a/libs/market-list/src/lib/markets.graphql b/libs/market-list/src/lib/markets.graphql index 445f6a90c..334023978 100644 --- a/libs/market-list/src/lib/markets.graphql +++ b/libs/market-list/src/lib/markets.graphql @@ -31,6 +31,13 @@ fragment MarketFields on Market { dataSourceSpecForTradingTermination { id } + dataSourceSpecForSettlementData { + id + } + dataSourceSpecBinding { + settlementDataProperty + tradingTerminationProperty + } } } } diff --git a/libs/market-list/src/lib/markets.mock.ts b/libs/market-list/src/lib/markets.mock.ts index 02d4cf013..78bfe9f18 100644 --- a/libs/market-list/src/lib/markets.mock.ts +++ b/libs/market-list/src/lib/markets.mock.ts @@ -22,8 +22,10 @@ export const marketsQuery = ( return merge(defaultResult, override); }; -const marketFieldsFragments: MarketFieldsFragment[] = [ - { +export const createMarketFragment = ( + override?: PartialDeep +): MarketFieldsFragment => { + const defaultFragment = { id: 'market-0', decimalPlaces: 5, positionDecimalPlaces: 0, @@ -63,6 +65,13 @@ const marketFieldsFragments: MarketFieldsFragment[] = [ dataSourceSpecForTradingTermination: { id: 'oracleId', }, + dataSourceSpecForSettlementData: { + id: 'oracleId', + }, + dataSourceSpecBinding: { + tradingTerminationProperty: 'trading-termination-property', + settlementDataProperty: 'settlement-data-property', + }, quoteName: 'DAI', __typename: 'Future', }, @@ -71,36 +80,20 @@ const marketFieldsFragments: MarketFieldsFragment[] = [ __typename: 'TradableInstrument', }, __typename: 'Market', - }, - { + }; + + return merge(defaultFragment, override); +}; + +const marketFieldsFragments: MarketFieldsFragment[] = [ + createMarketFragment({ id: 'market-0' }), + createMarketFragment({ id: 'market-1', decimalPlaces: 2, - positionDecimalPlaces: 0, - tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS, - state: Schema.MarketState.STATE_ACTIVE, - marketTimestamps: { - __typename: 'MarketTimestamps', - close: '', - open: '', - }, - fees: { - __typename: 'Fees', - factors: { - __typename: 'FeeFactors', - makerFee: '', - infrastructureFee: '', - liquidityFee: '', - }, - }, tradableInstrument: { instrument: { - id: 'SOLUSD', name: 'SUSPENDED MARKET', code: 'SOLUSD', - metadata: { - __typename: 'InstrumentMetadata', - tags: [], - }, product: { settlementAsset: { id: 'asset-1', @@ -109,33 +102,19 @@ const marketFieldsFragments: MarketFieldsFragment[] = [ decimals: 5, __typename: 'Asset', }, - dataSourceSpecForTradingTermination: { - id: 'oracleId', - }, - quoteName: 'USD', - __typename: 'Future', }, - __typename: 'Instrument', }, - __typename: 'TradableInstrument', }, - __typename: 'Market', - }, - { + }), + createMarketFragment({ id: 'market-2', - decimalPlaces: 5, - positionDecimalPlaces: 0, tradingMode: Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION, state: Schema.MarketState.STATE_SUSPENDED, marketTimestamps: { - __typename: 'MarketTimestamps', close: '2022-08-26T11:36:32.252490405Z', - open: null, }, fees: { - __typename: 'Fees', factors: { - __typename: 'FeeFactors', makerFee: '0.0002', infrastructureFee: '0.0005', liquidityFee: '0.001', @@ -143,13 +122,8 @@ const marketFieldsFragments: MarketFieldsFragment[] = [ }, tradableInstrument: { instrument: { - id: '', code: 'AAPL.MF21', name: 'Apple Monthly (30 Jun 2022)', - metadata: { - __typename: 'InstrumentMetadata', - tags: [], - }, product: { settlementAsset: { id: 'asset-2', @@ -158,33 +132,18 @@ const marketFieldsFragments: MarketFieldsFragment[] = [ decimals: 5, __typename: 'Asset', }, - dataSourceSpecForTradingTermination: { - id: 'oracleId', - }, quoteName: 'USDC', - __typename: 'Future', }, - __typename: 'Instrument', }, - __typename: 'TradableInstrument', }, - __typename: 'Market', - }, - { + }), + createMarketFragment({ id: 'market-3', - decimalPlaces: 5, - positionDecimalPlaces: 0, - tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS, - state: Schema.MarketState.STATE_ACTIVE, marketTimestamps: { - __typename: 'MarketTimestamps', close: '2022-08-26T11:36:32.252490405Z', - open: null, }, fees: { - __typename: 'Fees', factors: { - __typename: 'FeeFactors', makerFee: '0.0002', infrastructureFee: '0.0005', liquidityFee: '0.001', @@ -192,13 +151,8 @@ const marketFieldsFragments: MarketFieldsFragment[] = [ }, tradableInstrument: { instrument: { - id: '', code: 'ETHBTC.QM21', name: 'ETHBTC Quarterly (30 Jun 2022)', - metadata: { - __typename: 'InstrumentMetadata', - tags: [], - }, product: { settlementAsset: { id: 'asset-3', @@ -207,16 +161,9 @@ const marketFieldsFragments: MarketFieldsFragment[] = [ decimals: 5, __typename: 'Asset', }, - dataSourceSpecForTradingTermination: { - id: 'oracleId', - }, quoteName: 'BTC', - __typename: 'Future', }, - __typename: 'Instrument', }, - __typename: 'TradableInstrument', }, - __typename: 'Market', - }, + }), ]; diff --git a/libs/market-list/src/lib/utils/market-utils.ts b/libs/market-list/src/lib/utils/market-utils.ts index e58fc86c1..2af9ec6c0 100644 --- a/libs/market-list/src/lib/utils/market-utils.ts +++ b/libs/market-list/src/lib/utils/market-utils.ts @@ -43,6 +43,15 @@ export const filterAndSortMarkets = (markets: Market[]) => { ); }; +export const filterAndSortClosedMarkets = (markets: Market[]) => { + return markets.filter((m) => { + return [ + MarketState.STATE_SETTLED, + MarketState.STATE_TRADING_TERMINATED, + ].includes(m.state); + }); +}; + export const calcCandleLow = (candles: Candle[]): string | undefined => { return candles ?.reduce((acc: BigNumber, c) => {