feat(trading): show total value of the valume traded in last 24hrs
This commit is contained in:
parent
bf70dc33ec
commit
be38813a33
@ -19,6 +19,7 @@ import {
|
||||
useFundingRate,
|
||||
useMarketTradingMode,
|
||||
useExternalTwap,
|
||||
getQuoteName,
|
||||
} from '@vegaprotocol/markets';
|
||||
import { MarketState as State } from '@vegaprotocol/types';
|
||||
import { HeaderStat } from '../../components/header';
|
||||
@ -41,6 +42,7 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
|
||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||
|
||||
const asset = getAsset(market);
|
||||
const quoteUnit = getQuoteName(market);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -60,6 +62,8 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
|
||||
<Last24hVolume
|
||||
marketId={market.id}
|
||||
positionDecimalPlaces={market.positionDecimalPlaces}
|
||||
marketDecimals={market.decimalPlaces}
|
||||
quoteUnit={quoteUnit}
|
||||
/>
|
||||
</HeaderStat>
|
||||
<HeaderStatMarketTradingMode
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
useDataGridEvents,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import type { MarketMaybeWithData } from '@vegaprotocol/markets';
|
||||
import { useColumnDefs } from './use-column-defs';
|
||||
import { useMarketsColumnDefs } from './use-column-defs';
|
||||
import type { DataGridStore } from '../../stores/datagrid-store-slice';
|
||||
import { type StateCreator, create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
@ -50,7 +50,7 @@ export const useMarketsStore = create<DataGridSlice>()(
|
||||
);
|
||||
|
||||
export const MarketListTable = (props: Props) => {
|
||||
const columnDefs = useColumnDefs();
|
||||
const columnDefs = useMarketsColumnDefs();
|
||||
const gridStore = useMarketsStore((store) => store.gridStore);
|
||||
const updateGridStore = useMarketsStore((store) => store.updateGridStore);
|
||||
|
||||
|
@ -7,21 +7,31 @@ import type {
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { COL_DEFS, SetFilter } from '@vegaprotocol/datagrid';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { addDecimalsFormatNumber, toBigNum } from '@vegaprotocol/utils';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
formatNumber,
|
||||
toBigNum,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { ButtonLink, Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
import type {
|
||||
MarketFieldsFragment,
|
||||
MarketMaybeWithData,
|
||||
MarketMaybeWithDataAndCandles,
|
||||
} from '@vegaprotocol/markets';
|
||||
import { MarketActionsDropdown } from './market-table-actions';
|
||||
import { calcCandleVolume, getAsset } from '@vegaprotocol/markets';
|
||||
import {
|
||||
calcCandleVolume,
|
||||
calcCandleVolumePrice,
|
||||
getAsset,
|
||||
getQuoteName,
|
||||
} from '@vegaprotocol/markets';
|
||||
import { MarketCodeCell } from './market-code-cell';
|
||||
import { useT } from '../../lib/use-t';
|
||||
|
||||
const { MarketTradingMode, AuctionTrigger } = Schema;
|
||||
|
||||
export const useColumnDefs = () => {
|
||||
export const useMarketsColumnDefs = () => {
|
||||
const t = useT();
|
||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||
return useMemo<ColDef[]>(
|
||||
@ -158,11 +168,25 @@ export const useColumnDefs = () => {
|
||||
}: ValueFormatterParams<MarketMaybeWithDataAndCandles, 'candles'>) => {
|
||||
const candles = data?.candles;
|
||||
const vol = candles ? calcCandleVolume(candles) : '0';
|
||||
const quoteName = getQuoteName(data as MarketFieldsFragment);
|
||||
const volPrice =
|
||||
candles &&
|
||||
calcCandleVolumePrice(
|
||||
candles,
|
||||
data.decimalPlaces,
|
||||
data.positionDecimalPlaces
|
||||
);
|
||||
|
||||
const volume =
|
||||
data && vol && vol !== '0'
|
||||
? addDecimalsFormatNumber(vol, data.positionDecimalPlaces)
|
||||
: '0.00';
|
||||
return volume;
|
||||
const volumePrice =
|
||||
volPrice && formatNumber(volPrice, data?.decimalPlaces);
|
||||
|
||||
return volumePrice
|
||||
? `${volume} (${volumePrice} ${quoteName})`
|
||||
: volume;
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { calcCandleVolume } from '../../market-utils';
|
||||
import { addDecimalsFormatNumber, isNumeric } from '@vegaprotocol/utils';
|
||||
import { calcCandleVolume, calcCandleVolumePrice } from '../../market-utils';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
formatNumber,
|
||||
isNumeric,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { Tooltip } from '@vegaprotocol/ui-toolkit';
|
||||
import { useCandles } from '../../hooks';
|
||||
import { useT } from '../../use-t';
|
||||
@ -9,13 +13,17 @@ interface Props {
|
||||
positionDecimalPlaces?: number;
|
||||
formatDecimals?: number;
|
||||
initialValue?: string;
|
||||
marketDecimals?: number;
|
||||
quoteUnit?: string;
|
||||
}
|
||||
|
||||
export const Last24hVolume = ({
|
||||
marketId,
|
||||
marketDecimals,
|
||||
positionDecimalPlaces,
|
||||
formatDecimals,
|
||||
initialValue,
|
||||
quoteUnit,
|
||||
}: Props) => {
|
||||
const t = useT();
|
||||
const { oneDayCandles, fiveDaysCandles } = useCandles({
|
||||
@ -28,6 +36,11 @@ export const Last24hVolume = ({
|
||||
(!oneDayCandles || oneDayCandles?.length === 0)
|
||||
) {
|
||||
const candleVolume = calcCandleVolume(fiveDaysCandles);
|
||||
const candleVolumePrice = calcCandleVolumePrice(
|
||||
fiveDaysCandles,
|
||||
marketDecimals,
|
||||
positionDecimalPlaces
|
||||
);
|
||||
const candleVolumeValue =
|
||||
candleVolume && isNumeric(positionDecimalPlaces)
|
||||
? addDecimalsFormatNumber(
|
||||
@ -42,8 +55,8 @@ export const Last24hVolume = ({
|
||||
<div>
|
||||
<span className="flex flex-col">
|
||||
{t(
|
||||
'24 hour change is unavailable at this time. The volume change in the last 120 hours is {{candleVolumeValue}}',
|
||||
{ candleVolumeValue }
|
||||
'24 hour change is unavailable at this time. The volume change in the last 120 hours is {{candleVolumeValue}} ({{candleVolumePrice}} {{quoteUnit}})',
|
||||
{ candleVolumeValue, candleVolumePrice, quoteUnit }
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
@ -57,10 +70,18 @@ export const Last24hVolume = ({
|
||||
? calcCandleVolume(oneDayCandles)
|
||||
: initialValue;
|
||||
|
||||
const candleVolumePrice = oneDayCandles
|
||||
? calcCandleVolumePrice(
|
||||
oneDayCandles,
|
||||
marketDecimals,
|
||||
positionDecimalPlaces
|
||||
)
|
||||
: initialValue;
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
description={t(
|
||||
'The total number of contracts traded in the last 24 hours.'
|
||||
'The total number of contracts traded in the last 24 hours. (Total value of contracts traded in the last 24 hours)'
|
||||
)}
|
||||
>
|
||||
<span>
|
||||
@ -70,7 +91,12 @@ export const Last24hVolume = ({
|
||||
positionDecimalPlaces,
|
||||
formatDecimals
|
||||
)
|
||||
: '-'}
|
||||
: '-'}{' '}
|
||||
(
|
||||
{candleVolumePrice && isNumeric(positionDecimalPlaces)
|
||||
? formatNumber(candleVolumePrice, formatDecimals)
|
||||
: '-'}{' '}
|
||||
{quoteUnit})
|
||||
</span>
|
||||
</Tooltip>
|
||||
);
|
||||
|
@ -155,6 +155,7 @@ export const MarketVolumeInfoPanel = ({ market }: MarketInfoProps) => {
|
||||
<Last24hVolume
|
||||
marketId={market.id}
|
||||
positionDecimalPlaces={market.positionDecimalPlaces}
|
||||
marketDecimals={market.decimalPlaces}
|
||||
/>
|
||||
),
|
||||
openInterest: dash(data?.openInterest),
|
||||
|
@ -1,6 +1,7 @@
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import type { Market, MarketMaybeWithDataAndCandles } from './markets-provider';
|
||||
import {
|
||||
calcCandleVolumePrice,
|
||||
calcTradedFactor,
|
||||
filterAndSortMarkets,
|
||||
sumFeesFactors,
|
||||
@ -145,3 +146,31 @@ describe('sumFeesFactors', () => {
|
||||
).toEqual(0.6);
|
||||
});
|
||||
});
|
||||
|
||||
describe('calcCandleVolumePrice', () => {
|
||||
it('calculates the volume price', () => {
|
||||
const candles = [
|
||||
{
|
||||
volume: '1000',
|
||||
high: '100',
|
||||
low: '10',
|
||||
open: '15',
|
||||
close: '90',
|
||||
periodStart: '2022-05-18T13:08:27.693537312Z',
|
||||
},
|
||||
{
|
||||
volume: '1000',
|
||||
high: '100',
|
||||
low: '10',
|
||||
open: '15',
|
||||
close: '90',
|
||||
periodStart: '2022-05-18T14:08:27.693537312Z',
|
||||
},
|
||||
];
|
||||
const marketDecimals = 3;
|
||||
const positionDecimalPlaces = 2;
|
||||
expect(
|
||||
calcCandleVolumePrice(candles, marketDecimals, positionDecimalPlaces)
|
||||
).toEqual('2');
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { formatNumberPercentage, toBigNum } from '@vegaprotocol/utils';
|
||||
import {
|
||||
addDecimal,
|
||||
formatNumberPercentage,
|
||||
toBigNum,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import orderBy from 'lodash/orderBy';
|
||||
@ -147,10 +151,51 @@ export const calcCandleHigh = (candles: Candle[]): string | undefined => {
|
||||
.toString();
|
||||
};
|
||||
|
||||
/**
|
||||
* The total number of contracts traded in the last 24 hours.
|
||||
*
|
||||
* @param candles
|
||||
* @returns the volume of a given set of candles
|
||||
*/
|
||||
export const calcCandleVolume = (candles: Candle[]): string | undefined =>
|
||||
candles &&
|
||||
candles.reduce((acc, c) => new BigNumber(acc).plus(c.volume).toString(), '0');
|
||||
|
||||
/**
|
||||
* The total number of contracts traded in the last 24 hours. (Total value of contracts traded in the last 24 hours)
|
||||
* The volume is calculated as the sum of the product of the volume and the high price of each candle.
|
||||
* The result is formatted using positionDecimalPlaces to account for the position size.
|
||||
* The result is formatted using marketDecimals to account for the market precision.
|
||||
*
|
||||
* @param candles
|
||||
* @param marketDecimals
|
||||
* @param positionDecimalPlaces
|
||||
* @returns the volume (in quote price) of a given set of candles
|
||||
*/
|
||||
export const calcCandleVolumePrice = (
|
||||
candles: Candle[],
|
||||
marketDecimals: number = 1,
|
||||
positionDecimalPlaces: number = 1
|
||||
): string | undefined =>
|
||||
candles &&
|
||||
candles.reduce(
|
||||
(acc, c) =>
|
||||
new BigNumber(acc)
|
||||
.plus(
|
||||
BigNumber(addDecimal(c.volume, positionDecimalPlaces)).times(
|
||||
addDecimal(c.high, marketDecimals)
|
||||
)
|
||||
)
|
||||
.toString(),
|
||||
'0'
|
||||
);
|
||||
|
||||
/**
|
||||
* Calculates the traded factor of a given market.
|
||||
*
|
||||
* @param m
|
||||
* @returns
|
||||
*/
|
||||
export const calcTradedFactor = (m: MarketMaybeWithDataAndCandles) => {
|
||||
const volume = Number(calcCandleVolume(m.candles || []) || 0);
|
||||
const price = m.data?.markPrice ? Number(m.data.markPrice) : 0;
|
||||
|
Loading…
Reference in New Issue
Block a user