Feature/1243 market data providers refactoring (#1254)
* feat(#1243): Market data providers * feat(#1243): Market data providers * feat(#1243): Market data providers * feat(#1243): refactor market lists * feat(#1243): refactor market lists * feat(#1243): refactor market lists * feat(#1243): refactor orderbook data providers * feat(#1243): refactor orderbook data providers * feat(#1243): refactor depth chart data layer * feat(#1243): fix market depth typing * fixed unit tests * feat(#1243): e2e test fixes * feat(#1243): code style fixes * feat(#1243): post merge fixes * feat(#1243): fix lint issues * feat(#1243): post merge fixes * feat(#1243): remove market name from market * feat(#1243): fix console lite e2e data depth mocks * feat(#1243): fix console lite e2e market trade test * feat(#1243): fix lint issues * feat(#1243): fix trading e2e home test Co-authored-by: asiaznik <artur@vegaprotocol.io>
This commit is contained in:
parent
3ff5bbb5a7
commit
a08f63c7d8
@ -9,6 +9,7 @@ import { generatePartyBalance } from '../support/mocks/generate-party-balance';
|
|||||||
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
|
import { generatePartyMarketData } from '../support/mocks/generate-party-market-data';
|
||||||
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
|
import { generateMarketMarkPrice } from '../support/mocks/generate-market-mark-price';
|
||||||
import { generateMarketNames } from '../support/mocks/generate-market-names';
|
import { generateMarketNames } from '../support/mocks/generate-market-names';
|
||||||
|
import { generateMarketDepth } from '../support/mocks/generate-market-depth';
|
||||||
|
|
||||||
describe('market selector', () => {
|
describe('market selector', () => {
|
||||||
let markets;
|
let markets;
|
||||||
@ -23,6 +24,7 @@ describe('market selector', () => {
|
|||||||
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
aliasQuery(req, 'PartyMarketData', generatePartyMarketData());
|
||||||
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
aliasQuery(req, 'MarketMarkPrice', generateMarketMarkPrice());
|
||||||
aliasQuery(req, 'MarketNames', generateMarketNames());
|
aliasQuery(req, 'MarketNames', generateMarketNames());
|
||||||
|
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.visit('/markets');
|
cy.visit('/markets');
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||||
import { generateSimpleMarkets } from '../support/mocks/generate-markets';
|
import {
|
||||||
|
generateSimpleMarkets,
|
||||||
|
generateMarkets,
|
||||||
|
} from '../support/mocks/generate-markets';
|
||||||
import { generateDealTicket } from '../support/mocks/generate-deal-ticket';
|
import { generateDealTicket } from '../support/mocks/generate-deal-ticket';
|
||||||
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
import { generateMarketTags } from '../support/mocks/generate-market-tags';
|
||||||
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
|
import { generateMarketPositions } from '../support/mocks/generate-market-positions';
|
||||||
@ -14,6 +17,7 @@ describe('Market trade', () => {
|
|||||||
let markets;
|
let markets;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
|
aliasQuery(req, 'Markets', generateMarkets());
|
||||||
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
||||||
aliasQuery(req, 'DealTicketQuery', generateDealTicket());
|
aliasQuery(req, 'DealTicketQuery', generateDealTicket());
|
||||||
aliasQuery(req, 'MarketTags', generateMarketTags());
|
aliasQuery(req, 'MarketTags', generateMarketTags());
|
||||||
|
@ -1,24 +1,15 @@
|
|||||||
export const generateMarketDepth = () => {
|
import merge from 'lodash/merge';
|
||||||
return {
|
import type { PartialDeep } from 'type-fest';
|
||||||
|
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
||||||
|
import type { MarketDepth } from '../../../../../libs/market-depth/src/lib/__generated__/MarketDepth';
|
||||||
|
|
||||||
|
export const generateMarketDepth = (
|
||||||
|
override?: PartialDeep<MarketDepth>
|
||||||
|
): MarketDepth => {
|
||||||
|
const defaultResult: MarketDepth = {
|
||||||
market: {
|
market: {
|
||||||
id: 'a46bd7e5277087723b7ab835844dec3cef8b4445738101269624bf5537d5d423',
|
id: 'a46bd7e5277087723b7ab835844dec3cef8b4445738101269624bf5537d5d423',
|
||||||
decimalPlaces: 5,
|
|
||||||
positionDecimalPlaces: 0,
|
|
||||||
data: {
|
|
||||||
staticMidPrice: '9893006',
|
|
||||||
marketTradingMode: 'TRADING_MODE_CONTINUOUS',
|
|
||||||
indicativeVolume: '0',
|
|
||||||
indicativePrice: '0',
|
|
||||||
bestStaticBidPrice: '9893006',
|
|
||||||
bestStaticOfferPrice: '9893006',
|
|
||||||
market: {
|
|
||||||
id: 'a46bd7e5277087723b7ab835844dec3cef8b4445738101269624bf5537d5d423',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
__typename: 'MarketData',
|
|
||||||
},
|
|
||||||
depth: {
|
depth: {
|
||||||
lastTrade: { price: '9893006', __typename: 'Trade' },
|
|
||||||
sell: [
|
sell: [
|
||||||
{
|
{
|
||||||
price: '9893007',
|
price: '9893007',
|
||||||
@ -215,4 +206,5 @@ export const generateMarketDepth = () => {
|
|||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
return merge(defaultResult, override);
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import merge from 'lodash/merge';
|
||||||
|
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
||||||
import { protoMarket } from './commons';
|
import { protoMarket } from './commons';
|
||||||
|
|
||||||
export const generateSimpleMarkets = () => {
|
export const generateSimpleMarkets = () => {
|
||||||
@ -880,3 +882,41 @@ export const generateLongListMarkets = (count: number) => {
|
|||||||
}
|
}
|
||||||
return { markets };
|
return { markets };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const generateMarkets = (override?) => {
|
||||||
|
const markets = [
|
||||||
|
{
|
||||||
|
...protoMarket,
|
||||||
|
decimalPlaces: 5,
|
||||||
|
positionDecimalPlaces: 0,
|
||||||
|
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
state: MarketState.STATE_ACTIVE,
|
||||||
|
marketTimestamps: {
|
||||||
|
__typename: 'MarketTimestamps',
|
||||||
|
close: '',
|
||||||
|
open: '',
|
||||||
|
},
|
||||||
|
fees: {
|
||||||
|
__typename: 'Fees',
|
||||||
|
factors: {
|
||||||
|
__typename: 'FeeFactors',
|
||||||
|
makerFee: '',
|
||||||
|
infrastructureFee: '',
|
||||||
|
liquidityFee: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const defaultResult = {
|
||||||
|
marketsConnection: {
|
||||||
|
__typename: 'MarketConnection',
|
||||||
|
edges: markets.map((node) => ({
|
||||||
|
__typename: 'MarketEdge',
|
||||||
|
node,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return merge(defaultResult, override);
|
||||||
|
};
|
||||||
|
@ -64,6 +64,15 @@ jest.mock('@vegaprotocol/market-depth', () => ({
|
|||||||
useOrderBookData: jest.fn(() => mockOrderBookData),
|
useOrderBookData: jest.fn(() => mockOrderBookData),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock('@vegaprotocol/react-helpers', () => ({
|
||||||
|
...jest.requireActual('@vegaprotocol/react-helpers'),
|
||||||
|
useDataProvider: jest.fn(() => ({
|
||||||
|
data: {
|
||||||
|
marketsConnection: [],
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('useCalculateSlippage Hook', () => {
|
describe('useCalculateSlippage Hook', () => {
|
||||||
describe('calculate proper result', () => {
|
describe('calculate proper result', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { Side } from '@vegaprotocol/types';
|
import { Side } from '@vegaprotocol/types';
|
||||||
import { useOrderBookData } from '@vegaprotocol/market-depth';
|
import { useOrderBookData } from '@vegaprotocol/market-depth';
|
||||||
|
import { marketProvider } from '@vegaprotocol/market-list';
|
||||||
|
import type { Market } from '@vegaprotocol/market-list';
|
||||||
import type { Order } from '@vegaprotocol/orders';
|
import type { Order } from '@vegaprotocol/orders';
|
||||||
import { BigNumber } from 'bignumber.js';
|
import { BigNumber } from 'bignumber.js';
|
||||||
import { formatNumber, toBigNum } from '@vegaprotocol/react-helpers';
|
import {
|
||||||
|
formatNumber,
|
||||||
|
toBigNum,
|
||||||
|
useDataProvider,
|
||||||
|
} from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
marketId: string;
|
marketId: string;
|
||||||
@ -16,11 +22,16 @@ const useCalculateSlippage = ({ marketId, order }: Props) => {
|
|||||||
variables,
|
variables,
|
||||||
throttleMilliseconds: 5000,
|
throttleMilliseconds: 5000,
|
||||||
});
|
});
|
||||||
|
const { data: market } = useDataProvider<Market, never>({
|
||||||
|
dataProvider: marketProvider,
|
||||||
|
noUpdate: true,
|
||||||
|
variables,
|
||||||
|
});
|
||||||
const volPriceArr =
|
const volPriceArr =
|
||||||
data?.depth[order.side === Side.SIDE_BUY ? 'sell' : 'buy'] || [];
|
data?.depth[order.side === Side.SIDE_BUY ? 'sell' : 'buy'] || [];
|
||||||
if (volPriceArr.length) {
|
if (volPriceArr.length && market) {
|
||||||
const decimals = data?.decimalPlaces ?? 0;
|
const decimals = market.decimalPlaces ?? 0;
|
||||||
const positionDecimals = data?.positionDecimalPlaces ?? 0;
|
const positionDecimals = market.positionDecimalPlaces ?? 0;
|
||||||
const bestPrice = toBigNum(volPriceArr[0].price, decimals);
|
const bestPrice = toBigNum(volPriceArr[0].price, decimals);
|
||||||
const { size } = order;
|
const { size } = order;
|
||||||
let descSize = new BigNumber(size);
|
let descSize = new BigNumber(size);
|
||||||
|
@ -55,11 +55,16 @@ describe('home', () => {
|
|||||||
it('redirects to a the market list page if no sensible default is found', () => {
|
it('redirects to a the market list page if no sensible default is found', () => {
|
||||||
// Mock markets query that is triggered by home page to find default market
|
// Mock markets query that is triggered by home page to find default market
|
||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
aliasQuery(req, 'MarketList', { markets: [] });
|
const data = {
|
||||||
|
marketsConnection: {
|
||||||
|
__typename: 'MarketConnection',
|
||||||
|
edges: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
aliasQuery(req, 'Markets', data);
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@MarketList');
|
cy.wait('@Markets');
|
||||||
cy.url().should('eq', Cypress.config().baseUrl + '/markets');
|
cy.url().should('eq', Cypress.config().baseUrl + '/markets');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,9 @@ describe('markets table', () => {
|
|||||||
it('renders markets correctly', () => {
|
it('renders markets correctly', () => {
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
cy.wait('@MarketList');
|
cy.wait('@Markets');
|
||||||
|
cy.wait('@MarketsDataQuery');
|
||||||
|
cy.wait('@MarketsCandlesQuery');
|
||||||
cy.get('[data-testid^="market-link-"]')
|
cy.get('[data-testid^="market-link-"]')
|
||||||
.should('not.be.empty')
|
.should('not.be.empty')
|
||||||
.and('have.attr', 'href');
|
.and('have.attr', 'href');
|
||||||
@ -24,7 +26,9 @@ describe('markets table', () => {
|
|||||||
|
|
||||||
it('renders market list drop down', () => {
|
it('renders market list drop down', () => {
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@MarketList');
|
cy.wait('@Markets');
|
||||||
|
cy.wait('@MarketsDataQuery');
|
||||||
|
cy.wait('@MarketsCandlesQuery');
|
||||||
openMarketDropDown();
|
openMarketDropDown();
|
||||||
cy.getByTestId('price').invoke('text').should('not.be.empty');
|
cy.getByTestId('price').invoke('text').should('not.be.empty');
|
||||||
cy.getByTestId('trading-mode').should('not.be.empty');
|
cy.getByTestId('trading-mode').should('not.be.empty');
|
||||||
@ -35,7 +39,9 @@ describe('markets table', () => {
|
|||||||
|
|
||||||
it('Able to select market from dropdown', () => {
|
it('Able to select market from dropdown', () => {
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@MarketList');
|
cy.wait('@Markets');
|
||||||
|
cy.wait('@MarketsDataQuery');
|
||||||
|
cy.wait('@MarketsCandlesQuery');
|
||||||
openMarketDropDown();
|
openMarketDropDown();
|
||||||
cy.getByTestId('market-link-market-0').should('be.visible').click();
|
cy.getByTestId('market-link-market-0').should('be.visible').click();
|
||||||
|
|
||||||
@ -53,7 +59,9 @@ describe('markets table', () => {
|
|||||||
'SOLUSD',
|
'SOLUSD',
|
||||||
];
|
];
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@MarketList');
|
cy.wait('@Markets');
|
||||||
|
cy.wait('@MarketsDataQuery');
|
||||||
|
cy.wait('@MarketsCandlesQuery');
|
||||||
cy.getByTestId('link').should('have.attr', 'href', '/markets').click();
|
cy.getByTestId('link').should('have.attr', 'href', '/markets').click();
|
||||||
cy.url().should('eq', Cypress.config('baseUrl') + '/markets');
|
cy.url().should('eq', Cypress.config('baseUrl') + '/markets');
|
||||||
cy.contains('AAPL.MF21').should('be.visible');
|
cy.contains('AAPL.MF21').should('be.visible');
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
import { MarketTradingMode } from '@vegaprotocol/types';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
import type { PartialDeep } from 'type-fest';
|
||||||
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
|
||||||
import type { MarketDepth } from '../../../../../libs/market-depth/src/lib/__generated__/MarketDepth';
|
import type { MarketDepth } from '../../../../../libs/market-depth/src/lib/__generated__/MarketDepth';
|
||||||
@ -10,26 +9,10 @@ export const generateMarketDepth = (
|
|||||||
const defaultResult: MarketDepth = {
|
const defaultResult: MarketDepth = {
|
||||||
market: {
|
market: {
|
||||||
id: 'market-0',
|
id: 'market-0',
|
||||||
decimalPlaces: 5,
|
|
||||||
positionDecimalPlaces: 0,
|
|
||||||
data: {
|
|
||||||
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
staticMidPrice: '0',
|
|
||||||
indicativePrice: '0',
|
|
||||||
bestStaticBidPrice: '0',
|
|
||||||
bestStaticOfferPrice: '0',
|
|
||||||
indicativeVolume: '0',
|
|
||||||
market: {
|
|
||||||
id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
__typename: 'MarketData',
|
|
||||||
},
|
|
||||||
depth: {
|
depth: {
|
||||||
__typename: 'MarketDepth',
|
__typename: 'MarketDepth',
|
||||||
buy: [],
|
buy: [],
|
||||||
sell: [],
|
sell: [],
|
||||||
lastTrade: null,
|
|
||||||
sequenceNumber: '',
|
sequenceNumber: '',
|
||||||
},
|
},
|
||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
|
@ -5,12 +5,17 @@ import {
|
|||||||
MarketTradingMode,
|
MarketTradingMode,
|
||||||
} from '@vegaprotocol/types';
|
} from '@vegaprotocol/types';
|
||||||
import type { PartialDeep } from 'type-fest';
|
import type { PartialDeep } from 'type-fest';
|
||||||
import type { MarketList, MarketList_markets } from '@vegaprotocol/market-list';
|
import type {
|
||||||
|
Markets,
|
||||||
|
Markets_marketsConnection_edges_node,
|
||||||
|
MarketsCandlesQuery,
|
||||||
|
MarketsCandlesQuery_marketsConnection_edges_node,
|
||||||
|
MarketsDataQuery,
|
||||||
|
MarketsDataQuery_marketsConnection_edges_node,
|
||||||
|
} from '@vegaprotocol/market-list';
|
||||||
|
|
||||||
export const generateMarkets = (
|
export const generateMarkets = (override?: PartialDeep<Markets>): Markets => {
|
||||||
override?: PartialDeep<MarketList>
|
const markets: Markets_marketsConnection_edges_node[] = [
|
||||||
): MarketList => {
|
|
||||||
const markets: MarketList_markets[] = [
|
|
||||||
{
|
{
|
||||||
id: 'market-0',
|
id: 'market-0',
|
||||||
decimalPlaces: 5,
|
decimalPlaces: 5,
|
||||||
@ -22,15 +27,6 @@ export const generateMarkets = (
|
|||||||
close: '',
|
close: '',
|
||||||
open: '',
|
open: '',
|
||||||
},
|
},
|
||||||
candles: [
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '100',
|
|
||||||
close: '100',
|
|
||||||
high: '110',
|
|
||||||
low: '90',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
fees: {
|
fees: {
|
||||||
__typename: 'Fees',
|
__typename: 'Fees',
|
||||||
factors: {
|
factors: {
|
||||||
@ -40,20 +36,6 @@ export const generateMarkets = (
|
|||||||
liquidityFee: '',
|
liquidityFee: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: {
|
|
||||||
market: {
|
|
||||||
id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
|
|
||||||
state: MarketState.STATE_ACTIVE,
|
|
||||||
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
indicativeVolume: '0',
|
|
||||||
bestBidPrice: '0',
|
|
||||||
bestOfferPrice: '0',
|
|
||||||
markPrice: '4612690058',
|
|
||||||
trigger: AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
|
||||||
__typename: 'MarketData',
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
id: '',
|
id: '',
|
||||||
@ -87,15 +69,6 @@ export const generateMarkets = (
|
|||||||
close: '',
|
close: '',
|
||||||
open: '',
|
open: '',
|
||||||
},
|
},
|
||||||
candles: [
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '100',
|
|
||||||
close: '100',
|
|
||||||
high: '110',
|
|
||||||
low: '90',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
fees: {
|
fees: {
|
||||||
__typename: 'Fees',
|
__typename: 'Fees',
|
||||||
factors: {
|
factors: {
|
||||||
@ -105,20 +78,6 @@ export const generateMarkets = (
|
|||||||
liquidityFee: '',
|
liquidityFee: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: {
|
|
||||||
market: {
|
|
||||||
id: '34d95e10faa00c21d19d382d6d7e6fc9722a96985369f0caec041b0f44b775ed',
|
|
||||||
state: MarketState.STATE_SUSPENDED,
|
|
||||||
tradingMode: MarketTradingMode.TRADING_MODE_NO_TRADING,
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
bestBidPrice: '0',
|
|
||||||
bestOfferPrice: '0',
|
|
||||||
indicativeVolume: '0',
|
|
||||||
markPrice: '8441',
|
|
||||||
trigger: AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
|
||||||
__typename: 'MarketData',
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
id: 'SOLUSD',
|
id: 'SOLUSD',
|
||||||
@ -152,15 +111,6 @@ export const generateMarkets = (
|
|||||||
close: '2022-08-26T11:36:32.252490405Z',
|
close: '2022-08-26T11:36:32.252490405Z',
|
||||||
open: null,
|
open: null,
|
||||||
},
|
},
|
||||||
candles: [
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '100',
|
|
||||||
close: '100',
|
|
||||||
high: '110',
|
|
||||||
low: '90',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
fees: {
|
fees: {
|
||||||
__typename: 'Fees',
|
__typename: 'Fees',
|
||||||
factors: {
|
factors: {
|
||||||
@ -170,20 +120,6 @@ export const generateMarkets = (
|
|||||||
liquidityFee: '0.001',
|
liquidityFee: '0.001',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: {
|
|
||||||
market: {
|
|
||||||
id: 'a1c731af07570ca49b22a3cd253cc143dc14068edbec918e1087e69db934af5f',
|
|
||||||
state: MarketState.STATE_SUSPENDED,
|
|
||||||
tradingMode: MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
indicativeVolume: '0',
|
|
||||||
bestBidPrice: '0',
|
|
||||||
bestOfferPrice: '0',
|
|
||||||
markPrice: '4612690058',
|
|
||||||
trigger: AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY,
|
|
||||||
__typename: 'MarketData',
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
id: '',
|
id: '',
|
||||||
@ -217,15 +153,6 @@ export const generateMarkets = (
|
|||||||
close: '2022-08-26T11:36:32.252490405Z',
|
close: '2022-08-26T11:36:32.252490405Z',
|
||||||
open: null,
|
open: null,
|
||||||
},
|
},
|
||||||
candles: [
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '100',
|
|
||||||
close: '100',
|
|
||||||
high: '110',
|
|
||||||
low: '90',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
fees: {
|
fees: {
|
||||||
__typename: 'Fees',
|
__typename: 'Fees',
|
||||||
factors: {
|
factors: {
|
||||||
@ -235,20 +162,6 @@ export const generateMarkets = (
|
|||||||
liquidityFee: '0.001',
|
liquidityFee: '0.001',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: {
|
|
||||||
market: {
|
|
||||||
id: 'bebea8ec669b913a7d6a704a6d8cede164bc1376229e0d472bc6fdaa976629b2',
|
|
||||||
state: MarketState.STATE_ACTIVE,
|
|
||||||
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
indicativeVolume: '0',
|
|
||||||
bestBidPrice: '0',
|
|
||||||
bestOfferPrice: '0',
|
|
||||||
markPrice: '4612690058',
|
|
||||||
trigger: AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY,
|
|
||||||
__typename: 'MarketData',
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
id: '',
|
id: '',
|
||||||
@ -272,8 +185,212 @@ export const generateMarkets = (
|
|||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const defaultResult = {
|
|
||||||
markets,
|
const defaultResult: Markets = {
|
||||||
|
marketsConnection: {
|
||||||
|
__typename: 'MarketConnection',
|
||||||
|
edges: markets.map((node) => ({
|
||||||
|
__typename: 'MarketEdge',
|
||||||
|
node,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return merge(defaultResult, override);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const generateMarketsData = (
|
||||||
|
override?: PartialDeep<MarketsDataQuery>
|
||||||
|
): MarketsDataQuery => {
|
||||||
|
const markets: MarketsDataQuery_marketsConnection_edges_node[] = [
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
market: {
|
||||||
|
id: 'market-0',
|
||||||
|
__typename: 'Market',
|
||||||
|
},
|
||||||
|
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
staticMidPrice: '0',
|
||||||
|
indicativePrice: '0',
|
||||||
|
bestStaticBidPrice: '0',
|
||||||
|
bestStaticOfferPrice: '0',
|
||||||
|
indicativeVolume: '0',
|
||||||
|
bestBidPrice: '0',
|
||||||
|
bestOfferPrice: '0',
|
||||||
|
markPrice: '4612690058',
|
||||||
|
trigger: AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||||
|
__typename: 'MarketData',
|
||||||
|
},
|
||||||
|
__typename: 'Market',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
market: {
|
||||||
|
id: 'market-1',
|
||||||
|
__typename: 'Market',
|
||||||
|
},
|
||||||
|
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
staticMidPrice: '0',
|
||||||
|
indicativePrice: '0',
|
||||||
|
bestStaticBidPrice: '0',
|
||||||
|
bestStaticOfferPrice: '0',
|
||||||
|
indicativeVolume: '0',
|
||||||
|
bestBidPrice: '0',
|
||||||
|
bestOfferPrice: '0',
|
||||||
|
markPrice: '8441',
|
||||||
|
trigger: AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED,
|
||||||
|
__typename: 'MarketData',
|
||||||
|
},
|
||||||
|
__typename: 'Market',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
market: {
|
||||||
|
id: 'market-2',
|
||||||
|
__typename: 'Market',
|
||||||
|
},
|
||||||
|
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
staticMidPrice: '0',
|
||||||
|
indicativePrice: '0',
|
||||||
|
bestStaticBidPrice: '0',
|
||||||
|
bestStaticOfferPrice: '0',
|
||||||
|
indicativeVolume: '0',
|
||||||
|
bestBidPrice: '0',
|
||||||
|
bestOfferPrice: '0',
|
||||||
|
markPrice: '4612690058',
|
||||||
|
trigger: AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY,
|
||||||
|
__typename: 'MarketData',
|
||||||
|
},
|
||||||
|
__typename: 'Market',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
market: {
|
||||||
|
id: 'market-3',
|
||||||
|
__typename: 'Market',
|
||||||
|
},
|
||||||
|
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
staticMidPrice: '0',
|
||||||
|
indicativePrice: '0',
|
||||||
|
bestStaticBidPrice: '0',
|
||||||
|
bestStaticOfferPrice: '0',
|
||||||
|
indicativeVolume: '0',
|
||||||
|
bestBidPrice: '0',
|
||||||
|
bestOfferPrice: '0',
|
||||||
|
markPrice: '4612690058',
|
||||||
|
trigger: AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY,
|
||||||
|
__typename: 'MarketData',
|
||||||
|
},
|
||||||
|
__typename: 'Market',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const defaultResult: MarketsDataQuery = {
|
||||||
|
marketsConnection: {
|
||||||
|
__typename: 'MarketConnection',
|
||||||
|
edges: markets.map((node) => ({
|
||||||
|
__typename: 'MarketEdge',
|
||||||
|
node,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return merge(defaultResult, override);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const generateMarketsCandles = (
|
||||||
|
override?: PartialDeep<MarketsCandlesQuery>
|
||||||
|
): MarketsCandlesQuery => {
|
||||||
|
const markets: MarketsCandlesQuery_marketsConnection_edges_node[] = [
|
||||||
|
{
|
||||||
|
__typename: 'Market',
|
||||||
|
id: 'market-0',
|
||||||
|
candlesConnection: {
|
||||||
|
__typename: 'CandleDataConnection',
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
__typename: 'CandleEdge',
|
||||||
|
node: {
|
||||||
|
__typename: 'CandleNode',
|
||||||
|
open: '100',
|
||||||
|
close: '100',
|
||||||
|
high: '110',
|
||||||
|
low: '90',
|
||||||
|
volume: '1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'Market',
|
||||||
|
id: 'market-1',
|
||||||
|
candlesConnection: {
|
||||||
|
__typename: 'CandleDataConnection',
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
__typename: 'CandleEdge',
|
||||||
|
node: {
|
||||||
|
__typename: 'CandleNode',
|
||||||
|
open: '100',
|
||||||
|
close: '100',
|
||||||
|
high: '110',
|
||||||
|
low: '90',
|
||||||
|
volume: '1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'Market',
|
||||||
|
id: 'market-2',
|
||||||
|
candlesConnection: {
|
||||||
|
__typename: 'CandleDataConnection',
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
__typename: 'CandleEdge',
|
||||||
|
node: {
|
||||||
|
__typename: 'CandleNode',
|
||||||
|
open: '100',
|
||||||
|
close: '100',
|
||||||
|
high: '110',
|
||||||
|
low: '90',
|
||||||
|
volume: '1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'Market',
|
||||||
|
id: 'market-3',
|
||||||
|
candlesConnection: {
|
||||||
|
__typename: 'CandleDataConnection',
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
__typename: 'CandleEdge',
|
||||||
|
node: {
|
||||||
|
__typename: 'CandleNode',
|
||||||
|
open: '100',
|
||||||
|
close: '100',
|
||||||
|
high: '110',
|
||||||
|
low: '90',
|
||||||
|
volume: '1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const defaultResult: MarketsCandlesQuery = {
|
||||||
|
marketsConnection: {
|
||||||
|
__typename: 'MarketConnection',
|
||||||
|
edges: markets.map((node) => ({
|
||||||
|
__typename: 'MarketEdge',
|
||||||
|
node,
|
||||||
|
})),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return merge(defaultResult, override);
|
return merge(defaultResult, override);
|
||||||
|
@ -4,33 +4,13 @@ import type {
|
|||||||
MarketDepth,
|
MarketDepth,
|
||||||
MarketDepth_market,
|
MarketDepth_market,
|
||||||
} from '@vegaprotocol/market-depth';
|
} from '@vegaprotocol/market-depth';
|
||||||
import { MarketTradingMode } from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
export const generateOrderBook = (
|
export const generateOrderBook = (
|
||||||
override?: PartialDeep<MarketDepth>
|
override?: PartialDeep<MarketDepth>
|
||||||
): MarketDepth => {
|
): MarketDepth => {
|
||||||
const marketDepth: MarketDepth_market = {
|
const marketDepth: MarketDepth_market = {
|
||||||
id: 'b2426f67b085ba8fb429f1b529d49372b2d096c6fb6f509f76c5863abb6d969e',
|
id: 'b2426f67b085ba8fb429f1b529d49372b2d096c6fb6f509f76c5863abb6d969e',
|
||||||
decimalPlaces: 5,
|
|
||||||
positionDecimalPlaces: 0,
|
|
||||||
data: {
|
|
||||||
staticMidPrice: '826337',
|
|
||||||
marketTradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
indicativeVolume: '0',
|
|
||||||
indicativePrice: '0',
|
|
||||||
bestStaticBidPrice: '826336',
|
|
||||||
bestStaticOfferPrice: '826338',
|
|
||||||
market: {
|
|
||||||
id: 'b2426f67b085ba8fb429f1b529d49372b2d096c6fb6f509f76c5863abb6d969e',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
__typename: 'MarketData',
|
|
||||||
},
|
|
||||||
depth: {
|
depth: {
|
||||||
lastTrade: {
|
|
||||||
price: '826338',
|
|
||||||
__typename: 'Trade',
|
|
||||||
},
|
|
||||||
sell: [
|
sell: [
|
||||||
{
|
{
|
||||||
price: '826338',
|
price: '826338',
|
||||||
|
@ -8,7 +8,11 @@ import { generateDealTicketQuery } from './mocks/generate-deal-ticket-query';
|
|||||||
import { generateMarket } from './mocks/generate-market';
|
import { generateMarket } from './mocks/generate-market';
|
||||||
import { generateMarketDepth } from './mocks/generate-market-depth';
|
import { generateMarketDepth } from './mocks/generate-market-depth';
|
||||||
import { generateMarketInfoQuery } from './mocks/generate-market-info-query';
|
import { generateMarketInfoQuery } from './mocks/generate-market-info-query';
|
||||||
import { generateMarkets } from './mocks/generate-markets';
|
import {
|
||||||
|
generateMarkets,
|
||||||
|
generateMarketsData,
|
||||||
|
generateMarketsCandles,
|
||||||
|
} from './mocks/generate-markets';
|
||||||
import { generateOrders } from './mocks/generate-orders';
|
import { generateOrders } from './mocks/generate-orders';
|
||||||
import { generatePositions } from './mocks/generate-positions';
|
import { generatePositions } from './mocks/generate-positions';
|
||||||
import { generateTrades } from './mocks/generate-trades';
|
import { generateTrades } from './mocks/generate-trades';
|
||||||
@ -31,7 +35,10 @@ export const mockTradingPage = (
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
aliasQuery(req, 'MarketList', generateMarkets());
|
aliasQuery(req, 'Markets', generateMarkets());
|
||||||
|
aliasQuery(req, 'MarketsDataQuery', generateMarketsData());
|
||||||
|
aliasQuery(req, 'MarketsCandlesQuery', generateMarketsCandles());
|
||||||
|
|
||||||
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
aliasQuery(req, 'MarketDepth', generateMarketDepth());
|
||||||
aliasQuery(req, 'Orders', generateOrders());
|
aliasQuery(req, 'Orders', generateOrders());
|
||||||
aliasQuery(req, 'Accounts', generateAccounts());
|
aliasQuery(req, 'Accounts', generateAccounts());
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { useMarketList } from '@vegaprotocol/market-list';
|
import { activeMarketsProvider } from '@vegaprotocol/market-list';
|
||||||
|
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
@ -8,7 +9,10 @@ export function Index() {
|
|||||||
const { replace } = useRouter();
|
const { replace } = useRouter();
|
||||||
// The default market selected in the platform behind the overlay
|
// The default market selected in the platform behind the overlay
|
||||||
// should be the oldest market that is currently trading in continuous mode(i.e. not in auction).
|
// should be the oldest market that is currently trading in continuous mode(i.e. not in auction).
|
||||||
const { data, error, loading } = useMarketList();
|
const { data, error, loading } = useDataProvider({
|
||||||
|
dataProvider: activeMarketsProvider,
|
||||||
|
noUpdate: true,
|
||||||
|
});
|
||||||
const { riskNoticeDialog, update } = useGlobalStore((store) => ({
|
const { riskNoticeDialog, update } = useGlobalStore((store) => ({
|
||||||
riskNoticeDialog: store.riskNoticeDialog,
|
riskNoticeDialog: store.riskNoticeDialog,
|
||||||
update: store.update,
|
update: store.update,
|
||||||
|
@ -64,6 +64,7 @@ export const DealTicketContainer = ({
|
|||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
<Splash>
|
<Splash>
|
||||||
|
{JSON.stringify(data)}
|
||||||
<p>{t('Could not load market')}</p>
|
<p>{t('Could not load market')}</p>
|
||||||
</Splash>
|
</Splash>
|
||||||
)}
|
)}
|
||||||
|
@ -3,60 +3,10 @@
|
|||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { MarketTradingMode } from "@vegaprotocol/types";
|
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: MarketDepth
|
// GraphQL query operation: MarketDepth
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface MarketDepth_market_data_market {
|
|
||||||
__typename: "Market";
|
|
||||||
/**
|
|
||||||
* Market ID
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketDepth_market_data {
|
|
||||||
__typename: "MarketData";
|
|
||||||
/**
|
|
||||||
* the arithmetic average of the best static bid price and best static offer price
|
|
||||||
*/
|
|
||||||
staticMidPrice: string;
|
|
||||||
/**
|
|
||||||
* what state the market is in (auction, continuous, etc)
|
|
||||||
*/
|
|
||||||
marketTradingMode: MarketTradingMode;
|
|
||||||
/**
|
|
||||||
* indicative volume if the auction ended now, 0 if not in auction mode
|
|
||||||
*/
|
|
||||||
indicativeVolume: string;
|
|
||||||
/**
|
|
||||||
* indicative price if the auction ended now, 0 if not in auction mode
|
|
||||||
*/
|
|
||||||
indicativePrice: string;
|
|
||||||
/**
|
|
||||||
* the highest price level on an order book for buy orders not including pegged orders.
|
|
||||||
*/
|
|
||||||
bestStaticBidPrice: string;
|
|
||||||
/**
|
|
||||||
* the lowest price level on an order book for offer orders not including pegged orders.
|
|
||||||
*/
|
|
||||||
bestStaticOfferPrice: string;
|
|
||||||
/**
|
|
||||||
* market ID of the associated mark price
|
|
||||||
*/
|
|
||||||
market: MarketDepth_market_data_market;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketDepth_market_depth_lastTrade {
|
|
||||||
__typename: "Trade";
|
|
||||||
/**
|
|
||||||
* The price of the trade (probably initially the passive order price, other determination algorithms are possible though) (uint64)
|
|
||||||
*/
|
|
||||||
price: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketDepth_market_depth_sell {
|
export interface MarketDepth_market_depth_sell {
|
||||||
__typename: "PriceLevel";
|
__typename: "PriceLevel";
|
||||||
/**
|
/**
|
||||||
@ -91,10 +41,6 @@ export interface MarketDepth_market_depth_buy {
|
|||||||
|
|
||||||
export interface MarketDepth_market_depth {
|
export interface MarketDepth_market_depth {
|
||||||
__typename: "MarketDepth";
|
__typename: "MarketDepth";
|
||||||
/**
|
|
||||||
* Last trade for the given market (if available)
|
|
||||||
*/
|
|
||||||
lastTrade: MarketDepth_market_depth_lastTrade | null;
|
|
||||||
/**
|
/**
|
||||||
* Sell side price levels (if available)
|
* Sell side price levels (if available)
|
||||||
*/
|
*/
|
||||||
@ -115,34 +61,6 @@ export interface MarketDepth_market {
|
|||||||
* Market ID
|
* Market ID
|
||||||
*/
|
*/
|
||||||
id: string;
|
id: string;
|
||||||
/**
|
|
||||||
* 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 )
|
|
||||||
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
|
|
||||||
*/
|
|
||||||
decimalPlaces: number;
|
|
||||||
/**
|
|
||||||
* positionDecimalPlaces indicates the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
|
|
||||||
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
|
|
||||||
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
|
|
||||||
* This sets how big the smallest order / position on the market can be.
|
|
||||||
*/
|
|
||||||
positionDecimalPlaces: number;
|
|
||||||
/**
|
|
||||||
* marketData for the given market
|
|
||||||
*/
|
|
||||||
data: MarketDepth_market_data | null;
|
|
||||||
/**
|
/**
|
||||||
* Current depth on the order book for this market
|
* Current depth on the order book for this market
|
||||||
*/
|
*/
|
||||||
|
@ -3,72 +3,11 @@
|
|||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { MarketTradingMode } from "@vegaprotocol/types";
|
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL subscription operation: MarketDepthSubscription
|
// GraphQL subscription operation: MarketDepthSubscription
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface MarketDepthSubscription_marketDepthUpdate_market_data_market {
|
export interface MarketDepthSubscription_marketsDepthUpdate_sell {
|
||||||
__typename: "Market";
|
|
||||||
/**
|
|
||||||
* Market ID
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketDepthSubscription_marketDepthUpdate_market_data {
|
|
||||||
__typename: "MarketData";
|
|
||||||
/**
|
|
||||||
* the arithmetic average of the best static bid price and best static offer price
|
|
||||||
*/
|
|
||||||
staticMidPrice: string;
|
|
||||||
/**
|
|
||||||
* what state the market is in (auction, continuous, etc)
|
|
||||||
*/
|
|
||||||
marketTradingMode: MarketTradingMode;
|
|
||||||
/**
|
|
||||||
* indicative volume if the auction ended now, 0 if not in auction mode
|
|
||||||
*/
|
|
||||||
indicativeVolume: string;
|
|
||||||
/**
|
|
||||||
* indicative price if the auction ended now, 0 if not in auction mode
|
|
||||||
*/
|
|
||||||
indicativePrice: string;
|
|
||||||
/**
|
|
||||||
* the highest price level on an order book for buy orders not including pegged orders.
|
|
||||||
*/
|
|
||||||
bestStaticBidPrice: string;
|
|
||||||
/**
|
|
||||||
* the lowest price level on an order book for offer orders not including pegged orders.
|
|
||||||
*/
|
|
||||||
bestStaticOfferPrice: string;
|
|
||||||
/**
|
|
||||||
* market ID of the associated mark price
|
|
||||||
*/
|
|
||||||
market: MarketDepthSubscription_marketDepthUpdate_market_data_market;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketDepthSubscription_marketDepthUpdate_market {
|
|
||||||
__typename: "Market";
|
|
||||||
/**
|
|
||||||
* Market ID
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
/**
|
|
||||||
* positionDecimalPlaces indicates the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
|
|
||||||
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
|
|
||||||
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
|
|
||||||
* This sets how big the smallest order / position on the market can be.
|
|
||||||
*/
|
|
||||||
positionDecimalPlaces: number;
|
|
||||||
/**
|
|
||||||
* marketData for the given market
|
|
||||||
*/
|
|
||||||
data: MarketDepthSubscription_marketDepthUpdate_market_data | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketDepthSubscription_marketDepthUpdate_sell {
|
|
||||||
__typename: "PriceLevel";
|
__typename: "PriceLevel";
|
||||||
/**
|
/**
|
||||||
* The price of all the orders at this level (uint64)
|
* The price of all the orders at this level (uint64)
|
||||||
@ -84,7 +23,7 @@ export interface MarketDepthSubscription_marketDepthUpdate_sell {
|
|||||||
numberOfOrders: string;
|
numberOfOrders: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketDepthSubscription_marketDepthUpdate_buy {
|
export interface MarketDepthSubscription_marketsDepthUpdate_buy {
|
||||||
__typename: "PriceLevel";
|
__typename: "PriceLevel";
|
||||||
/**
|
/**
|
||||||
* The price of all the orders at this level (uint64)
|
* The price of all the orders at this level (uint64)
|
||||||
@ -100,33 +39,37 @@ export interface MarketDepthSubscription_marketDepthUpdate_buy {
|
|||||||
numberOfOrders: string;
|
numberOfOrders: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketDepthSubscription_marketDepthUpdate {
|
export interface MarketDepthSubscription_marketsDepthUpdate {
|
||||||
__typename: "MarketDepthUpdate";
|
__typename: "ObservableMarketDepthUpdate";
|
||||||
/**
|
/**
|
||||||
* Market
|
* Market ID
|
||||||
*/
|
*/
|
||||||
market: MarketDepthSubscription_marketDepthUpdate_market;
|
marketId: string;
|
||||||
/**
|
/**
|
||||||
* Sell side price levels (if available)
|
* Sell side price levels (if available)
|
||||||
*/
|
*/
|
||||||
sell: MarketDepthSubscription_marketDepthUpdate_sell[] | null;
|
sell: MarketDepthSubscription_marketsDepthUpdate_sell[] | null;
|
||||||
/**
|
/**
|
||||||
* Buy side price levels (if available)
|
* Buy side price levels (if available)
|
||||||
*/
|
*/
|
||||||
buy: MarketDepthSubscription_marketDepthUpdate_buy[] | null;
|
buy: MarketDepthSubscription_marketsDepthUpdate_buy[] | null;
|
||||||
/**
|
/**
|
||||||
* Sequence number for the current snapshot of the market depth. It is always increasing but not monotonic.
|
* Sequence number for the current snapshot of the market depth. It is always increasing but not monotonic.
|
||||||
*/
|
*/
|
||||||
sequenceNumber: string;
|
sequenceNumber: string;
|
||||||
|
/**
|
||||||
|
* Sequence number of the last update sent; useful for checking that no updates were missed.
|
||||||
|
*/
|
||||||
|
previousSequenceNumber: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketDepthSubscription {
|
export interface MarketDepthSubscription {
|
||||||
/**
|
/**
|
||||||
* Subscribe to price level market depth updates
|
* Subscribe to price level market depth updates
|
||||||
*/
|
*/
|
||||||
marketDepthUpdate: MarketDepthSubscription_marketDepthUpdate;
|
marketsDepthUpdate: MarketDepthSubscription_marketsDepthUpdate[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketDepthSubscriptionVariables {
|
export interface MarketDepthSubscriptionVariables {
|
||||||
marketId: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
ThemeContext,
|
ThemeContext,
|
||||||
getNumberFormat,
|
getNumberFormat,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import dataProvider from './market-depth-data-provider';
|
import dataProvider from './market-depth-provider';
|
||||||
import {
|
import {
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
@ -16,7 +16,13 @@ import {
|
|||||||
useState,
|
useState,
|
||||||
useContext,
|
useContext,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import type { MarketDepthSubscription_marketDepthUpdate } from './__generated__/MarketDepthSubscription';
|
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||||
|
import type { MarketData } from '@vegaprotocol/market-list';
|
||||||
|
import type {
|
||||||
|
MarketDepthSubscription_marketsDepthUpdate,
|
||||||
|
MarketDepthSubscription_marketsDepthUpdate_sell,
|
||||||
|
MarketDepthSubscription_marketsDepthUpdate_buy,
|
||||||
|
} from './__generated__/MarketDepthSubscription';
|
||||||
import type { DepthChartProps } from 'pennant';
|
import type { DepthChartProps } from 'pennant';
|
||||||
import { parseLevel, updateLevels } from './depth-chart-utils';
|
import { parseLevel, updateLevels } from './depth-chart-utils';
|
||||||
|
|
||||||
@ -33,46 +39,80 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
|||||||
const theme = useContext(ThemeContext);
|
const theme = useContext(ThemeContext);
|
||||||
const variables = useMemo(() => ({ marketId }), [marketId]);
|
const variables = useMemo(() => ({ marketId }), [marketId]);
|
||||||
const [depthData, setDepthData] = useState<DepthData | null>(null);
|
const [depthData, setDepthData] = useState<DepthData | null>(null);
|
||||||
const [decimalPlaces, setDecimalPlaces] = useState<number>(0);
|
|
||||||
const [positionDecimalPlaces, setPositionDecimalPlaces] = useState<number>(0);
|
|
||||||
const dataRef = useRef<DepthData | null>(null);
|
const dataRef = useRef<DepthData | null>(null);
|
||||||
const setDepthDataThrottledRef = useRef(throttle(setDepthData, 1000));
|
const marketDataRef = useRef<MarketData | null>(null);
|
||||||
|
const deltaRef = useRef<{
|
||||||
|
sell: MarketDepthSubscription_marketsDepthUpdate_sell[];
|
||||||
|
buy: MarketDepthSubscription_marketsDepthUpdate_buy[];
|
||||||
|
}>({
|
||||||
|
sell: [],
|
||||||
|
buy: [],
|
||||||
|
});
|
||||||
|
|
||||||
// Apply updates to the table
|
const updateDepthData = useRef(
|
||||||
const update = useCallback(
|
throttle(() => {
|
||||||
({ delta }: { delta: MarketDepthSubscription_marketDepthUpdate }) => {
|
if (!dataRef.current || !marketDataRef.current || !market) {
|
||||||
if (!dataRef.current) {
|
return;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
dataRef.current = {
|
dataRef.current = {
|
||||||
...dataRef.current,
|
...dataRef.current,
|
||||||
midPrice: delta.market.data?.staticMidPrice
|
midPrice: marketDataRef.current?.staticMidPrice
|
||||||
? formatMidPrice(delta.market.data?.staticMidPrice, decimalPlaces)
|
? formatMidPrice(
|
||||||
|
marketDataRef.current?.staticMidPrice,
|
||||||
|
market.decimalPlaces
|
||||||
|
)
|
||||||
: undefined,
|
: undefined,
|
||||||
data: {
|
data: {
|
||||||
buy: delta.buy
|
buy: deltaRef.current.buy
|
||||||
? updateLevels(
|
? updateLevels(
|
||||||
dataRef.current.data.buy,
|
dataRef.current.data.buy,
|
||||||
delta.buy,
|
deltaRef.current.buy,
|
||||||
decimalPlaces,
|
market.decimalPlaces,
|
||||||
positionDecimalPlaces,
|
market.positionDecimalPlaces,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
: dataRef.current.data.buy,
|
: dataRef.current.data.buy,
|
||||||
sell: delta.sell
|
sell: deltaRef.current.sell
|
||||||
? updateLevels(
|
? updateLevels(
|
||||||
dataRef.current.data.sell,
|
dataRef.current.data.sell,
|
||||||
delta.sell,
|
deltaRef.current.sell,
|
||||||
decimalPlaces,
|
market.decimalPlaces,
|
||||||
positionDecimalPlaces
|
market.positionDecimalPlaces
|
||||||
)
|
)
|
||||||
: dataRef.current.data.sell,
|
: dataRef.current.data.sell,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
setDepthDataThrottledRef.current(dataRef.current);
|
deltaRef.current.buy = [];
|
||||||
|
deltaRef.current.sell = [];
|
||||||
|
setDepthData(dataRef.current);
|
||||||
|
}, 1000)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Apply updates to the table
|
||||||
|
const update = useCallback(
|
||||||
|
({
|
||||||
|
delta: deltas,
|
||||||
|
}: {
|
||||||
|
delta: MarketDepthSubscription_marketsDepthUpdate[];
|
||||||
|
}) => {
|
||||||
|
if (!dataRef.current) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (const delta of deltas) {
|
||||||
|
if (delta.marketId !== marketId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (delta.sell) {
|
||||||
|
deltaRef.current.sell.push(...delta.sell);
|
||||||
|
}
|
||||||
|
if (delta.buy) {
|
||||||
|
deltaRef.current.buy.push(...delta.buy);
|
||||||
|
}
|
||||||
|
updateDepthData.current();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[decimalPlaces, positionDecimalPlaces]
|
[marketId, updateDepthData]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data, error, loading } = useDataProvider({
|
const { data, error, loading } = useDataProvider({
|
||||||
@ -81,53 +121,86 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
|||||||
variables,
|
variables,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: market,
|
||||||
|
error: marketError,
|
||||||
|
loading: marketLoading,
|
||||||
|
} = useDataProvider({
|
||||||
|
dataProvider: marketProvider,
|
||||||
|
noUpdate: true,
|
||||||
|
variables,
|
||||||
|
});
|
||||||
|
|
||||||
|
const marketDataUpdate = useCallback(({ data }: { data: MarketData }) => {
|
||||||
|
marketDataRef.current = data;
|
||||||
|
return true;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: marketData,
|
||||||
|
error: marketDataError,
|
||||||
|
loading: marketDataLoading,
|
||||||
|
} = useDataProvider({
|
||||||
|
dataProvider: marketDataProvider,
|
||||||
|
update: marketDataUpdate,
|
||||||
|
variables,
|
||||||
|
});
|
||||||
|
|
||||||
|
marketDataRef.current = marketData;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!marketData || !market || !data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!data) {
|
if (!data) {
|
||||||
dataRef.current = null;
|
dataRef.current = null;
|
||||||
setDepthData(dataRef.current);
|
setDepthData(dataRef.current);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dataRef.current = {
|
dataRef.current = {
|
||||||
midPrice: data.data?.staticMidPrice
|
midPrice: marketData.staticMidPrice
|
||||||
? formatMidPrice(data.data?.staticMidPrice, data.decimalPlaces)
|
? formatMidPrice(marketData.staticMidPrice, market.decimalPlaces)
|
||||||
: undefined,
|
: undefined,
|
||||||
data: {
|
data: {
|
||||||
buy:
|
buy:
|
||||||
data.depth.buy?.map((priceLevel) =>
|
data.depth.buy?.map((priceLevel) =>
|
||||||
parseLevel(
|
parseLevel(
|
||||||
priceLevel,
|
priceLevel,
|
||||||
data.decimalPlaces,
|
market.decimalPlaces,
|
||||||
data.positionDecimalPlaces
|
market.positionDecimalPlaces
|
||||||
)
|
)
|
||||||
) ?? [],
|
) ?? [],
|
||||||
sell:
|
sell:
|
||||||
data.depth.sell?.map((priceLevel) =>
|
data.depth.sell?.map((priceLevel) =>
|
||||||
parseLevel(
|
parseLevel(
|
||||||
priceLevel,
|
priceLevel,
|
||||||
data.decimalPlaces,
|
market.decimalPlaces,
|
||||||
data.positionDecimalPlaces
|
market.positionDecimalPlaces
|
||||||
)
|
)
|
||||||
) ?? [],
|
) ?? [],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
setDepthData(dataRef.current);
|
setDepthData(dataRef.current);
|
||||||
setDecimalPlaces(data.decimalPlaces);
|
}, [data, marketData, market]);
|
||||||
setPositionDecimalPlaces(data.positionDecimalPlaces);
|
|
||||||
}, [data]);
|
|
||||||
|
|
||||||
const volumeFormat = useCallback(
|
const volumeFormat = useCallback(
|
||||||
(volume: number) =>
|
(volume: number) =>
|
||||||
getNumberFormat(data?.positionDecimalPlaces || 0).format(volume),
|
getNumberFormat(market?.positionDecimalPlaces || 0).format(volume),
|
||||||
[data?.positionDecimalPlaces]
|
[market?.positionDecimalPlaces]
|
||||||
);
|
);
|
||||||
|
|
||||||
const priceFormat = useCallback(
|
const priceFormat = useCallback(
|
||||||
(price: number) => getNumberFormat(data?.decimalPlaces || 0).format(price),
|
(price: number) =>
|
||||||
[data?.decimalPlaces]
|
getNumberFormat(market?.decimalPlaces || 0).format(price),
|
||||||
|
[market?.decimalPlaces]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
<AsyncRenderer
|
||||||
|
loading={loading || marketLoading || marketDataLoading}
|
||||||
|
error={error || marketError || marketDataError}
|
||||||
|
data={data}
|
||||||
|
>
|
||||||
{depthData && (
|
{depthData && (
|
||||||
<DepthChart
|
<DepthChart
|
||||||
{...depthData}
|
{...depthData}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export * from './__generated__/MarketDepth';
|
export * from './__generated__/MarketDepth';
|
||||||
export * from './__generated__/MarketDepthSubscription';
|
export * from './__generated__/MarketDepthSubscription';
|
||||||
export * from './depth-chart';
|
export * from './depth-chart';
|
||||||
export * from './market-depth-data-provider';
|
export * from './market-depth-provider';
|
||||||
export * from './orderbook-container';
|
export * from './orderbook-container';
|
||||||
export * from './orderbook-data';
|
export * from './orderbook-data';
|
||||||
export * from './orderbook-manager';
|
export * from './orderbook-manager';
|
||||||
|
@ -1,138 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
import { makeDataProvider } from '@vegaprotocol/react-helpers';
|
|
||||||
import { updateLevels } from './orderbook-data';
|
|
||||||
import type { Update } from '@vegaprotocol/react-helpers';
|
|
||||||
import type {
|
|
||||||
MarketDepth,
|
|
||||||
MarketDepth_market,
|
|
||||||
} from './__generated__/MarketDepth';
|
|
||||||
import type {
|
|
||||||
MarketDepthSubscription,
|
|
||||||
MarketDepthSubscription_marketDepthUpdate,
|
|
||||||
} from './__generated__/MarketDepthSubscription';
|
|
||||||
|
|
||||||
const MARKET_DEPTH_QUERY = gql`
|
|
||||||
query MarketDepth($marketId: ID!) {
|
|
||||||
market(id: $marketId) {
|
|
||||||
id
|
|
||||||
decimalPlaces
|
|
||||||
positionDecimalPlaces
|
|
||||||
data {
|
|
||||||
staticMidPrice
|
|
||||||
marketTradingMode
|
|
||||||
indicativeVolume
|
|
||||||
indicativePrice
|
|
||||||
bestStaticBidPrice
|
|
||||||
bestStaticOfferPrice
|
|
||||||
market {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
depth {
|
|
||||||
lastTrade {
|
|
||||||
price
|
|
||||||
}
|
|
||||||
sell {
|
|
||||||
price
|
|
||||||
volume
|
|
||||||
numberOfOrders
|
|
||||||
}
|
|
||||||
buy {
|
|
||||||
price
|
|
||||||
volume
|
|
||||||
numberOfOrders
|
|
||||||
}
|
|
||||||
sequenceNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const MARKET_DEPTH_SUBSCRIPTION_QUERY = gql`
|
|
||||||
subscription MarketDepthSubscription($marketId: ID!) {
|
|
||||||
marketDepthUpdate(marketId: $marketId) {
|
|
||||||
market {
|
|
||||||
id
|
|
||||||
positionDecimalPlaces
|
|
||||||
data {
|
|
||||||
staticMidPrice
|
|
||||||
marketTradingMode
|
|
||||||
indicativeVolume
|
|
||||||
indicativePrice
|
|
||||||
bestStaticBidPrice
|
|
||||||
bestStaticOfferPrice
|
|
||||||
market {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sell {
|
|
||||||
price
|
|
||||||
volume
|
|
||||||
numberOfOrders
|
|
||||||
}
|
|
||||||
buy {
|
|
||||||
price
|
|
||||||
volume
|
|
||||||
numberOfOrders
|
|
||||||
}
|
|
||||||
sequenceNumber
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const sequenceNumbers: Record<string, number> = {};
|
|
||||||
|
|
||||||
const update: Update<
|
|
||||||
MarketDepth_market,
|
|
||||||
MarketDepthSubscription_marketDepthUpdate
|
|
||||||
> = (data, delta, reload) => {
|
|
||||||
if (delta.market.id !== data.id) {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
const sequenceNumber = Number(delta.sequenceNumber);
|
|
||||||
if (sequenceNumber <= sequenceNumbers[delta.market.id]) {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (sequenceNumber - 1 !== sequenceNumbers[delta.market.id]) {
|
|
||||||
sequenceNumbers[delta.market.id] = 0;
|
|
||||||
reload();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
sequenceNumbers[delta.market.id] = sequenceNumber;
|
|
||||||
const updatedData = {
|
|
||||||
...data,
|
|
||||||
data: delta.market.data,
|
|
||||||
depth: { ...data.depth },
|
|
||||||
};
|
|
||||||
if (delta.buy) {
|
|
||||||
updatedData.depth.buy = updateLevels(data.depth.buy ?? [], delta.buy);
|
|
||||||
}
|
|
||||||
if (delta.sell) {
|
|
||||||
updatedData.depth.sell = updateLevels(data.depth.sell ?? [], delta.sell);
|
|
||||||
}
|
|
||||||
return updatedData;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getData = (responseData: MarketDepth) => {
|
|
||||||
if (responseData.market?.id) {
|
|
||||||
sequenceNumbers[responseData.market.id] = Number(
|
|
||||||
responseData.market.depth.sequenceNumber
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return responseData.market;
|
|
||||||
};
|
|
||||||
const getDelta = (subscriptionData: MarketDepthSubscription) =>
|
|
||||||
subscriptionData.marketDepthUpdate;
|
|
||||||
|
|
||||||
export const marketDepthDataProvider = makeDataProvider({
|
|
||||||
query: MARKET_DEPTH_QUERY,
|
|
||||||
subscriptionQuery: MARKET_DEPTH_SUBSCRIPTION_QUERY,
|
|
||||||
update,
|
|
||||||
getData,
|
|
||||||
getDelta,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default marketDepthDataProvider;
|
|
111
libs/market-depth/src/lib/market-depth-provider.ts
Normal file
111
libs/market-depth/src/lib/market-depth-provider.ts
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
import { makeDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
|
import { updateLevels } from './orderbook-data';
|
||||||
|
import type { Update } from '@vegaprotocol/react-helpers';
|
||||||
|
import type {
|
||||||
|
MarketDepth,
|
||||||
|
MarketDepth_market,
|
||||||
|
} from './__generated__/MarketDepth';
|
||||||
|
import type {
|
||||||
|
MarketDepthSubscription,
|
||||||
|
MarketDepthSubscription_marketsDepthUpdate,
|
||||||
|
} from './__generated__/MarketDepthSubscription';
|
||||||
|
|
||||||
|
const MARKET_DEPTH_QUERY = gql`
|
||||||
|
query MarketDepth($marketId: ID!) {
|
||||||
|
market(id: $marketId) {
|
||||||
|
id
|
||||||
|
depth {
|
||||||
|
sell {
|
||||||
|
price
|
||||||
|
volume
|
||||||
|
numberOfOrders
|
||||||
|
}
|
||||||
|
buy {
|
||||||
|
price
|
||||||
|
volume
|
||||||
|
numberOfOrders
|
||||||
|
}
|
||||||
|
sequenceNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const MARKET_DEPTH_SUBSCRIPTION_QUERY = gql`
|
||||||
|
subscription MarketDepthSubscription($marketId: ID!) {
|
||||||
|
marketsDepthUpdate(marketIds: [$marketId]) {
|
||||||
|
marketId
|
||||||
|
sell {
|
||||||
|
price
|
||||||
|
volume
|
||||||
|
numberOfOrders
|
||||||
|
}
|
||||||
|
buy {
|
||||||
|
price
|
||||||
|
volume
|
||||||
|
numberOfOrders
|
||||||
|
}
|
||||||
|
sequenceNumber
|
||||||
|
previousSequenceNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const sequenceNumbers: Record<string, number> = {};
|
||||||
|
|
||||||
|
const update: Update<
|
||||||
|
MarketDepth_market,
|
||||||
|
MarketDepthSubscription_marketsDepthUpdate[]
|
||||||
|
> = (data, deltas, reload) => {
|
||||||
|
for (const delta of deltas) {
|
||||||
|
if (delta.marketId !== data.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const sequenceNumber = Number(delta.sequenceNumber);
|
||||||
|
if (sequenceNumber <= sequenceNumbers[delta.marketId]) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (sequenceNumber - 1 !== sequenceNumbers[delta.market.id]) {
|
||||||
|
sequenceNumbers[delta.market.id] = 0;
|
||||||
|
reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
sequenceNumbers[delta.marketId] = sequenceNumber;
|
||||||
|
const updatedData = {
|
||||||
|
...data,
|
||||||
|
depth: { ...data.depth },
|
||||||
|
};
|
||||||
|
if (delta.buy) {
|
||||||
|
updatedData.depth.buy = updateLevels(data.depth.buy ?? [], delta.buy);
|
||||||
|
}
|
||||||
|
if (delta.sell) {
|
||||||
|
updatedData.depth.sell = updateLevels(data.depth.sell ?? [], delta.sell);
|
||||||
|
}
|
||||||
|
return updatedData;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getData = (responseData: MarketDepth) => {
|
||||||
|
if (responseData.market?.id) {
|
||||||
|
sequenceNumbers[responseData.market.id] = Number(
|
||||||
|
responseData.market.depth.sequenceNumber
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return responseData.market;
|
||||||
|
};
|
||||||
|
const getDelta = (subscriptionData: MarketDepthSubscription) =>
|
||||||
|
subscriptionData.marketsDepthUpdate;
|
||||||
|
|
||||||
|
export const marketDepthProvider = makeDataProvider({
|
||||||
|
query: MARKET_DEPTH_QUERY,
|
||||||
|
subscriptionQuery: MARKET_DEPTH_SUBSCRIPTION_QUERY,
|
||||||
|
update,
|
||||||
|
getData,
|
||||||
|
getDelta,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default marketDepthProvider;
|
@ -1,15 +1,14 @@
|
|||||||
import groupBy from 'lodash/groupBy';
|
import groupBy from 'lodash/groupBy';
|
||||||
import { VolumeType } from '@vegaprotocol/react-helpers';
|
import { VolumeType } from '@vegaprotocol/react-helpers';
|
||||||
import { MarketTradingMode } from '@vegaprotocol/types';
|
import { MarketTradingMode } from '@vegaprotocol/types';
|
||||||
|
import type { MarketData } from '@vegaprotocol/market-list';
|
||||||
import type {
|
import type {
|
||||||
MarketDepth_market_depth_sell,
|
MarketDepth_market_depth_sell,
|
||||||
MarketDepth_market_depth_buy,
|
MarketDepth_market_depth_buy,
|
||||||
MarketDepth_market_data,
|
|
||||||
} from './__generated__/MarketDepth';
|
} from './__generated__/MarketDepth';
|
||||||
import type {
|
import type {
|
||||||
MarketDepthSubscription_marketDepthUpdate_sell,
|
MarketDepthSubscription_marketsDepthUpdate_sell,
|
||||||
MarketDepthSubscription_marketDepthUpdate_buy,
|
MarketDepthSubscription_marketsDepthUpdate_buy,
|
||||||
MarketDepthSubscription_marketDepthUpdate_market_data,
|
|
||||||
} from './__generated__/MarketDepthSubscription';
|
} from './__generated__/MarketDepthSubscription';
|
||||||
|
|
||||||
export interface CumulativeVol {
|
export interface CumulativeVol {
|
||||||
@ -33,7 +32,7 @@ export interface OrderbookRowData {
|
|||||||
type PartialOrderbookRowData = Pick<OrderbookRowData, 'price' | 'ask' | 'bid'>;
|
type PartialOrderbookRowData = Pick<OrderbookRowData, 'price' | 'ask' | 'bid'>;
|
||||||
|
|
||||||
export type OrderbookData = Partial<
|
export type OrderbookData = Partial<
|
||||||
Omit<MarketDepth_market_data, '__typename' | 'market'>
|
Omit<MarketData, '__typename' | 'market'>
|
||||||
> & { rows: OrderbookRowData[] | null };
|
> & { rows: OrderbookRowData[] | null };
|
||||||
|
|
||||||
export const getPriceLevel = (price: string | bigint, resolution: number) => {
|
export const getPriceLevel = (price: string | bigint, resolution: number) => {
|
||||||
@ -105,11 +104,13 @@ export const createRow = (
|
|||||||
const mapRawData =
|
const mapRawData =
|
||||||
(dataType: VolumeType.ask | VolumeType.bid) =>
|
(dataType: VolumeType.ask | VolumeType.bid) =>
|
||||||
(
|
(
|
||||||
data:
|
data: Omit<
|
||||||
| MarketDepth_market_depth_sell
|
| MarketDepth_market_depth_sell
|
||||||
| MarketDepthSubscription_marketDepthUpdate_sell
|
| MarketDepthSubscription_marketsDepthUpdate_sell
|
||||||
| MarketDepth_market_depth_buy
|
| MarketDepth_market_depth_buy
|
||||||
| MarketDepthSubscription_marketDepthUpdate_buy
|
| MarketDepthSubscription_marketsDepthUpdate_buy,
|
||||||
|
'__typename'
|
||||||
|
>
|
||||||
): PartialOrderbookRowData =>
|
): PartialOrderbookRowData =>
|
||||||
createPartialRow(data.price, Number(data.volume), dataType);
|
createPartialRow(data.price, Number(data.volume), dataType);
|
||||||
|
|
||||||
@ -118,16 +119,18 @@ const mapRawData =
|
|||||||
*/
|
*/
|
||||||
export const compactRows = (
|
export const compactRows = (
|
||||||
sell:
|
sell:
|
||||||
| (
|
| Omit<
|
||||||
| MarketDepth_market_depth_sell
|
| MarketDepth_market_depth_sell
|
||||||
| MarketDepthSubscription_marketDepthUpdate_sell
|
| MarketDepthSubscription_marketsDepthUpdate_sell,
|
||||||
)[]
|
'__typename'
|
||||||
|
>[]
|
||||||
| null,
|
| null,
|
||||||
buy:
|
buy:
|
||||||
| (
|
| Omit<
|
||||||
| MarketDepth_market_depth_buy
|
| MarketDepth_market_depth_buy
|
||||||
| MarketDepthSubscription_marketDepthUpdate_buy
|
| MarketDepthSubscription_marketsDepthUpdate_buy,
|
||||||
)[]
|
'__typename'
|
||||||
|
>[]
|
||||||
| null,
|
| null,
|
||||||
resolution: number
|
resolution: number
|
||||||
) => {
|
) => {
|
||||||
@ -199,8 +202,8 @@ const partiallyUpdateCompactedRows = (
|
|||||||
dataType: VolumeType,
|
dataType: VolumeType,
|
||||||
data: OrderbookRowData[],
|
data: OrderbookRowData[],
|
||||||
delta:
|
delta:
|
||||||
| MarketDepthSubscription_marketDepthUpdate_sell
|
| MarketDepthSubscription_marketsDepthUpdate_sell
|
||||||
| MarketDepthSubscription_marketDepthUpdate_buy,
|
| MarketDepthSubscription_marketsDepthUpdate_buy,
|
||||||
resolution: number,
|
resolution: number,
|
||||||
modifiedIndex: number
|
modifiedIndex: number
|
||||||
): [number, OrderbookRowData[]] => {
|
): [number, OrderbookRowData[]] => {
|
||||||
@ -255,8 +258,8 @@ const partiallyUpdateCompactedRows = (
|
|||||||
*/
|
*/
|
||||||
export const updateCompactedRows = (
|
export const updateCompactedRows = (
|
||||||
rows: OrderbookRowData[],
|
rows: OrderbookRowData[],
|
||||||
sell: MarketDepthSubscription_marketDepthUpdate_sell[] | null,
|
sell: MarketDepthSubscription_marketsDepthUpdate_sell[] | null,
|
||||||
buy: MarketDepthSubscription_marketDepthUpdate_buy[] | null,
|
buy: MarketDepthSubscription_marketsDepthUpdate_buy[] | null,
|
||||||
resolution: number
|
resolution: number
|
||||||
) => {
|
) => {
|
||||||
let sellModifiedIndex = -1;
|
let sellModifiedIndex = -1;
|
||||||
@ -320,10 +323,13 @@ export const updateCompactedRows = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const mapMarketData = (
|
export const mapMarketData = (
|
||||||
data:
|
data: Pick<
|
||||||
| MarketDepth_market_data
|
MarketData,
|
||||||
| MarketDepthSubscription_marketDepthUpdate_market_data
|
| 'staticMidPrice'
|
||||||
| null,
|
| 'bestStaticBidPrice'
|
||||||
|
| 'bestStaticOfferPrice'
|
||||||
|
| 'indicativePrice'
|
||||||
|
> | null,
|
||||||
resolution: number
|
resolution: number
|
||||||
) => ({
|
) => ({
|
||||||
staticMidPrice:
|
staticMidPrice:
|
||||||
@ -347,8 +353,8 @@ export const mapMarketData = (
|
|||||||
export const updateLevels = (
|
export const updateLevels = (
|
||||||
draft: (MarketDepth_market_depth_buy | MarketDepth_market_depth_sell)[],
|
draft: (MarketDepth_market_depth_buy | MarketDepth_market_depth_sell)[],
|
||||||
updates: (
|
updates: (
|
||||||
| MarketDepthSubscription_marketDepthUpdate_buy
|
| MarketDepthSubscription_marketsDepthUpdate_buy
|
||||||
| MarketDepthSubscription_marketDepthUpdate_sell
|
| MarketDepthSubscription_marketsDepthUpdate_sell
|
||||||
)[]
|
)[]
|
||||||
) => {
|
) => {
|
||||||
const levels = [...draft];
|
const levels = [...draft];
|
||||||
@ -399,41 +405,37 @@ export const generateMockData = ({
|
|||||||
}: MockDataGeneratorParams) => {
|
}: MockDataGeneratorParams) => {
|
||||||
let matrix = new Array(numberOfSellRows).fill(undefined);
|
let matrix = new Array(numberOfSellRows).fill(undefined);
|
||||||
let price = midPrice + (numberOfSellRows - Math.ceil(overlap / 2) + 1);
|
let price = midPrice + (numberOfSellRows - Math.ceil(overlap / 2) + 1);
|
||||||
const sell: MarketDepth_market_depth_sell[] = matrix.map((row, i) => ({
|
const sell: Omit<MarketDepth_market_depth_sell, '__typename'>[] = matrix.map(
|
||||||
__typename: 'PriceLevel',
|
(row, i) => ({
|
||||||
price: (price -= 1).toString(),
|
price: (price -= 1).toString(),
|
||||||
volume: (numberOfSellRows - i + 1).toString(),
|
volume: (numberOfSellRows - i + 1).toString(),
|
||||||
numberOfOrders: '',
|
numberOfOrders: '',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
price += overlap;
|
price += overlap;
|
||||||
matrix = new Array(numberOfBuyRows).fill(undefined);
|
matrix = new Array(numberOfBuyRows).fill(undefined);
|
||||||
const buy: MarketDepth_market_depth_buy[] = matrix.map((row, i) => ({
|
const buy: Omit<MarketDepth_market_depth_buy, '__typename'>[] = matrix.map(
|
||||||
__typename: 'PriceLevel',
|
(row, i) => ({
|
||||||
price: (price -= 1).toString(),
|
price: (price -= 1).toString(),
|
||||||
volume: (i + 2).toString(),
|
volume: (i + 2).toString(),
|
||||||
numberOfOrders: '',
|
numberOfOrders: '',
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
const rows = compactRows(sell, buy, resolution);
|
const rows = compactRows(sell, buy, resolution);
|
||||||
return {
|
return {
|
||||||
rows,
|
rows,
|
||||||
resolution,
|
resolution,
|
||||||
indicativeVolume: indicativeVolume?.toString(),
|
indicativeVolume: indicativeVolume?.toString(),
|
||||||
|
marketTradingMode:
|
||||||
|
overlap > 0
|
||||||
|
? MarketTradingMode.TRADING_MODE_BATCH_AUCTION
|
||||||
|
: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
...mapMarketData(
|
...mapMarketData(
|
||||||
{
|
{
|
||||||
__typename: 'MarketData',
|
|
||||||
staticMidPrice: '',
|
staticMidPrice: '',
|
||||||
marketTradingMode:
|
|
||||||
overlap > 0
|
|
||||||
? MarketTradingMode.TRADING_MODE_BATCH_AUCTION
|
|
||||||
: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
bestStaticBidPrice: bestStaticBidPrice.toString(),
|
bestStaticBidPrice: bestStaticBidPrice.toString(),
|
||||||
bestStaticOfferPrice: bestStaticOfferPrice.toString(),
|
bestStaticOfferPrice: bestStaticOfferPrice.toString(),
|
||||||
indicativePrice: indicativePrice?.toString() ?? '',
|
indicativePrice: indicativePrice?.toString() ?? '',
|
||||||
indicativeVolume: indicativeVolume?.toString() ?? '',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: '',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
resolution
|
resolution
|
||||||
),
|
),
|
||||||
|
@ -2,9 +2,15 @@ import throttle from 'lodash/throttle';
|
|||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import { Orderbook } from './orderbook';
|
import { Orderbook } from './orderbook';
|
||||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import dataProvider from './market-depth-data-provider';
|
import marketDepthProvider from './market-depth-provider';
|
||||||
|
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||||
|
import type { MarketData } from '@vegaprotocol/market-list';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import type { MarketDepthSubscription_marketDepthUpdate } from './__generated__/MarketDepthSubscription';
|
import type {
|
||||||
|
MarketDepthSubscription_marketsDepthUpdate,
|
||||||
|
MarketDepthSubscription_marketsDepthUpdate_sell,
|
||||||
|
MarketDepthSubscription_marketsDepthUpdate_buy,
|
||||||
|
} from './__generated__/MarketDepthSubscription';
|
||||||
import {
|
import {
|
||||||
compactRows,
|
compactRows,
|
||||||
updateCompactedRows,
|
updateCompactedRows,
|
||||||
@ -24,82 +30,116 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
|
|||||||
rows: null,
|
rows: null,
|
||||||
});
|
});
|
||||||
const dataRef = useRef<OrderbookData>({ rows: null });
|
const dataRef = useRef<OrderbookData>({ rows: null });
|
||||||
const deltaRef = useRef<MarketDepthSubscription_marketDepthUpdate>();
|
const marketDataRef = useRef<MarketData | null>(null);
|
||||||
|
const deltaRef = useRef<{
|
||||||
|
sell: MarketDepthSubscription_marketsDepthUpdate_sell[];
|
||||||
|
buy: MarketDepthSubscription_marketsDepthUpdate_buy[];
|
||||||
|
}>({
|
||||||
|
sell: [],
|
||||||
|
buy: [],
|
||||||
|
});
|
||||||
const updateOrderbookData = useRef(
|
const updateOrderbookData = useRef(
|
||||||
throttle(() => {
|
throttle(() => {
|
||||||
if (!deltaRef.current) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dataRef.current = {
|
dataRef.current = {
|
||||||
...deltaRef.current.market.data,
|
...marketDataRef.current,
|
||||||
...mapMarketData(deltaRef.current.market.data, resolutionRef.current),
|
...mapMarketData(marketDataRef.current, resolutionRef.current),
|
||||||
rows: updateCompactedRows(
|
rows:
|
||||||
dataRef.current.rows ?? [],
|
deltaRef.current.buy.length || deltaRef.current.sell.length
|
||||||
deltaRef.current.sell,
|
? updateCompactedRows(
|
||||||
deltaRef.current.buy,
|
dataRef.current.rows ?? [],
|
||||||
resolutionRef.current
|
deltaRef.current.sell,
|
||||||
),
|
deltaRef.current.buy,
|
||||||
|
resolutionRef.current
|
||||||
|
)
|
||||||
|
: dataRef.current.rows,
|
||||||
};
|
};
|
||||||
deltaRef.current = undefined;
|
deltaRef.current.buy = [];
|
||||||
|
deltaRef.current.sell = [];
|
||||||
setOrderbookData(dataRef.current);
|
setOrderbookData(dataRef.current);
|
||||||
}, 1000)
|
}, 1000)
|
||||||
);
|
);
|
||||||
|
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
({ delta }: { delta: MarketDepthSubscription_marketDepthUpdate }) => {
|
({
|
||||||
|
delta: deltas,
|
||||||
|
}: {
|
||||||
|
delta: MarketDepthSubscription_marketsDepthUpdate[];
|
||||||
|
}) => {
|
||||||
if (!dataRef.current.rows) {
|
if (!dataRef.current.rows) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (deltaRef.current) {
|
for (const delta of deltas) {
|
||||||
deltaRef.current.market = delta.market;
|
if (delta.marketId !== marketId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (delta.sell) {
|
if (delta.sell) {
|
||||||
if (deltaRef.current.sell) {
|
deltaRef.current.sell.push(...delta.sell);
|
||||||
deltaRef.current.sell.push(...delta.sell);
|
|
||||||
} else {
|
|
||||||
deltaRef.current.sell = delta.sell;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (delta.buy) {
|
if (delta.buy) {
|
||||||
if (deltaRef.current.buy) {
|
deltaRef.current.buy.push(...delta.buy);
|
||||||
deltaRef.current.buy.push(...delta.buy);
|
|
||||||
} else {
|
|
||||||
deltaRef.current.buy = delta.buy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
updateOrderbookData.current();
|
||||||
deltaRef.current = delta;
|
|
||||||
}
|
}
|
||||||
updateOrderbookData.current();
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
// using resolutionRef.current to avoid using resolution as a dependency - it will cause data provider restart on resolution change
|
[marketId, updateOrderbookData]
|
||||||
[]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data, error, loading, flush } = useDataProvider({
|
const { data, error, loading, flush } = useDataProvider({
|
||||||
dataProvider,
|
dataProvider: marketDepthProvider,
|
||||||
update,
|
update,
|
||||||
variables,
|
variables,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: market,
|
||||||
|
error: marketError,
|
||||||
|
loading: marketLoading,
|
||||||
|
} = useDataProvider({
|
||||||
|
dataProvider: marketProvider,
|
||||||
|
noUpdate: true,
|
||||||
|
variables,
|
||||||
|
});
|
||||||
|
|
||||||
|
const marketDataUpdate = useCallback(({ data }: { data: MarketData }) => {
|
||||||
|
marketDataRef.current = data;
|
||||||
|
updateOrderbookData.current();
|
||||||
|
return true;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: marketData,
|
||||||
|
error: marketDataError,
|
||||||
|
loading: marketDataLoading,
|
||||||
|
} = useDataProvider({
|
||||||
|
dataProvider: marketDataProvider,
|
||||||
|
update: marketDataUpdate,
|
||||||
|
variables,
|
||||||
|
});
|
||||||
|
|
||||||
|
marketDataRef.current = marketData;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const throttleRunnner = updateOrderbookData.current;
|
const throttleRunnner = updateOrderbookData.current;
|
||||||
|
if (!marketDataRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!data) {
|
if (!data) {
|
||||||
dataRef.current = { rows: null };
|
dataRef.current = { rows: null };
|
||||||
setOrderbookData(dataRef.current);
|
setOrderbookData(dataRef.current);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dataRef.current = {
|
dataRef.current = {
|
||||||
...data.data,
|
...marketDataRef.current,
|
||||||
|
...mapMarketData(marketDataRef.current, resolution),
|
||||||
rows: compactRows(data.depth.sell, data.depth.buy, resolution),
|
rows: compactRows(data.depth.sell, data.depth.buy, resolution),
|
||||||
...mapMarketData(data.data, resolution),
|
|
||||||
};
|
};
|
||||||
setOrderbookData(dataRef.current);
|
setOrderbookData(dataRef.current);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
throttleRunnner.cancel();
|
throttleRunnner.cancel();
|
||||||
};
|
};
|
||||||
}, [data, resolution]);
|
}, [data, marketData, resolution]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
resolutionRef.current = resolution;
|
resolutionRef.current = resolution;
|
||||||
@ -107,11 +147,15 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
|
|||||||
}, [resolution, flush]);
|
}, [resolution, flush]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
<AsyncRenderer
|
||||||
|
loading={loading || marketDataLoading || marketLoading}
|
||||||
|
error={error || marketDataError || marketError}
|
||||||
|
data={data}
|
||||||
|
>
|
||||||
<Orderbook
|
<Orderbook
|
||||||
{...orderbookData}
|
{...orderbookData}
|
||||||
decimalPlaces={data?.decimalPlaces ?? 0}
|
decimalPlaces={market?.decimalPlaces ?? 0}
|
||||||
positionDecimalPlaces={data?.positionDecimalPlaces ?? 0}
|
positionDecimalPlaces={market?.positionDecimalPlaces ?? 0}
|
||||||
resolution={resolution}
|
resolution={resolution}
|
||||||
onResolutionChange={(resolution: number) => setResolution(resolution)}
|
onResolutionChange={(resolution: number) => setResolution(resolution)}
|
||||||
/>
|
/>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import throttle from 'lodash/throttle';
|
import throttle from 'lodash/throttle';
|
||||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import dataProvider from './market-depth-data-provider';
|
import dataProvider from './market-depth-provider';
|
||||||
import type { MarketDepth_market } from './';
|
import type { MarketDepth_market } from './__generated__/MarketDepth';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
variables: { marketId: string };
|
variables: { marketId: string };
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
fragment MarketDataFields on MarketData {
|
|
||||||
market {
|
|
||||||
id
|
|
||||||
state
|
|
||||||
tradingMode
|
|
||||||
}
|
|
||||||
bestBidPrice
|
|
||||||
bestOfferPrice
|
|
||||||
markPrice
|
|
||||||
trigger
|
|
||||||
indicativeVolume
|
|
||||||
}
|
|
||||||
|
|
||||||
query MarketList($interval: Interval!, $since: String!) {
|
|
||||||
markets {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
decimalPlaces
|
|
||||||
positionDecimalPlaces
|
|
||||||
state
|
|
||||||
tradingMode
|
|
||||||
fees {
|
|
||||||
factors {
|
|
||||||
makerFee
|
|
||||||
infrastructureFee
|
|
||||||
liquidityFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data {
|
|
||||||
market {
|
|
||||||
id
|
|
||||||
state
|
|
||||||
tradingMode
|
|
||||||
}
|
|
||||||
bestBidPrice
|
|
||||||
bestOfferPrice
|
|
||||||
markPrice
|
|
||||||
trigger
|
|
||||||
indicativeVolume
|
|
||||||
}
|
|
||||||
tradableInstrument {
|
|
||||||
instrument {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
code
|
|
||||||
metadata {
|
|
||||||
tags
|
|
||||||
}
|
|
||||||
product {
|
|
||||||
... on Future {
|
|
||||||
settlementAsset {
|
|
||||||
symbol
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
marketTimestamps {
|
|
||||||
open
|
|
||||||
close
|
|
||||||
}
|
|
||||||
candles(interval: $interval, since: $since) {
|
|
||||||
open
|
|
||||||
close
|
|
||||||
high
|
|
||||||
low
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
subscription MarketDataSub {
|
|
||||||
marketData {
|
|
||||||
...MarketDataFields
|
|
||||||
}
|
|
||||||
}
|
|
78
libs/market-list/src/lib/__generated__/MarketCandlesQuery.ts
generated
Normal file
78
libs/market-list/src/lib/__generated__/MarketCandlesQuery.ts
generated
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @generated
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { Interval } from "@vegaprotocol/types";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL query operation: MarketCandlesQuery
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node {
|
||||||
|
__typename: "CandleNode";
|
||||||
|
/**
|
||||||
|
* High price (uint64)
|
||||||
|
*/
|
||||||
|
high: string;
|
||||||
|
/**
|
||||||
|
* Low price (uint64)
|
||||||
|
*/
|
||||||
|
low: string;
|
||||||
|
/**
|
||||||
|
* Open price (uint64)
|
||||||
|
*/
|
||||||
|
open: string;
|
||||||
|
/**
|
||||||
|
* Close price (uint64)
|
||||||
|
*/
|
||||||
|
close: string;
|
||||||
|
/**
|
||||||
|
* Volume price (uint64)
|
||||||
|
*/
|
||||||
|
volume: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges {
|
||||||
|
__typename: "CandleEdge";
|
||||||
|
node: MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketCandlesQuery_marketsConnection_edges_node_candlesConnection {
|
||||||
|
__typename: "CandleDataConnection";
|
||||||
|
/**
|
||||||
|
* The candles
|
||||||
|
*/
|
||||||
|
edges: (MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges | null)[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketCandlesQuery_marketsConnection_edges_node {
|
||||||
|
__typename: "Market";
|
||||||
|
/**
|
||||||
|
* Candles on a market, for the 'last' n candles, at 'interval' seconds as specified by parameters using cursor based pagination
|
||||||
|
*/
|
||||||
|
candlesConnection: MarketCandlesQuery_marketsConnection_edges_node_candlesConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketCandlesQuery_marketsConnection_edges {
|
||||||
|
__typename: "MarketEdge";
|
||||||
|
node: MarketCandlesQuery_marketsConnection_edges_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketCandlesQuery_marketsConnection {
|
||||||
|
__typename: "MarketConnection";
|
||||||
|
/**
|
||||||
|
* The markets in this connection
|
||||||
|
*/
|
||||||
|
edges: MarketCandlesQuery_marketsConnection_edges[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketCandlesQuery {
|
||||||
|
marketsConnection: MarketCandlesQuery_marketsConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketCandlesQueryVariables {
|
||||||
|
interval: Interval;
|
||||||
|
since: string;
|
||||||
|
marketId: string;
|
||||||
|
}
|
46
libs/market-list/src/lib/__generated__/MarketCandlesSub.ts
generated
Normal file
46
libs/market-list/src/lib/__generated__/MarketCandlesSub.ts
generated
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @generated
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { Interval } from "@vegaprotocol/types";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL subscription operation: MarketCandlesSub
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface MarketCandlesSub_candles {
|
||||||
|
__typename: "Candle";
|
||||||
|
/**
|
||||||
|
* High price (uint64)
|
||||||
|
*/
|
||||||
|
high: string;
|
||||||
|
/**
|
||||||
|
* Low price (uint64)
|
||||||
|
*/
|
||||||
|
low: string;
|
||||||
|
/**
|
||||||
|
* Open price (uint64)
|
||||||
|
*/
|
||||||
|
open: string;
|
||||||
|
/**
|
||||||
|
* Close price (uint64)
|
||||||
|
*/
|
||||||
|
close: string;
|
||||||
|
/**
|
||||||
|
* Volume price (uint64)
|
||||||
|
*/
|
||||||
|
volume: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketCandlesSub {
|
||||||
|
/**
|
||||||
|
* Subscribe to the candles updates
|
||||||
|
*/
|
||||||
|
candles: MarketCandlesSub_candles;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketCandlesSubVariables {
|
||||||
|
marketId: string;
|
||||||
|
interval: Interval;
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { MarketState, MarketTradingMode, AuctionTrigger } from "@vegaprotocol/types";
|
import { AuctionTrigger, MarketTradingMode } from "@vegaprotocol/types";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: MarketDataFields
|
// GraphQL fragment: MarketDataFields
|
||||||
@ -15,20 +15,12 @@ export interface MarketDataFields_market {
|
|||||||
* Market ID
|
* Market ID
|
||||||
*/
|
*/
|
||||||
id: string;
|
id: string;
|
||||||
/**
|
|
||||||
* Current state of the market
|
|
||||||
*/
|
|
||||||
state: MarketState;
|
|
||||||
/**
|
|
||||||
* Current mode of execution of the market
|
|
||||||
*/
|
|
||||||
tradingMode: MarketTradingMode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketDataFields {
|
export interface MarketDataFields {
|
||||||
__typename: "MarketData";
|
__typename: "MarketData";
|
||||||
/**
|
/**
|
||||||
* market ID of the associated mark price
|
* market of the associated mark price
|
||||||
*/
|
*/
|
||||||
market: MarketDataFields_market;
|
market: MarketDataFields_market;
|
||||||
/**
|
/**
|
||||||
@ -47,8 +39,28 @@ export interface MarketDataFields {
|
|||||||
* what triggered an auction (if an auction was started)
|
* what triggered an auction (if an auction was started)
|
||||||
*/
|
*/
|
||||||
trigger: AuctionTrigger;
|
trigger: AuctionTrigger;
|
||||||
|
/**
|
||||||
|
* the arithmetic average of the best static bid price and best static offer price
|
||||||
|
*/
|
||||||
|
staticMidPrice: string;
|
||||||
|
/**
|
||||||
|
* what state the market is in (auction, continuous, etc)
|
||||||
|
*/
|
||||||
|
marketTradingMode: MarketTradingMode;
|
||||||
/**
|
/**
|
||||||
* indicative volume if the auction ended now, 0 if not in auction mode
|
* indicative volume if the auction ended now, 0 if not in auction mode
|
||||||
*/
|
*/
|
||||||
indicativeVolume: string;
|
indicativeVolume: string;
|
||||||
|
/**
|
||||||
|
* indicative price if the auction ended now, 0 if not in auction mode
|
||||||
|
*/
|
||||||
|
indicativePrice: string;
|
||||||
|
/**
|
||||||
|
* the highest price level on an order book for buy orders not including pegged orders.
|
||||||
|
*/
|
||||||
|
bestStaticBidPrice: string;
|
||||||
|
/**
|
||||||
|
* the lowest price level on an order book for offer orders not including pegged orders.
|
||||||
|
*/
|
||||||
|
bestStaticOfferPrice: string;
|
||||||
}
|
}
|
||||||
|
95
libs/market-list/src/lib/__generated__/MarketDataQuery.ts
generated
Normal file
95
libs/market-list/src/lib/__generated__/MarketDataQuery.ts
generated
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @generated
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { AuctionTrigger, MarketTradingMode } from "@vegaprotocol/types";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL query operation: MarketDataQuery
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface MarketDataQuery_marketsConnection_edges_node_data_market {
|
||||||
|
__typename: "Market";
|
||||||
|
/**
|
||||||
|
* Market ID
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketDataQuery_marketsConnection_edges_node_data {
|
||||||
|
__typename: "MarketData";
|
||||||
|
/**
|
||||||
|
* market of the associated mark price
|
||||||
|
*/
|
||||||
|
market: MarketDataQuery_marketsConnection_edges_node_data_market;
|
||||||
|
/**
|
||||||
|
* the highest price level on an order book for buy orders.
|
||||||
|
*/
|
||||||
|
bestBidPrice: string;
|
||||||
|
/**
|
||||||
|
* the lowest price level on an order book for offer orders.
|
||||||
|
*/
|
||||||
|
bestOfferPrice: string;
|
||||||
|
/**
|
||||||
|
* the mark price (an unsigned integer)
|
||||||
|
*/
|
||||||
|
markPrice: string;
|
||||||
|
/**
|
||||||
|
* what triggered an auction (if an auction was started)
|
||||||
|
*/
|
||||||
|
trigger: AuctionTrigger;
|
||||||
|
/**
|
||||||
|
* the arithmetic average of the best static bid price and best static offer price
|
||||||
|
*/
|
||||||
|
staticMidPrice: string;
|
||||||
|
/**
|
||||||
|
* what state the market is in (auction, continuous, etc)
|
||||||
|
*/
|
||||||
|
marketTradingMode: MarketTradingMode;
|
||||||
|
/**
|
||||||
|
* indicative volume if the auction ended now, 0 if not in auction mode
|
||||||
|
*/
|
||||||
|
indicativeVolume: string;
|
||||||
|
/**
|
||||||
|
* indicative price if the auction ended now, 0 if not in auction mode
|
||||||
|
*/
|
||||||
|
indicativePrice: string;
|
||||||
|
/**
|
||||||
|
* the highest price level on an order book for buy orders not including pegged orders.
|
||||||
|
*/
|
||||||
|
bestStaticBidPrice: string;
|
||||||
|
/**
|
||||||
|
* the lowest price level on an order book for offer orders not including pegged orders.
|
||||||
|
*/
|
||||||
|
bestStaticOfferPrice: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketDataQuery_marketsConnection_edges_node {
|
||||||
|
__typename: "Market";
|
||||||
|
/**
|
||||||
|
* marketData for the given market
|
||||||
|
*/
|
||||||
|
data: MarketDataQuery_marketsConnection_edges_node_data | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketDataQuery_marketsConnection_edges {
|
||||||
|
__typename: "MarketEdge";
|
||||||
|
node: MarketDataQuery_marketsConnection_edges_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketDataQuery_marketsConnection {
|
||||||
|
__typename: "MarketConnection";
|
||||||
|
/**
|
||||||
|
* The markets in this connection
|
||||||
|
*/
|
||||||
|
edges: MarketDataQuery_marketsConnection_edges[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketDataQuery {
|
||||||
|
marketsConnection: MarketDataQuery_marketsConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketDataQueryVariables {
|
||||||
|
id: string;
|
||||||
|
}
|
@ -3,34 +3,18 @@
|
|||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { MarketState, MarketTradingMode, AuctionTrigger } from "@vegaprotocol/types";
|
import { AuctionTrigger, MarketTradingMode } from "@vegaprotocol/types";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL subscription operation: MarketDataSub
|
// GraphQL subscription operation: MarketDataSub
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface MarketDataSub_marketData_market {
|
export interface MarketDataSub_marketsData {
|
||||||
__typename: "Market";
|
__typename: "ObservableMarketData";
|
||||||
/**
|
|
||||||
* Market ID
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
/**
|
|
||||||
* Current state of the market
|
|
||||||
*/
|
|
||||||
state: MarketState;
|
|
||||||
/**
|
|
||||||
* Current mode of execution of the market
|
|
||||||
*/
|
|
||||||
tradingMode: MarketTradingMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketDataSub_marketData {
|
|
||||||
__typename: "MarketData";
|
|
||||||
/**
|
/**
|
||||||
* market ID of the associated mark price
|
* market ID of the associated mark price
|
||||||
*/
|
*/
|
||||||
market: MarketDataSub_marketData_market;
|
marketId: string;
|
||||||
/**
|
/**
|
||||||
* the highest price level on an order book for buy orders.
|
* the highest price level on an order book for buy orders.
|
||||||
*/
|
*/
|
||||||
@ -47,15 +31,39 @@ export interface MarketDataSub_marketData {
|
|||||||
* what triggered an auction (if an auction was started)
|
* what triggered an auction (if an auction was started)
|
||||||
*/
|
*/
|
||||||
trigger: AuctionTrigger;
|
trigger: AuctionTrigger;
|
||||||
|
/**
|
||||||
|
* the arithmetic average of the best static bid price and best static offer price
|
||||||
|
*/
|
||||||
|
staticMidPrice: string;
|
||||||
|
/**
|
||||||
|
* what state the market is in (auction, continuous etc)
|
||||||
|
*/
|
||||||
|
marketTradingMode: MarketTradingMode;
|
||||||
/**
|
/**
|
||||||
* indicative volume if the auction ended now, 0 if not in auction mode
|
* indicative volume if the auction ended now, 0 if not in auction mode
|
||||||
*/
|
*/
|
||||||
indicativeVolume: string;
|
indicativeVolume: string;
|
||||||
|
/**
|
||||||
|
* indicative price if the auction ended now, 0 if not in auction mode
|
||||||
|
*/
|
||||||
|
indicativePrice: string;
|
||||||
|
/**
|
||||||
|
* the highest price level on an order book for buy orders not including pegged orders.
|
||||||
|
*/
|
||||||
|
bestStaticBidPrice: string;
|
||||||
|
/**
|
||||||
|
* the lowest price level on an order book for offer orders not including pegged orders
|
||||||
|
*/
|
||||||
|
bestStaticOfferPrice: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketDataSub {
|
export interface MarketDataSub {
|
||||||
/**
|
/**
|
||||||
* Subscribe to the mark price changes
|
* Subscribe to the mark price changes
|
||||||
*/
|
*/
|
||||||
marketData: MarketDataSub_marketData;
|
marketsData: MarketDataSub_marketsData[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketDataSubVariables {
|
||||||
|
id: string;
|
||||||
}
|
}
|
||||||
|
154
libs/market-list/src/lib/__generated__/MarketFields.ts
generated
Normal file
154
libs/market-list/src/lib/__generated__/MarketFields.ts
generated
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @generated
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { MarketState, MarketTradingMode } from "@vegaprotocol/types";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL fragment: MarketFields
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface MarketFields_fees_factors {
|
||||||
|
__typename: "FeeFactors";
|
||||||
|
/**
|
||||||
|
* The factor applied to calculate MakerFees, a non-negative float
|
||||||
|
*/
|
||||||
|
makerFee: string;
|
||||||
|
/**
|
||||||
|
* The factor applied to calculate InfrastructureFees, a non-negative float
|
||||||
|
*/
|
||||||
|
infrastructureFee: string;
|
||||||
|
/**
|
||||||
|
* The factor applied to calculate LiquidityFees, a non-negative float
|
||||||
|
*/
|
||||||
|
liquidityFee: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketFields_fees {
|
||||||
|
__typename: "Fees";
|
||||||
|
/**
|
||||||
|
* The factors used to calculate the different fees
|
||||||
|
*/
|
||||||
|
factors: MarketFields_fees_factors;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketFields_tradableInstrument_instrument_metadata {
|
||||||
|
__typename: "InstrumentMetadata";
|
||||||
|
/**
|
||||||
|
* An arbitrary list of tags to associated to associate to the Instrument (string list)
|
||||||
|
*/
|
||||||
|
tags: string[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketFields_tradableInstrument_instrument_product_settlementAsset {
|
||||||
|
__typename: "Asset";
|
||||||
|
/**
|
||||||
|
* The symbol of the asset (e.g: GBP)
|
||||||
|
*/
|
||||||
|
symbol: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketFields_tradableInstrument_instrument_product {
|
||||||
|
__typename: "Future";
|
||||||
|
/**
|
||||||
|
* The name of the asset (string)
|
||||||
|
*/
|
||||||
|
settlementAsset: MarketFields_tradableInstrument_instrument_product_settlementAsset;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketFields_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: MarketFields_tradableInstrument_instrument_metadata;
|
||||||
|
/**
|
||||||
|
* A reference to or instance of a fully specified product, including all required product parameters for that product (Product union)
|
||||||
|
*/
|
||||||
|
product: MarketFields_tradableInstrument_instrument_product;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketFields_tradableInstrument {
|
||||||
|
__typename: "TradableInstrument";
|
||||||
|
/**
|
||||||
|
* An instance of, or reference to, a fully specified instrument.
|
||||||
|
*/
|
||||||
|
instrument: MarketFields_tradableInstrument_instrument;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketFields_marketTimestamps {
|
||||||
|
__typename: "MarketTimestamps";
|
||||||
|
/**
|
||||||
|
* Time when the market is open and ready to accept trades
|
||||||
|
*/
|
||||||
|
open: string | null;
|
||||||
|
/**
|
||||||
|
* Time when the market is closed
|
||||||
|
*/
|
||||||
|
close: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketFields {
|
||||||
|
__typename: "Market";
|
||||||
|
/**
|
||||||
|
* Market ID
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
/**
|
||||||
|
* 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 )
|
||||||
|
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
|
||||||
|
*/
|
||||||
|
decimalPlaces: number;
|
||||||
|
/**
|
||||||
|
* positionDecimalPlaces indicates the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
|
||||||
|
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
|
||||||
|
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
|
||||||
|
* This sets how big the smallest order / position on the market can be.
|
||||||
|
*/
|
||||||
|
positionDecimalPlaces: number;
|
||||||
|
/**
|
||||||
|
* Current state of the market
|
||||||
|
*/
|
||||||
|
state: MarketState;
|
||||||
|
/**
|
||||||
|
* Current mode of execution of the market
|
||||||
|
*/
|
||||||
|
tradingMode: MarketTradingMode;
|
||||||
|
/**
|
||||||
|
* Fees related data
|
||||||
|
*/
|
||||||
|
fees: MarketFields_fees;
|
||||||
|
/**
|
||||||
|
* An instance of, or reference to, a tradable instrument.
|
||||||
|
*/
|
||||||
|
tradableInstrument: MarketFields_tradableInstrument;
|
||||||
|
/**
|
||||||
|
* timestamps for state changes in the market
|
||||||
|
*/
|
||||||
|
marketTimestamps: MarketFields_marketTimestamps;
|
||||||
|
}
|
@ -3,13 +3,13 @@
|
|||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { Interval, MarketState, MarketTradingMode, AuctionTrigger } from "@vegaprotocol/types";
|
import { MarketState, MarketTradingMode } from "@vegaprotocol/types";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: MarketList
|
// GraphQL query operation: Markets
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface MarketList_markets_fees_factors {
|
export interface Markets_marketsConnection_edges_node_fees_factors {
|
||||||
__typename: "FeeFactors";
|
__typename: "FeeFactors";
|
||||||
/**
|
/**
|
||||||
* The factor applied to calculate MakerFees, a non-negative float
|
* The factor applied to calculate MakerFees, a non-negative float
|
||||||
@ -25,59 +25,15 @@ export interface MarketList_markets_fees_factors {
|
|||||||
liquidityFee: string;
|
liquidityFee: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketList_markets_fees {
|
export interface Markets_marketsConnection_edges_node_fees {
|
||||||
__typename: "Fees";
|
__typename: "Fees";
|
||||||
/**
|
/**
|
||||||
* The factors used to calculate the different fees
|
* The factors used to calculate the different fees
|
||||||
*/
|
*/
|
||||||
factors: MarketList_markets_fees_factors;
|
factors: Markets_marketsConnection_edges_node_fees_factors;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketList_markets_data_market {
|
export interface Markets_marketsConnection_edges_node_tradableInstrument_instrument_metadata {
|
||||||
__typename: "Market";
|
|
||||||
/**
|
|
||||||
* Market ID
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
/**
|
|
||||||
* Current state of the market
|
|
||||||
*/
|
|
||||||
state: MarketState;
|
|
||||||
/**
|
|
||||||
* Current mode of execution of the market
|
|
||||||
*/
|
|
||||||
tradingMode: MarketTradingMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketList_markets_data {
|
|
||||||
__typename: "MarketData";
|
|
||||||
/**
|
|
||||||
* market ID of the associated mark price
|
|
||||||
*/
|
|
||||||
market: MarketList_markets_data_market;
|
|
||||||
/**
|
|
||||||
* the highest price level on an order book for buy orders.
|
|
||||||
*/
|
|
||||||
bestBidPrice: string;
|
|
||||||
/**
|
|
||||||
* the lowest price level on an order book for offer orders.
|
|
||||||
*/
|
|
||||||
bestOfferPrice: string;
|
|
||||||
/**
|
|
||||||
* the mark price (an unsigned integer)
|
|
||||||
*/
|
|
||||||
markPrice: string;
|
|
||||||
/**
|
|
||||||
* what triggered an auction (if an auction was started)
|
|
||||||
*/
|
|
||||||
trigger: AuctionTrigger;
|
|
||||||
/**
|
|
||||||
* indicative volume if the auction ended now, 0 if not in auction mode
|
|
||||||
*/
|
|
||||||
indicativeVolume: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketList_markets_tradableInstrument_instrument_metadata {
|
|
||||||
__typename: "InstrumentMetadata";
|
__typename: "InstrumentMetadata";
|
||||||
/**
|
/**
|
||||||
* An arbitrary list of tags to associated to associate to the Instrument (string list)
|
* An arbitrary list of tags to associated to associate to the Instrument (string list)
|
||||||
@ -85,7 +41,7 @@ export interface MarketList_markets_tradableInstrument_instrument_metadata {
|
|||||||
tags: string[] | null;
|
tags: string[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketList_markets_tradableInstrument_instrument_product_settlementAsset {
|
export interface Markets_marketsConnection_edges_node_tradableInstrument_instrument_product_settlementAsset {
|
||||||
__typename: "Asset";
|
__typename: "Asset";
|
||||||
/**
|
/**
|
||||||
* The symbol of the asset (e.g: GBP)
|
* The symbol of the asset (e.g: GBP)
|
||||||
@ -93,15 +49,15 @@ export interface MarketList_markets_tradableInstrument_instrument_product_settle
|
|||||||
symbol: string;
|
symbol: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketList_markets_tradableInstrument_instrument_product {
|
export interface Markets_marketsConnection_edges_node_tradableInstrument_instrument_product {
|
||||||
__typename: "Future";
|
__typename: "Future";
|
||||||
/**
|
/**
|
||||||
* The name of the asset (string)
|
* The name of the asset (string)
|
||||||
*/
|
*/
|
||||||
settlementAsset: MarketList_markets_tradableInstrument_instrument_product_settlementAsset;
|
settlementAsset: Markets_marketsConnection_edges_node_tradableInstrument_instrument_product_settlementAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketList_markets_tradableInstrument_instrument {
|
export interface Markets_marketsConnection_edges_node_tradableInstrument_instrument {
|
||||||
__typename: "Instrument";
|
__typename: "Instrument";
|
||||||
/**
|
/**
|
||||||
* Uniquely identify an instrument across all instruments available on Vega (string)
|
* Uniquely identify an instrument across all instruments available on Vega (string)
|
||||||
@ -118,22 +74,22 @@ export interface MarketList_markets_tradableInstrument_instrument {
|
|||||||
/**
|
/**
|
||||||
* Metadata for this instrument
|
* Metadata for this instrument
|
||||||
*/
|
*/
|
||||||
metadata: MarketList_markets_tradableInstrument_instrument_metadata;
|
metadata: Markets_marketsConnection_edges_node_tradableInstrument_instrument_metadata;
|
||||||
/**
|
/**
|
||||||
* A reference to or instance of a fully specified product, including all required product parameters for that product (Product union)
|
* A reference to or instance of a fully specified product, including all required product parameters for that product (Product union)
|
||||||
*/
|
*/
|
||||||
product: MarketList_markets_tradableInstrument_instrument_product;
|
product: Markets_marketsConnection_edges_node_tradableInstrument_instrument_product;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketList_markets_tradableInstrument {
|
export interface Markets_marketsConnection_edges_node_tradableInstrument {
|
||||||
__typename: "TradableInstrument";
|
__typename: "TradableInstrument";
|
||||||
/**
|
/**
|
||||||
* An instance of, or reference to, a fully specified instrument.
|
* An instance of, or reference to, a fully specified instrument.
|
||||||
*/
|
*/
|
||||||
instrument: MarketList_markets_tradableInstrument_instrument;
|
instrument: Markets_marketsConnection_edges_node_tradableInstrument_instrument;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketList_markets_marketTimestamps {
|
export interface Markets_marketsConnection_edges_node_marketTimestamps {
|
||||||
__typename: "MarketTimestamps";
|
__typename: "MarketTimestamps";
|
||||||
/**
|
/**
|
||||||
* Time when the market is open and ready to accept trades
|
* Time when the market is open and ready to accept trades
|
||||||
@ -145,27 +101,7 @@ export interface MarketList_markets_marketTimestamps {
|
|||||||
close: string | null;
|
close: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketList_markets_candles {
|
export interface Markets_marketsConnection_edges_node {
|
||||||
__typename: "Candle";
|
|
||||||
/**
|
|
||||||
* Open price (uint64)
|
|
||||||
*/
|
|
||||||
open: string;
|
|
||||||
/**
|
|
||||||
* Close price (uint64)
|
|
||||||
*/
|
|
||||||
close: string;
|
|
||||||
/**
|
|
||||||
* High price (uint64)
|
|
||||||
*/
|
|
||||||
high: string;
|
|
||||||
/**
|
|
||||||
* Low price (uint64)
|
|
||||||
*/
|
|
||||||
low: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketList_markets {
|
|
||||||
__typename: "Market";
|
__typename: "Market";
|
||||||
/**
|
/**
|
||||||
* Market ID
|
* Market ID
|
||||||
@ -206,33 +142,30 @@ export interface MarketList_markets {
|
|||||||
/**
|
/**
|
||||||
* Fees related data
|
* Fees related data
|
||||||
*/
|
*/
|
||||||
fees: MarketList_markets_fees;
|
fees: Markets_marketsConnection_edges_node_fees;
|
||||||
/**
|
|
||||||
* marketData for the given market
|
|
||||||
*/
|
|
||||||
data: MarketList_markets_data | null;
|
|
||||||
/**
|
/**
|
||||||
* An instance of, or reference to, a tradable instrument.
|
* An instance of, or reference to, a tradable instrument.
|
||||||
*/
|
*/
|
||||||
tradableInstrument: MarketList_markets_tradableInstrument;
|
tradableInstrument: Markets_marketsConnection_edges_node_tradableInstrument;
|
||||||
/**
|
/**
|
||||||
* timestamps for state changes in the market
|
* timestamps for state changes in the market
|
||||||
*/
|
*/
|
||||||
marketTimestamps: MarketList_markets_marketTimestamps;
|
marketTimestamps: Markets_marketsConnection_edges_node_marketTimestamps;
|
||||||
/**
|
|
||||||
* Candles on a market, for the 'last' n candles, at 'interval' seconds as specified by parameters
|
|
||||||
*/
|
|
||||||
candles: (MarketList_markets_candles | null)[] | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketList {
|
export interface Markets_marketsConnection_edges {
|
||||||
/**
|
__typename: "MarketEdge";
|
||||||
* One or more instruments that are trading on the VEGA network
|
node: Markets_marketsConnection_edges_node;
|
||||||
*/
|
|
||||||
markets: MarketList_markets[] | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MarketListVariables {
|
export interface Markets_marketsConnection {
|
||||||
interval: Interval;
|
__typename: "MarketConnection";
|
||||||
since: string;
|
/**
|
||||||
|
* The markets in this connection
|
||||||
|
*/
|
||||||
|
edges: Markets_marketsConnection_edges[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Markets {
|
||||||
|
marketsConnection: Markets_marketsConnection;
|
||||||
}
|
}
|
81
libs/market-list/src/lib/__generated__/MarketsCandlesQuery.ts
generated
Normal file
81
libs/market-list/src/lib/__generated__/MarketsCandlesQuery.ts
generated
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @generated
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { Interval } from "@vegaprotocol/types";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL query operation: MarketsCandlesQuery
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node {
|
||||||
|
__typename: "CandleNode";
|
||||||
|
/**
|
||||||
|
* High price (uint64)
|
||||||
|
*/
|
||||||
|
high: string;
|
||||||
|
/**
|
||||||
|
* Low price (uint64)
|
||||||
|
*/
|
||||||
|
low: string;
|
||||||
|
/**
|
||||||
|
* Open price (uint64)
|
||||||
|
*/
|
||||||
|
open: string;
|
||||||
|
/**
|
||||||
|
* Close price (uint64)
|
||||||
|
*/
|
||||||
|
close: string;
|
||||||
|
/**
|
||||||
|
* Volume price (uint64)
|
||||||
|
*/
|
||||||
|
volume: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection_edges {
|
||||||
|
__typename: "CandleEdge";
|
||||||
|
node: MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection {
|
||||||
|
__typename: "CandleDataConnection";
|
||||||
|
/**
|
||||||
|
* The candles
|
||||||
|
*/
|
||||||
|
edges: (MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection_edges | null)[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsCandlesQuery_marketsConnection_edges_node {
|
||||||
|
__typename: "Market";
|
||||||
|
/**
|
||||||
|
* Market ID
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
/**
|
||||||
|
* Candles on a market, for the 'last' n candles, at 'interval' seconds as specified by parameters using cursor based pagination
|
||||||
|
*/
|
||||||
|
candlesConnection: MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsCandlesQuery_marketsConnection_edges {
|
||||||
|
__typename: "MarketEdge";
|
||||||
|
node: MarketsCandlesQuery_marketsConnection_edges_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsCandlesQuery_marketsConnection {
|
||||||
|
__typename: "MarketConnection";
|
||||||
|
/**
|
||||||
|
* The markets in this connection
|
||||||
|
*/
|
||||||
|
edges: MarketsCandlesQuery_marketsConnection_edges[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsCandlesQuery {
|
||||||
|
marketsConnection: MarketsCandlesQuery_marketsConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsCandlesQueryVariables {
|
||||||
|
interval: Interval;
|
||||||
|
since: string;
|
||||||
|
}
|
91
libs/market-list/src/lib/__generated__/MarketsDataQuery.ts
generated
Normal file
91
libs/market-list/src/lib/__generated__/MarketsDataQuery.ts
generated
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @generated
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { AuctionTrigger, MarketTradingMode } from "@vegaprotocol/types";
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL query operation: MarketsDataQuery
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface MarketsDataQuery_marketsConnection_edges_node_data_market {
|
||||||
|
__typename: "Market";
|
||||||
|
/**
|
||||||
|
* Market ID
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsDataQuery_marketsConnection_edges_node_data {
|
||||||
|
__typename: "MarketData";
|
||||||
|
/**
|
||||||
|
* market of the associated mark price
|
||||||
|
*/
|
||||||
|
market: MarketsDataQuery_marketsConnection_edges_node_data_market;
|
||||||
|
/**
|
||||||
|
* the highest price level on an order book for buy orders.
|
||||||
|
*/
|
||||||
|
bestBidPrice: string;
|
||||||
|
/**
|
||||||
|
* the lowest price level on an order book for offer orders.
|
||||||
|
*/
|
||||||
|
bestOfferPrice: string;
|
||||||
|
/**
|
||||||
|
* the mark price (an unsigned integer)
|
||||||
|
*/
|
||||||
|
markPrice: string;
|
||||||
|
/**
|
||||||
|
* what triggered an auction (if an auction was started)
|
||||||
|
*/
|
||||||
|
trigger: AuctionTrigger;
|
||||||
|
/**
|
||||||
|
* the arithmetic average of the best static bid price and best static offer price
|
||||||
|
*/
|
||||||
|
staticMidPrice: string;
|
||||||
|
/**
|
||||||
|
* what state the market is in (auction, continuous, etc)
|
||||||
|
*/
|
||||||
|
marketTradingMode: MarketTradingMode;
|
||||||
|
/**
|
||||||
|
* indicative volume if the auction ended now, 0 if not in auction mode
|
||||||
|
*/
|
||||||
|
indicativeVolume: string;
|
||||||
|
/**
|
||||||
|
* indicative price if the auction ended now, 0 if not in auction mode
|
||||||
|
*/
|
||||||
|
indicativePrice: string;
|
||||||
|
/**
|
||||||
|
* the highest price level on an order book for buy orders not including pegged orders.
|
||||||
|
*/
|
||||||
|
bestStaticBidPrice: string;
|
||||||
|
/**
|
||||||
|
* the lowest price level on an order book for offer orders not including pegged orders.
|
||||||
|
*/
|
||||||
|
bestStaticOfferPrice: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsDataQuery_marketsConnection_edges_node {
|
||||||
|
__typename: "Market";
|
||||||
|
/**
|
||||||
|
* marketData for the given market
|
||||||
|
*/
|
||||||
|
data: MarketsDataQuery_marketsConnection_edges_node_data | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsDataQuery_marketsConnection_edges {
|
||||||
|
__typename: "MarketEdge";
|
||||||
|
node: MarketsDataQuery_marketsConnection_edges_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsDataQuery_marketsConnection {
|
||||||
|
__typename: "MarketConnection";
|
||||||
|
/**
|
||||||
|
* The markets in this connection
|
||||||
|
*/
|
||||||
|
edges: MarketsDataQuery_marketsConnection_edges[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketsDataQuery {
|
||||||
|
marketsConnection: MarketsDataQuery_marketsConnection;
|
||||||
|
}
|
9
libs/market-list/src/lib/__generated__/index.ts
generated
Normal file
9
libs/market-list/src/lib/__generated__/index.ts
generated
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
export * from './MarketCandlesQuery';
|
||||||
|
export * from './MarketCandlesSub';
|
||||||
|
export * from './MarketDataFields';
|
||||||
|
export * from './MarketDataQuery';
|
||||||
|
export * from './MarketDataSub';
|
||||||
|
export * from './MarketFields';
|
||||||
|
export * from './Markets';
|
||||||
|
export * from './MarketsCandlesQuery';
|
||||||
|
export * from './MarketsDataQuery';
|
@ -22,7 +22,7 @@ import {
|
|||||||
MarketTradingModeMapping,
|
MarketTradingModeMapping,
|
||||||
AuctionTriggerMapping,
|
AuctionTriggerMapping,
|
||||||
} from '@vegaprotocol/types';
|
} from '@vegaprotocol/types';
|
||||||
import type { MarketList_markets } from '../../';
|
import type { MarketWithData } from '../../';
|
||||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||||
|
|
||||||
type Props = AgGridReactProps | AgReactUiProps;
|
type Props = AgGridReactProps | AgReactUiProps;
|
||||||
@ -31,7 +31,7 @@ type MarketListTableValueFormatterParams = Omit<
|
|||||||
ValueFormatterParams,
|
ValueFormatterParams,
|
||||||
'data' | 'value'
|
'data' | 'value'
|
||||||
> & {
|
> & {
|
||||||
data: MarketList_markets;
|
data: MarketWithData;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRowId = ({ data }: { data: { id: string } }) => data.id;
|
export const getRowId = ({ data }: { data: { id: string } }) => data.id;
|
||||||
@ -83,17 +83,17 @@ export const MarketListTable = forwardRef<AgGridReact, Props>((props, ref) => {
|
|||||||
headerName={t('Trading mode')}
|
headerName={t('Trading mode')}
|
||||||
field="data"
|
field="data"
|
||||||
minWidth={170}
|
minWidth={170}
|
||||||
valueGetter={({ data }: { data?: MarketList_markets }) => {
|
valueGetter={({ data }: { data?: MarketWithData }) => {
|
||||||
if (!data?.data) return undefined;
|
if (!data?.data) return undefined;
|
||||||
const { market, trigger } = data.data;
|
const { trigger } = data.data;
|
||||||
return market &&
|
const { tradingMode } = data;
|
||||||
market.tradingMode ===
|
return tradingMode ===
|
||||||
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
||||||
trigger &&
|
trigger &&
|
||||||
trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
||||||
? `${MarketTradingModeMapping[market.tradingMode]}
|
? `${MarketTradingModeMapping[tradingMode]}
|
||||||
- ${AuctionTriggerMapping[trigger]}`
|
- ${AuctionTriggerMapping[trigger]}`
|
||||||
: MarketTradingModeMapping[market.tradingMode];
|
: MarketTradingModeMapping[tradingMode];
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AgGridColumn
|
<AgGridColumn
|
||||||
@ -102,7 +102,7 @@ export const MarketListTable = forwardRef<AgGridReact, Props>((props, ref) => {
|
|||||||
type="rightAligned"
|
type="rightAligned"
|
||||||
cellRenderer="PriceFlashCell"
|
cellRenderer="PriceFlashCell"
|
||||||
filter="agNumberColumnFilter"
|
filter="agNumberColumnFilter"
|
||||||
valueGetter={({ data }: { data?: MarketList_markets }) => {
|
valueGetter={({ data }: { data?: MarketWithData }) => {
|
||||||
return data?.data?.bestBidPrice === undefined
|
return data?.data?.bestBidPrice === undefined
|
||||||
? undefined
|
? undefined
|
||||||
: toBigNum(data?.data?.bestBidPrice, data.decimalPlaces).toNumber();
|
: toBigNum(data?.data?.bestBidPrice, data.decimalPlaces).toNumber();
|
||||||
@ -122,7 +122,7 @@ export const MarketListTable = forwardRef<AgGridReact, Props>((props, ref) => {
|
|||||||
type="rightAligned"
|
type="rightAligned"
|
||||||
cellRenderer="PriceFlashCell"
|
cellRenderer="PriceFlashCell"
|
||||||
filter="agNumberColumnFilter"
|
filter="agNumberColumnFilter"
|
||||||
valueGetter={({ data }: { data?: MarketList_markets }) => {
|
valueGetter={({ data }: { data?: MarketWithData }) => {
|
||||||
return data?.data?.bestOfferPrice === undefined
|
return data?.data?.bestOfferPrice === undefined
|
||||||
? undefined
|
? undefined
|
||||||
: toBigNum(
|
: toBigNum(
|
||||||
@ -145,7 +145,7 @@ export const MarketListTable = forwardRef<AgGridReact, Props>((props, ref) => {
|
|||||||
type="rightAligned"
|
type="rightAligned"
|
||||||
cellRenderer="PriceFlashCell"
|
cellRenderer="PriceFlashCell"
|
||||||
filter="agNumberColumnFilter"
|
filter="agNumberColumnFilter"
|
||||||
valueGetter={({ data }: { data?: MarketList_markets }) => {
|
valueGetter={({ data }: { data?: MarketWithData }) => {
|
||||||
return data?.data?.markPrice === undefined
|
return data?.data?.markPrice === undefined
|
||||||
? undefined
|
? undefined
|
||||||
: toBigNum(data?.data?.markPrice, data.decimalPlaces).toNumber();
|
: toBigNum(data?.data?.markPrice, data.decimalPlaces).toNumber();
|
||||||
|
@ -1,89 +1,29 @@
|
|||||||
import { useRef, useCallback, useMemo } from 'react';
|
|
||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import { MarketListTable, getRowId } from './market-list-table';
|
import { MarketListTable } from './market-list-table';
|
||||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
|
||||||
import type { RowClickedEvent } from 'ag-grid-community';
|
import type { RowClickedEvent } from 'ag-grid-community';
|
||||||
import { produce } from 'immer';
|
import { marketsWithDataProvider as dataProvider } from '../../markets-provider';
|
||||||
import merge from 'lodash/merge';
|
import type { MarketWithData } from '../../markets-provider';
|
||||||
import type {
|
|
||||||
MarketList_markets,
|
|
||||||
MarketList_markets_data,
|
|
||||||
MarketDataSub_marketData,
|
|
||||||
} from '../../';
|
|
||||||
import { marketsDataProvider as dataProvider } from '../../markets-data-provider';
|
|
||||||
import { Interval, MarketState } from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
interface MarketsContainerProps {
|
interface MarketsContainerProps {
|
||||||
onSelect: (marketId: string) => void;
|
onSelect: (marketId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const { data, error, loading } = useDataProvider<MarketWithData[], never>({
|
||||||
|
dataProvider,
|
||||||
const yTimestamp = useMemo(() => {
|
noUpdate: true,
|
||||||
const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600;
|
});
|
||||||
return new Date(yesterday * 1000).toISOString();
|
|
||||||
}, []);
|
|
||||||
const variables = useMemo(
|
|
||||||
() => ({ interval: Interval.INTERVAL_I1H, since: yTimestamp }),
|
|
||||||
[yTimestamp]
|
|
||||||
);
|
|
||||||
|
|
||||||
const update = useCallback(
|
|
||||||
({ delta }: { delta: MarketDataSub_marketData }) => {
|
|
||||||
const update: MarketList_markets[] = [];
|
|
||||||
const add: MarketList_markets[] = [];
|
|
||||||
const remove: MarketList_markets[] = [];
|
|
||||||
if (!gridRef.current?.api) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const rowNode = gridRef.current.api.getRowNode(
|
|
||||||
getRowId({ data: delta.market })
|
|
||||||
);
|
|
||||||
if (rowNode) {
|
|
||||||
const updatedData = produce<MarketList_markets>(
|
|
||||||
rowNode.data.data,
|
|
||||||
(draft: MarketList_markets) => merge(draft, delta)
|
|
||||||
);
|
|
||||||
if (updatedData !== rowNode.data.data) {
|
|
||||||
update.push({ ...rowNode.data, data: updatedData });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// @TODO - else add new market
|
|
||||||
if (update.length || add.length || remove.length) {
|
|
||||||
gridRef.current.api.applyTransactionAsync({
|
|
||||||
update,
|
|
||||||
add,
|
|
||||||
addIndex: 0,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
[gridRef]
|
|
||||||
);
|
|
||||||
|
|
||||||
const { data, error, loading } = useDataProvider<
|
|
||||||
MarketList_markets[],
|
|
||||||
MarketList_markets_data
|
|
||||||
>({ dataProvider, update, variables });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer loading={loading} error={error} data={data}>
|
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||||
<MarketListTable
|
<MarketListTable
|
||||||
rowData={
|
rowData={data}
|
||||||
data &&
|
|
||||||
data.filter(
|
|
||||||
(m) => m.data?.market.state !== MarketState.STATE_REJECTED
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ref={gridRef}
|
|
||||||
onRowClicked={(rowEvent: RowClickedEvent) => {
|
onRowClicked={(rowEvent: RowClickedEvent) => {
|
||||||
const { data, event } = rowEvent;
|
const { data, event } = rowEvent;
|
||||||
// filters out clicks on the symbol column because it should display asset details
|
// filters out clicks on the symbol column because it should display asset details
|
||||||
if ((event?.target as HTMLElement).tagName.toUpperCase() === 'BUTTON')
|
if ((event?.target as HTMLElement).tagName.toUpperCase() === 'BUTTON')
|
||||||
return;
|
return;
|
||||||
onSelect((data as MarketList_markets).id);
|
onSelect((data as MarketWithData).id);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</AsyncRenderer>
|
</AsyncRenderer>
|
||||||
|
@ -3,6 +3,7 @@ import {
|
|||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
formatNumberPercentage,
|
formatNumberPercentage,
|
||||||
PriceCell,
|
PriceCell,
|
||||||
|
signedNumberCssClass,
|
||||||
t,
|
t,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import {
|
import {
|
||||||
@ -18,10 +19,7 @@ import Link from 'next/link';
|
|||||||
import { calcCandleHigh, calcCandleLow, totalFees } from '../utils';
|
import { calcCandleHigh, calcCandleLow, totalFees } from '../utils';
|
||||||
|
|
||||||
import type { CandleClose } from '@vegaprotocol/types';
|
import type { CandleClose } from '@vegaprotocol/types';
|
||||||
import type {
|
import type { Market, MarketData, Candle } from '../';
|
||||||
MarketList_markets,
|
|
||||||
MarketList_markets_fees_factors,
|
|
||||||
} from '../__generated__/MarketList';
|
|
||||||
import isNil from 'lodash/isNil';
|
import isNil from 'lodash/isNil';
|
||||||
|
|
||||||
export const cellClassNames = 'py-1 first:text-left text-right';
|
export const cellClassNames = 'py-1 first:text-left text-right';
|
||||||
@ -171,10 +169,12 @@ export const columnHeaders: Column[] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export const columns = (
|
export const columns = (
|
||||||
market: MarketList_markets,
|
market: Market,
|
||||||
|
marketData: MarketData | undefined,
|
||||||
|
candles: Candle[] | undefined,
|
||||||
onSelect: (id: string) => void
|
onSelect: (id: string) => void
|
||||||
) => {
|
) => {
|
||||||
const candlesClose = market.candles
|
const candlesClose = candles
|
||||||
?.map((candle) => candle?.close)
|
?.map((candle) => candle?.close)
|
||||||
.filter((c: string | undefined): c is CandleClose => !isNil(c));
|
.filter((c: string | undefined): c is CandleClose => !isNil(c));
|
||||||
const handleKeyPress = (
|
const handleKeyPress = (
|
||||||
@ -185,8 +185,8 @@ export const columns = (
|
|||||||
return onSelect(id);
|
return onSelect(id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const candleLow = calcCandleLow(market);
|
const candleLow = candles && calcCandleLow(candles);
|
||||||
const candleHigh = calcCandleHigh(market);
|
const candleHigh = candles && calcCandleHigh(candles);
|
||||||
const selectMarketColumns: Column[] = [
|
const selectMarketColumns: Column[] = [
|
||||||
{
|
{
|
||||||
value: (
|
value: (
|
||||||
@ -207,11 +207,11 @@ export const columns = (
|
|||||||
onlyOnDetailed: false,
|
onlyOnDetailed: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: market.data?.markPrice ? (
|
value: marketData?.markPrice ? (
|
||||||
<PriceCell
|
<PriceCell
|
||||||
value={Number(market.data?.markPrice)}
|
value={Number(marketData?.markPrice)}
|
||||||
valueFormatted={addDecimalsFormatNumber(
|
valueFormatted={addDecimalsFormatNumber(
|
||||||
market.data?.markPrice.toString(),
|
marketData?.markPrice.toString(),
|
||||||
market.decimalPlaces,
|
market.decimalPlaces,
|
||||||
2
|
2
|
||||||
)}
|
)}
|
||||||
@ -240,7 +240,7 @@ export const columns = (
|
|||||||
onlyOnDetailed: false,
|
onlyOnDetailed: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: market.candles && (
|
value: candles && (
|
||||||
<Sparkline
|
<Sparkline
|
||||||
width={100}
|
width={100}
|
||||||
height={20}
|
height={20}
|
||||||
@ -287,10 +287,10 @@ export const columns = (
|
|||||||
value:
|
value:
|
||||||
market.tradingMode ===
|
market.tradingMode ===
|
||||||
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
||||||
market.data?.trigger &&
|
marketData?.trigger &&
|
||||||
market.data.trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
marketData.trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
||||||
? `${MarketTradingModeMapping[market.tradingMode]}
|
? `${MarketTradingModeMapping[market.tradingMode]}
|
||||||
- ${AuctionTriggerMapping[market.data.trigger]}`
|
- ${AuctionTriggerMapping[marketData.trigger]}`
|
||||||
: MarketTradingModeMapping[market.tradingMode],
|
: MarketTradingModeMapping[market.tradingMode],
|
||||||
className: `${cellClassNames} hidden lg:table-cell`,
|
className: `${cellClassNames} hidden lg:table-cell`,
|
||||||
onlyOnDetailed: true,
|
onlyOnDetailed: true,
|
||||||
@ -298,9 +298,9 @@ export const columns = (
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value:
|
value:
|
||||||
market.data?.indicativeVolume && market.data.indicativeVolume !== '0'
|
marketData?.indicativeVolume && marketData.indicativeVolume !== '0'
|
||||||
? addDecimalsFormatNumber(
|
? addDecimalsFormatNumber(
|
||||||
market.data.indicativeVolume,
|
marketData.indicativeVolume,
|
||||||
market.positionDecimalPlaces
|
market.positionDecimalPlaces
|
||||||
)
|
)
|
||||||
: '-',
|
: '-',
|
||||||
@ -325,14 +325,17 @@ export const columns = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const columnsPositionMarkets = (
|
export const columnsPositionMarkets = (
|
||||||
market: MarketList_markets & { openVolume: string },
|
market: Market,
|
||||||
onSelect: (id: string) => void
|
marketData: MarketData | undefined,
|
||||||
|
candles: Candle[] | undefined,
|
||||||
|
onSelect: (id: string) => void,
|
||||||
|
openVolume?: string
|
||||||
) => {
|
) => {
|
||||||
const candlesClose = market.candles
|
const candlesClose = candles
|
||||||
?.map((candle) => candle?.close)
|
?.map((candle) => candle?.close)
|
||||||
.filter((c: string | undefined): c is CandleClose => !isNil(c));
|
.filter((c: string | undefined): c is CandleClose => !isNil(c));
|
||||||
const candleLow = calcCandleLow(market);
|
const candleLow = candles && calcCandleLow(candles);
|
||||||
const candleHigh = calcCandleHigh(market);
|
const candleHigh = candles && calcCandleHigh(candles);
|
||||||
const handleKeyPress = (
|
const handleKeyPress = (
|
||||||
event: React.KeyboardEvent<HTMLAnchorElement>,
|
event: React.KeyboardEvent<HTMLAnchorElement>,
|
||||||
id: string
|
id: string
|
||||||
@ -361,11 +364,11 @@ export const columnsPositionMarkets = (
|
|||||||
onlyOnDetailed: false,
|
onlyOnDetailed: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: market.data?.markPrice ? (
|
value: marketData?.markPrice ? (
|
||||||
<PriceCell
|
<PriceCell
|
||||||
value={Number(market.data.markPrice)}
|
value={Number(marketData.markPrice)}
|
||||||
valueFormatted={addDecimalsFormatNumber(
|
valueFormatted={addDecimalsFormatNumber(
|
||||||
market.data.markPrice.toString(),
|
marketData.markPrice.toString(),
|
||||||
market.decimalPlaces,
|
market.decimalPlaces,
|
||||||
2
|
2
|
||||||
)}
|
)}
|
||||||
@ -440,10 +443,10 @@ export const columnsPositionMarkets = (
|
|||||||
value:
|
value:
|
||||||
market.tradingMode ===
|
market.tradingMode ===
|
||||||
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
||||||
market.data?.trigger &&
|
marketData?.trigger &&
|
||||||
market.data.trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
marketData.trigger !== AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
||||||
? `${MarketTradingModeMapping[market.tradingMode]}
|
? `${MarketTradingModeMapping[market.tradingMode]}
|
||||||
- ${AuctionTriggerMapping[market.data.trigger]}`
|
- ${AuctionTriggerMapping[marketData.trigger]}`
|
||||||
: MarketTradingModeMapping[market.tradingMode],
|
: MarketTradingModeMapping[market.tradingMode],
|
||||||
className: `${cellClassNames} hidden lg:table-cell`,
|
className: `${cellClassNames} hidden lg:table-cell`,
|
||||||
onlyOnDetailed: true,
|
onlyOnDetailed: true,
|
||||||
@ -451,9 +454,9 @@ export const columnsPositionMarkets = (
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value:
|
value:
|
||||||
market.data && market.data.indicativeVolume !== '0'
|
marketData && marketData.indicativeVolume !== '0'
|
||||||
? addDecimalsFormatNumber(
|
? addDecimalsFormatNumber(
|
||||||
market.data.indicativeVolume,
|
marketData.indicativeVolume,
|
||||||
market.positionDecimalPlaces
|
market.positionDecimalPlaces
|
||||||
)
|
)
|
||||||
: '-',
|
: '-',
|
||||||
@ -467,17 +470,7 @@ export const columnsPositionMarkets = (
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: (
|
value: (
|
||||||
<p
|
<p className={signedNumberCssClass(openVolume || '')}>{openVolume}</p>
|
||||||
className={
|
|
||||||
market.openVolume.includes('+')
|
|
||||||
? 'text-vega-green-dark dark:text-vega-green'
|
|
||||||
: market.openVolume.includes('-')
|
|
||||||
? 'text-vega-red-dark dark:text-vega-red'
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{market.openVolume}
|
|
||||||
</p>
|
|
||||||
),
|
),
|
||||||
className: `${cellClassNames} hidden xxl:table-cell font-mono`,
|
className: `${cellClassNames} hidden xxl:table-cell font-mono`,
|
||||||
onlyOnDetailed: true,
|
onlyOnDetailed: true,
|
||||||
@ -489,7 +482,7 @@ export const columnsPositionMarkets = (
|
|||||||
const FeesCell = ({
|
const FeesCell = ({
|
||||||
feeFactors,
|
feeFactors,
|
||||||
}: {
|
}: {
|
||||||
feeFactors: MarketList_markets_fees_factors;
|
feeFactors: Market['fees']['factors'];
|
||||||
}) => (
|
}) => (
|
||||||
<Tooltip description={<FeesBreakdown feeFactors={feeFactors} />}>
|
<Tooltip description={<FeesBreakdown feeFactors={feeFactors} />}>
|
||||||
<span>{totalFees(feeFactors) ?? '-'}</span>
|
<span>{totalFees(feeFactors) ?? '-'}</span>
|
||||||
@ -499,7 +492,7 @@ const FeesCell = ({
|
|||||||
export const FeesBreakdown = ({
|
export const FeesBreakdown = ({
|
||||||
feeFactors,
|
feeFactors,
|
||||||
}: {
|
}: {
|
||||||
feeFactors?: MarketList_markets_fees_factors;
|
feeFactors?: Market['fees']['factors'];
|
||||||
}) => {
|
}) => {
|
||||||
if (!feeFactors) return null;
|
if (!feeFactors) return null;
|
||||||
return (
|
return (
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { fireEvent, render, screen } from '@testing-library/react';
|
import { fireEvent, render, screen } from '@testing-library/react';
|
||||||
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
import { AuctionTrigger, MarketTradingMode } from '@vegaprotocol/types';
|
||||||
|
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import type { MarketList_markets } from '../__generated__/MarketList';
|
import type { MarketData } from '../market-data-provider';
|
||||||
|
import type { MarketCandles } from '../markets-candles-provider';
|
||||||
|
import type { Market } from '../markets-provider';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
SelectAllMarketsTableBody,
|
SelectAllMarketsTableBody,
|
||||||
@ -16,186 +18,173 @@ jest.mock(
|
|||||||
children
|
children
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const MARKET_A: Partial<Market> = {
|
||||||
|
__typename: 'Market',
|
||||||
|
id: '1',
|
||||||
|
decimalPlaces: 2,
|
||||||
|
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
tradableInstrument: {
|
||||||
|
__typename: 'TradableInstrument',
|
||||||
|
instrument: {
|
||||||
|
__typename: 'Instrument',
|
||||||
|
id: '1',
|
||||||
|
code: 'ABCDEF',
|
||||||
|
name: 'ABCDEF 1-Day',
|
||||||
|
product: {
|
||||||
|
__typename: 'Future',
|
||||||
|
settlementAsset: {
|
||||||
|
__typename: 'Asset',
|
||||||
|
symbol: 'ABC',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
__typename: 'InstrumentMetadata',
|
||||||
|
tags: ['ABC', 'DEF'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fees: {
|
||||||
|
__typename: 'Fees',
|
||||||
|
factors: {
|
||||||
|
__typename: 'FeeFactors',
|
||||||
|
infrastructureFee: '0.01',
|
||||||
|
liquidityFee: '0.01',
|
||||||
|
makerFee: '0.01',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const MARKET_B: Partial<Market> = {
|
||||||
|
__typename: 'Market',
|
||||||
|
id: '2',
|
||||||
|
decimalPlaces: 2,
|
||||||
|
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
tradableInstrument: {
|
||||||
|
__typename: 'TradableInstrument',
|
||||||
|
instrument: {
|
||||||
|
__typename: 'Instrument',
|
||||||
|
id: '2',
|
||||||
|
code: 'XYZ',
|
||||||
|
name: 'XYZ 1-Day',
|
||||||
|
product: {
|
||||||
|
__typename: 'Future',
|
||||||
|
settlementAsset: {
|
||||||
|
__typename: 'Asset',
|
||||||
|
symbol: 'XYZ',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
__typename: 'InstrumentMetadata',
|
||||||
|
tags: ['XYZ'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fees: {
|
||||||
|
__typename: 'Fees',
|
||||||
|
factors: {
|
||||||
|
__typename: 'FeeFactors',
|
||||||
|
infrastructureFee: '0.01',
|
||||||
|
liquidityFee: '0.01',
|
||||||
|
makerFee: '0.01',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const MARKET_DATA_A: Partial<MarketData> = {
|
||||||
|
__typename: 'MarketData',
|
||||||
|
market: {
|
||||||
|
__typename: 'Market',
|
||||||
|
id: '1',
|
||||||
|
},
|
||||||
|
markPrice: '90',
|
||||||
|
trigger: AuctionTrigger.AUCTION_TRIGGER_OPENING,
|
||||||
|
indicativeVolume: '1000',
|
||||||
|
};
|
||||||
|
|
||||||
|
const MARKET_DATA_B: Partial<MarketData> = {
|
||||||
|
__typename: 'MarketData',
|
||||||
|
market: {
|
||||||
|
__typename: 'Market',
|
||||||
|
id: '2',
|
||||||
|
},
|
||||||
|
markPrice: '123.123',
|
||||||
|
trigger: AuctionTrigger.AUCTION_TRIGGER_OPENING,
|
||||||
|
indicativeVolume: '2000',
|
||||||
|
};
|
||||||
|
|
||||||
|
const MARKET_CANDLES_A: Partial<MarketCandles> = {
|
||||||
|
marketId: '1',
|
||||||
|
candles: [
|
||||||
|
{
|
||||||
|
__typename: 'CandleNode',
|
||||||
|
high: '100',
|
||||||
|
low: '10',
|
||||||
|
open: '10',
|
||||||
|
close: '80',
|
||||||
|
volume: '1000',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
__typename: 'CandleNode',
|
||||||
|
high: '10',
|
||||||
|
low: '1',
|
||||||
|
open: '1',
|
||||||
|
close: '100',
|
||||||
|
volume: '1000',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const MARKET_CANDLES_B: Partial<MarketCandles> = {
|
||||||
|
marketId: '2',
|
||||||
|
candles: [
|
||||||
|
{
|
||||||
|
__typename: 'CandleNode',
|
||||||
|
high: '100',
|
||||||
|
low: '10',
|
||||||
|
open: '10',
|
||||||
|
close: '80',
|
||||||
|
volume: '1000',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
describe('SelectMarket', () => {
|
describe('SelectMarket', () => {
|
||||||
it('should render the SelectAllMarketsTableBody', () => {
|
it('should render the SelectAllMarketsTableBody', () => {
|
||||||
const onSelect = jest.fn();
|
const onSelect = jest.fn();
|
||||||
const expectedMarket = mockData.data.markets[0];
|
|
||||||
const { container } = render(
|
const { container } = render(
|
||||||
<SelectAllMarketsTableBody
|
<SelectAllMarketsTableBody
|
||||||
data={mockData.data.markets}
|
markets={[MARKET_A as Market, MARKET_B as Market]}
|
||||||
|
marketsData={[MARKET_DATA_A as MarketData, MARKET_DATA_B as MarketData]}
|
||||||
|
marketsCandles={[
|
||||||
|
MARKET_CANDLES_A as MarketCandles,
|
||||||
|
MARKET_CANDLES_B as MarketCandles,
|
||||||
|
]}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
expect(screen.getByText('AAPL.MF21')).toBeTruthy();
|
expect(screen.getByText('ABCDEF')).toBeTruthy(); // name
|
||||||
expect(screen.getByText('-3.14%')).toBeTruthy();
|
expect(screen.getByText('25.00%')).toBeTruthy(); // price change
|
||||||
expect(container).toHaveTextContent(/141\.75/);
|
expect(container).toHaveTextContent(/1,000/); // volume
|
||||||
fireEvent.click(screen.getByTestId(`market-link-${expectedMarket.id}`));
|
fireEvent.click(screen.getByTestId(`market-link-1`));
|
||||||
expect(onSelect).toHaveBeenCalledWith(expectedMarket.id);
|
expect(onSelect).toHaveBeenCalledWith('1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call onSelect callback on SelectMarketLandingTable', () => {
|
it('should call onSelect callback on SelectMarketLandingTable', () => {
|
||||||
const onSelect = jest.fn();
|
const onSelect = jest.fn();
|
||||||
const expectedMarket = mockData.data.markets[0];
|
|
||||||
render(
|
render(
|
||||||
<SelectMarketLandingTable
|
<SelectMarketLandingTable
|
||||||
data={mockData.data.markets}
|
markets={[MARKET_A as Market, MARKET_B as Market]}
|
||||||
|
marketsData={[MARKET_DATA_A as MarketData, MARKET_DATA_B as MarketData]}
|
||||||
|
marketsCandles={[
|
||||||
|
MARKET_CANDLES_A as MarketCandles,
|
||||||
|
MARKET_CANDLES_B as MarketCandles,
|
||||||
|
]}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
fireEvent.click(screen.getByTestId(`market-link-${expectedMarket.id}`));
|
fireEvent.click(screen.getByTestId(`market-link-1`));
|
||||||
expect(onSelect).toHaveBeenCalledWith(expectedMarket.id);
|
expect(onSelect).toHaveBeenCalledWith('1');
|
||||||
|
fireEvent.click(screen.getByTestId(`market-link-2`));
|
||||||
|
expect(onSelect).toHaveBeenCalledWith('2');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockData = {
|
|
||||||
data: {
|
|
||||||
markets: [
|
|
||||||
{
|
|
||||||
__typename: 'Market',
|
|
||||||
id: '062ddcb97beae5b7cc4fa20621fe0c83b2a6f7e76cf5b129c6bd3dc14e8111ef',
|
|
||||||
decimalPlaces: 2,
|
|
||||||
name: '',
|
|
||||||
positionDecimalPlaces: 4,
|
|
||||||
state: MarketState.STATE_ACTIVE,
|
|
||||||
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
data: {
|
|
||||||
markPrice: '14175',
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
instrument: {
|
|
||||||
__typename: 'Instrument',
|
|
||||||
name: 'APEUSD (May 2022)',
|
|
||||||
code: 'APEUSD',
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
settlementAsset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
symbol: 'USD',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
marketTimestamps: {
|
|
||||||
__typename: 'MarketTimestamps',
|
|
||||||
open: '2022-05-18T13:08:27.693537312Z',
|
|
||||||
close: null,
|
|
||||||
},
|
|
||||||
fees: {
|
|
||||||
__typename: 'Fees',
|
|
||||||
factors: {
|
|
||||||
__typename: 'FeeFactors',
|
|
||||||
infrastructureFee: '0.01',
|
|
||||||
makerFee: '0.01',
|
|
||||||
liquidityFee: '0.01',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
candles: [
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '822',
|
|
||||||
close: '798',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '793',
|
|
||||||
close: '792',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '794',
|
|
||||||
close: '776',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '785',
|
|
||||||
close: '786',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '803',
|
|
||||||
close: '770',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '785',
|
|
||||||
close: '774',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
} as MarketList_markets,
|
|
||||||
{
|
|
||||||
__typename: 'Market',
|
|
||||||
id: '3e6671566ccf5c33702e955fe8b018683fcdb812bfe3ed283fc250bb4f798ff3',
|
|
||||||
decimalPlaces: 5,
|
|
||||||
tradableInstrument: {
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
instrument: {
|
|
||||||
__typename: 'Instrument',
|
|
||||||
name: 'Apple Monthly (30 Jun 2022)',
|
|
||||||
code: 'AAPL.MF21',
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
settlementAsset: {
|
|
||||||
__typename: 'Asset',
|
|
||||||
symbol: 'USD',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fees: {
|
|
||||||
__typename: 'Fees',
|
|
||||||
factors: {
|
|
||||||
__typename: 'FeeFactors',
|
|
||||||
infrastructureFee: '0.01',
|
|
||||||
makerFee: '0.01',
|
|
||||||
liquidityFee: '0.01',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
marketTimestamps: {
|
|
||||||
__typename: 'MarketTimestamps',
|
|
||||||
open: '2022-05-18T13:00:39.328347732Z',
|
|
||||||
close: null,
|
|
||||||
},
|
|
||||||
candles: [
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '14707175',
|
|
||||||
close: '14633864',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '14658400',
|
|
||||||
close: '14550193',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '14550193',
|
|
||||||
close: '14373526',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '14307141',
|
|
||||||
close: '14339846',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '14357485',
|
|
||||||
close: '14179971',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Candle',
|
|
||||||
open: '14179972',
|
|
||||||
close: '14174855',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
name: '',
|
|
||||||
positionDecimalPlaces: 4,
|
|
||||||
state: MarketState.STATE_ACTIVE,
|
|
||||||
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
data: {
|
|
||||||
markPrice: '14175',
|
|
||||||
},
|
|
||||||
} as MarketList_markets,
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { useQuery } from '@apollo/client';
|
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import { t, volumePrefix } from '@vegaprotocol/react-helpers';
|
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
Icon,
|
Icon,
|
||||||
@ -8,6 +7,7 @@ import {
|
|||||||
Link,
|
Link,
|
||||||
Popover,
|
Popover,
|
||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import type { Column } from './select-market-columns';
|
import type { Column } from './select-market-columns';
|
||||||
@ -17,21 +17,29 @@ import {
|
|||||||
} from './select-market-columns';
|
} from './select-market-columns';
|
||||||
import { columnHeaders } from './select-market-columns';
|
import { columnHeaders } from './select-market-columns';
|
||||||
import { columns } from './select-market-columns';
|
import { columns } from './select-market-columns';
|
||||||
import type { MarketList_markets } from '../';
|
import type { Market, MarketData, MarketCandles, Candle } from '../';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import type { Positions } from '@vegaprotocol/positions';
|
import type {
|
||||||
import { POSITIONS_QUERY } from '@vegaprotocol/positions';
|
Positions_party,
|
||||||
|
PositionsSubscription_positions,
|
||||||
|
Positions_party_positionsConnection_edges_node,
|
||||||
|
} from '@vegaprotocol/positions';
|
||||||
|
import { positionsDataProvider } from '@vegaprotocol/positions';
|
||||||
import {
|
import {
|
||||||
SelectMarketTableHeader,
|
SelectMarketTableHeader,
|
||||||
SelectMarketTableRow,
|
SelectMarketTableRow,
|
||||||
} from './select-market-table';
|
} from './select-market-table';
|
||||||
import { useMarketList } from '../markets-data-provider';
|
import { useMarketList } from '../markets-provider';
|
||||||
|
|
||||||
export const SelectMarketLandingTable = ({
|
export const SelectMarketLandingTable = ({
|
||||||
data,
|
markets,
|
||||||
|
marketsData,
|
||||||
|
marketsCandles,
|
||||||
onSelect,
|
onSelect,
|
||||||
}: {
|
}: {
|
||||||
data: MarketList_markets[] | undefined;
|
markets: Market[] | undefined;
|
||||||
|
marketsData: MarketData[] | undefined;
|
||||||
|
marketsCandles: MarketCandles[] | undefined;
|
||||||
onSelect: (id: string) => void;
|
onSelect: (id: string) => void;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
@ -45,11 +53,20 @@ export const SelectMarketLandingTable = ({
|
|||||||
<SelectMarketTableHeader />
|
<SelectMarketTableHeader />
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{data?.map((market, i) => (
|
{markets?.map((market, i) => (
|
||||||
<SelectMarketTableRow
|
<SelectMarketTableRow
|
||||||
key={i}
|
key={i}
|
||||||
detailed={false}
|
detailed={false}
|
||||||
columns={columns(market, onSelect)}
|
columns={columns(
|
||||||
|
market,
|
||||||
|
marketsData?.find(
|
||||||
|
(marketData) => marketData.market.id === market.id
|
||||||
|
),
|
||||||
|
marketsCandles?.find(
|
||||||
|
(marketCandles) => marketCandles.marketId === market.id
|
||||||
|
)?.candles,
|
||||||
|
onSelect
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -61,31 +78,52 @@ export const SelectMarketLandingTable = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const SelectAllMarketsTableBody = ({
|
export const SelectAllMarketsTableBody = ({
|
||||||
data,
|
markets,
|
||||||
|
marketsData,
|
||||||
|
marketsCandles,
|
||||||
|
positions,
|
||||||
onSelect,
|
onSelect,
|
||||||
headers = columnHeaders,
|
headers = columnHeaders,
|
||||||
tableColumns = (market) => columns(market, onSelect),
|
tableColumns = (market, marketData, candles) =>
|
||||||
|
columns(market, marketData, candles, onSelect),
|
||||||
}: {
|
}: {
|
||||||
data?: MarketList_markets[];
|
markets: Market[] | undefined;
|
||||||
|
marketsData: MarketData[] | undefined;
|
||||||
|
marketsCandles: MarketCandles[] | undefined;
|
||||||
|
positions?: Positions_party_positionsConnection_edges_node[];
|
||||||
title?: string;
|
title?: string;
|
||||||
onSelect: (id: string) => void;
|
onSelect: (id: string) => void;
|
||||||
headers?: Column[];
|
headers?: Column[];
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
tableColumns?: (
|
||||||
tableColumns?: (market: any) => Column[];
|
market: Market,
|
||||||
|
marketData: MarketData | undefined,
|
||||||
|
candles: Candle[] | undefined,
|
||||||
|
openVolume?: string
|
||||||
|
) => Column[];
|
||||||
}) => {
|
}) => {
|
||||||
if (!data) return null;
|
if (!markets) return null;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<thead className="bg-neutral-100 dark:bg-neutral-800">
|
<thead className="bg-neutral-100 dark:bg-neutral-800">
|
||||||
<SelectMarketTableHeader detailed={true} headers={headers} />
|
<SelectMarketTableHeader detailed={true} headers={headers} />
|
||||||
</thead>
|
</thead>
|
||||||
{/* Border styles required to create space between tbody elements margin/padding dont work */}
|
{/* Border styles required to create space between tbody elements margin/padding don't work */}
|
||||||
<tbody className="border-b-[10px] border-transparent">
|
<tbody className="border-b-[10px] border-transparent">
|
||||||
{data?.map((market, i) => (
|
{markets?.map((market, i) => (
|
||||||
<SelectMarketTableRow
|
<SelectMarketTableRow
|
||||||
key={i}
|
key={i}
|
||||||
detailed={true}
|
detailed={true}
|
||||||
columns={tableColumns(market)}
|
columns={tableColumns(
|
||||||
|
market,
|
||||||
|
marketsData?.find(
|
||||||
|
(marketData) => marketData.market.id === market.id
|
||||||
|
),
|
||||||
|
marketsCandles?.find(
|
||||||
|
(marketCandles) => marketCandles.marketId === market.id
|
||||||
|
)?.candles,
|
||||||
|
positions &&
|
||||||
|
positions.find((p) => p.market.id === market.id)?.openVolume
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -106,35 +144,15 @@ export const SelectMarketPopover = ({
|
|||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const { data, loading: marketsLoading } = useMarketList();
|
const { data, loading: marketsLoading } = useMarketList();
|
||||||
const variables = useMemo(() => ({ partyId: keypair?.pub }), [keypair?.pub]);
|
const variables = useMemo(() => ({ partyId: keypair?.pub }), [keypair?.pub]);
|
||||||
const { data: marketDataPositions, loading: positionsLoading } =
|
const { data: party, loading: positionsLoading } = useDataProvider<
|
||||||
useQuery<Positions>(POSITIONS_QUERY, {
|
Positions_party,
|
||||||
variables,
|
PositionsSubscription_positions
|
||||||
skip: !keypair?.pub,
|
>({
|
||||||
});
|
dataProvider: positionsDataProvider,
|
||||||
|
update: () => false,
|
||||||
const positionMarkets = useMemo(
|
variables,
|
||||||
() => ({
|
skip: !keypair,
|
||||||
markets:
|
});
|
||||||
data
|
|
||||||
?.filter((market) =>
|
|
||||||
marketDataPositions?.party?.positionsConnection.edges?.find(
|
|
||||||
(edge) => edge.node.market.id === market.id
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.map((market) => {
|
|
||||||
const position =
|
|
||||||
marketDataPositions?.party?.positionsConnection.edges?.find(
|
|
||||||
(edge) => edge.node.market.id === market.id
|
|
||||||
)?.node;
|
|
||||||
return {
|
|
||||||
...market,
|
|
||||||
openVolume:
|
|
||||||
position?.openVolume && volumePrefix(position.openVolume),
|
|
||||||
};
|
|
||||||
}) || null,
|
|
||||||
}),
|
|
||||||
[data, marketDataPositions]
|
|
||||||
);
|
|
||||||
|
|
||||||
const onSelectMarket = (marketId: string) => {
|
const onSelectMarket = (marketId: string) => {
|
||||||
onSelect(marketId);
|
onSelect(marketId);
|
||||||
@ -142,6 +160,15 @@ export const SelectMarketPopover = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const iconClass = open ? 'rotate-180' : '';
|
const iconClass = open ? 'rotate-180' : '';
|
||||||
|
const markets = useMemo(
|
||||||
|
() =>
|
||||||
|
data?.markets?.filter((market) =>
|
||||||
|
party?.positionsConnection.edges?.find(
|
||||||
|
(edge) => edge.node.market.id === market.id
|
||||||
|
)
|
||||||
|
),
|
||||||
|
[data, party]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
@ -165,25 +192,36 @@ export const SelectMarketPopover = ({
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{keypair &&
|
{keypair && (party?.positionsConnection.edges?.length ?? 0) > 0 ? (
|
||||||
positionMarkets?.markets &&
|
<table className="relative text-sm w-full whitespace-nowrap">
|
||||||
positionMarkets.markets.length > 0 && (
|
<TableTitle>{t('My markets')}</TableTitle>
|
||||||
<table className="relative text-sm w-full whitespace-nowrap">
|
<SelectAllMarketsTableBody
|
||||||
<TableTitle>{t('My markets')}</TableTitle>
|
markets={markets}
|
||||||
<SelectAllMarketsTableBody
|
marketsData={data?.marketsData}
|
||||||
data={positionMarkets.markets}
|
marketsCandles={data?.marketsCandles}
|
||||||
onSelect={onSelectMarket}
|
positions={party?.positionsConnection.edges
|
||||||
headers={columnHeadersPositionMarkets}
|
?.filter((edge) => edge.node)
|
||||||
tableColumns={(market) =>
|
.map((edge) => edge.node)}
|
||||||
columnsPositionMarkets(market, onSelectMarket)
|
onSelect={onSelectMarket}
|
||||||
}
|
headers={columnHeadersPositionMarkets}
|
||||||
/>
|
tableColumns={(market, marketData, candles, openVolume) =>
|
||||||
</table>
|
columnsPositionMarkets(
|
||||||
)}
|
market,
|
||||||
|
marketData,
|
||||||
|
candles,
|
||||||
|
onSelectMarket,
|
||||||
|
openVolume
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</table>
|
||||||
|
) : null}
|
||||||
<table className="relative text-sm w-full whitespace-nowrap">
|
<table className="relative text-sm w-full whitespace-nowrap">
|
||||||
<TableTitle>{t('All markets')}</TableTitle>
|
<TableTitle>{t('All markets')}</TableTitle>
|
||||||
<SelectAllMarketsTableBody
|
<SelectAllMarketsTableBody
|
||||||
data={data}
|
markets={data?.markets}
|
||||||
|
marketsData={data?.marketsData}
|
||||||
|
marketsCandles={data?.marketsCandles}
|
||||||
onSelect={onSelectMarket}
|
onSelect={onSelectMarket}
|
||||||
/>
|
/>
|
||||||
</table>
|
</table>
|
||||||
@ -256,5 +294,12 @@ const LandingDialogContainer = ({ onSelect }: LandingDialogContainerProps) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <SelectMarketLandingTable data={data} onSelect={onSelect} />;
|
return (
|
||||||
|
<SelectMarketLandingTable
|
||||||
|
markets={data?.markets}
|
||||||
|
marketsData={data?.marketsData}
|
||||||
|
marketsCandles={data?.marketsCandles}
|
||||||
|
onSelect={onSelect}
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
export * from './__generated__/MarketDataFields';
|
export * from './__generated__';
|
||||||
export * from './__generated__/MarketList';
|
|
||||||
export * from './__generated__/MarketDataSub';
|
|
||||||
export * from './components';
|
export * from './components';
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
|
export * from './market-candles-provider';
|
||||||
|
export * from './market-data-provider';
|
||||||
|
export * from './market-provider';
|
||||||
|
export * from './markets-candles-provider';
|
||||||
export * from './markets-data-provider';
|
export * from './markets-data-provider';
|
||||||
|
export * from './markets-provider';
|
||||||
|
83
libs/market-list/src/lib/market-candles-provider.ts
Normal file
83
libs/market-list/src/lib/market-candles-provider.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
import { makeDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
|
import type {
|
||||||
|
MarketCandlesQuery,
|
||||||
|
MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node,
|
||||||
|
MarketCandlesSub,
|
||||||
|
MarketCandlesSub_candles,
|
||||||
|
} from './__generated__';
|
||||||
|
|
||||||
|
export const MARKET_CANDLES_QUERY = gql`
|
||||||
|
query MarketCandlesQuery(
|
||||||
|
$interval: Interval!
|
||||||
|
$since: String!
|
||||||
|
$marketId: ID!
|
||||||
|
) {
|
||||||
|
marketsConnection(id: $marketId) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
candlesConnection(interval: $interval, since: $since) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
high
|
||||||
|
low
|
||||||
|
open
|
||||||
|
close
|
||||||
|
volume
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MARKET_CANDLES_SUB = gql`
|
||||||
|
subscription MarketCandlesSub($marketId: ID!, $interval: Interval!) {
|
||||||
|
candles(interval: $interval, marketId: $marketId) {
|
||||||
|
high
|
||||||
|
low
|
||||||
|
open
|
||||||
|
close
|
||||||
|
volume
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export type Candle =
|
||||||
|
MarketCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node;
|
||||||
|
|
||||||
|
const update = (data: Candle[], delta: MarketCandlesSub_candles) => {
|
||||||
|
return data && delta
|
||||||
|
? [
|
||||||
|
...data,
|
||||||
|
{
|
||||||
|
...delta,
|
||||||
|
__typename: 'CandleNode',
|
||||||
|
} as Candle,
|
||||||
|
]
|
||||||
|
: data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getData = (responseData: MarketCandlesQuery): Candle[] | null =>
|
||||||
|
responseData.marketsConnection.edges[0].node.candlesConnection.edges
|
||||||
|
?.filter((edge) => edge?.node)
|
||||||
|
.map((edge) => edge?.node as Candle) || null;
|
||||||
|
|
||||||
|
const getDelta = (
|
||||||
|
subscriptionData: MarketCandlesSub
|
||||||
|
): MarketCandlesSub_candles => subscriptionData.candles;
|
||||||
|
|
||||||
|
export const marketCandlesProvider = makeDataProvider<
|
||||||
|
MarketCandlesQuery,
|
||||||
|
Candle[],
|
||||||
|
MarketCandlesSub,
|
||||||
|
MarketCandlesSub_candles
|
||||||
|
>({
|
||||||
|
query: MARKET_CANDLES_QUERY,
|
||||||
|
subscriptionQuery: MARKET_CANDLES_SUB,
|
||||||
|
update,
|
||||||
|
getData,
|
||||||
|
getDelta,
|
||||||
|
});
|
81
libs/market-list/src/lib/market-data-provider.ts
Normal file
81
libs/market-list/src/lib/market-data-provider.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import produce from 'immer';
|
||||||
|
import { gql } from '@apollo/client';
|
||||||
|
import { makeDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
|
import type {
|
||||||
|
MarketDataSub,
|
||||||
|
MarketDataSub_marketsData,
|
||||||
|
MarketDataQuery,
|
||||||
|
MarketDataQuery_marketsConnection_edges_node_data,
|
||||||
|
} from './__generated__';
|
||||||
|
|
||||||
|
export const MARKET_DATA_QUERY = gql`
|
||||||
|
query MarketDataQuery($marketId: ID!) {
|
||||||
|
marketsConnection(id: $marketId) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
data {
|
||||||
|
market {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
bestBidPrice
|
||||||
|
bestOfferPrice
|
||||||
|
markPrice
|
||||||
|
trigger
|
||||||
|
staticMidPrice
|
||||||
|
marketTradingMode
|
||||||
|
indicativeVolume
|
||||||
|
indicativePrice
|
||||||
|
bestStaticBidPrice
|
||||||
|
bestStaticOfferPrice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MARKET_DATA_SUB = gql`
|
||||||
|
subscription MarketDataSub($marketId: ID!) {
|
||||||
|
marketsData(marketIds: [$marketId]) {
|
||||||
|
marketId
|
||||||
|
bestBidPrice
|
||||||
|
bestOfferPrice
|
||||||
|
markPrice
|
||||||
|
trigger
|
||||||
|
staticMidPrice
|
||||||
|
marketTradingMode
|
||||||
|
indicativeVolume
|
||||||
|
indicativePrice
|
||||||
|
bestStaticBidPrice
|
||||||
|
bestStaticOfferPrice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export type MarketData = MarketDataQuery_marketsConnection_edges_node_data;
|
||||||
|
|
||||||
|
const update = (data: MarketData, delta: MarketDataSub_marketsData) => {
|
||||||
|
return produce(data, (draft) => {
|
||||||
|
const { marketId, __typename, ...marketData } = delta;
|
||||||
|
Object.assign(draft, marketData);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getData = (responseData: MarketDataQuery): MarketData | null =>
|
||||||
|
responseData.marketsConnection.edges[0].node.data || null;
|
||||||
|
|
||||||
|
const getDelta = (subscriptionData: MarketDataSub): MarketDataSub_marketsData =>
|
||||||
|
subscriptionData.marketsData[0];
|
||||||
|
|
||||||
|
export const marketDataProvider = makeDataProvider<
|
||||||
|
MarketDataQuery,
|
||||||
|
MarketData,
|
||||||
|
MarketDataSub,
|
||||||
|
MarketDataSub_marketsData
|
||||||
|
>({
|
||||||
|
query: MARKET_DATA_QUERY,
|
||||||
|
subscriptionQuery: MARKET_DATA_SUB,
|
||||||
|
update,
|
||||||
|
getData,
|
||||||
|
getDelta,
|
||||||
|
});
|
19
libs/market-list/src/lib/market-provider.ts
Normal file
19
libs/market-list/src/lib/market-provider.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { makeDerivedDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
|
import type { Market } from './markets-provider';
|
||||||
|
import { marketsProvider } from './markets-provider';
|
||||||
|
|
||||||
|
export const marketProvider = makeDerivedDataProvider<Market>(
|
||||||
|
[(callback, client) => marketsProvider(callback, client)], // omit variables param
|
||||||
|
([markets], variables) => {
|
||||||
|
if (markets) {
|
||||||
|
const market = (markets as Market[]).find(
|
||||||
|
(market) => market.id === variables?.marketId
|
||||||
|
);
|
||||||
|
if (market) {
|
||||||
|
return market;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
);
|
53
libs/market-list/src/lib/markets-candles-provider.ts
Normal file
53
libs/market-list/src/lib/markets-candles-provider.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
import { makeDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
|
import type {
|
||||||
|
MarketsCandlesQuery,
|
||||||
|
MarketsCandlesQuery_marketsConnection_edges_node as Market,
|
||||||
|
MarketsCandlesQuery_marketsConnection_edges_node_candlesConnection_edges_node as Candle,
|
||||||
|
} from './__generated__';
|
||||||
|
|
||||||
|
export const MARKETS_CANDLES_QUERY = gql`
|
||||||
|
query MarketsCandlesQuery($interval: Interval!, $since: String!) {
|
||||||
|
marketsConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
candlesConnection(interval: $interval, since: $since) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
high
|
||||||
|
low
|
||||||
|
open
|
||||||
|
close
|
||||||
|
volume
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export interface MarketCandles {
|
||||||
|
marketId: Market['id'];
|
||||||
|
candles: Candle[] | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = (responseData: MarketsCandlesQuery): MarketCandles[] | null =>
|
||||||
|
responseData.marketsConnection.edges.map((edge) => ({
|
||||||
|
marketId: edge.node.id,
|
||||||
|
candles: edge.node.candlesConnection.edges
|
||||||
|
?.filter((edge) => edge?.node)
|
||||||
|
.map((edge) => edge?.node as Candle),
|
||||||
|
})) || null;
|
||||||
|
|
||||||
|
export const marketsCandlesProvider = makeDataProvider<
|
||||||
|
MarketsCandlesQuery,
|
||||||
|
MarketCandles[],
|
||||||
|
never,
|
||||||
|
never
|
||||||
|
>({
|
||||||
|
query: MARKETS_CANDLES_QUERY,
|
||||||
|
getData,
|
||||||
|
});
|
@ -1,141 +1,45 @@
|
|||||||
import produce from 'immer';
|
import { gql } from '@apollo/client';
|
||||||
import { gql, useQuery } from '@apollo/client';
|
|
||||||
import { makeDataProvider } from '@vegaprotocol/react-helpers';
|
import { makeDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import type {
|
import type { MarketsDataQuery } from './__generated__/MarketsDataQuery';
|
||||||
MarketDataSub,
|
import type { MarketData } from './market-data-provider';
|
||||||
MarketDataSub_marketData,
|
|
||||||
MarketList,
|
|
||||||
MarketList_markets,
|
|
||||||
} from './';
|
|
||||||
import { useMemo } from 'react';
|
|
||||||
import { Interval } from '@vegaprotocol/types';
|
|
||||||
import { mapDataToMarketList } from './utils';
|
|
||||||
|
|
||||||
export const useMarketList = () => {
|
export const MARKETS_DATA_QUERY = gql`
|
||||||
const since = useMemo(() => {
|
query MarketsDataQuery {
|
||||||
const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600;
|
marketsConnection {
|
||||||
return new Date(yesterday * 1000).toISOString();
|
edges {
|
||||||
}, []);
|
node {
|
||||||
const { data, loading, error } = useQuery<MarketList>(MARKET_LIST_QUERY, {
|
data {
|
||||||
variables: { interval: Interval.INTERVAL_I1H, since },
|
market {
|
||||||
});
|
id
|
||||||
|
|
||||||
return {
|
|
||||||
data: useMemo(() => data && mapDataToMarketList(data), [data]),
|
|
||||||
loading,
|
|
||||||
error,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const MARKET_DATA_FRAGMENT = gql`
|
|
||||||
fragment MarketDataFields on MarketData {
|
|
||||||
market {
|
|
||||||
id
|
|
||||||
state
|
|
||||||
tradingMode
|
|
||||||
}
|
|
||||||
bestBidPrice
|
|
||||||
bestOfferPrice
|
|
||||||
markPrice
|
|
||||||
trigger
|
|
||||||
indicativeVolume
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const MARKET_LIST_QUERY = gql`
|
|
||||||
query MarketList($interval: Interval!, $since: String!) {
|
|
||||||
markets {
|
|
||||||
id
|
|
||||||
decimalPlaces
|
|
||||||
positionDecimalPlaces
|
|
||||||
state
|
|
||||||
tradingMode
|
|
||||||
fees {
|
|
||||||
factors {
|
|
||||||
makerFee
|
|
||||||
infrastructureFee
|
|
||||||
liquidityFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data {
|
|
||||||
market {
|
|
||||||
id
|
|
||||||
state
|
|
||||||
tradingMode
|
|
||||||
}
|
|
||||||
bestBidPrice
|
|
||||||
bestOfferPrice
|
|
||||||
markPrice
|
|
||||||
trigger
|
|
||||||
indicativeVolume
|
|
||||||
}
|
|
||||||
tradableInstrument {
|
|
||||||
instrument {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
code
|
|
||||||
metadata {
|
|
||||||
tags
|
|
||||||
}
|
|
||||||
product {
|
|
||||||
... on Future {
|
|
||||||
settlementAsset {
|
|
||||||
symbol
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
bestBidPrice
|
||||||
|
bestOfferPrice
|
||||||
|
markPrice
|
||||||
|
trigger
|
||||||
|
staticMidPrice
|
||||||
|
marketTradingMode
|
||||||
|
indicativeVolume
|
||||||
|
indicativePrice
|
||||||
|
bestStaticBidPrice
|
||||||
|
bestStaticOfferPrice
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
marketTimestamps {
|
|
||||||
open
|
|
||||||
close
|
|
||||||
}
|
|
||||||
candles(interval: $interval, since: $since) {
|
|
||||||
open
|
|
||||||
close
|
|
||||||
high
|
|
||||||
low
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const MARKET_DATA_SUB = gql`
|
const getData = (responseData: MarketsDataQuery): MarketData[] | null =>
|
||||||
${MARKET_DATA_FRAGMENT}
|
responseData.marketsConnection.edges
|
||||||
subscription MarketDataSub {
|
.filter((edge) => edge.node.data)
|
||||||
marketData {
|
.map((edge) => edge.node.data as MarketData) || null;
|
||||||
...MarketDataFields
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const update = (
|
|
||||||
data: MarketList_markets[],
|
|
||||||
delta: MarketDataSub_marketData
|
|
||||||
) => {
|
|
||||||
return produce(data, (draft) => {
|
|
||||||
const index = draft.findIndex((m) => m.id === delta.market.id);
|
|
||||||
if (index !== -1) {
|
|
||||||
draft[index].data = delta;
|
|
||||||
}
|
|
||||||
// @TODO - else push new market to draft
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getData = (responseData: MarketList): MarketList_markets[] | null =>
|
|
||||||
responseData.markets;
|
|
||||||
const getDelta = (subscriptionData: MarketDataSub): MarketDataSub_marketData =>
|
|
||||||
subscriptionData.marketData;
|
|
||||||
|
|
||||||
export const marketsDataProvider = makeDataProvider<
|
export const marketsDataProvider = makeDataProvider<
|
||||||
MarketList,
|
MarketsDataQuery,
|
||||||
MarketList_markets[],
|
MarketData[],
|
||||||
MarketDataSub,
|
never,
|
||||||
MarketDataSub_marketData
|
never
|
||||||
>({
|
>({
|
||||||
query: MARKET_LIST_QUERY,
|
query: MARKETS_DATA_QUERY,
|
||||||
subscriptionQuery: MARKET_DATA_SUB,
|
|
||||||
update,
|
|
||||||
getData,
|
getData,
|
||||||
getDelta,
|
|
||||||
});
|
});
|
||||||
|
144
libs/market-list/src/lib/markets-provider.ts
Normal file
144
libs/market-list/src/lib/markets-provider.ts
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
import {
|
||||||
|
makeDataProvider,
|
||||||
|
makeDerivedDataProvider,
|
||||||
|
useDataProvider,
|
||||||
|
} from '@vegaprotocol/react-helpers';
|
||||||
|
import type {
|
||||||
|
Markets,
|
||||||
|
Markets_marketsConnection_edges_node,
|
||||||
|
} from './__generated__';
|
||||||
|
import { marketsDataProvider } from './markets-data-provider';
|
||||||
|
import { marketsCandlesProvider } from './markets-candles-provider';
|
||||||
|
import type { MarketData } from './market-data-provider';
|
||||||
|
import type { MarketCandles } from './markets-candles-provider';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { Interval } from '@vegaprotocol/types';
|
||||||
|
import { mapDataToMarketList } from './utils';
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||||
|
export type Market = Markets_marketsConnection_edges_node;
|
||||||
|
|
||||||
|
const MARKET_DATA_FRAGMENT = gql`
|
||||||
|
fragment MarketFields on Market {
|
||||||
|
id
|
||||||
|
decimalPlaces
|
||||||
|
positionDecimalPlaces
|
||||||
|
state
|
||||||
|
tradingMode
|
||||||
|
fees {
|
||||||
|
factors {
|
||||||
|
makerFee
|
||||||
|
infrastructureFee
|
||||||
|
liquidityFee
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tradableInstrument {
|
||||||
|
instrument {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
code
|
||||||
|
metadata {
|
||||||
|
tags
|
||||||
|
}
|
||||||
|
product {
|
||||||
|
... on Future {
|
||||||
|
settlementAsset {
|
||||||
|
symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
marketTimestamps {
|
||||||
|
open
|
||||||
|
close
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const MARKET_LIST_QUERY = gql`
|
||||||
|
${MARKET_DATA_FRAGMENT}
|
||||||
|
query Markets {
|
||||||
|
marketsConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
...MarketFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const getData = (responseData: Markets): Market[] | null =>
|
||||||
|
responseData.marketsConnection.edges.map((edge) => edge.node);
|
||||||
|
|
||||||
|
export const marketsProvider = makeDataProvider<
|
||||||
|
Markets,
|
||||||
|
Market[],
|
||||||
|
never,
|
||||||
|
never
|
||||||
|
>({
|
||||||
|
query: MARKET_LIST_QUERY,
|
||||||
|
getData,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const activeMarketsProvider = makeDerivedDataProvider<Market[]>(
|
||||||
|
[marketsProvider],
|
||||||
|
([markets]) => mapDataToMarketList(markets)
|
||||||
|
);
|
||||||
|
|
||||||
|
interface MarketsListData {
|
||||||
|
markets: Market[];
|
||||||
|
marketsData: MarketData[];
|
||||||
|
marketsCandles: MarketCandles[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const marketListProvider = makeDerivedDataProvider<MarketsListData>(
|
||||||
|
[
|
||||||
|
(callback, client) => activeMarketsProvider(callback, client),
|
||||||
|
(callback, client) => marketsDataProvider(callback, client),
|
||||||
|
marketsCandlesProvider,
|
||||||
|
],
|
||||||
|
(parts) => {
|
||||||
|
return {
|
||||||
|
markets: parts[0] as Market[],
|
||||||
|
marketsData: parts[1] as MarketData[],
|
||||||
|
marketsCandles: parts[2] as MarketCandles[],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export type MarketWithData = Market & { data?: MarketData };
|
||||||
|
|
||||||
|
export const marketsWithDataProvider = makeDerivedDataProvider<
|
||||||
|
MarketWithData[]
|
||||||
|
>([activeMarketsProvider, marketsDataProvider], (parts) =>
|
||||||
|
(parts[0] as Market[]).map((market) => ({
|
||||||
|
...market,
|
||||||
|
data: (parts[1] as MarketData[]).find(
|
||||||
|
(data) => data.market.id === market.id
|
||||||
|
),
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
export const useMarketList = () => {
|
||||||
|
const variables = useMemo(() => {
|
||||||
|
const yesterday = Math.round(new Date().getTime() / 1000) - 24 * 3600;
|
||||||
|
return {
|
||||||
|
since: new Date(yesterday * 1000).toISOString(),
|
||||||
|
interval: Interval.INTERVAL_I1H,
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
const { data, loading, error } = useDataProvider<MarketsListData, never>({
|
||||||
|
dataProvider: marketListProvider,
|
||||||
|
variables,
|
||||||
|
noUpdate: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
};
|
||||||
|
};
|
@ -1,210 +1,59 @@
|
|||||||
import type { MarketList } from '../__generated__/MarketList';
|
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
||||||
|
import type { Market } from '../markets-provider';
|
||||||
import { mapDataToMarketList } from './market-utils';
|
import { mapDataToMarketList } from './market-utils';
|
||||||
|
|
||||||
|
const MARKET_A: Partial<Market> = {
|
||||||
|
id: '1',
|
||||||
|
marketTimestamps: {
|
||||||
|
__typename: 'MarketTimestamps',
|
||||||
|
open: '2022-05-18T13:08:27.693537312Z',
|
||||||
|
close: null,
|
||||||
|
},
|
||||||
|
state: MarketState.STATE_ACTIVE,
|
||||||
|
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
const MARKET_B: Partial<Market> = {
|
||||||
|
id: '2',
|
||||||
|
marketTimestamps: {
|
||||||
|
__typename: 'MarketTimestamps',
|
||||||
|
open: '2022-05-18T13:00:39.328347732Z',
|
||||||
|
close: null,
|
||||||
|
},
|
||||||
|
state: MarketState.STATE_ACTIVE,
|
||||||
|
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
const MARKET_C: Partial<Market> = {
|
||||||
|
id: '3',
|
||||||
|
marketTimestamps: {
|
||||||
|
__typename: 'MarketTimestamps',
|
||||||
|
open: '2022-05-17T13:00:39.328347732Z',
|
||||||
|
close: null,
|
||||||
|
},
|
||||||
|
state: MarketState.STATE_REJECTED,
|
||||||
|
tradingMode: MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
};
|
||||||
|
|
||||||
|
const MARKET_D: Partial<Market> = {
|
||||||
|
id: '4',
|
||||||
|
marketTimestamps: {
|
||||||
|
__typename: 'MarketTimestamps',
|
||||||
|
open: '2022-05-16T13:00:39.328347732Z',
|
||||||
|
close: null,
|
||||||
|
},
|
||||||
|
state: MarketState.STATE_ACTIVE,
|
||||||
|
tradingMode: MarketTradingMode.TRADING_MODE_NO_TRADING,
|
||||||
|
};
|
||||||
|
|
||||||
describe('mapDataToMarketList', () => {
|
describe('mapDataToMarketList', () => {
|
||||||
it('should map queried data to market list format', () => {
|
it('should map queried data to market list format', () => {
|
||||||
const result = mapDataToMarketList(mockData.data as unknown as MarketList);
|
const result = mapDataToMarketList([
|
||||||
expect(result).toEqual(mockList);
|
MARKET_A,
|
||||||
|
MARKET_B,
|
||||||
|
MARKET_C,
|
||||||
|
MARKET_D,
|
||||||
|
] as unknown as Market[]);
|
||||||
|
expect(result).toEqual([MARKET_B, MARKET_A]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockList = [
|
|
||||||
{
|
|
||||||
__typename: 'Market',
|
|
||||||
id: '3e6671566ccf5c33702e955fe8b018683fcdb812bfe3ed283fc250bb4f798ff3',
|
|
||||||
decimalPlaces: 5,
|
|
||||||
candles: [
|
|
||||||
{
|
|
||||||
open: '16141155',
|
|
||||||
close: '16293551',
|
|
||||||
high: '16320190',
|
|
||||||
low: '16023805',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
open: '16293548',
|
|
||||||
close: '16322118',
|
|
||||||
high: '16365861',
|
|
||||||
low: '16192970',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
fees: {
|
|
||||||
factors: {
|
|
||||||
makerFee: 0.0002,
|
|
||||||
infrastructureFee: 0.0005,
|
|
||||||
liquidityFee: 0.001,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
instrument: {
|
|
||||||
__typename: 'Instrument',
|
|
||||||
name: 'Apple Monthly (30 Jun 2022)',
|
|
||||||
code: 'AAPL.MF21',
|
|
||||||
product: {
|
|
||||||
settlementAsset: { symbol: 'AAPL.MF21', __typename: 'Asset' },
|
|
||||||
__typename: 'Future',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
marketTimestamps: {
|
|
||||||
__typename: 'MarketTimestamps',
|
|
||||||
open: '2022-05-18T13:00:39.328347732Z',
|
|
||||||
close: null,
|
|
||||||
},
|
|
||||||
open: 1652878839328,
|
|
||||||
close: null,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Market',
|
|
||||||
id: '062ddcb97beae5b7cc4fa20621fe0c83b2a6f7e76cf5b129c6bd3dc14e8111ef',
|
|
||||||
decimalPlaces: 2,
|
|
||||||
fees: {
|
|
||||||
factors: {
|
|
||||||
makerFee: 0.0002,
|
|
||||||
infrastructureFee: 0.0005,
|
|
||||||
liquidityFee: 0.001,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
instrument: {
|
|
||||||
__typename: 'Instrument',
|
|
||||||
name: 'APEUSD (May 2022)',
|
|
||||||
code: 'APEUSD',
|
|
||||||
product: {
|
|
||||||
settlementAsset: { symbol: 'APEUSD', __typename: 'Asset' },
|
|
||||||
__typename: 'Future',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
marketTimestamps: {
|
|
||||||
__typename: 'MarketTimestamps',
|
|
||||||
open: '2022-05-18T13:08:27.693537312Z',
|
|
||||||
close: null,
|
|
||||||
},
|
|
||||||
candles: [
|
|
||||||
{
|
|
||||||
open: '16141155',
|
|
||||||
close: '16293551',
|
|
||||||
high: '16320190',
|
|
||||||
low: '16023805',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
open: '16293548',
|
|
||||||
close: '16322118',
|
|
||||||
high: '16365861',
|
|
||||||
low: '16192970',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
open: 1652879307693,
|
|
||||||
close: null,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const mockData = {
|
|
||||||
data: {
|
|
||||||
markets: [
|
|
||||||
{
|
|
||||||
__typename: 'Market',
|
|
||||||
id: '062ddcb97beae5b7cc4fa20621fe0c83b2a6f7e76cf5b129c6bd3dc14e8111ef',
|
|
||||||
decimalPlaces: 2,
|
|
||||||
fees: {
|
|
||||||
factors: {
|
|
||||||
makerFee: 0.0002,
|
|
||||||
infrastructureFee: 0.0005,
|
|
||||||
liquidityFee: 0.001,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
instrument: {
|
|
||||||
__typename: 'Instrument',
|
|
||||||
name: 'APEUSD (May 2022)',
|
|
||||||
code: 'APEUSD',
|
|
||||||
product: {
|
|
||||||
settlementAsset: {
|
|
||||||
symbol: 'APEUSD',
|
|
||||||
__typename: 'Asset',
|
|
||||||
},
|
|
||||||
__typename: 'Future',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
marketTimestamps: {
|
|
||||||
__typename: 'MarketTimestamps',
|
|
||||||
open: '2022-05-18T13:08:27.693537312Z',
|
|
||||||
close: null,
|
|
||||||
},
|
|
||||||
candles: [
|
|
||||||
{
|
|
||||||
open: '16141155',
|
|
||||||
close: '16293551',
|
|
||||||
high: '16320190',
|
|
||||||
low: '16023805',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
open: '16293548',
|
|
||||||
close: '16322118',
|
|
||||||
high: '16365861',
|
|
||||||
low: '16192970',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
__typename: 'Market',
|
|
||||||
id: '3e6671566ccf5c33702e955fe8b018683fcdb812bfe3ed283fc250bb4f798ff3',
|
|
||||||
decimalPlaces: 5,
|
|
||||||
candles: [
|
|
||||||
{
|
|
||||||
open: '16141155',
|
|
||||||
close: '16293551',
|
|
||||||
high: '16320190',
|
|
||||||
low: '16023805',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
open: '16293548',
|
|
||||||
close: '16322118',
|
|
||||||
high: '16365861',
|
|
||||||
low: '16192970',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
fees: {
|
|
||||||
factors: {
|
|
||||||
makerFee: 0.0002,
|
|
||||||
infrastructureFee: 0.0005,
|
|
||||||
liquidityFee: 0.001,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
instrument: {
|
|
||||||
__typename: 'Instrument',
|
|
||||||
name: 'Apple Monthly (30 Jun 2022)',
|
|
||||||
code: 'AAPL.MF21',
|
|
||||||
product: {
|
|
||||||
settlementAsset: {
|
|
||||||
symbol: 'AAPL.MF21',
|
|
||||||
__typename: 'Asset',
|
|
||||||
},
|
|
||||||
__typename: 'Future',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
marketTimestamps: {
|
|
||||||
__typename: 'MarketTimestamps',
|
|
||||||
open: '2022-05-18T13:00:39.328347732Z',
|
|
||||||
close: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
@ -2,13 +2,9 @@ import { formatNumberPercentage } from '@vegaprotocol/react-helpers';
|
|||||||
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import orderBy from 'lodash/orderBy';
|
import orderBy from 'lodash/orderBy';
|
||||||
import type {
|
import type { Market, Candle } from '../';
|
||||||
MarketList,
|
|
||||||
MarketList_markets,
|
|
||||||
MarketList_markets_fees_factors,
|
|
||||||
} from '../__generated__/MarketList';
|
|
||||||
|
|
||||||
export const totalFees = (fees: MarketList_markets_fees_factors) => {
|
export const totalFees = (fees: Market['fees']['factors']) => {
|
||||||
if (!fees) {
|
if (!fees) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -20,7 +16,7 @@ export const totalFees = (fees: MarketList_markets_fees_factors) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mapDataToMarketList = ({ markets }: MarketList) => {
|
export const mapDataToMarketList = (markets: Market[]) => {
|
||||||
const tradingModesOrdering = [
|
const tradingModesOrdering = [
|
||||||
MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||||
@ -29,24 +25,12 @@ export const mapDataToMarketList = ({ markets }: MarketList) => {
|
|||||||
MarketTradingMode.TRADING_MODE_NO_TRADING,
|
MarketTradingMode.TRADING_MODE_NO_TRADING,
|
||||||
];
|
];
|
||||||
const orderedMarkets = orderBy(
|
const orderedMarkets = orderBy(
|
||||||
markets
|
markets?.filter(
|
||||||
?.filter(
|
(m) =>
|
||||||
(m) =>
|
m.state !== MarketState.STATE_REJECTED &&
|
||||||
m.state !== MarketState.STATE_REJECTED &&
|
m.tradingMode !== MarketTradingMode.TRADING_MODE_NO_TRADING
|
||||||
m.tradingMode !== MarketTradingMode.TRADING_MODE_NO_TRADING
|
) || [],
|
||||||
)
|
['marketTimestamps.open', 'id'],
|
||||||
.map((m) => {
|
|
||||||
return {
|
|
||||||
...m,
|
|
||||||
open: m.marketTimestamps.open
|
|
||||||
? new Date(m.marketTimestamps.open).getTime()
|
|
||||||
: null,
|
|
||||||
close: m.marketTimestamps.close
|
|
||||||
? new Date(m.marketTimestamps.close).getTime()
|
|
||||||
: null,
|
|
||||||
};
|
|
||||||
}) || [],
|
|
||||||
['open', 'id'],
|
|
||||||
['asc', 'asc']
|
['asc', 'asc']
|
||||||
);
|
);
|
||||||
return orderedMarkets.sort(
|
return orderedMarkets.sort(
|
||||||
@ -56,8 +40,8 @@ export const mapDataToMarketList = ({ markets }: MarketList) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const calcCandleLow = (m: MarketList_markets): string | undefined => {
|
export const calcCandleLow = (candles: Candle[]): string | undefined => {
|
||||||
return m.candles
|
return candles
|
||||||
?.reduce((acc: BigNumber, c) => {
|
?.reduce((acc: BigNumber, c) => {
|
||||||
if (c?.low) {
|
if (c?.low) {
|
||||||
if (acc.isLessThan(new BigNumber(c.low))) {
|
if (acc.isLessThan(new BigNumber(c.low))) {
|
||||||
@ -66,12 +50,12 @@ export const calcCandleLow = (m: MarketList_markets): string | undefined => {
|
|||||||
return new BigNumber(c.low);
|
return new BigNumber(c.low);
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, new BigNumber(m.candles?.[0]?.high ?? 0))
|
}, new BigNumber(candles?.[0]?.high ?? 0))
|
||||||
.toString();
|
.toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const calcCandleHigh = (m: MarketList_markets): string | undefined => {
|
export const calcCandleHigh = (candles: Candle[]): string | undefined => {
|
||||||
return m.candles
|
return candles
|
||||||
?.reduce((acc: BigNumber, c) => {
|
?.reduce((acc: BigNumber, c) => {
|
||||||
if (c?.high) {
|
if (c?.high) {
|
||||||
if (acc.isGreaterThan(new BigNumber(c.high))) {
|
if (acc.isGreaterThan(new BigNumber(c.high))) {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export * from './lib/__generated__/Positions';
|
export * from './lib/__generated__/Positions';
|
||||||
|
export * from './lib/__generated__/PositionsSubscription';
|
||||||
export * from './lib/positions-container';
|
export * from './lib/positions-container';
|
||||||
export * from './lib/positions-data-providers';
|
export * from './lib/positions-data-providers';
|
||||||
export * from './lib/positions-table';
|
export * from './lib/positions-table';
|
||||||
|
@ -252,7 +252,7 @@ export const update = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const positionDataProvider = makeDataProvider<
|
export const positionsDataProvider = makeDataProvider<
|
||||||
Positions,
|
Positions,
|
||||||
Positions_party,
|
Positions_party,
|
||||||
PositionsSubscription,
|
PositionsSubscription,
|
||||||
@ -267,7 +267,7 @@ export const positionDataProvider = makeDataProvider<
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const positionsMetricsDataProvider = makeDerivedDataProvider<Position[]>(
|
export const positionsMetricsDataProvider = makeDerivedDataProvider<Position[]>(
|
||||||
[positionDataProvider, accountsDataProvider],
|
[positionsDataProvider, accountsDataProvider],
|
||||||
([positions, accounts]) => {
|
([positions, accounts]) => {
|
||||||
return sortBy(
|
return sortBy(
|
||||||
getMetrics(
|
getMetrics(
|
||||||
|
@ -19,6 +19,8 @@ export function useDataProvider<Data, Delta>({
|
|||||||
update,
|
update,
|
||||||
insert,
|
insert,
|
||||||
variables,
|
variables,
|
||||||
|
noUpdate,
|
||||||
|
skip,
|
||||||
}: {
|
}: {
|
||||||
dataProvider: Subscribe<Data, Delta>;
|
dataProvider: Subscribe<Data, Delta>;
|
||||||
update?: ({ delta, data }: { delta: Delta; data: Data }) => boolean;
|
update?: ({ delta, data }: { delta: Delta; data: Data }) => boolean;
|
||||||
@ -32,11 +34,13 @@ export function useDataProvider<Data, Delta>({
|
|||||||
totalCount?: number;
|
totalCount?: number;
|
||||||
}) => boolean;
|
}) => boolean;
|
||||||
variables?: OperationVariables;
|
variables?: OperationVariables;
|
||||||
|
noUpdate?: boolean;
|
||||||
|
skip?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
const [data, setData] = useState<Data | null>(null);
|
const [data, setData] = useState<Data | null>(null);
|
||||||
const [totalCount, setTotalCount] = useState<number>();
|
const [totalCount, setTotalCount] = useState<number>();
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(!skip);
|
||||||
const [error, setError] = useState<Error | undefined>(undefined);
|
const [error, setError] = useState<Error | undefined>(undefined);
|
||||||
const flushRef = useRef<(() => void) | undefined>(undefined);
|
const flushRef = useRef<(() => void) | undefined>(undefined);
|
||||||
const reloadRef = useRef<((force?: boolean) => void) | undefined>(undefined);
|
const reloadRef = useRef<((force?: boolean) => void) | undefined>(undefined);
|
||||||
@ -75,7 +79,12 @@ export function useDataProvider<Data, Delta>({
|
|||||||
// if update or insert function returns true it means that component handles updates
|
// if update or insert function returns true it means that component handles updates
|
||||||
// component can use flush() which will call callback without delta and cause data state update
|
// component can use flush() which will call callback without delta and cause data state update
|
||||||
if (initialized.current && data) {
|
if (initialized.current && data) {
|
||||||
if (isUpdate && update && (!delta || update({ delta, data }))) {
|
if (
|
||||||
|
isUpdate &&
|
||||||
|
!noUpdate &&
|
||||||
|
update &&
|
||||||
|
(!delta || update({ delta, data }))
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
@ -91,9 +100,12 @@ export function useDataProvider<Data, Delta>({
|
|||||||
setData(data);
|
setData(data);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[update, insert]
|
[update, insert, noUpdate]
|
||||||
);
|
);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (skip) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { unsubscribe, flush, reload, load } = dataProvider(
|
const { unsubscribe, flush, reload, load } = dataProvider(
|
||||||
callback,
|
callback,
|
||||||
client,
|
client,
|
||||||
@ -103,6 +115,6 @@ export function useDataProvider<Data, Delta>({
|
|||||||
reloadRef.current = reload;
|
reloadRef.current = reload;
|
||||||
loadRef.current = load;
|
loadRef.current = load;
|
||||||
return unsubscribe;
|
return unsubscribe;
|
||||||
}, [client, initialized, dataProvider, callback, variables]);
|
}, [client, initialized, dataProvider, callback, variables, skip]);
|
||||||
return { data, loading, error, flush, reload, load, totalCount };
|
return { data, loading, error, flush, reload, load, totalCount };
|
||||||
}
|
}
|
||||||
|
@ -133,10 +133,10 @@ export function defaultAppend<Data>(
|
|||||||
|
|
||||||
interface DataProviderParams<QueryData, Data, SubscriptionData, Delta> {
|
interface DataProviderParams<QueryData, Data, SubscriptionData, Delta> {
|
||||||
query: Query<QueryData>;
|
query: Query<QueryData>;
|
||||||
subscriptionQuery: Query<SubscriptionData>;
|
subscriptionQuery?: Query<SubscriptionData>;
|
||||||
update: Update<Data, Delta>;
|
update?: Update<Data, Delta>;
|
||||||
getData: GetData<QueryData, Data>;
|
getData: GetData<QueryData, Data>;
|
||||||
getDelta: GetDelta<SubscriptionData, Delta>;
|
getDelta?: GetDelta<SubscriptionData, Delta>;
|
||||||
pagination?: {
|
pagination?: {
|
||||||
getPageInfo: GetPageInfo<QueryData>;
|
getPageInfo: GetPageInfo<QueryData>;
|
||||||
getTotalCount?: GetTotalCount<QueryData>;
|
getTotalCount?: GetTotalCount<QueryData>;
|
||||||
@ -270,6 +270,7 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
? { ...variables, pagination: { first: pagination.first } }
|
? { ...variables, pagination: { first: pagination.first } }
|
||||||
: variables,
|
: variables,
|
||||||
fetchPolicy,
|
fetchPolicy,
|
||||||
|
errorPolicy: 'ignore',
|
||||||
});
|
});
|
||||||
data = getData(res.data);
|
data = getData(res.data);
|
||||||
if (data && pagination) {
|
if (data && pagination) {
|
||||||
@ -291,7 +292,7 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if there was some updates received from subscription during initial query loading apply them on just received data
|
// if there was some updates received from subscription during initial query loading apply them on just received data
|
||||||
if (data && updateQueue && updateQueue.length > 0) {
|
if (update && data && updateQueue && updateQueue.length > 0) {
|
||||||
while (updateQueue.length) {
|
while (updateQueue.length) {
|
||||||
const delta = updateQueue.shift();
|
const delta = updateQueue.shift();
|
||||||
if (delta) {
|
if (delta) {
|
||||||
@ -339,31 +340,33 @@ function makeDataProviderInternal<QueryData, Data, SubscriptionData, Delta>({
|
|||||||
if (!client) {
|
if (!client) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
subscription = client
|
if (subscriptionQuery && getDelta && update) {
|
||||||
.subscribe<SubscriptionData>({
|
subscription = client
|
||||||
query: subscriptionQuery,
|
.subscribe<SubscriptionData>({
|
||||||
variables,
|
query: subscriptionQuery,
|
||||||
fetchPolicy,
|
variables,
|
||||||
})
|
fetchPolicy,
|
||||||
.subscribe(
|
})
|
||||||
({ data: subscriptionData }) => {
|
.subscribe(
|
||||||
if (!subscriptionData) {
|
({ data: subscriptionData }) => {
|
||||||
return;
|
if (!subscriptionData) {
|
||||||
}
|
|
||||||
const delta = getDelta(subscriptionData);
|
|
||||||
if (loading || !data) {
|
|
||||||
updateQueue.push(delta);
|
|
||||||
} else {
|
|
||||||
const updatedData = update(data, delta, reload);
|
|
||||||
if (updatedData === data) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data = updatedData;
|
const delta = getDelta(subscriptionData);
|
||||||
notifyAll({ delta, isUpdate: true });
|
if (loading || !data) {
|
||||||
}
|
updateQueue.push(delta);
|
||||||
},
|
} else {
|
||||||
() => reload()
|
const updatedData = update(data, delta, reload);
|
||||||
);
|
if (updatedData === data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
data = updatedData;
|
||||||
|
notifyAll({ delta, isUpdate: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => reload()
|
||||||
|
);
|
||||||
|
}
|
||||||
await initialFetch();
|
await initialFetch();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -470,7 +473,8 @@ export function makeDataProvider<QueryData, Data, SubscriptionData, Delta>(
|
|||||||
type DependencySubscribe = Subscribe<any, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
type DependencySubscribe = Subscribe<any, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
type DependencyUpdateCallback = Parameters<DependencySubscribe>['0'];
|
type DependencyUpdateCallback = Parameters<DependencySubscribe>['0'];
|
||||||
export type CombineDerivedData<Data> = (
|
export type CombineDerivedData<Data> = (
|
||||||
parts: Parameters<DependencyUpdateCallback>['0']['data'][]
|
parts: Parameters<DependencyUpdateCallback>['0']['data'][],
|
||||||
|
variables?: OperationVariables
|
||||||
) => Data | null;
|
) => Data | null;
|
||||||
|
|
||||||
function makeDerivedDataProviderInternal<Data>(
|
function makeDerivedDataProviderInternal<Data>(
|
||||||
@ -521,7 +525,10 @@ function makeDerivedDataProviderInternal<Data>(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const newData = newLoaded
|
const newData = newLoaded
|
||||||
? combineData(parts.map((part) => part.data))
|
? combineData(
|
||||||
|
parts.map((part) => part.data),
|
||||||
|
variables
|
||||||
|
)
|
||||||
: data;
|
: data;
|
||||||
if (
|
if (
|
||||||
newLoading !== loading ||
|
newLoading !== loading ||
|
||||||
|
4
libs/types/src/__generated__/globalTypes.ts
generated
4
libs/types/src/__generated__/globalTypes.ts
generated
@ -10,7 +10,7 @@
|
|||||||
/**
|
/**
|
||||||
* The various account types in Vega (used by collateral)
|
* The various account types in Vega (used by collateral)
|
||||||
*/
|
*/
|
||||||
export enum AccountType {
|
export enum AccountType {
|
||||||
ACCOUNT_TYPE_BOND = "ACCOUNT_TYPE_BOND",
|
ACCOUNT_TYPE_BOND = "ACCOUNT_TYPE_BOND",
|
||||||
ACCOUNT_TYPE_EXTERNAL = "ACCOUNT_TYPE_EXTERNAL",
|
ACCOUNT_TYPE_EXTERNAL = "ACCOUNT_TYPE_EXTERNAL",
|
||||||
ACCOUNT_TYPE_FEES_INFRASTRUCTURE = "ACCOUNT_TYPE_FEES_INFRASTRUCTURE",
|
ACCOUNT_TYPE_FEES_INFRASTRUCTURE = "ACCOUNT_TYPE_FEES_INFRASTRUCTURE",
|
||||||
@ -361,4 +361,4 @@ export interface Pagination {
|
|||||||
|
|
||||||
//==============================================================
|
//==============================================================
|
||||||
// END Enums and Input Objects
|
// END Enums and Input Objects
|
||||||
//==============================================================
|
//==============================================================
|
Loading…
Reference in New Issue
Block a user