chore(trading): live update deal ticket market data (#2570)
This commit is contained in:
parent
4dd63da62b
commit
a5d53eee77
@ -39,10 +39,8 @@ export const MarketList = () => {
|
|||||||
|
|
||||||
const getRowId = useCallback(({ data }: GetRowIdParams) => data.id, []);
|
const getRowId = useCallback(({ data }: GetRowIdParams) => data.id, []);
|
||||||
|
|
||||||
const localData = data?.markets;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer loading={loading} error={error} data={localData}>
|
<AsyncRenderer loading={loading} error={error} data={data}>
|
||||||
<div
|
<div
|
||||||
className="grow w-full"
|
className="grow w-full"
|
||||||
style={{ minHeight: 500, overflow: 'hidden' }}
|
style={{ minHeight: 500, overflow: 'hidden' }}
|
||||||
@ -57,7 +55,7 @@ export const MarketList = () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
rowData={localData}
|
rowData={data}
|
||||||
defaultColDef={{
|
defaultColDef={{
|
||||||
resizable: true,
|
resizable: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
|
@ -59,11 +59,9 @@ describe('home', { tags: '@regression' }, () => {
|
|||||||
describe('default market found', () => {
|
describe('default market found', () => {
|
||||||
it('redirects to a default market with the landing dialog open', () => {
|
it('redirects to a default market with the landing dialog open', () => {
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
|
|
||||||
cy.get('main', { timeout: 20000 }).then((el) => {
|
cy.get('main[data-testid^="/markets/"]');
|
||||||
expect(el.attr('data-testid')?.startsWith('/market')).to.equal(true);
|
|
||||||
}); // Wait for page to be rendered to before checking url
|
|
||||||
|
|
||||||
// Overlay should be shown
|
// Overlay should be shown
|
||||||
cy.getByTestId(selectMarketOverlay).should('exist');
|
cy.getByTestId(selectMarketOverlay).should('exist');
|
||||||
@ -101,7 +99,7 @@ describe('home', { tags: '@regression' }, () => {
|
|||||||
// the choose market overlay is no longer showing
|
// the choose market overlay is no longer showing
|
||||||
cy.contains('Select a market to get started').should('not.exist');
|
cy.contains('Select a market to get started').should('not.exist');
|
||||||
cy.contains('Loading...').should('not.exist');
|
cy.contains('Loading...').should('not.exist');
|
||||||
cy.url().should('eq', Cypress.config().baseUrl + '/#/markets/market-0');
|
cy.url().should('eq', Cypress.config().baseUrl + '/#/markets/market-1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -125,7 +123,7 @@ describe('home', { tags: '@regression' }, () => {
|
|||||||
aliasGQLQuery(req, 'MarketsData', data);
|
aliasGQLQuery(req, 'MarketsData', data);
|
||||||
});
|
});
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
cy.getByTestId(selectMarketOverlay)
|
cy.getByTestId(selectMarketOverlay)
|
||||||
.get('table')
|
.get('table')
|
||||||
.invoke('outerWidth')
|
.invoke('outerWidth')
|
||||||
@ -233,7 +231,7 @@ describe('home', { tags: '@regression' }, () => {
|
|||||||
cy.window().then((window) => {
|
cy.window().then((window) => {
|
||||||
window.localStorage.setItem('marketId', 'market-1');
|
window.localStorage.setItem('marketId', 'market-1');
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
cy.location('hash').should('equal', '#/markets/market-1');
|
cy.location('hash').should('equal', '#/markets/market-1');
|
||||||
cy.getByTestId('dialog-content').should('not.exist');
|
cy.getByTestId('dialog-content').should('not.exist');
|
||||||
});
|
});
|
||||||
@ -246,7 +244,7 @@ describe('home', { tags: '@regression' }, () => {
|
|||||||
aliasGQLQuery(req, 'Market', null);
|
aliasGQLQuery(req, 'Market', null);
|
||||||
});
|
});
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
cy.location('hash').should('equal', '#/markets/market-not-existing');
|
cy.location('hash').should('equal', '#/markets/market-not-existing');
|
||||||
cy.getByTestId('dialog-content').should('not.exist');
|
cy.getByTestId('dialog-content').should('not.exist');
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,7 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
|||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
cy.getByTestId(marketInfoBtn).click();
|
cy.getByTestId(marketInfoBtn).click();
|
||||||
cy.wait('@MarketInfo');
|
cy.wait('@MarketInfo');
|
||||||
});
|
});
|
||||||
|
@ -237,7 +237,6 @@ describe('market states not accepting orders', { tags: '@smoke' }, function () {
|
|||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.setVegaWallet();
|
cy.setVegaWallet();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
|
||||||
});
|
});
|
||||||
it('must display that market is not accepting orders', function () {
|
it('must display that market is not accepting orders', function () {
|
||||||
cy.getByTestId('place-order').click();
|
cy.getByTestId('place-order').click();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
import { aliasGQLQuery } from '@vegaprotocol/cypress';
|
||||||
import { marketQuery } from '@vegaprotocol/mock';
|
import { marketsQuery } from '@vegaprotocol/mock';
|
||||||
import { getDateTimeFormat } from '@vegaprotocol/react-helpers';
|
import { getDateTimeFormat } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
describe('markets table', { tags: '@smoke' }, () => {
|
describe('markets table', { tags: '@smoke' }, () => {
|
||||||
@ -13,7 +13,6 @@ describe('markets table', { tags: '@smoke' }, () => {
|
|||||||
);
|
);
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@Market');
|
|
||||||
cy.wait('@Markets');
|
cy.wait('@Markets');
|
||||||
cy.wait('@MarketsData');
|
cy.wait('@MarketsData');
|
||||||
cy.wait('@MarketsCandles');
|
cy.wait('@MarketsCandles');
|
||||||
@ -123,17 +122,24 @@ describe('markets table', { tags: '@smoke' }, () => {
|
|||||||
);
|
);
|
||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
const override = {
|
const override = {
|
||||||
market: {
|
marketsConnection: {
|
||||||
tradableInstrument: {
|
edges: [
|
||||||
instrument: {
|
{
|
||||||
name: `opening auction MARKET`,
|
node: {
|
||||||
|
tradableInstrument: {
|
||||||
|
instrument: {
|
||||||
|
name: `opening auction MARKET`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
state: Schema.MarketState.STATE_ACTIVE,
|
||||||
|
tradingMode:
|
||||||
|
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
state: Schema.MarketState.STATE_ACTIVE,
|
|
||||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const market = marketQuery(override);
|
const market = marketsQuery(override);
|
||||||
aliasGQLQuery(req, 'Market', market);
|
aliasGQLQuery(req, 'Market', market);
|
||||||
aliasGQLQuery(req, 'ProposalOfMarket', {
|
aliasGQLQuery(req, 'ProposalOfMarket', {
|
||||||
proposal: { terms: { enactmentDatetime: '2023-01-31 12:00:01' } },
|
proposal: { terms: { enactmentDatetime: '2023-01-31 12:00:01' } },
|
||||||
|
@ -4,14 +4,15 @@ before(() => {
|
|||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
|
cy.wait('@MarketsData');
|
||||||
cy.getByTestId('dialog-close').click();
|
cy.getByTestId('dialog-close').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Desktop view', { tags: '@smoke' }, () => {
|
describe('Desktop view', { tags: '@smoke' }, () => {
|
||||||
describe('Navbar', () => {
|
describe('Navbar', () => {
|
||||||
const links = ['Markets', 'Trading', 'Portfolio'];
|
const links = ['Markets', 'Trading', 'Portfolio'];
|
||||||
const hashes = ['#/markets/all', '#/markets/market-0', '#/portfolio'];
|
const hashes = ['#/markets/all', '#/markets/market-1', '#/portfolio'];
|
||||||
|
|
||||||
links.forEach((link, index) => {
|
links.forEach((link, index) => {
|
||||||
it(`${link} should be correctly rendered`, () => {
|
it(`${link} should be correctly rendered`, () => {
|
||||||
@ -67,7 +68,7 @@ describe('Mobile view', { tags: '@smoke' }, () => {
|
|||||||
cy.getByTestId('button-menu-drawer').click();
|
cy.getByTestId('button-menu-drawer').click();
|
||||||
cy.getByTestId('menu-drawer').within((el) => {
|
cy.getByTestId('menu-drawer').within((el) => {
|
||||||
cy.wrap(el).getByTestId('Trading').click();
|
cy.wrap(el).getByTestId('Trading').click();
|
||||||
cy.location('hash').should('equal', '#/markets/market-0');
|
cy.location('hash').should('equal', '#/markets/market-1');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('Portfolio should be correctly rendered', () => {
|
it('Portfolio should be correctly rendered', () => {
|
||||||
|
@ -35,7 +35,7 @@ describe('time in force default values', () => {
|
|||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('must have market order set up to IOC by default', function () {
|
it('must have market order set up to IOC by default', function () {
|
||||||
@ -64,7 +64,7 @@ describe('must submit order', { tags: '@smoke' }, () => {
|
|||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -162,7 +162,7 @@ describe(
|
|||||||
);
|
);
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -231,7 +231,7 @@ describe(
|
|||||||
);
|
);
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -300,7 +300,7 @@ describe(
|
|||||||
);
|
);
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -360,7 +360,7 @@ describe('deal ticket validation', { tags: '@smoke' }, () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('must not place an order if wallet is not connected', () => {
|
it('must not place an order if wallet is not connected', () => {
|
||||||
@ -405,7 +405,7 @@ describe('deal ticket size validation', { tags: '@smoke' }, function () {
|
|||||||
cy.setVegaWallet();
|
cy.setVegaWallet();
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('must warn if order size input has too many digits after the decimal place', function () {
|
it('must warn if order size input has too many digits after the decimal place', function () {
|
||||||
@ -440,7 +440,7 @@ describe('limit order validations', { tags: '@smoke' }, () => {
|
|||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
cy.getByTestId(toggleLimit).click();
|
cy.getByTestId(toggleLimit).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -452,7 +452,7 @@ describe('limit order validations', { tags: '@smoke' }, () => {
|
|||||||
//7002-SORD-018
|
//7002-SORD-018
|
||||||
cy.getByTestId(orderPriceField)
|
cy.getByTestId(orderPriceField)
|
||||||
.siblings('label')
|
.siblings('label')
|
||||||
.should('have.text', 'Price (BTC)');
|
.should('have.text', 'Price (DAI)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('must see warning when placing an order with expiry date in past', () => {
|
it('must see warning when placing an order with expiry date in past', () => {
|
||||||
@ -532,7 +532,7 @@ describe('market order validations', { tags: '@smoke' }, () => {
|
|||||||
cy.setVegaWallet();
|
cy.setVegaWallet();
|
||||||
cy.mockTradingPage();
|
cy.mockTradingPage();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
cy.getByTestId(toggleMarket).click();
|
cy.getByTestId(toggleMarket).click();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -586,7 +586,7 @@ describe('suspended market validation', { tags: '@regression' }, () => {
|
|||||||
);
|
);
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -648,7 +648,7 @@ describe('account validation', { tags: '@regression' }, () => {
|
|||||||
market: null,
|
market: null,
|
||||||
asset: {
|
asset: {
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
id: 'asset-0',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -660,7 +660,7 @@ describe('account validation', { tags: '@regression' }, () => {
|
|||||||
});
|
});
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show an error if your balance is zero', () => {
|
it('should show an error if your balance is zero', () => {
|
||||||
@ -670,7 +670,7 @@ describe('account validation', { tags: '@regression' }, () => {
|
|||||||
//7002-SORD-003
|
//7002-SORD-003
|
||||||
cy.getByTestId('dealticket-error-message-zero-balance').should(
|
cy.getByTestId('dealticket-error-message-zero-balance').should(
|
||||||
'have.text',
|
'have.text',
|
||||||
'Insufficient balance. Deposit ' + 'tBTC'
|
'Insufficient balance. Deposit ' + 'tDAI'
|
||||||
);
|
);
|
||||||
cy.getByTestId('deal-ticket-deposit-dialog-button').should('exist');
|
cy.getByTestId('deal-ticket-deposit-dialog-button').should('exist');
|
||||||
});
|
});
|
||||||
@ -696,7 +696,7 @@ describe('account validation', { tags: '@regression' }, () => {
|
|||||||
});
|
});
|
||||||
cy.mockSubscription();
|
cy.mockSubscription();
|
||||||
cy.visit('/#/markets/market-0');
|
cy.visit('/#/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Markets');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display info and button for deposit', () => {
|
it('should display info and button for deposit', () => {
|
||||||
@ -708,7 +708,7 @@ describe('account validation', { tags: '@regression' }, () => {
|
|||||||
);
|
);
|
||||||
cy.getByTestId('dealticket-warning-margin').should(
|
cy.getByTestId('dealticket-warning-margin').should(
|
||||||
'contain.text',
|
'contain.text',
|
||||||
'9,999.99 tBTC currently required, 1,000.00 tBTC available'
|
'9,999.99 tDAI currently required, 1,000.00 tDAI available'
|
||||||
);
|
);
|
||||||
cy.getByTestId('deal-ticket-deposit-dialog-button').click();
|
cy.getByTestId('deal-ticket-deposit-dialog-button').click();
|
||||||
cy.getByTestId('dialog-content')
|
cy.getByTestId('dialog-content')
|
||||||
|
@ -15,7 +15,6 @@ import {
|
|||||||
marketDataQuery,
|
marketDataQuery,
|
||||||
marketDepthQuery,
|
marketDepthQuery,
|
||||||
marketInfoQuery,
|
marketInfoQuery,
|
||||||
marketQuery,
|
|
||||||
marketsCandlesQuery,
|
marketsCandlesQuery,
|
||||||
marketsDataQuery,
|
marketsDataQuery,
|
||||||
marketsQuery,
|
marketsQuery,
|
||||||
@ -28,7 +27,7 @@ import {
|
|||||||
withdrawalsQuery,
|
withdrawalsQuery,
|
||||||
} from '@vegaprotocol/mock';
|
} from '@vegaprotocol/mock';
|
||||||
import type { PartialDeep } from 'type-fest';
|
import type { PartialDeep } from 'type-fest';
|
||||||
import type { MarketDataQuery, MarketQuery } from '@vegaprotocol/market-list';
|
import type { MarketDataQuery, MarketsQuery } from '@vegaprotocol/market-list';
|
||||||
import type { MarketInfoQuery } from '@vegaprotocol/market-info';
|
import type { MarketInfoQuery } from '@vegaprotocol/market-info';
|
||||||
|
|
||||||
type MarketPageMockData = {
|
type MarketPageMockData = {
|
||||||
@ -55,17 +54,18 @@ const marketDataOverride = (
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const marketQueryOverride = (
|
const marketsDataOverride = (
|
||||||
data: MarketPageMockData
|
data: MarketPageMockData
|
||||||
): PartialDeep<MarketQuery> => ({
|
): PartialDeep<MarketsQuery> => ({
|
||||||
market: {
|
marketsConnection: {
|
||||||
tradableInstrument: {
|
edges: [
|
||||||
instrument: {
|
{
|
||||||
name: `${data.state?.toUpperCase()} MARKET`,
|
node: {
|
||||||
|
tradingMode: data.tradingMode,
|
||||||
|
state: data.state,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
state: data.state,
|
|
||||||
tradingMode: data.tradingMode,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -91,10 +91,9 @@ const mockTradingPage = (
|
|||||||
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
aliasGQLQuery(req, 'Statistics', statisticsQuery());
|
||||||
aliasGQLQuery(
|
aliasGQLQuery(
|
||||||
req,
|
req,
|
||||||
'Market',
|
'Markets',
|
||||||
marketQuery(marketQueryOverride({ state, tradingMode, trigger }))
|
marketsQuery(marketsDataOverride({ state, tradingMode, trigger }))
|
||||||
);
|
);
|
||||||
aliasGQLQuery(req, 'Markets', marketsQuery());
|
|
||||||
aliasGQLQuery(
|
aliasGQLQuery(
|
||||||
req,
|
req,
|
||||||
'MarketData',
|
'MarketData',
|
||||||
|
@ -59,7 +59,7 @@ export const LiquidityContainer = ({
|
|||||||
marketId: string | undefined;
|
marketId: string | undefined;
|
||||||
}) => {
|
}) => {
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const gridRef = useRef<AgGridReact | null>(null);
|
||||||
const market = useMarket(marketId);
|
const { data: market } = useMarket(marketId);
|
||||||
const dataRef = useRef<LiquidityProvisionData[] | null>(null);
|
const dataRef = useRef<LiquidityProvisionData[] | null>(null);
|
||||||
|
|
||||||
// To be removed when liquidityProvision subscriptions are working
|
// To be removed when liquidityProvision subscriptions are working
|
||||||
@ -129,8 +129,8 @@ export const LiquidityViewContainer = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey } = useVegaWallet();
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const gridRef = useRef<AgGridReact | null>(null);
|
||||||
const market = useMarket(marketId);
|
const { data: market } = useMarket(marketId);
|
||||||
const marketData = useStaticMarketData(marketId);
|
const { data: marketData } = useStaticMarketData(marketId);
|
||||||
|
|
||||||
const dataRef = useRef<LiquidityProvisionData[] | null>(null);
|
const dataRef = useRef<LiquidityProvisionData[] | null>(null);
|
||||||
|
|
||||||
|
@ -9,9 +9,7 @@ import {
|
|||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import { AsyncRenderer, ExternalLink, Splash } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer, ExternalLink, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import type {
|
import type {
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
MarketData,
|
MarketData,
|
||||||
Candle,
|
|
||||||
MarketDataUpdateFieldsFragment,
|
MarketDataUpdateFieldsFragment,
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
|
|
||||||
@ -27,11 +25,6 @@ const calculatePrice = (markPrice?: string, decimalPlaces?: number) => {
|
|||||||
: '-';
|
: '-';
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface SingleMarketData extends SingleMarketFieldsFragment {
|
|
||||||
candles: Candle[];
|
|
||||||
data: MarketData;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TitleUpdater = ({
|
const TitleUpdater = ({
|
||||||
marketId,
|
marketId,
|
||||||
marketName,
|
marketName,
|
||||||
@ -89,12 +82,9 @@ export const MarketPage = () => {
|
|||||||
[marketId, navigate]
|
[marketId, navigate]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data, error, loading } = useDataProvider<
|
const { data, error, loading } = useDataProvider({
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
never
|
|
||||||
>({
|
|
||||||
dataProvider: marketProvider,
|
dataProvider: marketProvider,
|
||||||
variables: useMemo(() => ({ marketId: marketId || '' }), [marketId]),
|
variables: { marketId: marketId || '' },
|
||||||
skip: !marketId,
|
skip: !marketId,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -115,7 +105,7 @@ export const MarketPage = () => {
|
|||||||
<Splash>
|
<Splash>
|
||||||
<span className="flex flex-col items-center gap-2">
|
<span className="flex flex-col items-center gap-2">
|
||||||
<p className="text-sm justify-center">
|
<p className="text-sm justify-center">
|
||||||
{t('This market URL is not available anymore.')}
|
{t('This market URL is not available any more.')}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm justify-center">
|
<p className="text-sm justify-center">
|
||||||
{t(`Please choose another market from the`)}{' '}
|
{t(`Please choose another market from the`)}{' '}
|
||||||
@ -129,7 +119,7 @@ export const MarketPage = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer<SingleMarketFieldsFragment>
|
<AsyncRenderer
|
||||||
loading={loading}
|
loading={loading}
|
||||||
error={error}
|
error={error}
|
||||||
data={data || undefined}
|
data={data || undefined}
|
||||||
|
@ -21,7 +21,7 @@ import {
|
|||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { AccountsContainer } from '../../components/accounts-container';
|
import { AccountsContainer } from '../../components/accounts-container';
|
||||||
import type { SingleMarketFieldsFragment } from '@vegaprotocol/market-list';
|
import type { Market } from '@vegaprotocol/market-list';
|
||||||
import { VegaWalletContainer } from '../../components/vega-wallet-container';
|
import { VegaWalletContainer } from '../../components/vega-wallet-container';
|
||||||
import { TradeMarketHeader } from './trade-market-header';
|
import { TradeMarketHeader } from './trade-market-header';
|
||||||
import { NO_MARKET } from './constants';
|
import { NO_MARKET } from './constants';
|
||||||
@ -63,7 +63,7 @@ const TradingViews = {
|
|||||||
type TradingView = keyof typeof TradingViews;
|
type TradingView = keyof typeof TradingViews;
|
||||||
|
|
||||||
interface TradeGridProps {
|
interface TradeGridProps {
|
||||||
market: SingleMarketFieldsFragment | null;
|
market: Market | null;
|
||||||
onSelect: (marketId: string) => void;
|
onSelect: (marketId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ const TradeGridChild = ({ children }: TradeGridChildProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface TradePanelsProps {
|
interface TradePanelsProps {
|
||||||
market: SingleMarketFieldsFragment | null;
|
market: Market | null;
|
||||||
onSelect: (marketId: string) => void;
|
onSelect: (marketId: string) => void;
|
||||||
onMarketClick?: (marketId: string) => void;
|
onMarketClick?: (marketId: string) => void;
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@ import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
|||||||
import { useEnvironment } from '@vegaprotocol/environment';
|
import { useEnvironment } from '@vegaprotocol/environment';
|
||||||
import { ButtonLink, Link } from '@vegaprotocol/ui-toolkit';
|
import { ButtonLink, Link } from '@vegaprotocol/ui-toolkit';
|
||||||
import { MarketProposalNotification } from '@vegaprotocol/governance';
|
import { MarketProposalNotification } from '@vegaprotocol/governance';
|
||||||
|
import type { Market } from '@vegaprotocol/market-list';
|
||||||
import {
|
import {
|
||||||
getExpiryDate,
|
getExpiryDate,
|
||||||
getMarketExpiryDate,
|
getMarketExpiryDate,
|
||||||
t,
|
t,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import type { SingleMarketFieldsFragment } from '@vegaprotocol/market-list';
|
|
||||||
import {
|
import {
|
||||||
ColumnKind,
|
ColumnKind,
|
||||||
SelectMarketPopover,
|
SelectMarketPopover,
|
||||||
@ -24,7 +24,7 @@ import { MarketLiquiditySupplied } from '../../components/liquidity-supplied';
|
|||||||
import { MarketState as State } from '@vegaprotocol/types';
|
import { MarketState as State } from '@vegaprotocol/types';
|
||||||
|
|
||||||
interface TradeMarketHeaderProps {
|
interface TradeMarketHeaderProps {
|
||||||
market: SingleMarketFieldsFragment | null;
|
market: Market | null;
|
||||||
onSelect: (marketId: string) => void;
|
onSelect: (marketId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ export const TradeMarketHeader = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
type ExpiryLabelProps = {
|
type ExpiryLabelProps = {
|
||||||
market: SingleMarketFieldsFragment | null;
|
market: Market | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ExpiryLabel = ({ market }: ExpiryLabelProps) => {
|
const ExpiryLabel = ({ market }: ExpiryLabelProps) => {
|
||||||
@ -140,7 +140,7 @@ const ExpiryLabel = ({ market }: ExpiryLabelProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type ExpiryTooltipContentProps = {
|
type ExpiryTooltipContentProps = {
|
||||||
market: SingleMarketFieldsFragment;
|
market: Market;
|
||||||
explorerUrl?: string;
|
explorerUrl?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ import {
|
|||||||
import type {
|
import type {
|
||||||
MarketData,
|
MarketData,
|
||||||
MarketDataUpdateFieldsFragment,
|
MarketDataUpdateFieldsFragment,
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||||
import { HeaderStat } from '../header';
|
import { HeaderStat } from '../header';
|
||||||
@ -44,12 +43,12 @@ export const MarketLiquiditySupplied = ({
|
|||||||
|
|
||||||
const variables = useMemo(
|
const variables = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
marketId: marketId,
|
marketId: marketId || '',
|
||||||
}),
|
}),
|
||||||
[marketId]
|
[marketId]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data } = useDataProvider<SingleMarketFieldsFragment, never>({
|
const { data } = useDataProvider({
|
||||||
dataProvider: marketProvider,
|
dataProvider: marketProvider,
|
||||||
variables,
|
variables,
|
||||||
skip: !marketId,
|
skip: !marketId,
|
||||||
|
@ -2,7 +2,7 @@ import throttle from 'lodash/throttle';
|
|||||||
import type {
|
import type {
|
||||||
MarketData,
|
MarketData,
|
||||||
MarketDataUpdateFieldsFragment,
|
MarketDataUpdateFieldsFragment,
|
||||||
SingleMarketFieldsFragment,
|
Market,
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
import { marketDataProvider } from '@vegaprotocol/market-list';
|
import { marketDataProvider } from '@vegaprotocol/market-list';
|
||||||
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
@ -11,11 +11,7 @@ import { HeaderStat } from '../header';
|
|||||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||||
import * as constants from '../constants';
|
import * as constants from '../constants';
|
||||||
|
|
||||||
export const MarketState = ({
|
export const MarketState = ({ market }: { market: Market | null }) => {
|
||||||
market,
|
|
||||||
}: {
|
|
||||||
market: SingleMarketFieldsFragment | null;
|
|
||||||
}) => {
|
|
||||||
const [marketState, setMarketState] = useState<Schema.MarketState | null>(
|
const [marketState, setMarketState] = useState<Schema.MarketState | null>(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
@ -1,37 +1,24 @@
|
|||||||
import type { RefObject } from 'react';
|
import type { RefObject } from 'react';
|
||||||
import { useMemo } from 'react';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
|
||||||
import { TradingModeTooltip } from '@vegaprotocol/deal-ticket';
|
import { TradingModeTooltip } from '@vegaprotocol/deal-ticket';
|
||||||
import { useInView } from 'react-intersection-observer';
|
import { useInView } from 'react-intersection-observer';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { HeaderStat } from '../header';
|
import { HeaderStat } from '../header';
|
||||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||||
import { marketDataProvider } from '@vegaprotocol/market-list';
|
import { useStaticMarketData } from '@vegaprotocol/market-list';
|
||||||
|
|
||||||
// This will cause often re-rendering
|
|
||||||
// Here it may not be a problem because the component is not very complex
|
|
||||||
// In general, we should avoid using this marketData hook without any throttling
|
|
||||||
const useMarketData = (marketId?: string, skip?: boolean) => {
|
|
||||||
const variables = useMemo(() => ({ marketId }), [marketId]);
|
|
||||||
const { data } = useDataProvider({
|
|
||||||
dataProvider: marketDataProvider,
|
|
||||||
variables,
|
|
||||||
skip: skip || !marketId,
|
|
||||||
});
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getTradingModeLabel = (
|
const getTradingModeLabel = (
|
||||||
tradingMode?: Schema.MarketTradingMode,
|
marketTradingMode?: Schema.MarketTradingMode,
|
||||||
trigger?: Schema.AuctionTrigger
|
trigger?: Schema.AuctionTrigger
|
||||||
) => {
|
) => {
|
||||||
return (
|
return (
|
||||||
(tradingMode === Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
(marketTradingMode ===
|
||||||
|
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
||||||
trigger &&
|
trigger &&
|
||||||
trigger !== Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
trigger !== Schema.AuctionTrigger.AUCTION_TRIGGER_UNSPECIFIED
|
||||||
? `${Schema.MarketTradingModeMapping[tradingMode]} - ${Schema.AuctionTriggerMapping[trigger]}`
|
? `${Schema.MarketTradingModeMapping[marketTradingMode]} - ${Schema.AuctionTriggerMapping[trigger]}`
|
||||||
: Schema.MarketTradingModeMapping[
|
: Schema.MarketTradingModeMapping[
|
||||||
tradingMode as Schema.MarketTradingMode
|
marketTradingMode as Schema.MarketTradingMode
|
||||||
]) || '-'
|
]) || '-'
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -49,8 +36,8 @@ export const HeaderStatMarketTradingMode = ({
|
|||||||
initialTradingMode,
|
initialTradingMode,
|
||||||
initialTrigger,
|
initialTrigger,
|
||||||
}: HeaderStatMarketTradingModeProps) => {
|
}: HeaderStatMarketTradingModeProps) => {
|
||||||
const data = useMarketData(marketId);
|
const { data } = useStaticMarketData(marketId);
|
||||||
const tradingMode = data?.marketTradingMode ?? initialTradingMode;
|
const marketTradingMode = data?.marketTradingMode ?? initialTradingMode;
|
||||||
const trigger = data?.trigger ?? initialTrigger;
|
const trigger = data?.trigger ?? initialTrigger;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -61,7 +48,7 @@ export const HeaderStatMarketTradingMode = ({
|
|||||||
}
|
}
|
||||||
testId="market-trading-mode"
|
testId="market-trading-mode"
|
||||||
>
|
>
|
||||||
<div>{getTradingModeLabel(tradingMode, trigger)}</div>
|
<div>{getTradingModeLabel(marketTradingMode, trigger)}</div>
|
||||||
</HeaderStat>
|
</HeaderStat>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -75,7 +62,7 @@ export const MarketTradingMode = ({
|
|||||||
inViewRoot?: RefObject<Element>;
|
inViewRoot?: RefObject<Element>;
|
||||||
}) => {
|
}) => {
|
||||||
const [ref, inView] = useInView({ root: inViewRoot?.current });
|
const [ref, inView] = useInView({ root: inViewRoot?.current });
|
||||||
const data = useMarketData(marketId, !inView);
|
const { data } = useStaticMarketData(marketId, !inView);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
|
@ -8,7 +8,6 @@ import {
|
|||||||
import type {
|
import type {
|
||||||
MarketData,
|
MarketData,
|
||||||
MarketDataUpdateFieldsFragment,
|
MarketDataUpdateFieldsFragment,
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||||
import { HeaderStat } from '../header';
|
import { HeaderStat } from '../header';
|
||||||
@ -22,7 +21,7 @@ export const MarketVolume = ({ marketId }: { marketId: string }) => {
|
|||||||
}),
|
}),
|
||||||
[marketId]
|
[marketId]
|
||||||
);
|
);
|
||||||
const { data } = useDataProvider<SingleMarketFieldsFragment, never>({
|
const { data } = useDataProvider({
|
||||||
dataProvider: marketProvider,
|
dataProvider: marketProvider,
|
||||||
variables,
|
variables,
|
||||||
skip: !marketId,
|
skip: !marketId,
|
||||||
|
@ -14,10 +14,7 @@ import {
|
|||||||
import { Link as UILink, Sparkline, Tooltip } from '@vegaprotocol/ui-toolkit';
|
import { Link as UILink, Sparkline, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||||
import isNil from 'lodash/isNil';
|
import isNil from 'lodash/isNil';
|
||||||
import type { CandleClose } from '@vegaprotocol/types';
|
import type { CandleClose } from '@vegaprotocol/types';
|
||||||
import type {
|
import type { MarketMaybeWithDataAndCandles } from '@vegaprotocol/market-list';
|
||||||
MarketWithData,
|
|
||||||
MarketWithCandles,
|
|
||||||
} from '@vegaprotocol/market-list';
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { MarketMarkPrice } from '../market-mark-price';
|
import { MarketMarkPrice } from '../market-mark-price';
|
||||||
import { Last24hPriceChange } from '../last-24h-price-change';
|
import { Last24hPriceChange } from '../last-24h-price-change';
|
||||||
@ -25,8 +22,6 @@ import { MarketTradingMode } from '../market-trading-mode';
|
|||||||
import { Last24hVolume } from '../last-24h-volume';
|
import { Last24hVolume } from '../last-24h-volume';
|
||||||
import { Links, Routes } from '../../pages/client-router';
|
import { Links, Routes } from '../../pages/client-router';
|
||||||
|
|
||||||
type Market = MarketWithData & MarketWithCandles;
|
|
||||||
|
|
||||||
const ellipsisClasses = 'whitespace-nowrap overflow-hidden text-ellipsis';
|
const ellipsisClasses = 'whitespace-nowrap overflow-hidden text-ellipsis';
|
||||||
export const cellClassNames = `py-1 first:text-left text-right ${ellipsisClasses}`;
|
export const cellClassNames = `py-1 first:text-left text-right ${ellipsisClasses}`;
|
||||||
|
|
||||||
@ -171,7 +166,7 @@ export type OnCellClickHandler = (
|
|||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
export const columns = (
|
export const columns = (
|
||||||
market: Market,
|
market: MarketMaybeWithDataAndCandles,
|
||||||
onSelect: (id: string) => void,
|
onSelect: (id: string) => void,
|
||||||
onCellClick: OnCellClickHandler,
|
onCellClick: OnCellClickHandler,
|
||||||
inViewRoot?: RefObject<HTMLElement>
|
inViewRoot?: RefObject<HTMLElement>
|
||||||
@ -359,7 +354,7 @@ export const columns = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const columnsPositionMarkets = (
|
export const columnsPositionMarkets = (
|
||||||
market: Market,
|
market: MarketMaybeWithDataAndCandles,
|
||||||
onSelect: (id: string) => void,
|
onSelect: (id: string) => void,
|
||||||
inViewRoot?: RefObject<HTMLElement>,
|
inViewRoot?: RefObject<HTMLElement>,
|
||||||
openVolume?: string,
|
openVolume?: string,
|
||||||
|
@ -4,13 +4,13 @@ import * as Schema from '@vegaprotocol/types';
|
|||||||
import { SelectAllMarketsTableBody } from './select-market';
|
import { SelectAllMarketsTableBody } from './select-market';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
MarketWithCandles,
|
MarketMaybeWithCandles,
|
||||||
MarketWithData,
|
MarketMaybeWithData,
|
||||||
MarketData,
|
MarketData,
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
import { MockedProvider } from '@apollo/client/testing';
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
type Market = MarketWithCandles & MarketWithData;
|
type Market = MarketMaybeWithCandles & MarketMaybeWithData;
|
||||||
|
|
||||||
type PartialMarket = Partial<
|
type PartialMarket = Partial<
|
||||||
Omit<Market, 'data'> & { data: Partial<MarketData> }
|
Omit<Market, 'data'> & { data: Partial<MarketData> }
|
||||||
@ -34,9 +34,13 @@ const MARKET_A: PartialMarket = {
|
|||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
id: 'asset-ABC',
|
id: 'asset-ABC',
|
||||||
|
name: '',
|
||||||
decimals: 2,
|
decimals: 2,
|
||||||
symbol: 'ABC',
|
symbol: 'ABC',
|
||||||
},
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
metadata: {
|
metadata: {
|
||||||
__typename: 'InstrumentMetadata',
|
__typename: 'InstrumentMetadata',
|
||||||
@ -106,9 +110,13 @@ const MARKET_B: PartialMarket = {
|
|||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
id: 'asset-XYZ',
|
id: 'asset-XYZ',
|
||||||
|
name: 'asset-XYZ',
|
||||||
decimals: 2,
|
decimals: 2,
|
||||||
symbol: 'XYZ',
|
symbol: 'XYZ',
|
||||||
},
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
metadata: {
|
metadata: {
|
||||||
__typename: 'InstrumentMetadata',
|
__typename: 'InstrumentMetadata',
|
||||||
|
@ -17,10 +17,7 @@ import {
|
|||||||
SelectMarketTableRowSplash,
|
SelectMarketTableRowSplash,
|
||||||
} from './select-market-table';
|
} from './select-market-table';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import type {
|
import type { MarketMaybeWithDataAndCandles } from '@vegaprotocol/market-list';
|
||||||
MarketWithCandles,
|
|
||||||
MarketWithData,
|
|
||||||
} from '@vegaprotocol/market-list';
|
|
||||||
import type { PositionFieldsFragment } from '@vegaprotocol/positions';
|
import type { PositionFieldsFragment } from '@vegaprotocol/positions';
|
||||||
import type { Column, OnCellClickHandler } from './select-market-columns';
|
import type { Column, OnCellClickHandler } from './select-market-columns';
|
||||||
import {
|
import {
|
||||||
@ -30,8 +27,6 @@ import {
|
|||||||
} from '@vegaprotocol/environment';
|
} from '@vegaprotocol/environment';
|
||||||
import { HeaderTitle } from '../header';
|
import { HeaderTitle } from '../header';
|
||||||
|
|
||||||
export type Market = MarketWithCandles & MarketWithData;
|
|
||||||
|
|
||||||
export const SelectAllMarketsTableBody = ({
|
export const SelectAllMarketsTableBody = ({
|
||||||
markets,
|
markets,
|
||||||
positions,
|
positions,
|
||||||
@ -41,14 +36,14 @@ export const SelectAllMarketsTableBody = ({
|
|||||||
headers = columnHeaders,
|
headers = columnHeaders,
|
||||||
tableColumns = (market) => columns(market, onSelect, onCellClick, inViewRoot),
|
tableColumns = (market) => columns(market, onSelect, onCellClick, inViewRoot),
|
||||||
}: {
|
}: {
|
||||||
markets?: Market[] | null;
|
markets?: MarketMaybeWithDataAndCandles[] | null;
|
||||||
positions?: PositionFieldsFragment[];
|
positions?: PositionFieldsFragment[];
|
||||||
title?: string;
|
title?: string;
|
||||||
onSelect: (id: string) => void;
|
onSelect: (id: string) => void;
|
||||||
onCellClick: OnCellClickHandler;
|
onCellClick: OnCellClickHandler;
|
||||||
headers?: Column[];
|
headers?: Column[];
|
||||||
tableColumns?: (
|
tableColumns?: (
|
||||||
market: Market,
|
market: MarketMaybeWithDataAndCandles,
|
||||||
inViewRoot?: RefObject<HTMLDivElement>,
|
inViewRoot?: RefObject<HTMLDivElement>,
|
||||||
openVolume?: string
|
openVolume?: string
|
||||||
) => Column[];
|
) => Column[];
|
||||||
|
@ -3,13 +3,13 @@ import { MemoryRouter } from 'react-router-dom';
|
|||||||
import { MockedProvider } from '@apollo/client/testing';
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import type {
|
import type {
|
||||||
MarketWithCandles,
|
MarketMaybeWithCandles,
|
||||||
MarketWithData,
|
MarketMaybeWithData,
|
||||||
MarketData,
|
MarketData,
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
import { SelectMarketLandingTable } from './welcome-landing-dialog';
|
import { SelectMarketLandingTable } from './welcome-landing-dialog';
|
||||||
|
|
||||||
type Market = MarketWithCandles & MarketWithData;
|
type Market = MarketMaybeWithCandles & MarketMaybeWithData;
|
||||||
type PartialMarket = Partial<
|
type PartialMarket = Partial<
|
||||||
Omit<Market, 'data'> & { data: Partial<MarketData> }
|
Omit<Market, 'data'> & { data: Partial<MarketData> }
|
||||||
>;
|
>;
|
||||||
@ -32,9 +32,13 @@ const MARKET_A: PartialMarket = {
|
|||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
id: 'asset-ABC',
|
id: 'asset-ABC',
|
||||||
|
name: 'asset-ABC',
|
||||||
decimals: 2,
|
decimals: 2,
|
||||||
symbol: 'ABC',
|
symbol: 'ABC',
|
||||||
},
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
metadata: {
|
metadata: {
|
||||||
__typename: 'InstrumentMetadata',
|
__typename: 'InstrumentMetadata',
|
||||||
@ -104,9 +108,13 @@ const MARKET_B: PartialMarket = {
|
|||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
id: 'asset-XYZ',
|
id: 'asset-XYZ',
|
||||||
|
name: 'asset-XYZ',
|
||||||
decimals: 2,
|
decimals: 2,
|
||||||
symbol: 'XYZ',
|
symbol: 'XYZ',
|
||||||
},
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
metadata: {
|
metadata: {
|
||||||
__typename: 'InstrumentMetadata',
|
__typename: 'InstrumentMetadata',
|
||||||
|
@ -3,7 +3,8 @@ import { useMarketList } from '@vegaprotocol/market-list';
|
|||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||||
import { Link as UILink } from '@vegaprotocol/ui-toolkit';
|
import { Link as UILink } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { Market, OnCellClickHandler } from '../select-market';
|
import type { OnCellClickHandler } from '../select-market';
|
||||||
|
import type { MarketMaybeWithDataAndCandles } from '@vegaprotocol/market-list';
|
||||||
import {
|
import {
|
||||||
ColumnKind,
|
ColumnKind,
|
||||||
columns,
|
columns,
|
||||||
@ -19,7 +20,7 @@ export const SelectMarketLandingTable = ({
|
|||||||
markets,
|
markets,
|
||||||
onClose,
|
onClose,
|
||||||
}: {
|
}: {
|
||||||
markets: Market[] | null;
|
markets: MarketMaybeWithDataAndCandles[] | null;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
|
@ -14,7 +14,6 @@ export * from '../market-depth/src/lib/market-depth.mock';
|
|||||||
export * from '../market-info/src/components/market-info/market-info.mock';
|
export * from '../market-info/src/components/market-info/market-info.mock';
|
||||||
export * from '../market-list/src/lib/market-candles.mock';
|
export * from '../market-list/src/lib/market-candles.mock';
|
||||||
export * from '../market-list/src/lib/market-data.mock';
|
export * from '../market-list/src/lib/market-data.mock';
|
||||||
export * from '../market-list/src/lib/market.mock';
|
|
||||||
export * from '../market-list/src/lib/markets-candles.mock';
|
export * from '../market-list/src/lib/markets-candles.mock';
|
||||||
export * from '../market-list/src/lib/markets-data.mock';
|
export * from '../market-list/src/lib/markets-data.mock';
|
||||||
export * from '../market-list/src/lib/markets.mock';
|
export * from '../market-list/src/lib/markets.mock';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { UseFormRegister } from 'react-hook-form';
|
import type { UseFormRegister } from 'react-hook-form';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
import { DealTicketMarketAmount } from './deal-ticket-market-amount';
|
import { DealTicketMarketAmount } from './deal-ticket-market-amount';
|
||||||
import { DealTicketLimitAmount } from './deal-ticket-limit-amount';
|
import { DealTicketLimitAmount } from './deal-ticket-limit-amount';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
@ -7,7 +7,8 @@ import type { DealTicketFormFields } from './deal-ticket';
|
|||||||
|
|
||||||
export interface DealTicketAmountProps {
|
export interface DealTicketAmountProps {
|
||||||
orderType: Schema.OrderType;
|
orderType: Schema.OrderType;
|
||||||
market: MarketDealTicket;
|
marketData: MarketData;
|
||||||
|
market: Market;
|
||||||
register: UseFormRegister<DealTicketFormFields>;
|
register: UseFormRegister<DealTicketFormFields>;
|
||||||
sizeError?: string;
|
sizeError?: string;
|
||||||
priceError?: string;
|
priceError?: string;
|
||||||
@ -15,11 +16,12 @@ export interface DealTicketAmountProps {
|
|||||||
|
|
||||||
export const DealTicketAmount = ({
|
export const DealTicketAmount = ({
|
||||||
orderType,
|
orderType,
|
||||||
|
marketData,
|
||||||
...props
|
...props
|
||||||
}: DealTicketAmountProps) => {
|
}: DealTicketAmountProps) => {
|
||||||
switch (orderType) {
|
switch (orderType) {
|
||||||
case Schema.OrderType.TYPE_MARKET:
|
case Schema.OrderType.TYPE_MARKET:
|
||||||
return <DealTicketMarketAmount {...props} />;
|
return <DealTicketMarketAmount {...props} marketData={marketData} />;
|
||||||
case Schema.OrderType.TYPE_LIMIT:
|
case Schema.OrderType.TYPE_LIMIT:
|
||||||
return <DealTicketLimitAmount {...props} />;
|
return <DealTicketLimitAmount {...props} />;
|
||||||
default: {
|
default: {
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||||
import { t, useDataProvider } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import type {
|
import { useThrottledDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
MarketDataUpdateFieldsFragment,
|
|
||||||
MarketDealTicket,
|
|
||||||
} from '@vegaprotocol/market-list';
|
|
||||||
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
|
import { useVegaTransactionStore } from '@vegaprotocol/wallet';
|
||||||
import { marketDealTicketProvider } from '@vegaprotocol/market-list';
|
import { useMarket, marketDataProvider } from '@vegaprotocol/market-list';
|
||||||
import { DealTicket } from './deal-ticket';
|
import { DealTicket } from './deal-ticket';
|
||||||
|
|
||||||
export interface DealTicketContainerProps {
|
export interface DealTicketContainerProps {
|
||||||
@ -14,31 +11,35 @@ export interface DealTicketContainerProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const DealTicketContainer = ({ marketId }: DealTicketContainerProps) => {
|
export const DealTicketContainer = ({ marketId }: DealTicketContainerProps) => {
|
||||||
const variables = useMemo(
|
const {
|
||||||
() => ({
|
data: market,
|
||||||
marketId: marketId || '',
|
error: marketError,
|
||||||
}),
|
loading: marketLoading,
|
||||||
[marketId]
|
} = useMarket(marketId);
|
||||||
|
|
||||||
|
const {
|
||||||
|
data: marketData,
|
||||||
|
error: marketDataError,
|
||||||
|
loading: marketDataLoading,
|
||||||
|
} = useThrottledDataProvider(
|
||||||
|
{
|
||||||
|
dataProvider: marketDataProvider,
|
||||||
|
variables: useMemo(() => ({ marketId }), [marketId]),
|
||||||
|
},
|
||||||
|
1000
|
||||||
);
|
);
|
||||||
const { data, error, loading } = useDataProvider<
|
|
||||||
MarketDealTicket,
|
|
||||||
MarketDataUpdateFieldsFragment
|
|
||||||
>({
|
|
||||||
dataProvider: marketDealTicketProvider,
|
|
||||||
variables,
|
|
||||||
skip: !marketId,
|
|
||||||
});
|
|
||||||
const create = useVegaTransactionStore((state) => state.create);
|
const create = useVegaTransactionStore((state) => state.create);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer<MarketDealTicket>
|
<AsyncRenderer
|
||||||
data={data || undefined}
|
data={market && marketData}
|
||||||
loading={loading}
|
loading={marketLoading || marketDataLoading}
|
||||||
error={error}
|
error={marketError || marketDataError}
|
||||||
>
|
>
|
||||||
{data ? (
|
{market && marketData ? (
|
||||||
<DealTicket
|
<DealTicket
|
||||||
market={data}
|
market={market}
|
||||||
|
marketData={marketData}
|
||||||
submit={(orderSubmission) => create({ orderSubmission })}
|
submit={(orderSubmission) => create({ orderSubmission })}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
import {
|
import {
|
||||||
getFeeDetailsValues,
|
getFeeDetailsValues,
|
||||||
useFeeDealTicketDetails,
|
useFeeDealTicketDetails,
|
||||||
@ -9,7 +9,8 @@ import {
|
|||||||
|
|
||||||
interface DealTicketFeeDetailsProps {
|
interface DealTicketFeeDetailsProps {
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
order: OrderSubmissionBody['orderSubmission'];
|
||||||
market: MarketDealTicket;
|
market: Market;
|
||||||
|
marketData: MarketData;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DealTicketFeeDetails {
|
export interface DealTicketFeeDetails {
|
||||||
@ -22,8 +23,9 @@ export interface DealTicketFeeDetails {
|
|||||||
export const DealTicketFeeDetails = ({
|
export const DealTicketFeeDetails = ({
|
||||||
order,
|
order,
|
||||||
market,
|
market,
|
||||||
|
marketData,
|
||||||
}: DealTicketFeeDetailsProps) => {
|
}: DealTicketFeeDetailsProps) => {
|
||||||
const feeDetails = useFeeDealTicketDetails(order, market);
|
const feeDetails = useFeeDealTicketDetails(order, market, marketData);
|
||||||
const details = getFeeDetailsValues(feeDetails);
|
const details = getFeeDetailsValues(feeDetails);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -3,7 +3,7 @@ import { t, toDecimal, validateAmount } from '@vegaprotocol/react-helpers';
|
|||||||
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
||||||
|
|
||||||
export type DealTicketLimitAmountProps = Omit<
|
export type DealTicketLimitAmountProps = Omit<
|
||||||
DealTicketAmountProps,
|
Omit<DealTicketAmountProps, 'marketData'>,
|
||||||
'orderType'
|
'orderType'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
@ -17,11 +17,12 @@ export type DealTicketMarketAmountProps = Omit<
|
|||||||
export const DealTicketMarketAmount = ({
|
export const DealTicketMarketAmount = ({
|
||||||
register,
|
register,
|
||||||
market,
|
market,
|
||||||
|
marketData,
|
||||||
sizeError,
|
sizeError,
|
||||||
}: DealTicketMarketAmountProps) => {
|
}: DealTicketMarketAmountProps) => {
|
||||||
const quoteName = market.tradableInstrument.instrument.product.quoteName;
|
const quoteName = market.tradableInstrument.instrument.product.quoteName;
|
||||||
const sizeStep = toDecimal(market?.positionDecimalPlaces);
|
const sizeStep = toDecimal(market?.positionDecimalPlaces);
|
||||||
const price = getMarketPrice(market);
|
const price = getMarketPrice(marketData);
|
||||||
|
|
||||||
const priceFormatted = price
|
const priceFormatted = price
|
||||||
? addDecimalsFormatNumber(price, market.decimalPlaces)
|
? addDecimalsFormatNumber(price, market.decimalPlaces)
|
||||||
@ -33,7 +34,7 @@ export const DealTicketMarketAmount = ({
|
|||||||
<div className="flex-1 text-sm">Size</div>
|
<div className="flex-1 text-sm">Size</div>
|
||||||
<div />
|
<div />
|
||||||
<div className="flex-2 text-sm text-right">
|
<div className="flex-2 text-sm text-right">
|
||||||
{isMarketInAuction(market) && (
|
{isMarketInAuction(marketData.marketTradingMode) && (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
description={t(
|
description={t(
|
||||||
'This market is in auction. The uncrossing price is an indication of what the price is expected to be when the auction ends.'
|
'This market is in auction. The uncrossing price is an indication of what the price is expected to be when the auction ends.'
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
act,
|
act,
|
||||||
waitFor,
|
waitFor,
|
||||||
} from '@testing-library/react';
|
} from '@testing-library/react';
|
||||||
import { generateMarket } from '../../test-helpers';
|
import { generateMarket, generateMarketData } from '../../test-helpers';
|
||||||
import { DealTicket } from './deal-ticket';
|
import { DealTicket } from './deal-ticket';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
@ -25,6 +25,7 @@ jest.mock('../../hooks/use-has-no-balance', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const market = generateMarket();
|
const market = generateMarket();
|
||||||
|
const marketData = generateMarketData();
|
||||||
const submit = jest.fn();
|
const submit = jest.fn();
|
||||||
|
|
||||||
const mockChainId = 'chain-id';
|
const mockChainId = 'chain-id';
|
||||||
@ -45,7 +46,7 @@ function generateJsx(order?: OrderSubmissionBody['orderSubmission']) {
|
|||||||
return (
|
return (
|
||||||
<MockedProvider mocks={[chainIdMock]}>
|
<MockedProvider mocks={[chainIdMock]}>
|
||||||
<VegaWalletContext.Provider value={{ pubKey: mockChainId } as any}>
|
<VegaWalletContext.Provider value={{ pubKey: mockChainId } as any}>
|
||||||
<DealTicket market={market} submit={submit} />
|
<DealTicket market={market} marketData={marketData} submit={submit} />
|
||||||
</VegaWalletContext.Provider>
|
</VegaWalletContext.Provider>
|
||||||
</MockedProvider>
|
</MockedProvider>
|
||||||
);
|
);
|
||||||
@ -79,11 +80,10 @@ describe('DealTicket', () => {
|
|||||||
expect(screen.getByTestId('order-tif')).toHaveValue(
|
expect(screen.getByTestId('order-tif')).toHaveValue(
|
||||||
Schema.OrderTimeInForce.TIME_IN_FORCE_IOC
|
Schema.OrderTimeInForce.TIME_IN_FORCE_IOC
|
||||||
);
|
);
|
||||||
|
|
||||||
// Assert last price is shown
|
// Assert last price is shown
|
||||||
expect(screen.getByTestId('last-price')).toHaveTextContent(
|
expect(screen.getByTestId('last-price')).toHaveTextContent(
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
`~${addDecimal(market!.data.markPrice, market.decimalPlaces)} ${
|
`~${addDecimal(marketData.markPrice, market.decimalPlaces)} ${
|
||||||
market.tradableInstrument.instrument.product.quoteName
|
market.tradableInstrument.instrument.product.quoteName
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
|
@ -25,14 +25,17 @@ import {
|
|||||||
import { ZeroBalanceError } from '../deal-ticket-validation/zero-balance-error';
|
import { ZeroBalanceError } from '../deal-ticket-validation/zero-balance-error';
|
||||||
import { SummaryValidationType } from '../../constants';
|
import { SummaryValidationType } from '../../constants';
|
||||||
import { useHasNoBalance } from '../../hooks/use-has-no-balance';
|
import { useHasNoBalance } from '../../hooks/use-has-no-balance';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
import {
|
import {
|
||||||
usePersistedOrderStore,
|
usePersistedOrderStore,
|
||||||
usePersistedOrderStoreSubscription,
|
usePersistedOrderStoreSubscription,
|
||||||
} from '@vegaprotocol/orders';
|
} from '@vegaprotocol/orders';
|
||||||
|
|
||||||
|
export type TransactionStatus = 'default' | 'pending';
|
||||||
|
|
||||||
export interface DealTicketProps {
|
export interface DealTicketProps {
|
||||||
market: MarketDealTicket;
|
market: Market;
|
||||||
|
marketData: MarketData;
|
||||||
submit: (order: OrderSubmissionBody['orderSubmission']) => void;
|
submit: (order: OrderSubmissionBody['orderSubmission']) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +45,7 @@ export type DealTicketFormFields = OrderSubmissionBody['orderSubmission'] & {
|
|||||||
summary: string;
|
summary: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
export const DealTicket = ({ market, marketData, submit }: DealTicketProps) => {
|
||||||
const { pubKey, isReadOnly } = useVegaWallet();
|
const { pubKey, isReadOnly } = useVegaWallet();
|
||||||
const { getPersistedOrder, setPersistedOrder } = usePersistedOrderStore(
|
const { getPersistedOrder, setPersistedOrder } = usePersistedOrderStore(
|
||||||
(store) => ({
|
(store) => ({
|
||||||
@ -77,12 +80,12 @@ export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const marketStateError = validateMarketState(market.data.marketState);
|
const marketStateError = validateMarketState(marketData.marketState);
|
||||||
const hasNoBalance = useHasNoBalance(
|
const hasNoBalance = useHasNoBalance(
|
||||||
market.tradableInstrument.instrument.product.settlementAsset.id
|
market.tradableInstrument.instrument.product.settlementAsset.id
|
||||||
);
|
);
|
||||||
const marketTradingModeError = validateMarketTradingMode(
|
const marketTradingModeError = validateMarketTradingMode(
|
||||||
market.data.marketTradingMode
|
marketData.marketTradingMode
|
||||||
);
|
);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
@ -165,13 +168,17 @@ export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
|||||||
name="type"
|
name="type"
|
||||||
control={control}
|
control={control}
|
||||||
rules={{
|
rules={{
|
||||||
validate: validateType(market),
|
validate: validateType(
|
||||||
|
marketData.marketTradingMode,
|
||||||
|
marketData.trigger
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<TypeSelector
|
<TypeSelector
|
||||||
value={field.value}
|
value={field.value}
|
||||||
onSelect={field.onChange}
|
onSelect={field.onChange}
|
||||||
market={market}
|
market={market}
|
||||||
|
marketData={marketData}
|
||||||
errorMessage={errors.type?.message}
|
errorMessage={errors.type?.message}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -186,6 +193,7 @@ export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
|||||||
<DealTicketAmount
|
<DealTicketAmount
|
||||||
orderType={order.type}
|
orderType={order.type}
|
||||||
market={market}
|
market={market}
|
||||||
|
marketData={marketData}
|
||||||
register={register}
|
register={register}
|
||||||
sizeError={errors.size?.message}
|
sizeError={errors.size?.message}
|
||||||
priceError={errors.price?.message}
|
priceError={errors.price?.message}
|
||||||
@ -194,7 +202,10 @@ export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
|||||||
name="timeInForce"
|
name="timeInForce"
|
||||||
control={control}
|
control={control}
|
||||||
rules={{
|
rules={{
|
||||||
validate: validateTimeInForce(market),
|
validate: validateTimeInForce(
|
||||||
|
marketData.marketTradingMode,
|
||||||
|
marketData.trigger
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<TimeInForceSelector
|
<TimeInForceSelector
|
||||||
@ -202,6 +213,7 @@ export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
|||||||
orderType={order.type}
|
orderType={order.type}
|
||||||
onSelect={field.onChange}
|
onSelect={field.onChange}
|
||||||
market={market}
|
market={market}
|
||||||
|
marketData={marketData}
|
||||||
errorMessage={errors.timeInForce?.message}
|
errorMessage={errors.timeInForce?.message}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -228,10 +240,15 @@ export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
|||||||
<SummaryMessage
|
<SummaryMessage
|
||||||
errorMessage={errors.summary?.message}
|
errorMessage={errors.summary?.message}
|
||||||
market={market}
|
market={market}
|
||||||
|
marketData={marketData}
|
||||||
order={order}
|
order={order}
|
||||||
isReadOnly={isReadOnly}
|
isReadOnly={isReadOnly}
|
||||||
/>
|
/>
|
||||||
<DealTicketFeeDetails order={order} market={market} />
|
<DealTicketFeeDetails
|
||||||
|
order={order}
|
||||||
|
market={market}
|
||||||
|
marketData={marketData}
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -242,17 +259,25 @@ export const DealTicket = ({ market, submit }: DealTicketProps) => {
|
|||||||
*/
|
*/
|
||||||
interface SummaryMessageProps {
|
interface SummaryMessageProps {
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
market: MarketDealTicket;
|
market: Market;
|
||||||
|
marketData: MarketData;
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
order: OrderSubmissionBody['orderSubmission'];
|
||||||
isReadOnly: boolean;
|
isReadOnly: boolean;
|
||||||
}
|
}
|
||||||
const SummaryMessage = memo(
|
const SummaryMessage = memo(
|
||||||
({ errorMessage, market, order, isReadOnly }: SummaryMessageProps) => {
|
({
|
||||||
|
errorMessage,
|
||||||
|
market,
|
||||||
|
marketData,
|
||||||
|
order,
|
||||||
|
isReadOnly,
|
||||||
|
}: SummaryMessageProps) => {
|
||||||
// Specific error UI for if balance is so we can
|
// Specific error UI for if balance is so we can
|
||||||
// render a deposit dialog
|
// render a deposit dialog
|
||||||
const asset = market.tradableInstrument.instrument.product.settlementAsset;
|
const asset = market.tradableInstrument.instrument.product.settlementAsset;
|
||||||
const { balanceError, balance, margin } = useOrderMarginValidation({
|
const { balanceError, balance, margin } = useOrderMarginValidation({
|
||||||
market,
|
market,
|
||||||
|
marketData,
|
||||||
order,
|
order,
|
||||||
});
|
});
|
||||||
if (isReadOnly) {
|
if (isReadOnly) {
|
||||||
@ -298,7 +323,7 @@ const SummaryMessage = memo(
|
|||||||
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
|
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||||
].includes(market.data.marketTradingMode)
|
].includes(marketData.marketTradingMode)
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -24,11 +24,10 @@ import {
|
|||||||
import { IconNames } from '@blueprintjs/icons';
|
import { IconNames } from '@blueprintjs/icons';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import type { Market } from '@vegaprotocol/market-list';
|
import type { Market } from '@vegaprotocol/market-list';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
|
||||||
import { marketsProvider } from '@vegaprotocol/market-list';
|
import { marketsProvider } from '@vegaprotocol/market-list';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
market: MarketDealTicket;
|
market: Market;
|
||||||
setMarket: (marketId: string) => void;
|
setMarket: (marketId: string) => void;
|
||||||
ItemRenderer?: React.FC<{
|
ItemRenderer?: React.FC<{
|
||||||
market: Market;
|
market: Market;
|
||||||
|
@ -8,15 +8,16 @@ import {
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { DataGrid, t } from '@vegaprotocol/react-helpers';
|
import { DataGrid, t } from '@vegaprotocol/react-helpers';
|
||||||
import { timeInForceLabel } from '@vegaprotocol/orders';
|
import { timeInForceLabel } from '@vegaprotocol/orders';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
|
||||||
import { compileGridData } from '../trading-mode-tooltip';
|
import { compileGridData } from '../trading-mode-tooltip';
|
||||||
import { MarketModeValidationType } from '../../constants';
|
import { MarketModeValidationType } from '../../constants';
|
||||||
|
import type { Market, StaticMarketData } from '@vegaprotocol/market-list';
|
||||||
|
|
||||||
interface TimeInForceSelectorProps {
|
interface TimeInForceSelectorProps {
|
||||||
value: Schema.OrderTimeInForce;
|
value: Schema.OrderTimeInForce;
|
||||||
orderType: Schema.OrderType;
|
orderType: Schema.OrderType;
|
||||||
onSelect: (tif: Schema.OrderTimeInForce) => void;
|
onSelect: (tif: Schema.OrderTimeInForce) => void;
|
||||||
market: MarketDealTicket;
|
market: Market;
|
||||||
|
marketData: StaticMarketData;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ export const TimeInForceSelector = ({
|
|||||||
orderType,
|
orderType,
|
||||||
onSelect,
|
onSelect,
|
||||||
market,
|
market,
|
||||||
|
marketData,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
}: TimeInForceSelectorProps) => {
|
}: TimeInForceSelectorProps) => {
|
||||||
const options =
|
const options =
|
||||||
@ -80,7 +82,7 @@ export const TimeInForceSelector = ({
|
|||||||
{t('This market is in auction until it reaches')}{' '}
|
{t('This market is in auction until it reaches')}{' '}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
description={
|
description={
|
||||||
<DataGrid grid={compileGridData(market, market.data)} />
|
<DataGrid grid={compileGridData(market, marketData)} />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>{t('sufficient liquidity')}</span>
|
<span>{t('sufficient liquidity')}</span>
|
||||||
@ -99,7 +101,7 @@ export const TimeInForceSelector = ({
|
|||||||
{t('This market is in auction due to')}{' '}
|
{t('This market is in auction due to')}{' '}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
description={
|
description={
|
||||||
<DataGrid grid={compileGridData(market, market.data)} />
|
<DataGrid grid={compileGridData(market, marketData)} />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>{t('high price volatility')}</span>
|
<span>{t('high price volatility')}</span>
|
||||||
|
@ -2,14 +2,15 @@ import { FormGroup, InputError, Tooltip } from '@vegaprotocol/ui-toolkit';
|
|||||||
import { DataGrid, t } from '@vegaprotocol/react-helpers';
|
import { DataGrid, t } from '@vegaprotocol/react-helpers';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { Toggle } from '@vegaprotocol/ui-toolkit';
|
import { Toggle } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
import { compileGridData } from '../trading-mode-tooltip';
|
import { compileGridData } from '../trading-mode-tooltip';
|
||||||
import { MarketModeValidationType } from '../../constants';
|
import { MarketModeValidationType } from '../../constants';
|
||||||
|
|
||||||
interface TypeSelectorProps {
|
interface TypeSelectorProps {
|
||||||
value: Schema.OrderType;
|
value: Schema.OrderType;
|
||||||
onSelect: (type: Schema.OrderType) => void;
|
onSelect: (type: Schema.OrderType) => void;
|
||||||
market: MarketDealTicket;
|
market: Market;
|
||||||
|
marketData: MarketData;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,6 +23,7 @@ export const TypeSelector = ({
|
|||||||
value,
|
value,
|
||||||
onSelect,
|
onSelect,
|
||||||
market,
|
market,
|
||||||
|
marketData,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
}: TypeSelectorProps) => {
|
}: TypeSelectorProps) => {
|
||||||
const renderError = (errorType: MarketModeValidationType) => {
|
const renderError = (errorType: MarketModeValidationType) => {
|
||||||
@ -35,7 +37,7 @@ export const TypeSelector = ({
|
|||||||
{t('This market is in auction until it reaches')}{' '}
|
{t('This market is in auction until it reaches')}{' '}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
description={
|
description={
|
||||||
<DataGrid grid={compileGridData(market, market.data)} />
|
<DataGrid grid={compileGridData(market, marketData)} />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>{t('sufficient liquidity')}</span>
|
<span>{t('sufficient liquidity')}</span>
|
||||||
@ -52,7 +54,7 @@ export const TypeSelector = ({
|
|||||||
{t('This market is in auction due to')}{' '}
|
{t('This market is in auction due to')}{' '}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
description={
|
description={
|
||||||
<DataGrid grid={compileGridData(market, market.data)} />
|
<DataGrid grid={compileGridData(market, marketData)} />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>{t('high price volatility')}</span>
|
<span>{t('high price volatility')}</span>
|
||||||
|
@ -13,9 +13,9 @@ import type { Market, MarketData } from '@vegaprotocol/market-list';
|
|||||||
export const compileGridData = (
|
export const compileGridData = (
|
||||||
market: Pick<
|
market: Pick<
|
||||||
Market,
|
Market,
|
||||||
'tradableInstrument' | 'id' | 'decimalPlaces' | 'positionDecimalPlaces'
|
'id' | 'tradableInstrument' | 'decimalPlaces' | 'positionDecimalPlaces'
|
||||||
>,
|
>,
|
||||||
marketData: Pick<
|
marketData?: Pick<
|
||||||
MarketData,
|
MarketData,
|
||||||
| 'marketTradingMode'
|
| 'marketTradingMode'
|
||||||
| 'auctionStart'
|
| 'auctionStart'
|
||||||
@ -25,14 +25,14 @@ export const compileGridData = (
|
|||||||
| 'suppliedStake'
|
| 'suppliedStake'
|
||||||
| 'targetStake'
|
| 'targetStake'
|
||||||
| 'trigger'
|
| 'trigger'
|
||||||
>,
|
> | null,
|
||||||
onSelect?: (id: string) => void
|
onSelect?: (id: string) => void
|
||||||
): { label: ReactNode; value?: ReactNode }[] => {
|
): { label: ReactNode; value?: ReactNode }[] => {
|
||||||
const grid: DataGridProps['grid'] = [];
|
const grid: DataGridProps['grid'] = [];
|
||||||
const isLiquidityMonitoringAuction =
|
const isLiquidityMonitoringAuction =
|
||||||
marketData.marketTradingMode ===
|
marketData?.marketTradingMode ===
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION &&
|
||||||
marketData.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY;
|
marketData?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY;
|
||||||
|
|
||||||
const formatStake = (value: string) => {
|
const formatStake = (value: string) => {
|
||||||
const formattedValue = addDecimalsFormatNumber(
|
const formattedValue = addDecimalsFormatNumber(
|
||||||
|
@ -22,15 +22,16 @@ export const TradingModeTooltip = ({
|
|||||||
skip,
|
skip,
|
||||||
}: TradingModeTooltipProps) => {
|
}: TradingModeTooltipProps) => {
|
||||||
const { VEGA_DOCS_URL } = useEnvironment();
|
const { VEGA_DOCS_URL } = useEnvironment();
|
||||||
const market = useMarket(marketId);
|
const { data: market } = useMarket(marketId);
|
||||||
const marketData = useStaticMarketData(marketId, skip);
|
const { data: marketData } = useStaticMarketData(marketId, skip);
|
||||||
const { marketTradingMode: tradingMode, trigger } = marketData || {};
|
const { marketTradingMode, trigger } = marketData || {};
|
||||||
const variables = useMemo(() => ({ marketId: marketId || '' }), [marketId]);
|
const variables = useMemo(() => ({ marketId: marketId || '' }), [marketId]);
|
||||||
const { data: proposalData } = useProposalOfMarketQuery({
|
const { data: proposalData } = useProposalOfMarketQuery({
|
||||||
variables,
|
variables,
|
||||||
skip:
|
skip:
|
||||||
!tradingMode ||
|
!marketTradingMode ||
|
||||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION !== tradingMode,
|
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION !==
|
||||||
|
marketTradingMode,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!market || !marketData) {
|
if (!market || !marketData) {
|
||||||
@ -43,7 +44,7 @@ export const TradingModeTooltip = ({
|
|||||||
const compiledGrid =
|
const compiledGrid =
|
||||||
onSelect && compileGridData(market, marketData, onSelect);
|
onSelect && compileGridData(market, marketData, onSelect);
|
||||||
|
|
||||||
switch (tradingMode) {
|
switch (marketTradingMode) {
|
||||||
case Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS: {
|
case Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS: {
|
||||||
return (
|
return (
|
||||||
<section data-testid="trading-mode-tooltip">
|
<section data-testid="trading-mode-tooltip">
|
||||||
@ -67,7 +68,7 @@ export const TradingModeTooltip = ({
|
|||||||
className="justify-center font-bold my-2"
|
className="justify-center font-bold my-2"
|
||||||
data-testid="opening-auction-sub-status"
|
data-testid="opening-auction-sub-status"
|
||||||
>
|
>
|
||||||
{`${Schema.MarketTradingModeMapping[tradingMode]}: ${t(
|
{`${Schema.MarketTradingModeMapping[marketTradingMode]}: ${t(
|
||||||
'Not enough liquidity to open'
|
'Not enough liquidity to open'
|
||||||
)}`}
|
)}`}
|
||||||
</span>
|
</span>
|
||||||
@ -84,7 +85,9 @@ export const TradingModeTooltip = ({
|
|||||||
className="justify-center font-bold my-2"
|
className="justify-center font-bold my-2"
|
||||||
data-testid="opening-auction-sub-status"
|
data-testid="opening-auction-sub-status"
|
||||||
>
|
>
|
||||||
{`${Schema.MarketTradingModeMapping[tradingMode]}: ${t(
|
{`${
|
||||||
|
Schema.MarketTradingModeMapping[marketTradingMode]
|
||||||
|
}: ${t(
|
||||||
'Closing on %s',
|
'Closing on %s',
|
||||||
getDateTimeFormat().format(enactmentDate)
|
getDateTimeFormat().format(enactmentDate)
|
||||||
)}`}
|
)}`}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { MockedProvider } from '@apollo/client/testing';
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
|
import type { Market } from '@vegaprotocol/market-list';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import { useCalculateSlippage } from './use-calculate-slippage';
|
import { useCalculateSlippage } from './use-calculate-slippage';
|
||||||
|
|
||||||
@ -74,12 +75,17 @@ describe('useCalculateSlippage Hook', () => {
|
|||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
const market = {
|
||||||
|
id: 'marketId',
|
||||||
|
decimalPlaces: 0,
|
||||||
|
positionDecimalPlaces: 0,
|
||||||
|
} as Market;
|
||||||
|
|
||||||
it('long order', () => {
|
it('long order', () => {
|
||||||
const { result } = renderHook(
|
const { result } = renderHook(
|
||||||
() =>
|
() =>
|
||||||
useCalculateSlippage({
|
useCalculateSlippage({
|
||||||
marketId: 'marketId',
|
market,
|
||||||
order: {
|
order: {
|
||||||
size: '10',
|
size: '10',
|
||||||
side: Schema.Side.SIDE_BUY,
|
side: Schema.Side.SIDE_BUY,
|
||||||
@ -96,7 +102,7 @@ describe('useCalculateSlippage Hook', () => {
|
|||||||
const { result } = renderHook(
|
const { result } = renderHook(
|
||||||
() =>
|
() =>
|
||||||
useCalculateSlippage({
|
useCalculateSlippage({
|
||||||
marketId: 'marketId',
|
market,
|
||||||
order: {
|
order: {
|
||||||
size: '10',
|
size: '10',
|
||||||
side: Schema.Side.SIDE_SELL,
|
side: Schema.Side.SIDE_SELL,
|
||||||
@ -122,7 +128,7 @@ describe('useCalculateSlippage Hook', () => {
|
|||||||
const { result } = renderHook(
|
const { result } = renderHook(
|
||||||
() =>
|
() =>
|
||||||
useCalculateSlippage({
|
useCalculateSlippage({
|
||||||
marketId: 'marketId',
|
market,
|
||||||
order: {
|
order: {
|
||||||
size: '10',
|
size: '10',
|
||||||
side: Schema.Side.SIDE_SELL,
|
side: Schema.Side.SIDE_SELL,
|
||||||
|
@ -1,36 +1,29 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { marketDepthProvider } from '@vegaprotocol/market-depth';
|
import { marketDepthProvider } from '@vegaprotocol/market-depth';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { marketProvider } from '@vegaprotocol/market-list';
|
import type { Market } from '@vegaprotocol/market-list';
|
||||||
import type { SingleMarketFieldsFragment } from '@vegaprotocol/market-list';
|
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import { BigNumber } from 'bignumber.js';
|
import { BigNumber } from 'bignumber.js';
|
||||||
import {
|
import {
|
||||||
formatNumber,
|
formatNumber,
|
||||||
toBigNum,
|
toBigNum,
|
||||||
useDataProvider,
|
|
||||||
useThrottledDataProvider,
|
useThrottledDataProvider,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
marketId: string;
|
market: Market;
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
order: OrderSubmissionBody['orderSubmission'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useCalculateSlippage = ({ marketId, order }: Props) => {
|
export const useCalculateSlippage = ({ market, order }: Props) => {
|
||||||
const variables = useMemo(() => ({ marketId }), [marketId]);
|
const variables = useMemo(() => ({ marketId: market.id }), [market.id]);
|
||||||
const { data } = useThrottledDataProvider(
|
const { data } = useThrottledDataProvider(
|
||||||
{
|
{
|
||||||
dataProvider: marketDepthProvider,
|
dataProvider: marketDepthProvider,
|
||||||
variables,
|
variables,
|
||||||
},
|
},
|
||||||
5000
|
1000
|
||||||
);
|
);
|
||||||
const { data: market } = useDataProvider<SingleMarketFieldsFragment, never>({
|
|
||||||
dataProvider: marketProvider,
|
|
||||||
skipUpdates: true,
|
|
||||||
variables,
|
|
||||||
});
|
|
||||||
const volPriceArr =
|
const volPriceArr =
|
||||||
data?.depth[order.side === Schema.Side.SIDE_BUY ? 'sell' : 'buy'] || [];
|
data?.depth[order.side === Schema.Side.SIDE_BUY ? 'sell' : 'buy'] || [];
|
||||||
if (volPriceArr.length && market) {
|
if (volPriceArr.length && market) {
|
||||||
|
@ -9,7 +9,7 @@ import * as Schema from '@vegaprotocol/types';
|
|||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import {
|
import {
|
||||||
EST_CLOSEOUT_TOOLTIP_TEXT,
|
EST_CLOSEOUT_TOOLTIP_TEXT,
|
||||||
@ -24,14 +24,15 @@ import { getDerivedPrice } from '../utils/get-price';
|
|||||||
|
|
||||||
export const useFeeDealTicketDetails = (
|
export const useFeeDealTicketDetails = (
|
||||||
order: OrderSubmissionBody['orderSubmission'],
|
order: OrderSubmissionBody['orderSubmission'],
|
||||||
market: MarketDealTicket
|
market: Market,
|
||||||
|
marketData: MarketData
|
||||||
) => {
|
) => {
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey } = useVegaWallet();
|
||||||
const slippage = useCalculateSlippage({ marketId: market.id, order });
|
const slippage = useCalculateSlippage({ market, order });
|
||||||
|
|
||||||
const derivedPrice = useMemo(() => {
|
const derivedPrice = useMemo(() => {
|
||||||
return getDerivedPrice(order, market);
|
return getDerivedPrice(order, market, marketData);
|
||||||
}, [order, market]);
|
}, [order, market, marketData]);
|
||||||
|
|
||||||
// Note this isn't currently used anywhere
|
// Note this isn't currently used anywhere
|
||||||
const slippageAdjustedPrice = useMemo(() => {
|
const slippageAdjustedPrice = useMemo(() => {
|
||||||
@ -51,6 +52,7 @@ export const useFeeDealTicketDetails = (
|
|||||||
const estMargin = useOrderMargin({
|
const estMargin = useOrderMargin({
|
||||||
order,
|
order,
|
||||||
market,
|
market,
|
||||||
|
marketData,
|
||||||
partyId: pubKey || '',
|
partyId: pubKey || '',
|
||||||
derivedPrice,
|
derivedPrice,
|
||||||
});
|
});
|
||||||
@ -58,6 +60,7 @@ export const useFeeDealTicketDetails = (
|
|||||||
const estCloseOut = useOrderCloseOut({
|
const estCloseOut = useOrderCloseOut({
|
||||||
order,
|
order,
|
||||||
market,
|
market,
|
||||||
|
marketData,
|
||||||
});
|
});
|
||||||
|
|
||||||
const notionalSize = useMemo(() => {
|
const notionalSize = useMemo(() => {
|
||||||
@ -94,7 +97,7 @@ export const useFeeDealTicketDetails = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export interface FeeDetails {
|
export interface FeeDetails {
|
||||||
market: MarketDealTicket;
|
market: Market;
|
||||||
symbol: string;
|
symbol: string;
|
||||||
notionalSize: string | null;
|
notionalSize: string | null;
|
||||||
estMargin: OrderMargin | null;
|
estMargin: OrderMargin | null;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
import { MockedProvider } from '@apollo/client/testing';
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
import { useOrderCloseOut } from './use-order-closeout';
|
import { useOrderCloseOut } from './use-order-closeout';
|
||||||
|
|
||||||
jest.mock('@vegaprotocol/wallet', () => ({
|
jest.mock('@vegaprotocol/wallet', () => ({
|
||||||
@ -18,11 +18,6 @@ describe('useOrderCloseOut', () => {
|
|||||||
const order = { size: '2', side: 'SIDE_BUY' };
|
const order = { size: '2', side: 'SIDE_BUY' };
|
||||||
const market = {
|
const market = {
|
||||||
decimalPlaces: 5,
|
decimalPlaces: 5,
|
||||||
depth: {
|
|
||||||
lastTrade: {
|
|
||||||
price: '1000000',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
instrument: {
|
instrument: {
|
||||||
product: {
|
product: {
|
||||||
@ -32,10 +27,11 @@ describe('useOrderCloseOut', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: {
|
} as unknown as Market;
|
||||||
markPrice: 100000,
|
|
||||||
},
|
const marketData = {
|
||||||
} as unknown as MarketDealTicket;
|
markPrice: 100000,
|
||||||
|
} as unknown as MarketData;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
@ -47,7 +43,10 @@ describe('useOrderCloseOut', () => {
|
|||||||
() =>
|
() =>
|
||||||
useOrderCloseOut({
|
useOrderCloseOut({
|
||||||
order: order as OrderSubmissionBody['orderSubmission'],
|
order: order as OrderSubmissionBody['orderSubmission'],
|
||||||
market: { ...market, data: { ...market.data, markPrice: '0' } },
|
market,
|
||||||
|
marketData: {
|
||||||
|
markPrice: '0',
|
||||||
|
} as MarketData,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: MockedProvider,
|
wrapper: MockedProvider,
|
||||||
@ -65,7 +64,8 @@ describe('useOrderCloseOut', () => {
|
|||||||
...order,
|
...order,
|
||||||
side: 'SIDE_SELL',
|
side: 'SIDE_SELL',
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
} as OrderSubmissionBody['orderSubmission'],
|
||||||
market: market,
|
market,
|
||||||
|
marketData,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: MockedProvider,
|
wrapper: MockedProvider,
|
||||||
@ -85,7 +85,8 @@ describe('useOrderCloseOut', () => {
|
|||||||
type: 'TYPE_LIMIT',
|
type: 'TYPE_LIMIT',
|
||||||
side: 'SIDE_SELL',
|
side: 'SIDE_SELL',
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
} as OrderSubmissionBody['orderSubmission'],
|
||||||
market: market,
|
market,
|
||||||
|
marketData,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: MockedProvider,
|
wrapper: MockedProvider,
|
||||||
@ -102,7 +103,10 @@ describe('useOrderCloseOut', () => {
|
|||||||
...order,
|
...order,
|
||||||
side: 'SIDE_SELL',
|
side: 'SIDE_SELL',
|
||||||
} as OrderSubmissionBody['orderSubmission'],
|
} as OrderSubmissionBody['orderSubmission'],
|
||||||
market: { ...market, data: { ...market.data, markPrice: '0' } },
|
market,
|
||||||
|
marketData: {
|
||||||
|
markPrice: '0',
|
||||||
|
} as MarketData,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: MockedProvider,
|
wrapper: MockedProvider,
|
||||||
|
@ -2,7 +2,7 @@ import { BigNumber } from 'bignumber.js';
|
|||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import { addDecimal } from '@vegaprotocol/react-helpers';
|
import { addDecimal } from '@vegaprotocol/react-helpers';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
import {
|
import {
|
||||||
useAccountBalance,
|
useAccountBalance,
|
||||||
useMarketAccountBalance,
|
useMarketAccountBalance,
|
||||||
@ -12,10 +12,15 @@ import { useMarketPositions } from './use-market-positions';
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
order: OrderSubmissionBody['orderSubmission'];
|
||||||
market: MarketDealTicket;
|
market: Market;
|
||||||
|
marketData: MarketData;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useOrderCloseOut = ({ order, market }: Props): string | null => {
|
export const useOrderCloseOut = ({
|
||||||
|
order,
|
||||||
|
market,
|
||||||
|
marketData,
|
||||||
|
}: Props): string | null => {
|
||||||
const { accountBalance, accountDecimals } = useAccountBalance(
|
const { accountBalance, accountDecimals } = useAccountBalance(
|
||||||
market.tradableInstrument.instrument.product.settlementAsset.id
|
market.tradableInstrument.instrument.product.settlementAsset.id
|
||||||
);
|
);
|
||||||
@ -43,9 +48,7 @@ export const useOrderCloseOut = ({ order, market }: Props): string | null => {
|
|||||||
const price =
|
const price =
|
||||||
order.type === Schema.OrderType.TYPE_LIMIT && order.price
|
order.type === Schema.OrderType.TYPE_LIMIT && order.price
|
||||||
? new BigNumber(order.price)
|
? new BigNumber(order.price)
|
||||||
: new BigNumber(
|
: new BigNumber(addDecimal(marketData.markPrice, market.decimalPlaces));
|
||||||
addDecimal(market.data.markPrice || 0, market.decimalPlaces || 0)
|
|
||||||
);
|
|
||||||
// regarding formula (marginMaintenanceLevel - positionAccountBalance - generalAccountBalance) / volume + markPrice
|
// regarding formula (marginMaintenanceLevel - positionAccountBalance - generalAccountBalance) / volume + markPrice
|
||||||
const marginDifference = marginMaintenanceLevel
|
const marginDifference = marginMaintenanceLevel
|
||||||
.minus(positionAccountBalance)
|
.minus(positionAccountBalance)
|
||||||
|
@ -4,18 +4,24 @@ import { toBigNum } from '@vegaprotocol/react-helpers';
|
|||||||
import { useAccountBalance } from '@vegaprotocol/accounts';
|
import { useAccountBalance } from '@vegaprotocol/accounts';
|
||||||
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
import { useOrderMargin } from './use-order-margin';
|
import { useOrderMargin } from './use-order-margin';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
market: MarketDealTicket;
|
market: Market;
|
||||||
|
marketData: MarketData;
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
order: OrderSubmissionBody['orderSubmission'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useOrderMarginValidation = ({ market, order }: Props) => {
|
export const useOrderMarginValidation = ({
|
||||||
|
market,
|
||||||
|
marketData,
|
||||||
|
order,
|
||||||
|
}: Props) => {
|
||||||
const { pubKey } = useVegaWallet();
|
const { pubKey } = useVegaWallet();
|
||||||
const estMargin = useOrderMargin({
|
const estMargin = useOrderMargin({
|
||||||
order,
|
order,
|
||||||
market,
|
market,
|
||||||
|
marketData,
|
||||||
partyId: pubKey || '',
|
partyId: pubKey || '',
|
||||||
});
|
});
|
||||||
const { id: assetId, decimals: assetDecimals } =
|
const { id: assetId, decimals: assetDecimals } =
|
||||||
|
@ -5,7 +5,7 @@ import type { PositionMargin } from './use-market-positions';
|
|||||||
import type { Props } from './use-order-margin';
|
import type { Props } from './use-order-margin';
|
||||||
import { useOrderMargin } from './use-order-margin';
|
import { useOrderMargin } from './use-order-margin';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
|
|
||||||
let mockEstimateData = {
|
let mockEstimateData = {
|
||||||
estimateOrder: {
|
estimateOrder: {
|
||||||
@ -55,11 +55,11 @@ describe('useOrderMargin', () => {
|
|||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
positionDecimalPlaces: 0,
|
positionDecimalPlaces: 0,
|
||||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
data: {
|
} as unknown as Market,
|
||||||
indicativePrice: '100',
|
marketData: {
|
||||||
markPrice: '200',
|
indicativePrice: '100',
|
||||||
},
|
markPrice: '200',
|
||||||
} as MarketDealTicket,
|
} as unknown as MarketData,
|
||||||
partyId: 'partyId',
|
partyId: 'partyId',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,12 +4,13 @@ import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
|
|||||||
import { removeDecimal } from '@vegaprotocol/react-helpers';
|
import { removeDecimal } from '@vegaprotocol/react-helpers';
|
||||||
import { useMarketPositions } from './use-market-positions';
|
import { useMarketPositions } from './use-market-positions';
|
||||||
import { useEstimateOrderQuery } from './__generated__/EstimateOrder';
|
import { useEstimateOrderQuery } from './__generated__/EstimateOrder';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
import { getDerivedPrice } from '../utils/get-price';
|
import { getDerivedPrice } from '../utils/get-price';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
order: OrderSubmissionBody['orderSubmission'];
|
order: OrderSubmissionBody['orderSubmission'];
|
||||||
market: MarketDealTicket;
|
market: Market;
|
||||||
|
marketData: MarketData;
|
||||||
partyId: string;
|
partyId: string;
|
||||||
derivedPrice?: string;
|
derivedPrice?: string;
|
||||||
}
|
}
|
||||||
@ -27,11 +28,13 @@ export interface OrderMargin {
|
|||||||
export const useOrderMargin = ({
|
export const useOrderMargin = ({
|
||||||
order,
|
order,
|
||||||
market,
|
market,
|
||||||
|
marketData,
|
||||||
partyId,
|
partyId,
|
||||||
derivedPrice,
|
derivedPrice,
|
||||||
}: Props): OrderMargin | null => {
|
}: Props): OrderMargin | null => {
|
||||||
const { balance } = useMarketPositions({ marketId: market.id }) || {};
|
const { balance } = useMarketPositions({ marketId: market.id }) || {};
|
||||||
const priceForEstimate = derivedPrice || getDerivedPrice(order, market);
|
const priceForEstimate =
|
||||||
|
derivedPrice || getDerivedPrice(order, market, marketData);
|
||||||
|
|
||||||
const { data } = useEstimateOrderQuery({
|
const { data } = useEstimateOrderQuery({
|
||||||
variables: {
|
variables: {
|
||||||
|
@ -1,68 +1,49 @@
|
|||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
import type { Market, MarketData } from '@vegaprotocol/market-list';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
import type { PartialDeep } from 'type-fest';
|
import type { PartialDeep } from 'type-fest';
|
||||||
|
|
||||||
export function generateMarket(
|
export function generateMarket(override?: PartialDeep<Market>): Market {
|
||||||
override?: PartialDeep<MarketDealTicket>
|
const defaultMarket: Market = {
|
||||||
): MarketDealTicket {
|
|
||||||
const defaultMarket: MarketDealTicket = {
|
|
||||||
__typename: 'Market',
|
__typename: 'Market',
|
||||||
id: 'market-id',
|
id: 'market-id',
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
positionDecimalPlaces: 1,
|
positionDecimalPlaces: 1,
|
||||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
state: Schema.MarketState.STATE_ACTIVE,
|
state: Schema.MarketState.STATE_ACTIVE,
|
||||||
|
marketTimestamps: {
|
||||||
|
__typename: 'MarketTimestamps',
|
||||||
|
close: '',
|
||||||
|
open: '',
|
||||||
|
},
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
__typename: 'TradableInstrument',
|
__typename: 'TradableInstrument',
|
||||||
instrument: {
|
instrument: {
|
||||||
__typename: 'Instrument',
|
id: '',
|
||||||
id: '1',
|
code: 'BTCUSD.MF21',
|
||||||
name: 'Instrument name',
|
name: 'ACTIVE MARKET',
|
||||||
code: 'instrument-code',
|
|
||||||
metadata: {
|
metadata: {
|
||||||
__typename: 'InstrumentMetadata',
|
__typename: 'InstrumentMetadata',
|
||||||
tags: [],
|
tags: [],
|
||||||
},
|
},
|
||||||
product: {
|
product: {
|
||||||
__typename: 'Future',
|
|
||||||
quoteName: 'quote-name',
|
|
||||||
dataSourceSpecForTradingTermination: {
|
|
||||||
id: 'data-source-for-trading-termination-id',
|
|
||||||
},
|
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
|
id: 'asset-0',
|
||||||
|
symbol: 'tDAI',
|
||||||
|
name: 'tDAI',
|
||||||
|
decimals: 5,
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
id: 'asset-id',
|
|
||||||
name: 'asset-name',
|
|
||||||
symbol: 'asset-symbol',
|
|
||||||
decimals: 2,
|
|
||||||
},
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: '',
|
||||||
|
},
|
||||||
|
quoteName: 'BTC',
|
||||||
|
__typename: 'Future',
|
||||||
},
|
},
|
||||||
|
__typename: 'Instrument',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data: {
|
|
||||||
__typename: 'MarketData',
|
|
||||||
market: {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'market-id',
|
|
||||||
},
|
|
||||||
bestBidPrice: '100',
|
|
||||||
bestOfferPrice: '100',
|
|
||||||
markPrice: '200',
|
|
||||||
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_BATCH,
|
|
||||||
staticMidPrice: '100',
|
|
||||||
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
marketState: Schema.MarketState.STATE_ACTIVE,
|
|
||||||
indicativePrice: '100',
|
|
||||||
indicativeVolume: '10',
|
|
||||||
bestStaticBidPrice: '100',
|
|
||||||
bestStaticOfferPrice: '100',
|
|
||||||
},
|
|
||||||
marketTimestamps: {
|
|
||||||
__typename: 'MarketTimestamps',
|
|
||||||
open: null,
|
|
||||||
close: null,
|
|
||||||
},
|
|
||||||
fees: {
|
fees: {
|
||||||
factors: {
|
factors: {
|
||||||
makerFee: '0.001',
|
makerFee: '0.001',
|
||||||
@ -70,14 +51,34 @@ export function generateMarket(
|
|||||||
liquidityFee: '0.003',
|
liquidityFee: '0.003',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
depth: {
|
|
||||||
__typename: 'MarketDepth',
|
|
||||||
lastTrade: {
|
|
||||||
__typename: 'Trade',
|
|
||||||
price: '100',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return merge(defaultMarket, override);
|
return merge(defaultMarket, override);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function generateMarketData(
|
||||||
|
override?: PartialDeep<MarketData>
|
||||||
|
): MarketData {
|
||||||
|
const defaultMarketData: MarketData = {
|
||||||
|
__typename: 'MarketData',
|
||||||
|
market: {
|
||||||
|
id: 'market-id',
|
||||||
|
__typename: 'Market',
|
||||||
|
},
|
||||||
|
auctionStart: '2022-06-21T17:18:43.484055236Z',
|
||||||
|
auctionEnd: '2022-06-21T17:18:43.484055236Z',
|
||||||
|
targetStake: '1000000',
|
||||||
|
suppliedStake: '1000',
|
||||||
|
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
||||||
|
marketState: Schema.MarketState.STATE_ACTIVE,
|
||||||
|
staticMidPrice: '0',
|
||||||
|
indicativePrice: '100',
|
||||||
|
bestStaticBidPrice: '0',
|
||||||
|
bestStaticOfferPrice: '0',
|
||||||
|
indicativeVolume: '10',
|
||||||
|
bestBidPrice: '0',
|
||||||
|
bestOfferPrice: '0',
|
||||||
|
markPrice: '200',
|
||||||
|
trigger: Schema.AuctionTrigger.AUCTION_TRIGGER_BATCH,
|
||||||
|
};
|
||||||
|
return merge(defaultMarketData, override);
|
||||||
|
}
|
||||||
|
@ -1,24 +1,25 @@
|
|||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
|
||||||
import { removeDecimal } from '@vegaprotocol/react-helpers';
|
import { removeDecimal } from '@vegaprotocol/react-helpers';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { isMarketInAuction } from './is-market-in-auction';
|
import { isMarketInAuction } from './is-market-in-auction';
|
||||||
|
import type { MarketData, Market } from '@vegaprotocol/market-list';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the market price based on market mode (auction or not auction)
|
* Get the market price based on market mode (auction or not auction)
|
||||||
*/
|
*/
|
||||||
export const getMarketPrice = (market: MarketDealTicket) => {
|
export const getMarketPrice = (marketData: MarketData) => {
|
||||||
if (isMarketInAuction(market)) {
|
const { marketTradingMode, indicativePrice, markPrice } = marketData;
|
||||||
|
if (isMarketInAuction(marketTradingMode)) {
|
||||||
// 0 can never be a valid uncrossing price
|
// 0 can never be a valid uncrossing price
|
||||||
// as it would require there being orders on the book at that price.
|
// as it would require there being orders on the book at that price.
|
||||||
if (
|
if (
|
||||||
market.data.indicativePrice &&
|
indicativePrice &&
|
||||||
market.data.indicativePrice !== '0' &&
|
indicativePrice !== '0' &&
|
||||||
BigInt(market.data.indicativePrice) !== BigInt(0)
|
BigInt(indicativePrice) !== BigInt(0)
|
||||||
) {
|
) {
|
||||||
return market.data.indicativePrice;
|
return indicativePrice;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return market.data.markPrice;
|
return markPrice;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
@ -33,7 +34,8 @@ export const getDerivedPrice = (
|
|||||||
type: Schema.OrderType;
|
type: Schema.OrderType;
|
||||||
price?: string | undefined;
|
price?: string | undefined;
|
||||||
},
|
},
|
||||||
market: MarketDealTicket
|
market: Market,
|
||||||
|
marketData: MarketData
|
||||||
) => {
|
) => {
|
||||||
// If order type is market we should use either the mark price
|
// If order type is market we should use either the mark price
|
||||||
// or the uncrossing price. If order type is limit use the price
|
// or the uncrossing price. If order type is limit use the price
|
||||||
@ -44,7 +46,7 @@ export const getDerivedPrice = (
|
|||||||
if (order.type === Schema.OrderType.TYPE_LIMIT && order.price) {
|
if (order.type === Schema.OrderType.TYPE_LIMIT && order.price) {
|
||||||
price = removeDecimal(order.price, market.decimalPlaces);
|
price = removeDecimal(order.price, market.decimalPlaces);
|
||||||
} else {
|
} else {
|
||||||
price = getMarketPrice(market);
|
price = getMarketPrice(marketData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return price === '0' ? undefined : price;
|
return price === '0' ? undefined : price;
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
|
|
||||||
export const isMarketInAuction = (market: {
|
export const isMarketInAuction = (
|
||||||
data: {
|
marketTradingMode: Schema.MarketTradingMode
|
||||||
marketTradingMode: Schema.MarketTradingMode;
|
) => {
|
||||||
};
|
|
||||||
}) => {
|
|
||||||
return [
|
return [
|
||||||
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
|
Schema.MarketTradingMode.TRADING_MODE_BATCH_AUCTION,
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||||
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
Schema.MarketTradingMode.TRADING_MODE_OPENING_AUCTION,
|
||||||
].includes(market.data.marketTradingMode);
|
].includes(marketTradingMode);
|
||||||
};
|
};
|
||||||
|
@ -2,9 +2,9 @@ import { t } from '@vegaprotocol/react-helpers';
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
|
|
||||||
export const validateMarketTradingMode = (
|
export const validateMarketTradingMode = (
|
||||||
tradingMode: Schema.MarketTradingMode
|
marketTradingMode: Schema.MarketTradingMode
|
||||||
) => {
|
) => {
|
||||||
if (tradingMode === Schema.MarketTradingMode.TRADING_MODE_NO_TRADING) {
|
if (marketTradingMode === Schema.MarketTradingMode.TRADING_MODE_NO_TRADING) {
|
||||||
return t('Trading terminated');
|
return t('Trading terminated');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { MarketModeValidationType } from '../constants';
|
import { MarketModeValidationType } from '../constants';
|
||||||
import { isMarketInAuction } from './is-market-in-auction';
|
import { isMarketInAuction } from './is-market-in-auction';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
|
||||||
|
|
||||||
export const validateTimeInForce = (market: MarketDealTicket) => {
|
export const validateTimeInForce = (
|
||||||
|
marketTradingMode: Schema.MarketTradingMode,
|
||||||
|
trigger: Schema.AuctionTrigger
|
||||||
|
) => {
|
||||||
return (value: Schema.OrderTimeInForce) => {
|
return (value: Schema.OrderTimeInForce) => {
|
||||||
const isMonitoringAuction =
|
const isMonitoringAuction =
|
||||||
market.data.marketTradingMode ===
|
marketTradingMode ===
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION;
|
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION;
|
||||||
const isPriceTrigger =
|
const isPriceTrigger =
|
||||||
market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE;
|
trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE;
|
||||||
const isLiquidityTrigger =
|
const isLiquidityTrigger =
|
||||||
market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY;
|
trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY;
|
||||||
|
|
||||||
if (isMarketInAuction(market)) {
|
if (isMarketInAuction(marketTradingMode)) {
|
||||||
if (
|
if (
|
||||||
[
|
[
|
||||||
Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { MarketModeValidationType } from '../constants';
|
import { MarketModeValidationType } from '../constants';
|
||||||
import { isMarketInAuction } from './is-market-in-auction';
|
import { isMarketInAuction } from './is-market-in-auction';
|
||||||
import type { MarketDealTicket } from '@vegaprotocol/market-list';
|
|
||||||
|
|
||||||
export const validateType = (market: MarketDealTicket) => {
|
export const validateType = (
|
||||||
|
marketTradingMode: Schema.MarketTradingMode,
|
||||||
|
trigger: Schema.AuctionTrigger
|
||||||
|
) => {
|
||||||
return (value: Schema.OrderType) => {
|
return (value: Schema.OrderType) => {
|
||||||
if (isMarketInAuction(market) && value === Schema.OrderType.TYPE_MARKET) {
|
if (
|
||||||
|
isMarketInAuction(marketTradingMode) &&
|
||||||
|
value === Schema.OrderType.TYPE_MARKET
|
||||||
|
) {
|
||||||
const isMonitoringAuction =
|
const isMonitoringAuction =
|
||||||
market.data.marketTradingMode ===
|
marketTradingMode ===
|
||||||
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION;
|
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION;
|
||||||
const isPriceTrigger =
|
const isPriceTrigger =
|
||||||
market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE;
|
trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_PRICE;
|
||||||
const isLiquidityTrigger =
|
const isLiquidityTrigger =
|
||||||
market.data.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY;
|
trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY;
|
||||||
|
|
||||||
if (isMonitoringAuction && isPriceTrigger) {
|
if (isMonitoringAuction && isPriceTrigger) {
|
||||||
return MarketModeValidationType.PriceMonitoringAuction;
|
return MarketModeValidationType.PriceMonitoringAuction;
|
||||||
|
@ -72,10 +72,14 @@ export const generateFill = (override?: PartialDeep<Trade>) => {
|
|||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
id: 'assset-id',
|
id: 'assset-id',
|
||||||
|
name: 'assset-id',
|
||||||
symbol: 'SYM',
|
symbol: 'SYM',
|
||||||
decimals: 18,
|
decimals: 18,
|
||||||
},
|
},
|
||||||
quoteName: '',
|
quoteName: '',
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -9,8 +9,7 @@ import {
|
|||||||
|
|
||||||
import type {
|
import type {
|
||||||
MarketCandles,
|
MarketCandles,
|
||||||
MarketWithCandles,
|
MarketMaybeWithDataAndCandles,
|
||||||
MarketWithData,
|
|
||||||
} from '@vegaprotocol/market-list';
|
} from '@vegaprotocol/market-list';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -37,21 +36,20 @@ export interface FeeLevels {
|
|||||||
fee: string;
|
fee: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Market = MarketWithData &
|
export type Market = MarketMaybeWithDataAndCandles & {
|
||||||
MarketWithCandles & {
|
feeLevels: FeeLevels[];
|
||||||
feeLevels: FeeLevels[];
|
target: string;
|
||||||
target: string;
|
dayVolume: string;
|
||||||
dayVolume: string;
|
liquidityCommitted: number;
|
||||||
liquidityCommitted: number;
|
volumeChange: string;
|
||||||
volumeChange: string;
|
tradableInstrument?: {
|
||||||
tradableInstrument?: {
|
instrument?: {
|
||||||
instrument?: {
|
metadata?: {
|
||||||
metadata?: {
|
tags?: string[] | null;
|
||||||
tags?: string[] | null;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export interface Markets {
|
export interface Markets {
|
||||||
markets: Market[];
|
markets: Market[];
|
||||||
@ -68,7 +66,7 @@ const getData = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const addData = (
|
export const addData = (
|
||||||
markets: (MarketWithData & MarketWithCandles)[],
|
markets: MarketMaybeWithDataAndCandles[],
|
||||||
marketsCandles24hAgo: MarketCandles[],
|
marketsCandles24hAgo: MarketCandles[],
|
||||||
marketsLiquidity: LiquidityProvisionMarket[]
|
marketsLiquidity: LiquidityProvisionMarket[]
|
||||||
) => {
|
) => {
|
||||||
@ -104,7 +102,7 @@ export const liquidityMarketsProvider = makeDataProvider<
|
|||||||
getData,
|
getData,
|
||||||
});
|
});
|
||||||
|
|
||||||
const liquidityProvisionProvider = makeDerivedDataProvider<Markets, never>(
|
const liquidityProvisionProvider = makeDerivedDataProvider<Market[], never>(
|
||||||
[
|
[
|
||||||
marketListProvider,
|
marketListProvider,
|
||||||
(callback, client, variables) =>
|
(callback, client, variables) =>
|
||||||
@ -115,12 +113,11 @@ const liquidityProvisionProvider = makeDerivedDataProvider<Markets, never>(
|
|||||||
liquidityMarketsProvider,
|
liquidityMarketsProvider,
|
||||||
],
|
],
|
||||||
(parts) => {
|
(parts) => {
|
||||||
const data = addData(
|
return addData(
|
||||||
parts[0] as (MarketWithData & MarketWithCandles)[],
|
parts[0] as MarketMaybeWithDataAndCandles[],
|
||||||
parts[1] as MarketCandles[],
|
parts[1] as MarketCandles[],
|
||||||
parts[2] as LiquidityProvisionMarket[]
|
parts[2] as LiquidityProvisionMarket[]
|
||||||
);
|
);
|
||||||
return { markets: data };
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
98
libs/market-list/src/lib/__generated__/market.ts
generated
98
libs/market-list/src/lib/__generated__/market.ts
generated
@ -1,98 +0,0 @@
|
|||||||
import * as Types from '@vegaprotocol/types';
|
|
||||||
|
|
||||||
import { gql } from '@apollo/client';
|
|
||||||
import * as Apollo from '@apollo/client';
|
|
||||||
const defaultOptions = {} as const;
|
|
||||||
export type SingleMarketFieldsFragment = { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', quoteName: string, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string }, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any }, depth: { __typename?: 'MarketDepth', lastTrade?: { __typename?: 'Trade', price: string } | null } };
|
|
||||||
|
|
||||||
export type MarketQueryVariables = Types.Exact<{
|
|
||||||
marketId: Types.Scalars['ID'];
|
|
||||||
}>;
|
|
||||||
|
|
||||||
|
|
||||||
export type MarketQuery = { __typename?: 'Query', market?: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', quoteName: string, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string }, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any }, depth: { __typename?: 'MarketDepth', lastTrade?: { __typename?: 'Trade', price: string } | null } } | null };
|
|
||||||
|
|
||||||
export const SingleMarketFieldsFragmentDoc = gql`
|
|
||||||
fragment SingleMarketFields on Market {
|
|
||||||
id
|
|
||||||
decimalPlaces
|
|
||||||
positionDecimalPlaces
|
|
||||||
state
|
|
||||||
tradingMode
|
|
||||||
fees {
|
|
||||||
factors {
|
|
||||||
makerFee
|
|
||||||
infrastructureFee
|
|
||||||
liquidityFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tradableInstrument {
|
|
||||||
instrument {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
code
|
|
||||||
metadata {
|
|
||||||
tags
|
|
||||||
}
|
|
||||||
product {
|
|
||||||
... on Future {
|
|
||||||
dataSourceSpecForTradingTermination {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
settlementAsset {
|
|
||||||
id
|
|
||||||
symbol
|
|
||||||
name
|
|
||||||
decimals
|
|
||||||
}
|
|
||||||
quoteName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
marketTimestamps {
|
|
||||||
open
|
|
||||||
close
|
|
||||||
}
|
|
||||||
depth {
|
|
||||||
lastTrade {
|
|
||||||
price
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
export const MarketDocument = gql`
|
|
||||||
query Market($marketId: ID!) {
|
|
||||||
market(id: $marketId) {
|
|
||||||
...SingleMarketFields
|
|
||||||
}
|
|
||||||
}
|
|
||||||
${SingleMarketFieldsFragmentDoc}`;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* __useMarketQuery__
|
|
||||||
*
|
|
||||||
* To run a query within a React component, call `useMarketQuery` and pass it any options that fit your needs.
|
|
||||||
* When your component renders, `useMarketQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
|
||||||
* you can use to render your UI.
|
|
||||||
*
|
|
||||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* const { data, loading, error } = useMarketQuery({
|
|
||||||
* variables: {
|
|
||||||
* marketId: // value for 'marketId'
|
|
||||||
* },
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
export function useMarketQuery(baseOptions: Apollo.QueryHookOptions<MarketQuery, MarketQueryVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return Apollo.useQuery<MarketQuery, MarketQueryVariables>(MarketDocument, options);
|
|
||||||
}
|
|
||||||
export function useMarketLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<MarketQuery, MarketQueryVariables>) {
|
|
||||||
const options = {...defaultOptions, ...baseOptions}
|
|
||||||
return Apollo.useLazyQuery<MarketQuery, MarketQueryVariables>(MarketDocument, options);
|
|
||||||
}
|
|
||||||
export type MarketQueryHookResult = ReturnType<typeof useMarketQuery>;
|
|
||||||
export type MarketLazyQueryHookResult = ReturnType<typeof useMarketLazyQuery>;
|
|
||||||
export type MarketQueryResult = Apollo.QueryResult<MarketQuery, MarketQueryVariables>;
|
|
@ -3,12 +3,12 @@ import * as Types from '@vegaprotocol/types';
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
import * as Apollo from '@apollo/client';
|
import * as Apollo from '@apollo/client';
|
||||||
const defaultOptions = {} as const;
|
const defaultOptions = {} as const;
|
||||||
export type MarketFieldsFragment = { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, decimals: number } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } };
|
export type MarketFieldsFragment = { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } };
|
||||||
|
|
||||||
export type MarketsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
export type MarketsQueryVariables = Types.Exact<{ [key: string]: never; }>;
|
||||||
|
|
||||||
|
|
||||||
export type MarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, decimals: number } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } } }> } | null };
|
export type MarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, decimalPlaces: number, positionDecimalPlaces: number, state: Types.MarketState, tradingMode: Types.MarketTradingMode, fees: { __typename?: 'Fees', factors: { __typename?: 'FeeFactors', makerFee: string, infrastructureFee: string, liquidityFee: string } }, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', id: string, name: string, code: string, metadata: { __typename?: 'InstrumentMetadata', tags?: Array<string> | null }, product: { __typename?: 'Future', quoteName: string, settlementAsset: { __typename?: 'Asset', id: string, symbol: string, name: string, decimals: number }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string } } } }, marketTimestamps: { __typename?: 'MarketTimestamps', open: any, close: any } } }> } | null };
|
||||||
|
|
||||||
export const MarketFieldsFragmentDoc = gql`
|
export const MarketFieldsFragmentDoc = gql`
|
||||||
fragment MarketFields on Market {
|
fragment MarketFields on Market {
|
||||||
@ -37,9 +37,13 @@ export const MarketFieldsFragmentDoc = gql`
|
|||||||
settlementAsset {
|
settlementAsset {
|
||||||
id
|
id
|
||||||
symbol
|
symbol
|
||||||
|
name
|
||||||
decimals
|
decimals
|
||||||
}
|
}
|
||||||
quoteName
|
quoteName
|
||||||
|
dataSourceSpecForTradingTermination {
|
||||||
|
id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import { AgGridDynamic as AgGrid, ButtonLink } from '@vegaprotocol/ui-toolkit';
|
|||||||
import { AgGridColumn } from 'ag-grid-react';
|
import { AgGridColumn } from 'ag-grid-react';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import type { MarketFieldsFragment, MarketWithData } from '../../';
|
import type { MarketMaybeWithData, MarketFieldsFragment } from '../../';
|
||||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||||
|
|
||||||
const { MarketTradingMode, AuctionTrigger } = Schema;
|
const { MarketTradingMode, AuctionTrigger } = Schema;
|
||||||
@ -24,7 +24,7 @@ export const getRowId = ({ data }: { data: { id: string } }) => data.id;
|
|||||||
|
|
||||||
export const MarketListTable = forwardRef<
|
export const MarketListTable = forwardRef<
|
||||||
AgGridReact,
|
AgGridReact,
|
||||||
TypedDataAgGrid<MarketWithData>
|
TypedDataAgGrid<MarketMaybeWithData>
|
||||||
>((props, ref) => {
|
>((props, ref) => {
|
||||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||||
return (
|
return (
|
||||||
@ -51,7 +51,7 @@ export const MarketListTable = forwardRef<
|
|||||||
value,
|
value,
|
||||||
data,
|
data,
|
||||||
}: VegaICellRendererParams<
|
}: VegaICellRendererParams<
|
||||||
MarketWithData,
|
MarketMaybeWithData,
|
||||||
'tradableInstrument.instrument.code'
|
'tradableInstrument.instrument.code'
|
||||||
>) => {
|
>) => {
|
||||||
if (!data) return null;
|
if (!data) return null;
|
||||||
@ -68,7 +68,7 @@ export const MarketListTable = forwardRef<
|
|||||||
minWidth={170}
|
minWidth={170}
|
||||||
valueGetter={({
|
valueGetter={({
|
||||||
data,
|
data,
|
||||||
}: VegaValueGetterParams<MarketWithData, 'data'>) => {
|
}: VegaValueGetterParams<MarketMaybeWithData, 'data'>) => {
|
||||||
if (!data?.data) return undefined;
|
if (!data?.data) return undefined;
|
||||||
const { trigger } = data.data;
|
const { trigger } = data.data;
|
||||||
const { tradingMode } = data;
|
const { tradingMode } = data;
|
||||||
@ -98,14 +98,17 @@ export const MarketListTable = forwardRef<
|
|||||||
filter="agNumberColumnFilter"
|
filter="agNumberColumnFilter"
|
||||||
valueGetter={({
|
valueGetter={({
|
||||||
data,
|
data,
|
||||||
}: VegaValueGetterParams<MarketWithData, 'data.bestBidPrice'>) => {
|
}: VegaValueGetterParams<MarketMaybeWithData, 'data.bestBidPrice'>) => {
|
||||||
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();
|
||||||
}}
|
}}
|
||||||
valueFormatter={({
|
valueFormatter={({
|
||||||
data,
|
data,
|
||||||
}: VegaValueFormatterParams<MarketWithData, 'data.bestBidPrice'>) =>
|
}: VegaValueFormatterParams<
|
||||||
|
MarketMaybeWithData,
|
||||||
|
'data.bestBidPrice'
|
||||||
|
>) =>
|
||||||
data?.data?.bestBidPrice === undefined
|
data?.data?.bestBidPrice === undefined
|
||||||
? undefined
|
? undefined
|
||||||
: addDecimalsFormatNumber(
|
: addDecimalsFormatNumber(
|
||||||
@ -122,7 +125,10 @@ export const MarketListTable = forwardRef<
|
|||||||
filter="agNumberColumnFilter"
|
filter="agNumberColumnFilter"
|
||||||
valueGetter={({
|
valueGetter={({
|
||||||
data,
|
data,
|
||||||
}: VegaValueGetterParams<MarketWithData, 'data.bestOfferPrice'>) => {
|
}: VegaValueGetterParams<
|
||||||
|
MarketMaybeWithData,
|
||||||
|
'data.bestOfferPrice'
|
||||||
|
>) => {
|
||||||
return data?.data?.bestOfferPrice === undefined
|
return data?.data?.bestOfferPrice === undefined
|
||||||
? undefined
|
? undefined
|
||||||
: toBigNum(
|
: toBigNum(
|
||||||
@ -132,7 +138,10 @@ export const MarketListTable = forwardRef<
|
|||||||
}}
|
}}
|
||||||
valueFormatter={({
|
valueFormatter={({
|
||||||
data,
|
data,
|
||||||
}: VegaValueFormatterParams<MarketWithData, 'data.bestOfferPrice'>) =>
|
}: VegaValueFormatterParams<
|
||||||
|
MarketMaybeWithData,
|
||||||
|
'data.bestOfferPrice'
|
||||||
|
>) =>
|
||||||
data?.data?.bestOfferPrice === undefined
|
data?.data?.bestOfferPrice === undefined
|
||||||
? undefined
|
? undefined
|
||||||
: addDecimalsFormatNumber(
|
: addDecimalsFormatNumber(
|
||||||
@ -149,14 +158,14 @@ export const MarketListTable = forwardRef<
|
|||||||
filter="agNumberColumnFilter"
|
filter="agNumberColumnFilter"
|
||||||
valueGetter={({
|
valueGetter={({
|
||||||
data,
|
data,
|
||||||
}: VegaValueGetterParams<MarketWithData, 'data.markPrice'>) => {
|
}: VegaValueGetterParams<MarketMaybeWithData, 'data.markPrice'>) => {
|
||||||
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();
|
||||||
}}
|
}}
|
||||||
valueFormatter={({
|
valueFormatter={({
|
||||||
data,
|
data,
|
||||||
}: VegaValueFormatterParams<MarketWithData, 'data.markPrice'>) =>
|
}: VegaValueFormatterParams<MarketMaybeWithData, 'data.markPrice'>) =>
|
||||||
data?.data?.bestOfferPrice === undefined
|
data?.data?.bestOfferPrice === undefined
|
||||||
? undefined
|
? undefined
|
||||||
: addDecimalsFormatNumber(data.data.markPrice, data.decimalPlaces)
|
: addDecimalsFormatNumber(data.data.markPrice, data.decimalPlaces)
|
||||||
@ -168,7 +177,7 @@ export const MarketListTable = forwardRef<
|
|||||||
cellRenderer={({
|
cellRenderer={({
|
||||||
value,
|
value,
|
||||||
}: VegaICellRendererParams<
|
}: VegaICellRendererParams<
|
||||||
MarketWithData,
|
MarketMaybeWithData,
|
||||||
'tradableInstrument.instrument.product.settlementAsset'
|
'tradableInstrument.instrument.product.settlementAsset'
|
||||||
>) =>
|
>) =>
|
||||||
value ? (
|
value ? (
|
||||||
|
@ -4,13 +4,13 @@ import { MarketListTable } from './market-list-table';
|
|||||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||||
import type { RowClickedEvent } from 'ag-grid-community';
|
import type { RowClickedEvent } from 'ag-grid-community';
|
||||||
import { marketsWithDataProvider as dataProvider } from '../../markets-provider';
|
import { marketsWithDataProvider as dataProvider } from '../../markets-provider';
|
||||||
import type { MarketWithData } from '../../markets-provider';
|
import type { MarketMaybeWithData } from '../../markets-provider';
|
||||||
interface MarketsContainerProps {
|
interface MarketsContainerProps {
|
||||||
onSelect: (marketId: string) => void;
|
onSelect: (marketId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
||||||
const { data, error, loading } = useDataProvider<MarketWithData[], never>({
|
const { data, error, loading } = useDataProvider({
|
||||||
dataProvider,
|
dataProvider,
|
||||||
skipUpdates: true,
|
skipUpdates: true,
|
||||||
});
|
});
|
||||||
@ -27,7 +27,7 @@ export const MarketsContainer = ({ onSelect }: MarketsContainerProps) => {
|
|||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onSelect((data as MarketWithData).id);
|
onSelect((data as MarketMaybeWithData).id);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="pointer-events-none absolute inset-0">
|
<div className="pointer-events-none absolute inset-0">
|
||||||
|
@ -3,13 +3,11 @@ export * from './utils';
|
|||||||
export { marketCandlesProvider } from './market-candles-provider';
|
export { marketCandlesProvider } from './market-candles-provider';
|
||||||
export type { Candle } from './market-candles-provider';
|
export type { Candle } from './market-candles-provider';
|
||||||
export * from './market-data-provider';
|
export * from './market-data-provider';
|
||||||
export * from './market-provider';
|
|
||||||
export * from './markets-candles-provider';
|
export * from './markets-candles-provider';
|
||||||
export * from './markets-data-provider';
|
export * from './markets-data-provider';
|
||||||
export * from './markets-provider';
|
export * from './markets-provider';
|
||||||
export * from './__generated__/market-candles';
|
export * from './__generated__/market-candles';
|
||||||
export * from './__generated__/market-data';
|
export * from './__generated__/market-data';
|
||||||
export * from './__generated__/market';
|
|
||||||
export * from './__generated__/markets';
|
export * from './__generated__/markets';
|
||||||
export * from './__generated__/markets-candles';
|
export * from './__generated__/markets-candles';
|
||||||
export * from './__generated__/markets-data';
|
export * from './__generated__/markets-data';
|
||||||
|
@ -54,6 +54,7 @@ export const marketDataProvider = makeDataProvider<
|
|||||||
export type StaticMarketData = Pick<
|
export type StaticMarketData = Pick<
|
||||||
MarketData,
|
MarketData,
|
||||||
| 'marketTradingMode'
|
| 'marketTradingMode'
|
||||||
|
| 'marketState'
|
||||||
| 'auctionStart'
|
| 'auctionStart'
|
||||||
| 'auctionEnd'
|
| 'auctionEnd'
|
||||||
| 'indicativePrice'
|
| 'indicativePrice'
|
||||||
@ -73,6 +74,7 @@ export const staticMarketDataProvider = makeDerivedDataProvider<
|
|||||||
}
|
}
|
||||||
const data: StaticMarketData = {
|
const data: StaticMarketData = {
|
||||||
marketTradingMode: marketData.marketTradingMode,
|
marketTradingMode: marketData.marketTradingMode,
|
||||||
|
marketState: marketData.marketState,
|
||||||
auctionStart: marketData.auctionStart,
|
auctionStart: marketData.auctionStart,
|
||||||
auctionEnd: marketData.auctionEnd,
|
auctionEnd: marketData.auctionEnd,
|
||||||
indicativePrice: marketData.indicativePrice,
|
indicativePrice: marketData.indicativePrice,
|
||||||
@ -91,10 +93,9 @@ export const staticMarketDataProvider = makeDerivedDataProvider<
|
|||||||
|
|
||||||
export const useStaticMarketData = (marketId?: string, skip?: boolean) => {
|
export const useStaticMarketData = (marketId?: string, skip?: boolean) => {
|
||||||
const variables = useMemo(() => ({ marketId }), [marketId]);
|
const variables = useMemo(() => ({ marketId }), [marketId]);
|
||||||
const { data } = useDataProvider({
|
return useDataProvider({
|
||||||
dataProvider: staticMarketDataProvider,
|
dataProvider: staticMarketDataProvider,
|
||||||
variables,
|
variables,
|
||||||
skip: skip || !marketId,
|
skip: skip || !marketId,
|
||||||
});
|
});
|
||||||
return data;
|
|
||||||
};
|
};
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
import {
|
|
||||||
makeDataProvider,
|
|
||||||
makeDerivedDataProvider,
|
|
||||||
} from '@vegaprotocol/react-helpers';
|
|
||||||
import { MarketDocument } from './__generated__/market';
|
|
||||||
import type {
|
|
||||||
MarketQuery,
|
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
} from './__generated__/market';
|
|
||||||
import type { MarketData } from './market-data-provider';
|
|
||||||
import { marketDataProvider } from './market-data-provider';
|
|
||||||
|
|
||||||
const getData = (
|
|
||||||
responseData: MarketQuery | null
|
|
||||||
): SingleMarketFieldsFragment | null => responseData?.market || null;
|
|
||||||
|
|
||||||
export const marketProvider = makeDataProvider<
|
|
||||||
MarketQuery,
|
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
never,
|
|
||||||
never
|
|
||||||
>({
|
|
||||||
query: MarketDocument,
|
|
||||||
getData,
|
|
||||||
});
|
|
||||||
|
|
||||||
export type MarketDealTicket = SingleMarketFieldsFragment & {
|
|
||||||
data: MarketData;
|
|
||||||
};
|
|
||||||
export type MarketDealTicketAsset =
|
|
||||||
MarketDealTicket['tradableInstrument']['instrument']['product']['settlementAsset'];
|
|
||||||
|
|
||||||
export const marketDealTicketProvider = makeDerivedDataProvider<
|
|
||||||
MarketDealTicket,
|
|
||||||
never
|
|
||||||
>([marketProvider, marketDataProvider], ([market, marketData]) => {
|
|
||||||
return {
|
|
||||||
...market,
|
|
||||||
data: marketData,
|
|
||||||
};
|
|
||||||
});
|
|
@ -1,53 +0,0 @@
|
|||||||
fragment SingleMarketFields on Market {
|
|
||||||
id
|
|
||||||
decimalPlaces
|
|
||||||
positionDecimalPlaces
|
|
||||||
state
|
|
||||||
tradingMode
|
|
||||||
fees {
|
|
||||||
factors {
|
|
||||||
makerFee
|
|
||||||
infrastructureFee
|
|
||||||
liquidityFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tradableInstrument {
|
|
||||||
instrument {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
code
|
|
||||||
metadata {
|
|
||||||
tags
|
|
||||||
}
|
|
||||||
product {
|
|
||||||
... on Future {
|
|
||||||
dataSourceSpecForTradingTermination {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
settlementAsset {
|
|
||||||
id
|
|
||||||
symbol
|
|
||||||
name
|
|
||||||
decimals
|
|
||||||
}
|
|
||||||
quoteName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
marketTimestamps {
|
|
||||||
open
|
|
||||||
close
|
|
||||||
}
|
|
||||||
depth {
|
|
||||||
lastTrade {
|
|
||||||
price
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
query Market($marketId: ID!) {
|
|
||||||
market(id: $marketId) {
|
|
||||||
...SingleMarketFields
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
import merge from 'lodash/merge';
|
|
||||||
import * as Schema from '@vegaprotocol/types';
|
|
||||||
import type { PartialDeep } from 'type-fest';
|
|
||||||
import type {
|
|
||||||
MarketQuery,
|
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
} from './__generated__/market';
|
|
||||||
|
|
||||||
export const marketQuery = (
|
|
||||||
override?: PartialDeep<MarketQuery>
|
|
||||||
): MarketQuery => {
|
|
||||||
const defaultResult: MarketQuery = {
|
|
||||||
__typename: 'Query',
|
|
||||||
market: Object.assign({}, singleMarketFieldsFragment),
|
|
||||||
};
|
|
||||||
return merge(Object.assign({}, defaultResult), override);
|
|
||||||
};
|
|
||||||
|
|
||||||
const singleMarketFieldsFragment: SingleMarketFieldsFragment = {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'market-0',
|
|
||||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
state: Schema.MarketState.STATE_ACTIVE,
|
|
||||||
decimalPlaces: 5,
|
|
||||||
positionDecimalPlaces: 0,
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
id: 'BTCUSD.MF21',
|
|
||||||
name: 'ACTIVE MARKET',
|
|
||||||
code: 'BTCUSD.MF21',
|
|
||||||
metadata: {
|
|
||||||
tags: [
|
|
||||||
'formerly:076BB86A5AA41E3E',
|
|
||||||
'base:BTC',
|
|
||||||
'quote:USD',
|
|
||||||
'class:fx/crypto',
|
|
||||||
'monthly',
|
|
||||||
'sector:crypto',
|
|
||||||
],
|
|
||||||
__typename: 'InstrumentMetadata',
|
|
||||||
},
|
|
||||||
product: {
|
|
||||||
dataSourceSpecForTradingTermination: {
|
|
||||||
id: 'd253c16c6a17ab88e098479635c611ab503582a1079752d1a49ac15f656f7e7b',
|
|
||||||
__typename: 'DataSourceSpec',
|
|
||||||
},
|
|
||||||
quoteName: 'BTC',
|
|
||||||
settlementAsset: {
|
|
||||||
decimals: 5,
|
|
||||||
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
|
|
||||||
symbol: 'tBTC',
|
|
||||||
name: 'tBTC TEST',
|
|
||||||
__typename: 'Asset',
|
|
||||||
},
|
|
||||||
__typename: 'Future',
|
|
||||||
},
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
marketTimestamps: {
|
|
||||||
open: '2022-06-21T17:18:43.484055236Z',
|
|
||||||
close: null,
|
|
||||||
__typename: 'MarketTimestamps',
|
|
||||||
},
|
|
||||||
fees: {
|
|
||||||
__typename: 'Fees',
|
|
||||||
factors: {
|
|
||||||
__typename: 'FeeFactors',
|
|
||||||
makerFee: '0.0002',
|
|
||||||
infrastructureFee: '0.0005',
|
|
||||||
liquidityFee: '0.0005',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
depth: {
|
|
||||||
__typename: 'MarketDepth',
|
|
||||||
lastTrade: { price: '100', __typename: 'Trade' },
|
|
||||||
},
|
|
||||||
};
|
|
@ -9,6 +9,7 @@ import type {
|
|||||||
MarketFieldsFragment,
|
MarketFieldsFragment,
|
||||||
} from './__generated__/markets';
|
} from './__generated__/markets';
|
||||||
import { marketsDataProvider } from './markets-data-provider';
|
import { marketsDataProvider } from './markets-data-provider';
|
||||||
|
import { marketDataProvider } from './market-data-provider';
|
||||||
import { marketsCandlesProvider } from './markets-candles-provider';
|
import { marketsCandlesProvider } from './markets-candles-provider';
|
||||||
import type { MarketData } from './market-data-provider';
|
import type { MarketData } from './market-data-provider';
|
||||||
import type { MarketCandles } from './markets-candles-provider';
|
import type { MarketCandles } from './markets-candles-provider';
|
||||||
@ -35,7 +36,7 @@ export const marketsProvider = makeDataProvider<
|
|||||||
fetchPolicy: 'cache-first',
|
fetchPolicy: 'cache-first',
|
||||||
});
|
});
|
||||||
|
|
||||||
const marketProvider = makeDerivedDataProvider<
|
export const marketProvider = makeDerivedDataProvider<
|
||||||
Market,
|
Market,
|
||||||
never,
|
never,
|
||||||
{ marketId: string }
|
{ marketId: string }
|
||||||
@ -49,20 +50,31 @@ const marketProvider = makeDerivedDataProvider<
|
|||||||
|
|
||||||
export const useMarket = (marketId?: string) => {
|
export const useMarket = (marketId?: string) => {
|
||||||
const variables = useMemo(() => ({ marketId: marketId || '' }), [marketId]);
|
const variables = useMemo(() => ({ marketId: marketId || '' }), [marketId]);
|
||||||
const { data } = useDataProvider({
|
return useDataProvider({
|
||||||
dataProvider: marketProvider,
|
dataProvider: marketProvider,
|
||||||
variables,
|
variables,
|
||||||
skip: !marketId,
|
skip: !marketId,
|
||||||
});
|
});
|
||||||
return data;
|
|
||||||
};
|
};
|
||||||
|
export type MarketWithData = Market & { data: MarketData };
|
||||||
|
|
||||||
|
export const marketWithDataProvider = makeDerivedDataProvider<
|
||||||
|
MarketWithData,
|
||||||
|
never,
|
||||||
|
{ marketId: string }
|
||||||
|
>([marketProvider, marketDataProvider], ([market, marketData]) => {
|
||||||
|
return {
|
||||||
|
...market,
|
||||||
|
data: marketData,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
export const activeMarketsProvider = makeDerivedDataProvider<Market[], never>(
|
export const activeMarketsProvider = makeDerivedDataProvider<Market[], never>(
|
||||||
[marketsProvider],
|
[marketsProvider],
|
||||||
([markets]) => filterAndSortMarkets(markets)
|
([markets]) => filterAndSortMarkets(markets)
|
||||||
);
|
);
|
||||||
|
|
||||||
export type MarketWithCandles = Market & { candles?: Candle[] };
|
export type MarketMaybeWithCandles = Market & { candles?: Candle[] };
|
||||||
|
|
||||||
const addCandles = <T extends Market>(
|
const addCandles = <T extends Market>(
|
||||||
markets: T[],
|
markets: T[],
|
||||||
@ -75,7 +87,7 @@ const addCandles = <T extends Market>(
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
export const marketsWithCandlesProvider = makeDerivedDataProvider<
|
export const marketsWithCandlesProvider = makeDerivedDataProvider<
|
||||||
MarketWithCandles[],
|
MarketMaybeWithCandles[],
|
||||||
never
|
never
|
||||||
>(
|
>(
|
||||||
[
|
[
|
||||||
@ -85,7 +97,7 @@ export const marketsWithCandlesProvider = makeDerivedDataProvider<
|
|||||||
(parts) => addCandles(parts[0] as Market[], parts[1] as MarketCandles[])
|
(parts) => addCandles(parts[0] as Market[], parts[1] as MarketCandles[])
|
||||||
);
|
);
|
||||||
|
|
||||||
export type MarketWithData = Market & { data?: MarketData };
|
export type MarketMaybeWithData = Market & { data?: MarketData };
|
||||||
|
|
||||||
const addData = <T extends Market>(markets: T[], marketsData: MarketData[]) =>
|
const addData = <T extends Market>(markets: T[], marketsData: MarketData[]) =>
|
||||||
markets.map((market) => ({
|
markets.map((market) => ({
|
||||||
@ -94,14 +106,17 @@ const addData = <T extends Market>(markets: T[], marketsData: MarketData[]) =>
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
export const marketsWithDataProvider = makeDerivedDataProvider<
|
export const marketsWithDataProvider = makeDerivedDataProvider<
|
||||||
MarketWithData[],
|
MarketMaybeWithData[],
|
||||||
never
|
never
|
||||||
>([activeMarketsProvider, marketsDataProvider], (parts) =>
|
>([activeMarketsProvider, marketsDataProvider], (parts) =>
|
||||||
addData(parts[0] as Market[], parts[1] as MarketData[])
|
addData(parts[0] as Market[], parts[1] as MarketData[])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export type MarketMaybeWithDataAndCandles = MarketMaybeWithData &
|
||||||
|
MarketMaybeWithCandles;
|
||||||
|
|
||||||
export const marketListProvider = makeDerivedDataProvider<
|
export const marketListProvider = makeDerivedDataProvider<
|
||||||
(MarketWithData & MarketWithCandles)[],
|
MarketMaybeWithDataAndCandles[],
|
||||||
never
|
never
|
||||||
>(
|
>(
|
||||||
[
|
[
|
||||||
@ -109,7 +124,7 @@ export const marketListProvider = makeDerivedDataProvider<
|
|||||||
marketsCandlesProvider,
|
marketsCandlesProvider,
|
||||||
],
|
],
|
||||||
(parts) =>
|
(parts) =>
|
||||||
addCandles(parts[0] as MarketWithCandles[], parts[1] as MarketCandles[])
|
addCandles(parts[0] as MarketMaybeWithData[], parts[1] as MarketCandles[])
|
||||||
);
|
);
|
||||||
|
|
||||||
export const useMarketList = () => {
|
export const useMarketList = () => {
|
||||||
|
@ -24,9 +24,13 @@ fragment MarketFields on Market {
|
|||||||
settlementAsset {
|
settlementAsset {
|
||||||
id
|
id
|
||||||
symbol
|
symbol
|
||||||
|
name
|
||||||
decimals
|
decimals
|
||||||
}
|
}
|
||||||
quoteName
|
quoteName
|
||||||
|
dataSourceSpecForTradingTermination {
|
||||||
|
id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,8 @@ const marketFieldsFragments: MarketFieldsFragment[] = [
|
|||||||
state: Schema.MarketState.STATE_ACTIVE,
|
state: Schema.MarketState.STATE_ACTIVE,
|
||||||
marketTimestamps: {
|
marketTimestamps: {
|
||||||
__typename: 'MarketTimestamps',
|
__typename: 'MarketTimestamps',
|
||||||
close: '',
|
close: null,
|
||||||
open: '',
|
open: null,
|
||||||
},
|
},
|
||||||
fees: {
|
fees: {
|
||||||
__typename: 'Fees',
|
__typename: 'Fees',
|
||||||
@ -56,9 +56,13 @@ const marketFieldsFragments: MarketFieldsFragment[] = [
|
|||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'asset-0',
|
id: 'asset-0',
|
||||||
symbol: 'tDAI',
|
symbol: 'tDAI',
|
||||||
|
name: 'tDAI',
|
||||||
decimals: 5,
|
decimals: 5,
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
},
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: 'oracleId',
|
||||||
|
},
|
||||||
quoteName: 'DAI',
|
quoteName: 'DAI',
|
||||||
__typename: 'Future',
|
__typename: 'Future',
|
||||||
},
|
},
|
||||||
@ -101,9 +105,13 @@ const marketFieldsFragments: MarketFieldsFragment[] = [
|
|||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'asset-1',
|
id: 'asset-1',
|
||||||
symbol: 'XYZalpha',
|
symbol: 'XYZalpha',
|
||||||
|
name: 'XYZalpha',
|
||||||
decimals: 5,
|
decimals: 5,
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
},
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: 'oracleId',
|
||||||
|
},
|
||||||
quoteName: 'USD',
|
quoteName: 'USD',
|
||||||
__typename: 'Future',
|
__typename: 'Future',
|
||||||
},
|
},
|
||||||
@ -145,10 +153,14 @@ const marketFieldsFragments: MarketFieldsFragment[] = [
|
|||||||
product: {
|
product: {
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'asset-2',
|
id: 'asset-2',
|
||||||
|
name: '',
|
||||||
symbol: 'tUSDC',
|
symbol: 'tUSDC',
|
||||||
decimals: 5,
|
decimals: 5,
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
},
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: 'oracleId',
|
||||||
|
},
|
||||||
quoteName: 'USDC',
|
quoteName: 'USDC',
|
||||||
__typename: 'Future',
|
__typename: 'Future',
|
||||||
},
|
},
|
||||||
@ -191,9 +203,13 @@ const marketFieldsFragments: MarketFieldsFragment[] = [
|
|||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
id: 'asset-3',
|
id: 'asset-3',
|
||||||
symbol: 'tBTC',
|
symbol: 'tBTC',
|
||||||
|
name: '',
|
||||||
decimals: 5,
|
decimals: 5,
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
},
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: 'oracleId',
|
||||||
|
},
|
||||||
quoteName: 'BTC',
|
quoteName: 'BTC',
|
||||||
__typename: 'Future',
|
__typename: 'Future',
|
||||||
},
|
},
|
||||||
|
@ -46,6 +46,10 @@ export const generateOrder = (partialOrder?: PartialDeep<Order>) => {
|
|||||||
id: 'asset-id',
|
id: 'asset-id',
|
||||||
decimals: 1,
|
decimals: 1,
|
||||||
symbol: 'XYZ',
|
symbol: 'XYZ',
|
||||||
|
name: 'XYZ',
|
||||||
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: '',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -10,31 +10,7 @@ import { OrderSubDocument } from './';
|
|||||||
import type { MockedResponse } from '@apollo/client/testing';
|
import type { MockedResponse } from '@apollo/client/testing';
|
||||||
import { MockedProvider } from '@apollo/client/testing';
|
import { MockedProvider } from '@apollo/client/testing';
|
||||||
|
|
||||||
const defaultMarket = {
|
const marketId = 'market-id';
|
||||||
__typename: 'Market',
|
|
||||||
id: 'market-id',
|
|
||||||
decimalPlaces: 2,
|
|
||||||
positionDecimalPlaces: 1,
|
|
||||||
tradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
|
|
||||||
state: Schema.MarketState.STATE_ACTIVE,
|
|
||||||
tradableInstrument: {
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
instrument: {
|
|
||||||
__typename: 'Instrument',
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
quoteName: 'quote-name',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
depth: {
|
|
||||||
__typename: 'MarketDepth',
|
|
||||||
lastTrade: {
|
|
||||||
__typename: 'Trade',
|
|
||||||
price: '100',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultWalletContext = {
|
const defaultWalletContext = {
|
||||||
pubKey: null,
|
pubKey: null,
|
||||||
@ -135,13 +111,13 @@ describe('useOrderSubmit', () => {
|
|||||||
expiresAt: new Date('2022-01-01').toISOString(),
|
expiresAt: new Date('2022-01-01').toISOString(),
|
||||||
};
|
};
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
result.current.submit({ ...order, marketId: defaultMarket.id });
|
result.current.submit({ ...order, marketId });
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(mockSendTx).toHaveBeenCalledWith(pubKey, {
|
expect(mockSendTx).toHaveBeenCalledWith(pubKey, {
|
||||||
orderSubmission: {
|
orderSubmission: {
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
type: Schema.OrderType.TYPE_LIMIT,
|
||||||
marketId: defaultMarket.id,
|
marketId,
|
||||||
size: '10',
|
size: '10',
|
||||||
side: Schema.Side.SIDE_BUY,
|
side: Schema.Side.SIDE_BUY,
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTT,
|
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTT,
|
||||||
@ -172,13 +148,13 @@ describe('useOrderSubmit', () => {
|
|||||||
expiresAt: new Date('2022-01-01').toISOString(),
|
expiresAt: new Date('2022-01-01').toISOString(),
|
||||||
};
|
};
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
result.current.submit({ ...order, marketId: defaultMarket.id });
|
result.current.submit({ ...order, marketId });
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(mockSendTx).toHaveBeenCalledWith(publicKeyObj.publicKey, {
|
expect(mockSendTx).toHaveBeenCalledWith(publicKeyObj.publicKey, {
|
||||||
orderSubmission: {
|
orderSubmission: {
|
||||||
type: Schema.OrderType.TYPE_LIMIT,
|
type: Schema.OrderType.TYPE_LIMIT,
|
||||||
marketId: defaultMarket.id,
|
marketId,
|
||||||
size: '10',
|
size: '10',
|
||||||
side: Schema.Side.SIDE_BUY,
|
side: Schema.Side.SIDE_BUY,
|
||||||
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
timeInForce: Schema.OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import type {
|
import type { MarketData, Market } from '@vegaprotocol/market-list';
|
||||||
MarketDataFieldsFragment,
|
|
||||||
SingleMarketFieldsFragment,
|
|
||||||
} from '@vegaprotocol/market-list';
|
|
||||||
import type { Order } from '@vegaprotocol/orders';
|
import type { Order } from '@vegaprotocol/orders';
|
||||||
import { timeInForceLabel } from '@vegaprotocol/orders';
|
import { timeInForceLabel } from '@vegaprotocol/orders';
|
||||||
import { addDecimalsFormatNumber, Size, t } from '@vegaprotocol/react-helpers';
|
import { addDecimalsFormatNumber, Size, t } from '@vegaprotocol/react-helpers';
|
||||||
@ -14,8 +11,8 @@ export const ClosingOrder = ({
|
|||||||
marketData,
|
marketData,
|
||||||
}: {
|
}: {
|
||||||
order: IClosingOrder;
|
order: IClosingOrder;
|
||||||
market: SingleMarketFieldsFragment;
|
market: Market;
|
||||||
marketData: MarketDataFieldsFragment;
|
marketData: MarketData;
|
||||||
}) => {
|
}) => {
|
||||||
const asset = market.tradableInstrument.instrument.product.settlementAsset;
|
const asset = market.tradableInstrument.instrument.product.settlementAsset;
|
||||||
const estimatedPrice =
|
const estimatedPrice =
|
||||||
@ -50,7 +47,7 @@ export const ActiveOrders = ({
|
|||||||
market,
|
market,
|
||||||
orders,
|
orders,
|
||||||
}: {
|
}: {
|
||||||
market: SingleMarketFieldsFragment;
|
market: Market;
|
||||||
orders: Order[];
|
orders: Order[];
|
||||||
}) => {
|
}) => {
|
||||||
const asset = market.tradableInstrument.instrument.product.settlementAsset;
|
const asset = market.tradableInstrument.instrument.product.settlementAsset;
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
removePaginationWrapper,
|
removePaginationWrapper,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import type { MarketWithData } from '@vegaprotocol/market-list';
|
import type { MarketMaybeWithData } from '@vegaprotocol/market-list';
|
||||||
import { marketsWithDataProvider } from '@vegaprotocol/market-list';
|
import { marketsWithDataProvider } from '@vegaprotocol/market-list';
|
||||||
import type {
|
import type {
|
||||||
PositionsQuery,
|
PositionsQuery,
|
||||||
@ -36,7 +36,7 @@ interface PositionRejoined {
|
|||||||
unrealisedPNL: string;
|
unrealisedPNL: string;
|
||||||
averageEntryPrice: string;
|
averageEntryPrice: string;
|
||||||
updatedAt?: string | null;
|
updatedAt?: string | null;
|
||||||
market: MarketWithData | null;
|
market: MarketMaybeWithData | null;
|
||||||
margins: PositionMarginLevel | null;
|
margins: PositionMarginLevel | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ const upgradeMarginsConnection = (
|
|||||||
|
|
||||||
export const rejoinPositionData = (
|
export const rejoinPositionData = (
|
||||||
positions: PositionFieldsFragment[] | null,
|
positions: PositionFieldsFragment[] | null,
|
||||||
marketsData: MarketWithData[] | null,
|
marketsData: MarketMaybeWithData[] | null,
|
||||||
margins: MarginFieldsFragment[] | null
|
margins: MarginFieldsFragment[] | null
|
||||||
): PositionRejoined[] | null => {
|
): PositionRejoined[] | null => {
|
||||||
if (positions && marketsData && margins) {
|
if (positions && marketsData && margins) {
|
||||||
|
@ -8,7 +8,10 @@ export const useRequestClosePositionData = (
|
|||||||
marketId?: string,
|
marketId?: string,
|
||||||
partyId?: string
|
partyId?: string
|
||||||
) => {
|
) => {
|
||||||
const marketVariables = useMemo(() => ({ marketId }), [marketId]);
|
const marketVariables = useMemo(
|
||||||
|
() => ({ marketId: marketId || '' }),
|
||||||
|
[marketId]
|
||||||
|
);
|
||||||
const orderVariables = useMemo<OrdersQueryVariables>(
|
const orderVariables = useMemo<OrdersQueryVariables>(
|
||||||
() => ({ partyId: partyId || '' }),
|
() => ({ partyId: partyId || '' }),
|
||||||
[partyId]
|
[partyId]
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { t } from './i18n';
|
import { t } from './i18n';
|
||||||
import { getDateTimeFormat } from './format';
|
import { getDateTimeFormat } from './format';
|
||||||
import { isValid, parseISO } from 'date-fns';
|
import { isValid, parseISO } from 'date-fns';
|
||||||
|
|
||||||
import { MarketState } from '@vegaprotocol/types';
|
import { MarketState } from '@vegaprotocol/types';
|
||||||
|
|
||||||
export const getMarketExpiryDate = (
|
export const getMarketExpiryDate = (
|
||||||
|
@ -123,14 +123,15 @@ mockUseGetWithdrawThreshold.mockReturnValue(() =>
|
|||||||
|
|
||||||
let dateNowSpy: jest.SpyInstance<number, []>;
|
let dateNowSpy: jest.SpyInstance<number, []>;
|
||||||
|
|
||||||
const erc20WithdrawalApproval = {
|
const erc20WithdrawalApproval: WithdrawalApprovalQuery['erc20WithdrawalApproval'] =
|
||||||
assetSource: 'asset-source',
|
{
|
||||||
amount: '100',
|
assetSource: 'asset-source',
|
||||||
nonce: '1',
|
amount: '100',
|
||||||
creation: '1',
|
nonce: '1',
|
||||||
signatures: 'signatures',
|
creation: '1',
|
||||||
targetAddress: 'target-address',
|
signatures: 'signatures',
|
||||||
};
|
targetAddress: 'target-address',
|
||||||
|
};
|
||||||
|
|
||||||
const mockedNetworkParams: MockedResponse<NetworkParamsQuery> = {
|
const mockedNetworkParams: MockedResponse<NetworkParamsQuery> = {
|
||||||
request: {
|
request: {
|
||||||
|
@ -143,9 +143,13 @@ describe('WithdrawFormContainer', () => {
|
|||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
id: 'asset-id',
|
id: 'asset-id',
|
||||||
|
name: 'asset-id',
|
||||||
symbol: 'tUSDC',
|
symbol: 'tUSDC',
|
||||||
decimals: 5,
|
decimals: 5,
|
||||||
},
|
},
|
||||||
|
dataSourceSpecForTradingTermination: {
|
||||||
|
id: '',
|
||||||
|
},
|
||||||
quoteName: 'USD',
|
quoteName: 'USD',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user