fix(trading): remove liquidation from positions & format price bounds with market dp (#3173)

This commit is contained in:
m.ray 2023-03-13 14:17:00 -04:00 committed by GitHub
parent 64cf0c90a7
commit 8f3cf390c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 14 additions and 91 deletions

View File

@ -131,7 +131,6 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
cy.get('p.col-span-1').contains('Within 43,200 seconds'); cy.get('p.col-span-1').contains('Within 43,200 seconds');
validateMarketDataRow(0, 'Highest Price', '7.97323 '); validateMarketDataRow(0, 'Highest Price', '7.97323 ');
validateMarketDataRow(1, 'Lowest Price', '6.54701 '); validateMarketDataRow(1, 'Lowest Price', '6.54701 ');
validateMarketDataRow(2, 'Reference Price', '7.22625 ');
}); });
it('liquidity monitoring parameters displayed', () => { it('liquidity monitoring parameters displayed', () => {

View File

@ -50,7 +50,6 @@ describe('positions', { tags: '@smoke' }, () => {
const emptyCells = [ const emptyCells = [
'notional', 'notional',
'markPrice', 'markPrice',
'liquidationPrice',
'currentLeverage', 'currentLeverage',
'averageEntryPrice', 'averageEntryPrice',
]; ];
@ -162,8 +161,6 @@ describe('positions', { tags: '@smoke' }, () => {
cy.wrap($prices).invoke('text').should('not.be.empty'); cy.wrap($prices).invoke('text').should('not.be.empty');
}); });
cy.get('[col-id="liquidationPrice"]').should('contain.text', '0'); // liquidation price
cy.get('[col-id="currentLeverage"]').should('contain.text', '2.846.1'); cy.get('[col-id="currentLeverage"]').should('contain.text', '2.846.1');
cy.get('[col-id="marginAccountBalance"]') // margin allocated cy.get('[col-id="marginAccountBalance"]') // margin allocated

View File

@ -322,9 +322,8 @@ export const Info = ({ market, onSelect }: InfoProps) => {
data={{ data={{
highestPrice: bounds.maxValidPrice, highestPrice: bounds.maxValidPrice,
lowestPrice: bounds.minValidPrice, lowestPrice: bounds.minValidPrice,
referencePrice: bounds.referencePrice,
}} }}
decimalPlaces={assetDecimals} decimalPlaces={market.decimalPlaces}
assetSymbol={quoteUnit} assetSymbol={quoteUnit}
/> />
)} )}

View File

@ -213,7 +213,6 @@ describe('getMetrics && rejoinPositionData', () => {
expect(metrics[0].marketDecimalPlaces).toEqual(5); expect(metrics[0].marketDecimalPlaces).toEqual(5);
expect(metrics[0].positionDecimalPlaces).toEqual(0); expect(metrics[0].positionDecimalPlaces).toEqual(0);
expect(metrics[0].decimals).toEqual(5); expect(metrics[0].decimals).toEqual(5);
expect(metrics[0].liquidationPrice).toEqual('169990');
expect(metrics[0].lowMarginLevel).toEqual(false); expect(metrics[0].lowMarginLevel).toEqual(false);
expect(metrics[0].markPrice).toEqual('9431775'); expect(metrics[0].markPrice).toEqual('9431775');
expect(metrics[0].marketId).toEqual( expect(metrics[0].marketId).toEqual(
@ -242,7 +241,6 @@ describe('getMetrics && rejoinPositionData', () => {
expect(metrics[1].marketDecimalPlaces).toEqual(5); expect(metrics[1].marketDecimalPlaces).toEqual(5);
expect(metrics[1].positionDecimalPlaces).toEqual(0); expect(metrics[1].positionDecimalPlaces).toEqual(0);
expect(metrics[1].decimals).toEqual(5); expect(metrics[1].decimals).toEqual(5);
expect(metrics[1].liquidationPrice).toEqual('9830750');
expect(metrics[1].lowMarginLevel).toEqual(false); expect(metrics[1].lowMarginLevel).toEqual(false);
expect(metrics[1].markPrice).toEqual('869762'); expect(metrics[1].markPrice).toEqual('869762');
expect(metrics[1].marketId).toEqual( expect(metrics[1].marketId).toEqual(

View File

@ -67,7 +67,6 @@ export interface Position {
positionDecimalPlaces: number; positionDecimalPlaces: number;
totalBalance: string; totalBalance: string;
assetSymbol: string; assetSymbol: string;
liquidationPrice: string | undefined;
lowMarginLevel: boolean; lowMarginLevel: boolean;
marketId: string; marketId: string;
marketTradingMode: Schema.MarketTradingMode; marketTradingMode: Schema.MarketTradingMode;
@ -140,7 +139,6 @@ export const getMetrics = (
? new BigNumber(0) ? new BigNumber(0)
: marginAccountBalance.dividedBy(totalBalance).multipliedBy(100); : marginAccountBalance.dividedBy(totalBalance).multipliedBy(100);
const marginMaintenance = toBigNum(marginLevel.maintenanceLevel, decimals);
const marginSearch = toBigNum(marginLevel.searchLevel, decimals); const marginSearch = toBigNum(marginLevel.searchLevel, decimals);
const marginInitial = toBigNum(marginLevel.initialLevel, decimals); const marginInitial = toBigNum(marginLevel.initialLevel, decimals);
@ -151,17 +149,6 @@ export const getMetrics = (
.plus(markPrice) .plus(markPrice)
: undefined; : undefined;
const liquidationPrice = markPrice
? BigNumber.maximum(
0,
marginMaintenance
.minus(marginAccountBalance)
.minus(generalAccountBalance)
.dividedBy(openVolume)
.plus(markPrice)
)
: undefined;
const lowMarginLevel = const lowMarginLevel =
marginAccountBalance.isLessThan( marginAccountBalance.isLessThan(
marginSearch.plus(marginInitial.minus(marginSearch).dividedBy(2)) marginSearch.plus(marginInitial.minus(marginSearch).dividedBy(2))
@ -180,9 +167,6 @@ export const getMetrics = (
market.tradableInstrument.instrument.product.settlementAsset.symbol, market.tradableInstrument.instrument.product.settlementAsset.symbol,
totalBalance: totalBalance.multipliedBy(10 ** decimals).toFixed(), totalBalance: totalBalance.multipliedBy(10 ** decimals).toFixed(),
lowMarginLevel, lowMarginLevel,
liquidationPrice: liquidationPrice
? liquidationPrice.multipliedBy(10 ** marketDecimalPlaces).toFixed(0)
: undefined,
marketId: market.id, marketId: market.id,
marketTradingMode: market.tradingMode, marketTradingMode: market.tradingMode,
markPrice: marketData ? marketData.markPrice : undefined, markPrice: marketData ? marketData.markPrice : undefined,

View File

@ -17,7 +17,6 @@ const singleRow: Position = {
decimals: 2, decimals: 2,
totalBalance: '123456', totalBalance: '123456',
assetSymbol: 'BTC', assetSymbol: 'BTC',
liquidationPrice: '83',
lowMarginLevel: false, lowMarginLevel: false,
marketId: 'string', marketId: 'string',
marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS, marketTradingMode: Schema.MarketTradingMode.TRADING_MODE_CONTINUOUS,
@ -50,7 +49,7 @@ it('render correct columns', async () => {
}); });
const headers = screen.getAllByRole('columnheader'); const headers = screen.getAllByRole('columnheader');
expect(headers).toHaveLength(12); expect(headers).toHaveLength(11);
expect( expect(
headers.map((h) => h.querySelector('[ref="eText"]')?.textContent?.trim()) headers.map((h) => h.querySelector('[ref="eText"]')?.textContent?.trim())
).toEqual([ ).toEqual([
@ -60,7 +59,6 @@ it('render correct columns', async () => {
'Mark price', 'Mark price',
'Settlement asset', 'Settlement asset',
'Entry price', 'Entry price',
'Liquidation price (est)',
'Leverage', 'Leverage',
'Margin allocated', 'Margin allocated',
'Realised PNL', 'Realised PNL',
@ -146,33 +144,12 @@ it('displays mark price', async () => {
expect(cells[3].textContent).toEqual('-'); expect(cells[3].textContent).toEqual('-');
}); });
it("displays properly entry, liquidation price and liquidation bar and it's intent", async () => {
let result: RenderResult;
await act(async () => {
result = render(
<PositionsTable rowData={singleRowData} isReadOnly={false} />
);
});
let cells = screen.getAllByRole('gridcell');
const entryPrice = cells[5].firstElementChild?.firstElementChild?.textContent;
expect(entryPrice).toEqual('13.3');
await act(async () => {
result.rerender(
<PositionsTable
rowData={[{ ...singleRow, lowMarginLevel: true }]}
isReadOnly={false}
/>
);
});
cells = screen.getAllByRole('gridcell');
});
it('displays leverage', async () => { it('displays leverage', async () => {
await act(async () => { await act(async () => {
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />); render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
}); });
const cells = screen.getAllByRole('gridcell'); const cells = screen.getAllByRole('gridcell');
expect(cells[7].textContent).toEqual('1.1'); expect(cells[6].textContent).toEqual('1.1');
}); });
it('displays allocated margin', async () => { it('displays allocated margin', async () => {
@ -180,7 +157,7 @@ it('displays allocated margin', async () => {
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />); render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
}); });
const cells = screen.getAllByRole('gridcell'); const cells = screen.getAllByRole('gridcell');
const cell = cells[8]; const cell = cells[7];
expect(cell.textContent).toEqual('123,456.00'); expect(cell.textContent).toEqual('123,456.00');
}); });
@ -189,8 +166,7 @@ it('displays realised and unrealised PNL', async () => {
render(<PositionsTable rowData={singleRowData} isReadOnly={false} />); render(<PositionsTable rowData={singleRowData} isReadOnly={false} />);
}); });
const cells = screen.getAllByRole('gridcell'); const cells = screen.getAllByRole('gridcell');
expect(cells[9].textContent).toEqual('1.23'); expect(cells[9].textContent).toEqual('4.56');
expect(cells[10].textContent).toEqual('4.56');
}); });
it('displays close button', async () => { it('displays close button', async () => {
@ -206,7 +182,7 @@ it('displays close button', async () => {
); );
}); });
const cells = screen.getAllByRole('gridcell'); const cells = screen.getAllByRole('gridcell');
expect(cells[12].textContent).toEqual('Close'); expect(cells[11].textContent).toEqual('Close');
}); });
it('do not display close button if openVolume is zero', async () => { it('do not display close button if openVolume is zero', async () => {
@ -222,7 +198,7 @@ it('do not display close button if openVolume is zero', async () => {
); );
}); });
const cells = screen.getAllByRole('gridcell'); const cells = screen.getAllByRole('gridcell');
expect(cells[12].textContent).toEqual(''); expect(cells[11].textContent).toEqual('');
}); });
describe('PNLCell', () => { describe('PNLCell', () => {

View File

@ -9,7 +9,9 @@ export default {
title: 'PositionsTable', title: 'PositionsTable',
} as Meta; } as Meta;
const Template: Story = (args) => <PositionsTable {...args} />; const Template: Story = (args) => (
<PositionsTable {...args} isReadOnly={false} />
);
export const Primary = Template.bind({}); export const Primary = Template.bind({});
const longPosition: Position = { const longPosition: Position = {
@ -27,7 +29,6 @@ const longPosition: Position = {
// leverageMaintenance: '0', // leverageMaintenance: '0',
// leverageRelease: '0', // leverageRelease: '0',
// leverageSearch: '0', // leverageSearch: '0',
liquidationPrice: '1129935',
lowMarginLevel: false, lowMarginLevel: false,
marginAccountBalance: new BigNumber('0').toString(), marginAccountBalance: new BigNumber('0').toString(),
// marginMaintenance: '0', // marginMaintenance: '0',
@ -42,6 +43,8 @@ const longPosition: Position = {
unrealisedPNL: '45', unrealisedPNL: '45',
searchPrice: '1132123', searchPrice: '1132123',
updatedAt: '2022-07-27T15:02:58.400Z', updatedAt: '2022-07-27T15:02:58.400Z',
lossSocializationAmount: '0',
status: Schema.PositionStatus.POSITION_STATUS_UNSPECIFIED,
}; };
const shortPosition: Position = { const shortPosition: Position = {
@ -59,7 +62,6 @@ const shortPosition: Position = {
// leverageMaintenance: '0', // leverageMaintenance: '0',
// leverageRelease: '0', // leverageRelease: '0',
// leverageSearch: '0', // leverageSearch: '0',
liquidationPrice: '23734',
lowMarginLevel: false, lowMarginLevel: false,
marginAccountBalance: new BigNumber('0').toString(), marginAccountBalance: new BigNumber('0').toString(),
// marginMaintenance: '0', // marginMaintenance: '0',
@ -74,6 +76,8 @@ const shortPosition: Position = {
unrealisedPNL: '0', unrealisedPNL: '0',
searchPrice: '0', searchPrice: '0',
updatedAt: '2022-07-26T14:01:34.800Z', updatedAt: '2022-07-26T14:01:34.800Z',
lossSocializationAmount: '0',
status: Schema.PositionStatus.POSITION_STATUS_UNSPECIFIED,
}; };
Primary.args = { Primary.args = {

View File

@ -249,40 +249,6 @@ export const PositionsTable = forwardRef<AgGridReact, Props>(
); );
}} }}
/> />
<AgGridColumn
headerName={t('Liquidation price (est)')}
field="liquidationPrice"
type="rightAligned"
cellRendererSelector={(): CellRendererSelectorResult => {
return {
component: PriceFlashCell,
};
}}
filter="agNumberColumnFilter"
valueGetter={({
data,
}: VegaValueGetterParams<Position, 'liquidationPrice'>) => {
return data?.liquidationPrice === undefined || !data
? undefined
: toBigNum(
data.liquidationPrice,
data.marketDecimalPlaces
).toNumber();
}}
valueFormatter={({
data,
}: VegaValueFormatterParams<Position, 'liquidationPrice'>):
| string
| undefined => {
if (!data || data?.liquidationPrice === undefined) {
return undefined;
}
return addDecimalsFormatNumber(
data.liquidationPrice,
data.marketDecimalPlaces
);
}}
/>
<AgGridColumn <AgGridColumn
headerName={t('Leverage')} headerName={t('Leverage')}
field="currentLeverage" field="currentLeverage"