fix(trading): liquidity provision table quantum formatting (#4114)
This commit is contained in:
parent
9441aee8cf
commit
df88e77cdf
@ -81,6 +81,7 @@ describe('liquidity table - trading', { tags: '@smoke' }, () => {
|
|||||||
|
|
||||||
cy.get(rowSelector).first().find(colFee).should('have.text', '0.09%');
|
cy.get(rowSelector).first().find(colFee).should('have.text', '0.09%');
|
||||||
|
|
||||||
|
// 5002-LIQP-013
|
||||||
cy.get(rowSelector)
|
cy.get(rowSelector)
|
||||||
.first()
|
.first()
|
||||||
.find(colAverageEntryValuation)
|
.find(colAverageEntryValuation)
|
||||||
@ -165,7 +166,7 @@ describe('liquidity table view', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can see liquidity supplied', () => {
|
it('can see liquidity supplied', () => {
|
||||||
//// 5002-LIQP-008
|
// 5002-LIQP-008
|
||||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||||
cy.getByTestId('liquidity-supplied').within(() => {
|
cy.getByTestId('liquidity-supplied').within(() => {
|
||||||
cy.getByTestId(itemHeader).should('have.text', 'Liquidity supplied');
|
cy.getByTestId(itemHeader).should('have.text', 'Liquidity supplied');
|
||||||
@ -237,6 +238,7 @@ describe('liquidity table view', { tags: '@smoke' }, () => {
|
|||||||
.find(colFee)
|
.find(colFee)
|
||||||
.should('have.text', '0.09%');
|
.should('have.text', '0.09%');
|
||||||
|
|
||||||
|
// 5002-LIQP-013
|
||||||
cy.get(rowSelectorLiquidityActive)
|
cy.get(rowSelectorLiquidityActive)
|
||||||
.first()
|
.first()
|
||||||
.find(colAverageEntryValuation)
|
.find(colAverageEntryValuation)
|
||||||
@ -268,7 +270,7 @@ describe('liquidity table view', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('renders liquidity inactive table correctly', () => {
|
it('renders liquidity inactive table correctly', () => {
|
||||||
//// 5002-LIQP-012
|
// 5002-LIQP-012
|
||||||
cy.getByTestId('Inactive').click();
|
cy.getByTestId('Inactive').click();
|
||||||
cy.get(rowSelectorLiquidityInactive)
|
cy.get(rowSelectorLiquidityInactive)
|
||||||
.first()
|
.first()
|
||||||
|
@ -128,6 +128,7 @@ describe('accounts', { tags: '@smoke' }, () => {
|
|||||||
cy.wrap(btn).click();
|
cy.wrap(btn).click();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
cy.contains('Loading...').should('not.exist');
|
||||||
});
|
});
|
||||||
// 7001-COLL-010
|
// 7001-COLL-010
|
||||||
it('sorting by asset', () => {
|
it('sorting by asset', () => {
|
||||||
@ -146,12 +147,17 @@ describe('accounts', { tags: '@smoke' }, () => {
|
|||||||
it('sorting by total', () => {
|
it('sorting by total', () => {
|
||||||
cy.getByTestId('Collateral').click();
|
cy.getByTestId('Collateral').click();
|
||||||
const marketsSortedDefault = [
|
const marketsSortedDefault = [
|
||||||
'1,000.00',
|
'1,000.00002',
|
||||||
'1,000.01',
|
'1,000.01',
|
||||||
'1,000.00',
|
'1,000.00',
|
||||||
'1,000.00',
|
'1,000.00001',
|
||||||
|
];
|
||||||
|
const marketsSortedAsc = [
|
||||||
|
'1,000.00',
|
||||||
|
'1,000.00001',
|
||||||
|
'1,000.00002',
|
||||||
|
'1,000.01',
|
||||||
];
|
];
|
||||||
const marketsSortedAsc = ['1,000.00', '1,000.00', '1,000.00', '1,000.01'];
|
|
||||||
const marketsSortedDesc = Array.from(marketsSortedAsc).reverse();
|
const marketsSortedDesc = Array.from(marketsSortedAsc).reverse();
|
||||||
|
|
||||||
checkSorting(
|
checkSorting(
|
||||||
@ -188,19 +194,24 @@ describe('accounts', { tags: '@smoke' }, () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sorting by total', () => {
|
it('sorting by available', () => {
|
||||||
cy.getByTestId('Collateral').click();
|
cy.getByTestId('Collateral').click();
|
||||||
const marketsSortedDefault = [
|
const marketsSortedDefault = [
|
||||||
'1,000.00',
|
'1,000.00002',
|
||||||
'1,000.01',
|
|
||||||
'1,000.00',
|
'1,000.00',
|
||||||
'1,000.00',
|
'1,000.00',
|
||||||
|
'1,000.00001',
|
||||||
|
];
|
||||||
|
const marketsSortedAsc = [
|
||||||
|
'1,000.00',
|
||||||
|
'1,000.00',
|
||||||
|
'1,000.00001',
|
||||||
|
'1,000.00002',
|
||||||
];
|
];
|
||||||
const marketsSortedAsc = ['1,000.00', '1,000.00', '1,000.00', '1,000.01'];
|
|
||||||
const marketsSortedDesc = Array.from(marketsSortedAsc).reverse();
|
const marketsSortedDesc = Array.from(marketsSortedAsc).reverse();
|
||||||
|
|
||||||
checkSorting(
|
checkSorting(
|
||||||
'total',
|
'available',
|
||||||
marketsSortedDefault,
|
marketsSortedDefault,
|
||||||
marketsSortedAsc,
|
marketsSortedAsc,
|
||||||
marketsSortedDesc
|
marketsSortedDesc
|
||||||
|
@ -83,6 +83,8 @@ export const LiquidityContainer = ({
|
|||||||
|
|
||||||
const assetDecimalPlaces =
|
const assetDecimalPlaces =
|
||||||
market?.tradableInstrument.instrument.product.settlementAsset.decimals || 0;
|
market?.tradableInstrument.instrument.product.settlementAsset.decimals || 0;
|
||||||
|
const quantum =
|
||||||
|
market?.tradableInstrument.instrument.product.settlementAsset.quantum || 0;
|
||||||
const symbol =
|
const symbol =
|
||||||
market?.tradableInstrument.instrument.product.settlementAsset.symbol;
|
market?.tradableInstrument.instrument.product.settlementAsset.symbol;
|
||||||
|
|
||||||
@ -98,6 +100,7 @@ export const LiquidityContainer = ({
|
|||||||
rowData={data}
|
rowData={data}
|
||||||
symbol={symbol}
|
symbol={symbol}
|
||||||
assetDecimalPlaces={assetDecimalPlaces}
|
assetDecimalPlaces={assetDecimalPlaces}
|
||||||
|
quantum={quantum}
|
||||||
stakeToCcyVolume={stakeToCcyVolume}
|
stakeToCcyVolume={stakeToCcyVolume}
|
||||||
overlayNoRowsTemplate={error ? error.message : t('No data')}
|
overlayNoRowsTemplate={error ? error.message : t('No data')}
|
||||||
/>
|
/>
|
||||||
|
@ -49,7 +49,7 @@ const MarketBottomPanel = memo(
|
|||||||
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'bottom' });
|
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'bottom' });
|
||||||
const { screenSize } = useScreenDimensions();
|
const { screenSize } = useScreenDimensions();
|
||||||
const onMarketClick = useMarketClickHandler(true);
|
const onMarketClick = useMarketClickHandler(true);
|
||||||
const onOrderTypeClick = useMarketLiquidityClickHandler(true);
|
const onOrderTypeClick = useMarketLiquidityClickHandler();
|
||||||
|
|
||||||
return 'xxxl' === screenSize ? (
|
return 'xxxl' === screenSize ? (
|
||||||
<ResizableGrid
|
<ResizableGrid
|
||||||
|
@ -39,7 +39,7 @@ export const TradePanels = ({
|
|||||||
}: TradePanelsProps) => {
|
}: TradePanelsProps) => {
|
||||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||||
const onMarketClick = useMarketClickHandler(true);
|
const onMarketClick = useMarketClickHandler(true);
|
||||||
const onOrderTypeClick = useMarketLiquidityClickHandler(true);
|
const onOrderTypeClick = useMarketLiquidityClickHandler();
|
||||||
|
|
||||||
const [view, setView] = useState<TradingView>('candles');
|
const [view, setView] = useState<TradingView>('candles');
|
||||||
const renderView = () => {
|
const renderView = () => {
|
||||||
|
@ -34,7 +34,7 @@ export const Portfolio = () => {
|
|||||||
}, [updateTitle]);
|
}, [updateTitle]);
|
||||||
|
|
||||||
const onMarketClick = useMarketClickHandler(true);
|
const onMarketClick = useMarketClickHandler(true);
|
||||||
const onOrderTypeClick = useMarketLiquidityClickHandler(true);
|
const onOrderTypeClick = useMarketLiquidityClickHandler();
|
||||||
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'portfolio' });
|
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'portfolio' });
|
||||||
const wrapperClasses = 'h-full max-h-full flex flex-col';
|
const wrapperClasses = 'h-full max-h-full flex flex-col';
|
||||||
return (
|
return (
|
||||||
|
@ -125,7 +125,11 @@ export const MarketLiquiditySupplied = ({
|
|||||||
</KeyValueTableRow>
|
</KeyValueTableRow>
|
||||||
</KeyValueTable>
|
</KeyValueTable>
|
||||||
<br />
|
<br />
|
||||||
<Link href={`/#/liquidity/${marketId}`} data-testid="view-liquidity-link">
|
<div className="flex flex-col gap-2">
|
||||||
|
<Link
|
||||||
|
href={`/#/liquidity/${marketId}`}
|
||||||
|
data-testid="view-liquidity-link"
|
||||||
|
>
|
||||||
{t('View liquidity provision table')}
|
{t('View liquidity provision table')}
|
||||||
</Link>
|
</Link>
|
||||||
{DocsLinks && (
|
{DocsLinks && (
|
||||||
@ -133,6 +137,7 @@ export const MarketLiquiditySupplied = ({
|
|||||||
{t('Learn about providing liquidity')}
|
{t('Learn about providing liquidity')}
|
||||||
</ExternalLink>
|
</ExternalLink>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
{showMessage && (
|
{showMessage && (
|
||||||
<p className="mt-4">
|
<p className="mt-4">
|
||||||
{t(
|
{t(
|
||||||
|
@ -20,20 +20,8 @@ export const useMarketClickHandler = (replace = false) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useMarketLiquidityClickHandler = (replace = false) => {
|
export const useMarketLiquidityClickHandler = () => {
|
||||||
const navigate = useNavigate();
|
return useCallback((selectedId: string, metaKey?: boolean) => {
|
||||||
const { marketId } = useParams();
|
window.open(`/#/liquidity/${selectedId}`, metaKey ? '_blank' : '_self');
|
||||||
const { pathname } = useLocation();
|
}, []);
|
||||||
const isLiquidityPage = pathname.match(/^\/liquidity\/(.+)/);
|
|
||||||
return useCallback(
|
|
||||||
(selectedId: string, metaKey?: boolean) => {
|
|
||||||
const link = Links[Routes.LIQUIDITY](selectedId);
|
|
||||||
if (metaKey) {
|
|
||||||
window.open(`/#${link}`, '_blank');
|
|
||||||
} else if (selectedId !== marketId || !isLiquidityPage) {
|
|
||||||
navigate(link, { replace });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[navigate, marketId, replace, isLiquidityPage]
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
@ -72,7 +72,6 @@ export const AccountBreakdownDialog = memo(
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
onMarketClick?: (marketId: string, metaKey?: boolean) => void;
|
||||||
}) => {
|
}) => {
|
||||||
console.log('render');
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
size="medium"
|
size="medium"
|
||||||
|
@ -290,6 +290,14 @@ export const TransferFee = ({
|
|||||||
decimals?: number;
|
decimals?: number;
|
||||||
}) => {
|
}) => {
|
||||||
if (!feeFactor || !amount || !transferAmount || !fee) return null;
|
if (!feeFactor || !amount || !transferAmount || !fee) return null;
|
||||||
|
if (
|
||||||
|
isNaN(Number(feeFactor)) ||
|
||||||
|
isNaN(Number(amount)) ||
|
||||||
|
isNaN(Number(transferAmount)) ||
|
||||||
|
isNaN(Number(fee))
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const totalValue = new BigNumber(transferAmount).plus(fee).toString();
|
const totalValue = new BigNumber(transferAmount).plus(fee).toString();
|
||||||
|
|
||||||
|
@ -44,21 +44,29 @@ export const checkSorting = (
|
|||||||
orderTabDesc: string[]
|
orderTabDesc: string[]
|
||||||
) => {
|
) => {
|
||||||
checkSortChange(orderTabDefault, column);
|
checkSortChange(orderTabDefault, column);
|
||||||
cy.get('.ag-header-container').within(() => {
|
cy.get('.ag-header-container')
|
||||||
cy.get(`[col-id="${column}"]`).click();
|
.last()
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id="${column}"]`).last().click();
|
||||||
});
|
});
|
||||||
checkSortChange(orderTabAsc, column);
|
checkSortChange(orderTabAsc, column);
|
||||||
cy.get('.ag-header-container').within(() => {
|
cy.get('.ag-header-container')
|
||||||
|
.last()
|
||||||
|
.within(() => {
|
||||||
cy.get(`[col-id="${column}"]`).click();
|
cy.get(`[col-id="${column}"]`).click();
|
||||||
});
|
});
|
||||||
checkSortChange(orderTabDesc, column);
|
checkSortChange(orderTabDesc, column);
|
||||||
cy.get('.ag-header-container').within(() => {
|
cy.get('.ag-header-container')
|
||||||
|
.last()
|
||||||
|
.within(() => {
|
||||||
cy.get(`[col-id="${column}"]`).click();
|
cy.get(`[col-id="${column}"]`).click();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkSortChange = (tabsArr: string[], column: string) => {
|
const checkSortChange = (tabsArr: string[], column: string) => {
|
||||||
cy.get('.ag-center-cols-container').within(() => {
|
cy.get('.ag-center-cols-container')
|
||||||
|
.last()
|
||||||
|
.within(() => {
|
||||||
tabsArr.forEach((entry, i) => {
|
tabsArr.forEach((entry, i) => {
|
||||||
cy.get(`[row-index="${i}"]`).within(() => {
|
cy.get(`[row-index="${i}"]`).within(() => {
|
||||||
cy.get(`[col-id="${column}"]`).should('have.text', tabsArr[i]);
|
cy.get(`[col-id="${column}"]`).should('have.text', tabsArr[i]);
|
||||||
|
@ -113,6 +113,7 @@ export const DealTicketFeeDetails = ({
|
|||||||
const { settlementAsset: asset } =
|
const { settlementAsset: asset } =
|
||||||
market.tradableInstrument.instrument.product;
|
market.tradableInstrument.instrument.product;
|
||||||
const { decimals: assetDecimals, quantum } = asset;
|
const { decimals: assetDecimals, quantum } = asset;
|
||||||
|
const marketDecimals = market.decimalPlaces;
|
||||||
let marginRequiredBestCase: string | undefined = undefined;
|
let marginRequiredBestCase: string | undefined = undefined;
|
||||||
let marginRequiredWorstCase: string | undefined = undefined;
|
let marginRequiredWorstCase: string | undefined = undefined;
|
||||||
if (marginEstimate) {
|
if (marginEstimate) {
|
||||||
@ -227,6 +228,9 @@ export const DealTicketFeeDetails = ({
|
|||||||
liquidationEstimateWorstCaseIncludingSellOrders
|
liquidationEstimateWorstCaseIncludingSellOrders
|
||||||
? liquidationEstimateWorstCaseIncludingBuyOrders
|
? liquidationEstimateWorstCaseIncludingBuyOrders
|
||||||
: liquidationEstimateWorstCaseIncludingSellOrders;
|
: liquidationEstimateWorstCaseIncludingSellOrders;
|
||||||
|
|
||||||
|
// The estimate order query API gives us the liquidation price in formatted by asset decimals.
|
||||||
|
// We need to calculate it with asset decimals, but display it with market decimals precision until the API changes.
|
||||||
liquidationPriceEstimate = formatRange(
|
liquidationPriceEstimate = formatRange(
|
||||||
(liquidationEstimateBestCase < liquidationEstimateWorstCase
|
(liquidationEstimateBestCase < liquidationEstimateWorstCase
|
||||||
? liquidationEstimateBestCase
|
? liquidationEstimateBestCase
|
||||||
@ -247,14 +251,16 @@ export const DealTicketFeeDetails = ({
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const quoteName = market.tradableInstrument.instrument.product.quoteName;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<DealTicketFeeDetail
|
<DealTicketFeeDetail
|
||||||
label={t('Notional')}
|
label={t('Notional')}
|
||||||
value={formatValue(notionalSize, assetDecimals)}
|
value={formatValue(notionalSize, marketDecimals)}
|
||||||
formattedValue={formatValue(notionalSize, assetDecimals, quantum)}
|
formattedValue={formatValue(notionalSize, marketDecimals)}
|
||||||
symbol={assetSymbol}
|
symbol={quoteName}
|
||||||
labelDescription={NOTIONAL_SIZE_TOOLTIP_TEXT(assetSymbol)}
|
labelDescription={NOTIONAL_SIZE_TOOLTIP_TEXT(quoteName)}
|
||||||
/>
|
/>
|
||||||
<DealTicketFeeDetail
|
<DealTicketFeeDetail
|
||||||
label={t('Fees')}
|
label={t('Fees')}
|
||||||
@ -335,8 +341,9 @@ export const DealTicketFeeDetails = ({
|
|||||||
{projectedMargin}
|
{projectedMargin}
|
||||||
<DealTicketFeeDetail
|
<DealTicketFeeDetail
|
||||||
label={t('Liquidation price estimate')}
|
label={t('Liquidation price estimate')}
|
||||||
|
value={liquidationPriceEstimate}
|
||||||
formattedValue={liquidationPriceEstimate}
|
formattedValue={liquidationPriceEstimate}
|
||||||
symbol={assetSymbol}
|
symbol={quoteName}
|
||||||
labelDescription={LIQUIDATION_PRICE_ESTIMATE_TOOLTIP_TEXT}
|
labelDescription={LIQUIDATION_PRICE_ESTIMATE_TOOLTIP_TEXT}
|
||||||
/>
|
/>
|
||||||
{partyId && (
|
{partyId && (
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
import { forwardRef } from 'react';
|
import { forwardRef, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
|
addDecimalsFormatNumberQuantum,
|
||||||
formatNumberPercentage,
|
formatNumberPercentage,
|
||||||
getDateTimeFormat,
|
getDateTimeFormat,
|
||||||
} from '@vegaprotocol/utils';
|
} from '@vegaprotocol/utils';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import type {
|
import type { TypedDataAgGrid } from '@vegaprotocol/datagrid';
|
||||||
VegaValueFormatterParams,
|
|
||||||
TypedDataAgGrid,
|
|
||||||
} from '@vegaprotocol/datagrid';
|
|
||||||
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
import { AgGridLazy as AgGrid } from '@vegaprotocol/datagrid';
|
||||||
import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit';
|
import { TooltipCellComponent } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
import { AgGridColumn } from 'ag-grid-react';
|
import type {
|
||||||
import type { ValueFormatterParams } from 'ag-grid-community';
|
ColDef,
|
||||||
|
ITooltipParams,
|
||||||
|
ValueFormatterParams,
|
||||||
|
} from 'ag-grid-community';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
|
import type { LiquidityProvisionStatus } from '@vegaprotocol/types';
|
||||||
import { LiquidityProvisionStatusMapping } from '@vegaprotocol/types';
|
import { LiquidityProvisionStatusMapping } from '@vegaprotocol/types';
|
||||||
import type { LiquidityProvisionData } from './liquidity-data-provider';
|
import type { LiquidityProvisionData } from './liquidity-data-provider';
|
||||||
|
|
||||||
@ -35,22 +37,153 @@ export interface LiquidityTableProps
|
|||||||
symbol?: string;
|
symbol?: string;
|
||||||
assetDecimalPlaces?: number;
|
assetDecimalPlaces?: number;
|
||||||
stakeToCcyVolume: string | null;
|
stakeToCcyVolume: string | null;
|
||||||
|
quantum?: string | number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LiquidityTable = forwardRef<AgGridReact, LiquidityTableProps>(
|
export const LiquidityTable = forwardRef<AgGridReact, LiquidityTableProps>(
|
||||||
({ symbol = '', assetDecimalPlaces, stakeToCcyVolume, ...props }, ref) => {
|
(
|
||||||
const assetDecimalsFormatter = ({ value }: ValueFormatterParams) => {
|
{ symbol = '', assetDecimalPlaces, stakeToCcyVolume, quantum, ...props },
|
||||||
|
ref
|
||||||
|
) => {
|
||||||
|
const colDefs = useMemo(() => {
|
||||||
|
const assetDecimalsFormatter = ({ value }: ITooltipParams) => {
|
||||||
if (!value) return '-';
|
if (!value) return '-';
|
||||||
return `${addDecimalsFormatNumber(value, assetDecimalPlaces ?? 0, 5)}`;
|
return `${addDecimalsFormatNumber(value, assetDecimalPlaces ?? 0)}`;
|
||||||
};
|
};
|
||||||
const stakeToCcyVolumeFormatter = ({ value }: ValueFormatterParams) => {
|
|
||||||
|
const assetDecimalsQuantumFormatter = ({
|
||||||
|
value,
|
||||||
|
}: ValueFormatterParams) => {
|
||||||
|
if (!value) return '-';
|
||||||
|
return `${addDecimalsFormatNumberQuantum(
|
||||||
|
value,
|
||||||
|
assetDecimalPlaces ?? 0,
|
||||||
|
quantum ?? 0
|
||||||
|
)}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const stakeToCcyVolumeFormatter = ({ value }: ITooltipParams) => {
|
||||||
if (!value) return '-';
|
if (!value) return '-';
|
||||||
const newValue = new BigNumber(value)
|
const newValue = new BigNumber(value)
|
||||||
.times(Number(stakeToCcyVolume) || 1)
|
.times(Number(stakeToCcyVolume) || 1)
|
||||||
.toString();
|
.toString();
|
||||||
return `${addDecimalsFormatNumber(newValue, assetDecimalPlaces ?? 0, 5)}`;
|
return `${addDecimalsFormatNumber(newValue, assetDecimalPlaces ?? 0)}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const stakeToCcyVolumeQuantumFormatter = ({
|
||||||
|
value,
|
||||||
|
}: ValueFormatterParams) => {
|
||||||
|
if (!value) return '-';
|
||||||
|
const newValue = new BigNumber(value)
|
||||||
|
.times(Number(stakeToCcyVolume) || 1)
|
||||||
|
.toString();
|
||||||
|
return `${addDecimalsFormatNumberQuantum(
|
||||||
|
newValue,
|
||||||
|
assetDecimalPlaces ?? 0,
|
||||||
|
quantum ?? 0
|
||||||
|
)}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const defs: ColDef[] = [
|
||||||
|
{
|
||||||
|
headerName: t('Party'),
|
||||||
|
field: 'party.id',
|
||||||
|
headerTooltip: t(
|
||||||
|
'The public key of the party making this commitment.'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t(`Commitment (${symbol})`),
|
||||||
|
field: 'commitmentAmount',
|
||||||
|
type: 'rightAligned',
|
||||||
|
headerTooltip: t(
|
||||||
|
'The amount committed to the market by this liquidity provider.'
|
||||||
|
),
|
||||||
|
valueFormatter: assetDecimalsQuantumFormatter,
|
||||||
|
tooltipValueGetter: assetDecimalsFormatter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t(`Share`),
|
||||||
|
field: 'equityLikeShare',
|
||||||
|
type: 'rightAligned',
|
||||||
|
headerTooltip: t(
|
||||||
|
'The equity-like share of liquidity of the market used to determine allocation of LP fees. Calculated based on share of total liquidity, with a premium added for length of commitment.'
|
||||||
|
),
|
||||||
|
valueFormatter: percentageFormatter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Proposed fee'),
|
||||||
|
headerTooltip: t(
|
||||||
|
'The fee percentage (per trade) proposed by each liquidity provider.'
|
||||||
|
),
|
||||||
|
field: 'fee',
|
||||||
|
type: 'rightAligned',
|
||||||
|
valueFormatter: percentageFormatter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Market valuation at entry'),
|
||||||
|
field: 'averageEntryValuation',
|
||||||
|
type: 'rightAligned',
|
||||||
|
headerTooltip: t(
|
||||||
|
'The valuation of the market at the time the liquidity commitment was made. Commitments made at a lower valuation earlier in the lifetime of the market would be expected to have a higher equity-like share if the market has grown. If a commitment is amended, value will reflect the average of the market valuations across the lifetime of the commitment.'
|
||||||
|
),
|
||||||
|
minWidth: 160,
|
||||||
|
valueFormatter: assetDecimalsQuantumFormatter,
|
||||||
|
tooltipValueGetter: assetDecimalsFormatter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Obligation'),
|
||||||
|
field: 'commitmentAmount',
|
||||||
|
type: 'rightAligned',
|
||||||
|
headerTooltip: t(
|
||||||
|
`The liquidity provider's obligation to the market, calculated as the liquidity commitment amount multiplied by the value of the stake_to_ccy_volume network parameter to convert into units of liquidity volume. The obligation can be met by a combination of LP orders and limit orders on the order book.`
|
||||||
|
),
|
||||||
|
valueFormatter: stakeToCcyVolumeQuantumFormatter,
|
||||||
|
tooltipValueGetter: stakeToCcyVolumeFormatter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Supplied'),
|
||||||
|
field: 'balance',
|
||||||
|
type: 'rightAligned',
|
||||||
|
headerTooltip: t(
|
||||||
|
`The amount of liquidity volume supplied by the LP order in order to meet the obligation. If the obligation is already met in full by other limit orders from the same Vega key the LP order is not required and this value will be zero. Also note if the target stake for the market is less than the obligation the full value of the obligation may not be required.`
|
||||||
|
),
|
||||||
|
valueFormatter: stakeToCcyVolumeQuantumFormatter,
|
||||||
|
tooltipValueGetter: stakeToCcyVolumeFormatter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Status'),
|
||||||
|
headerTooltip: t('The current status of this liquidity provision.'),
|
||||||
|
field: 'status',
|
||||||
|
valueFormatter: ({ value }) => {
|
||||||
|
if (!value) return value;
|
||||||
|
return LiquidityProvisionStatusMapping[
|
||||||
|
value as LiquidityProvisionStatus
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Created'),
|
||||||
|
headerTooltip: t(
|
||||||
|
'The date and time this liquidity provision was created.'
|
||||||
|
),
|
||||||
|
field: 'createdAt',
|
||||||
|
type: 'rightAligned',
|
||||||
|
valueFormatter: dateValueFormatter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
headerName: t('Updated'),
|
||||||
|
headerTooltip: t(
|
||||||
|
'The date and time this liquidity provision was last updated.'
|
||||||
|
),
|
||||||
|
field: 'updatedAt',
|
||||||
|
type: 'rightAligned',
|
||||||
|
valueFormatter: dateValueFormatter,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return defs;
|
||||||
|
}, [assetDecimalPlaces, quantum, stakeToCcyVolume, symbol]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AgGrid
|
<AgGrid
|
||||||
style={{ width: '100%', height: '100%' }}
|
style={{ width: '100%', height: '100%' }}
|
||||||
@ -66,99 +199,8 @@ export const LiquidityTable = forwardRef<AgGridReact, LiquidityTableProps>(
|
|||||||
}}
|
}}
|
||||||
storeKey="liquidityProvisionTable"
|
storeKey="liquidityProvisionTable"
|
||||||
{...props}
|
{...props}
|
||||||
>
|
columnDefs={colDefs}
|
||||||
<AgGridColumn
|
></AgGrid>
|
||||||
headerName={t('Party')}
|
|
||||||
field="party.id"
|
|
||||||
headerTooltip={t(
|
|
||||||
'The public key of the party making this commitment.'
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t(`Commitment (${symbol})`)}
|
|
||||||
field="commitmentAmount"
|
|
||||||
type="rightAligned"
|
|
||||||
headerTooltip={t(
|
|
||||||
'The amount committed to the market by this liquidity provider.'
|
|
||||||
)}
|
|
||||||
valueFormatter={assetDecimalsFormatter}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Share')}
|
|
||||||
field="equityLikeShare"
|
|
||||||
type="rightAligned"
|
|
||||||
headerTooltip={t(
|
|
||||||
'The equity-like share of liquidity of the market used to determine allocation of LP fees. Calculated based on share of total liquidity, with a premium added for length of commitment.'
|
|
||||||
)}
|
|
||||||
valueFormatter={percentageFormatter}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Proposed fee')}
|
|
||||||
headerTooltip={t(
|
|
||||||
'The fee percentage (per trade) proposed by each liquidity provider.'
|
|
||||||
)}
|
|
||||||
field="fee"
|
|
||||||
type="rightAligned"
|
|
||||||
valueFormatter={percentageFormatter}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Market valuation at entry')}
|
|
||||||
field="averageEntryValuation"
|
|
||||||
type="rightAligned"
|
|
||||||
headerTooltip={t(
|
|
||||||
'The valuation of the market at the time the liquidity commitment was made. Commitments made at a lower valuation earlier in the lifetime of the market would be expected to have a higher equity-like share if the market has grown. If a commitment is amended, value will reflect the average of the market valuations across the lifetime of the commitment.'
|
|
||||||
)}
|
|
||||||
minWidth={160}
|
|
||||||
valueFormatter={assetDecimalsFormatter}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Obligation')}
|
|
||||||
field="commitmentAmount"
|
|
||||||
type="rightAligned"
|
|
||||||
headerTooltip={t(
|
|
||||||
`The liquidity provider's obligation to the market, calculated as the liquidity commitment amount multiplied by the value of the stake_to_ccy_siskas network parameter to convert into units of liquidity volume. The obligation can be met by a combination of LP orders and limit orders on the order book.`
|
|
||||||
)}
|
|
||||||
valueFormatter={stakeToCcyVolumeFormatter}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Supplied')}
|
|
||||||
headerTooltip={t(
|
|
||||||
`The amount of liquidity volume supplied by the LP order in order to meet the obligation. If the obligation is already met in full by other limit orders from the same Vega key the LP order is not required and this value will be zero. Also note if the target stake for the market is less than the obligation the full value of the obligation may not be required.`
|
|
||||||
)}
|
|
||||||
field="balance"
|
|
||||||
type="rightAligned"
|
|
||||||
valueFormatter={stakeToCcyVolumeFormatter}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Status')}
|
|
||||||
headerTooltip={t('The current status of this liquidity provision.')}
|
|
||||||
field="status"
|
|
||||||
valueFormatter={({
|
|
||||||
value,
|
|
||||||
}: VegaValueFormatterParams<LiquidityProvisionData, 'status'>) => {
|
|
||||||
if (!value) return value;
|
|
||||||
return LiquidityProvisionStatusMapping[value];
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Created')}
|
|
||||||
headerTooltip={t(
|
|
||||||
'The date and time this liquidity provision was created.'
|
|
||||||
)}
|
|
||||||
field="createdAt"
|
|
||||||
type="rightAligned"
|
|
||||||
valueFormatter={dateValueFormatter}
|
|
||||||
/>
|
|
||||||
<AgGridColumn
|
|
||||||
headerName={t('Updated')}
|
|
||||||
headerTooltip={t(
|
|
||||||
'The last time this liquidity provision was updated.'
|
|
||||||
)}
|
|
||||||
field="updatedAt"
|
|
||||||
type="rightAligned"
|
|
||||||
valueFormatter={dateValueFormatter}
|
|
||||||
/>
|
|
||||||
</AgGrid>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -29,14 +29,21 @@ describe('number utils', () => {
|
|||||||
{ v: new BigNumber(123000), d: 3, o: '123.00', q: 0.1 },
|
{ v: new BigNumber(123000), d: 3, o: '123.00', q: 0.1 },
|
||||||
{ v: new BigNumber(123000), d: 1, o: '12,300.00', q: 0.1 },
|
{ v: new BigNumber(123000), d: 1, o: '12,300.00', q: 0.1 },
|
||||||
{ v: new BigNumber(123001000), d: 2, o: '1,230,010.00', q: 0.1 },
|
{ v: new BigNumber(123001000), d: 2, o: '1,230,010.00', q: 0.1 },
|
||||||
{ v: new BigNumber(123001), d: 2, o: '1,230', q: 100 },
|
{ v: new BigNumber(123001), d: 2, o: '1,230.01', q: 100 },
|
||||||
{ v: new BigNumber(123001), d: 2, o: '1,230.01', q: 0.1 },
|
{ v: new BigNumber(123001), d: 2, o: '1,230.01', q: 0.1 },
|
||||||
|
{ v: new BigNumber(123001), d: 2, o: '1,230.01', q: 1 },
|
||||||
{
|
{
|
||||||
v: BigNumber('123456789123456789'),
|
v: BigNumber('123456789123456789'),
|
||||||
d: 10,
|
d: 10,
|
||||||
o: '12,345,678.9123457',
|
o: '12,345,678.91234568',
|
||||||
q: '0.00003846',
|
q: '0.00003846',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
v: BigNumber('123456789123456789'),
|
||||||
|
d: 10,
|
||||||
|
o: '12,345,678.91234568',
|
||||||
|
q: '1',
|
||||||
|
},
|
||||||
])(
|
])(
|
||||||
'formats with addDecimalsFormatNumberQuantum given number correctly',
|
'formats with addDecimalsFormatNumberQuantum given number correctly',
|
||||||
({ v, d, o, q }) => {
|
({ v, d, o, q }) => {
|
||||||
@ -70,9 +77,8 @@ describe('number utils', () => {
|
|||||||
])('formats given number correctly', ({ v, d, o }) => {
|
])('formats given number correctly', ({ v, d, o }) => {
|
||||||
expect(formatNumberPercentage(v, d)).toStrictEqual(o);
|
expect(formatNumberPercentage(v, d)).toStrictEqual(o);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe('toNumberParts', () => {
|
describe('toNumberParts', () => {
|
||||||
it.each([
|
it.each([
|
||||||
{ v: null, d: 3, o: ['0', '000'] },
|
{ v: null, d: 3, o: ['0', '000'] },
|
||||||
{ v: undefined, d: 3, o: ['0', '000'] },
|
{ v: undefined, d: 3, o: ['0', '000'] },
|
||||||
@ -89,9 +95,9 @@ describe('toNumberParts', () => {
|
|||||||
])('returns correct tuple given the different arguments', ({ v, d, o }) => {
|
])('returns correct tuple given the different arguments', ({ v, d, o }) => {
|
||||||
expect(toNumberParts(v, d)).toStrictEqual(o);
|
expect(toNumberParts(v, d)).toStrictEqual(o);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isNumeric', () => {
|
describe('isNumeric', () => {
|
||||||
it.each([
|
it.each([
|
||||||
{ i: null, o: false },
|
{ i: null, o: false },
|
||||||
{ i: undefined, o: false },
|
{ i: undefined, o: false },
|
||||||
@ -129,9 +135,9 @@ describe('isNumeric', () => {
|
|||||||
expect(isNumeric(i)).toStrictEqual(o);
|
expect(isNumeric(i)).toStrictEqual(o);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('toDecimal', () => {
|
describe('toDecimal', () => {
|
||||||
it.each([
|
it.each([
|
||||||
{ v: 0, o: '1' },
|
{ v: 0, o: '1' },
|
||||||
{ v: 1, o: '0.1' },
|
{ v: 1, o: '0.1' },
|
||||||
@ -146,4 +152,5 @@ describe('toDecimal', () => {
|
|||||||
])('formats with toNumber given number correctly', ({ v, o }) => {
|
])('formats with toNumber given number correctly', ({ v, o }) => {
|
||||||
expect(toDecimal(v)).toStrictEqual(o);
|
expect(toDecimal(v)).toStrictEqual(o);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -98,7 +98,8 @@ export const addDecimalsFormatNumberQuantum = (
|
|||||||
if (isNaN(Number(quantum))) {
|
if (isNaN(Number(quantum))) {
|
||||||
return addDecimalsFormatNumber(rawValue, decimalPlaces);
|
return addDecimalsFormatNumber(rawValue, decimalPlaces);
|
||||||
}
|
}
|
||||||
const numberDP = Math.max(0, Math.log10(100 / Number(quantum)));
|
const quantumValue = addDecimal(quantum, decimalPlaces);
|
||||||
|
const numberDP = Math.max(0, Math.log10(100 / Number(quantumValue)));
|
||||||
return addDecimalsFormatNumber(rawValue, decimalPlaces, Math.ceil(numberDP));
|
return addDecimalsFormatNumber(rawValue, decimalPlaces, Math.ceil(numberDP));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -21,12 +21,12 @@ describe('formatValue', () => {
|
|||||||
{ v: 123000, d: 3, o: '123.00', q: '0.1' },
|
{ v: 123000, d: 3, o: '123.00', q: '0.1' },
|
||||||
{ v: 123000, d: 1, o: '12,300.00', q: '0.1' },
|
{ v: 123000, d: 1, o: '12,300.00', q: '0.1' },
|
||||||
{ v: 123001000, d: 2, o: '1,230,010.00', q: '0.1' },
|
{ v: 123001000, d: 2, o: '1,230,010.00', q: '0.1' },
|
||||||
{ v: 123001, d: 2, o: '1,230', q: '100' },
|
{ v: 123001, d: 2, o: '1,230.01', q: '100' },
|
||||||
{ v: 123001, d: 2, o: '1,230.01', q: '0.1' },
|
{ v: 123001, d: 2, o: '1,230.01', q: '0.1' },
|
||||||
{
|
{
|
||||||
v: '123456789123456789',
|
v: '123456789123456789',
|
||||||
d: 10,
|
d: 10,
|
||||||
o: '12,345,678.9123457',
|
o: '12,345,678.91234568',
|
||||||
q: '0.00003846',
|
q: '0.00003846',
|
||||||
},
|
},
|
||||||
])(
|
])(
|
||||||
@ -38,7 +38,13 @@ describe('formatValue', () => {
|
|||||||
});
|
});
|
||||||
describe('formatRange', () => {
|
describe('formatRange', () => {
|
||||||
it.each([
|
it.each([
|
||||||
{ min: 123000, max: 12300011111, d: 5, o: '1.23 - 123,000.111', q: '0.1' },
|
{
|
||||||
|
min: 123000,
|
||||||
|
max: 12300011111,
|
||||||
|
d: 5,
|
||||||
|
o: '1.23 - 123,000.11111',
|
||||||
|
q: '0.1',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
min: 123000,
|
min: 123000,
|
||||||
max: 12300011111,
|
max: 12300011111,
|
||||||
@ -57,7 +63,7 @@ describe('formatRange', () => {
|
|||||||
min: 123001000,
|
min: 123001000,
|
||||||
max: 12300011111,
|
max: 12300011111,
|
||||||
d: 2,
|
d: 2,
|
||||||
o: '1,230,010 - 123,000,111',
|
o: '1,230,010.00 - 123,000,111.11',
|
||||||
q: '100',
|
q: '100',
|
||||||
},
|
},
|
||||||
])(
|
])(
|
||||||
|
Loading…
Reference in New Issue
Block a user