feat(trading): use notional for candle calcs (#6119)

This commit is contained in:
Matthew Russell 2024-03-27 13:32:58 +00:00 committed by GitHub
parent 64fc075f7a
commit 840ca63464
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 35 additions and 44 deletions

View File

@ -61,8 +61,8 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => {
<HeaderStat heading={t('Volume (24h)')} testId="market-volume"> <HeaderStat heading={t('Volume (24h)')} testId="market-volume">
<Last24hVolume <Last24hVolume
marketId={market.id} marketId={market.id}
positionDecimalPlaces={market.positionDecimalPlaces}
marketDecimals={market.decimalPlaces} marketDecimals={market.decimalPlaces}
positionDecimalPlaces={market.positionDecimalPlaces}
quoteUnit={quoteUnit} quoteUnit={quoteUnit}
/> />
</HeaderStat> </HeaderStat>

View File

@ -15,7 +15,6 @@ import {
import { ButtonLink, Tooltip } from '@vegaprotocol/ui-toolkit'; import { ButtonLink, Tooltip } from '@vegaprotocol/ui-toolkit';
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets'; import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
import type { import type {
MarketFieldsFragment,
MarketMaybeWithData, MarketMaybeWithData,
MarketMaybeWithDataAndCandles, MarketMaybeWithDataAndCandles,
} from '@vegaprotocol/markets'; } from '@vegaprotocol/markets';
@ -166,16 +165,12 @@ export const useMarketsColumnDefs = () => {
valueFormatter: ({ valueFormatter: ({
data, data,
}: ValueFormatterParams<MarketMaybeWithDataAndCandles, 'candles'>) => { }: ValueFormatterParams<MarketMaybeWithDataAndCandles, 'candles'>) => {
const candles = data?.candles; if (!data) return '-';
const candles = data.candles;
const vol = candles ? calcCandleVolume(candles) : '0'; const vol = candles ? calcCandleVolume(candles) : '0';
const quoteName = getQuoteName(data as MarketFieldsFragment); const quoteName = getQuoteName(data);
const volPrice = const volPrice =
candles && candles && calcCandleVolumePrice(candles, data.decimalPlaces);
calcCandleVolumePrice(
candles,
data.decimalPlaces,
data.positionDecimalPlaces
);
const volume = const volume =
data && vol && vol !== '0' data && vol && vol !== '0'

View File

@ -115,6 +115,7 @@ describe('MarketSettledBanner', () => {
open: '100', open: '100',
close: '100', close: '100',
volume: '100', volume: '100',
notional: '10000',
periodStart: subHours(new Date(now), 1).toISOString(), periodStart: subHours(new Date(now), 1).toISOString(),
}, },
}, },
@ -125,6 +126,7 @@ describe('MarketSettledBanner', () => {
open: '100', open: '100',
close: '200', close: '200',
volume: '100', volume: '100',
notional: '10000',
periodStart: subHours(new Date(now), 2).toISOString(), periodStart: subHours(new Date(now), 2).toISOString(),
}, },
}, },
@ -161,6 +163,7 @@ describe('MarketSettledBanner', () => {
open: '100', open: '100',
close: '100', close: '100',
volume: '100', volume: '100',
notional: '10000',
periodStart: '2020-01-01T00:00:00', periodStart: '2020-01-01T00:00:00',
}, },
}, },

View File

@ -79,6 +79,7 @@ describe('MarketSelectorItem', () => {
high: '5', high: '5',
low: '5', low: '5',
volume: '50', volume: '50',
notional: '10000',
periodStart: yesterday.toISOString(), periodStart: yesterday.toISOString(),
}, },
{ {
@ -87,6 +88,7 @@ describe('MarketSelectorItem', () => {
high: '10', high: '10',
low: '10', low: '10',
volume: '50', volume: '50',
notional: '10000',
periodStart: yesterday.toISOString(), periodStart: yesterday.toISOString(),
}, },
]; ];

View File

@ -3,7 +3,7 @@ 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 MarketCandlesFieldsFragment = { __typename?: 'Candle', high: string, low: string, open: string, close: string, volume: string, periodStart: any }; export type MarketCandlesFieldsFragment = { __typename?: 'Candle', high: string, low: string, open: string, close: string, volume: string, notional: string, periodStart: any };
export type MarketCandlesQueryVariables = Types.Exact<{ export type MarketCandlesQueryVariables = Types.Exact<{
interval: Types.Interval; interval: Types.Interval;
@ -12,7 +12,7 @@ export type MarketCandlesQueryVariables = Types.Exact<{
}>; }>;
export type MarketCandlesQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', candlesConnection?: { __typename?: 'CandleDataConnection', edges?: Array<{ __typename?: 'CandleEdge', node: { __typename?: 'Candle', high: string, low: string, open: string, close: string, volume: string, periodStart: any } } | null> | null } | null } }> } | null }; export type MarketCandlesQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', candlesConnection?: { __typename?: 'CandleDataConnection', edges?: Array<{ __typename?: 'CandleEdge', node: { __typename?: 'Candle', high: string, low: string, open: string, close: string, volume: string, notional: string, periodStart: any } } | null> | null } | null } }> } | null };
export type MarketCandlesUpdateSubscriptionVariables = Types.Exact<{ export type MarketCandlesUpdateSubscriptionVariables = Types.Exact<{
marketId: Types.Scalars['ID']; marketId: Types.Scalars['ID'];
@ -20,7 +20,7 @@ export type MarketCandlesUpdateSubscriptionVariables = Types.Exact<{
}>; }>;
export type MarketCandlesUpdateSubscription = { __typename?: 'Subscription', candles: { __typename?: 'Candle', high: string, low: string, open: string, close: string, volume: string, periodStart: any } }; export type MarketCandlesUpdateSubscription = { __typename?: 'Subscription', candles: { __typename?: 'Candle', high: string, low: string, open: string, close: string, volume: string, notional: string, periodStart: any } };
export const MarketCandlesFieldsFragmentDoc = gql` export const MarketCandlesFieldsFragmentDoc = gql`
fragment MarketCandlesFields on Candle { fragment MarketCandlesFields on Candle {
@ -29,6 +29,7 @@ export const MarketCandlesFieldsFragmentDoc = gql`
open open
close close
volume volume
notional
periodStart periodStart
} }
`; `;

View File

@ -10,7 +10,7 @@ export type MarketsCandlesQueryVariables = Types.Exact<{
}>; }>;
export type MarketsCandlesQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, candlesConnection?: { __typename?: 'CandleDataConnection', edges?: Array<{ __typename?: 'CandleEdge', node: { __typename?: 'Candle', high: string, low: string, open: string, close: string, volume: string, periodStart: any } } | null> | null } | null } }> } | null }; export type MarketsCandlesQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, candlesConnection?: { __typename?: 'CandleDataConnection', edges?: Array<{ __typename?: 'CandleEdge', node: { __typename?: 'Candle', high: string, low: string, open: string, close: string, volume: string, notional: string, periodStart: any } } | null> | null } | null } }> } | null };
export const MarketsCandlesDocument = gql` export const MarketsCandlesDocument = gql`

View File

@ -13,7 +13,7 @@ interface Props {
positionDecimalPlaces?: number; positionDecimalPlaces?: number;
formatDecimals?: number; formatDecimals?: number;
initialValue?: string; initialValue?: string;
marketDecimals?: number; marketDecimals: number;
quoteUnit?: string; quoteUnit?: string;
} }
@ -41,11 +41,7 @@ export const Last24hVolume = ({
: initialValue; : initialValue;
const candleVolumePrice = oneDayCandles const candleVolumePrice = oneDayCandles
? calcCandleVolumePrice( ? calcCandleVolumePrice(oneDayCandles, marketDecimals)
oneDayCandles,
marketDecimals,
positionDecimalPlaces
)
: initialValue; : initialValue;
return ( return (

View File

@ -205,8 +205,8 @@ export const MarketVolumeInfoPanel = ({ market }: MarketInfoProps) => {
'24hourVolume': ( '24hourVolume': (
<Last24hVolume <Last24hVolume
marketId={market.id} marketId={market.id}
positionDecimalPlaces={market.positionDecimalPlaces}
marketDecimals={market.decimalPlaces} marketDecimals={market.decimalPlaces}
positionDecimalPlaces={market.positionDecimalPlaces}
quoteUnit={getQuoteName(market)} quoteUnit={getQuoteName(market)}
/> />
), ),

View File

@ -1,12 +1,15 @@
import { update } from './market-candles-provider'; import { update } from './market-candles-provider';
describe('market candles provider update', () => { describe('market candles provider update', () => {
const price = 153350000;
const volume = 50;
const data = [ const data = [
{ {
high: '153350000', high: price.toString(),
low: '153350000', low: price.toString(),
open: '153350000', open: price.toString(),
close: '153350000', close: price.toString(),
notional: (price * volume).toString(),
volume: '50', volume: '50',
periodStart: '2022-11-01T15:49:00Z', periodStart: '2022-11-01T15:49:00Z',
}, },

View File

@ -4,6 +4,7 @@ fragment MarketCandlesFields on Candle {
open open
close close
volume volume
notional
periodStart periodStart
} }

View File

@ -40,5 +40,6 @@ const marketCandlesFieldsFragment: MarketCandlesFieldsFragment = {
high: '110', high: '110',
low: '90', low: '90',
volume: '1', volume: '1',
notional: '100',
periodStart: '2022-11-01T15:49:00Z', periodStart: '2022-11-01T15:49:00Z',
}; };

View File

@ -164,6 +164,7 @@ describe('calcCandleVolumePrice', () => {
low: '10', low: '10',
open: '15', open: '15',
close: '90', close: '90',
notional: '100',
periodStart: '2022-05-18T13:08:27.693537312Z', periodStart: '2022-05-18T13:08:27.693537312Z',
}, },
{ {
@ -172,13 +173,11 @@ describe('calcCandleVolumePrice', () => {
low: '10', low: '10',
open: '15', open: '15',
close: '90', close: '90',
notional: '100',
periodStart: '2022-05-18T14:08:27.693537312Z', periodStart: '2022-05-18T14:08:27.693537312Z',
}, },
]; ];
const marketDecimals = 3; const decimalPlaces = 2;
const positionDecimalPlaces = 2; expect(calcCandleVolumePrice(candles, decimalPlaces)).toEqual('2');
expect(
calcCandleVolumePrice(candles, marketDecimals, positionDecimalPlaces)
).toEqual('2');
}); });
}); });

View File

@ -1,8 +1,4 @@
import { import { formatNumberPercentage, toBigNum } from '@vegaprotocol/utils';
addDecimal,
formatNumberPercentage,
toBigNum,
} from '@vegaprotocol/utils';
import { MarketState, MarketTradingMode } from '@vegaprotocol/types'; import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import orderBy from 'lodash/orderBy'; import orderBy from 'lodash/orderBy';
@ -182,19 +178,12 @@ export const calcCandleVolume = (candles: Candle[]): string | undefined =>
*/ */
export const calcCandleVolumePrice = ( export const calcCandleVolumePrice = (
candles: Candle[], candles: Candle[],
marketDecimals: number = 1, decimalPlaces: number
positionDecimalPlaces: number = 1
): string | undefined => ): string | undefined =>
candles && candles &&
candles.reduce( candles.reduce(
(acc, c) => (acc, c) =>
new BigNumber(acc) new BigNumber(acc).plus(toBigNum(c.notional, decimalPlaces)).toString(),
.plus(
BigNumber(addDecimal(c.volume, positionDecimalPlaces)).times(
addDecimal(c.high, marketDecimals)
)
)
.toString(),
'0' '0'
); );

View File

@ -50,6 +50,7 @@ const createCandle = (
high: '110', high: '110',
low: '90', low: '90',
volume: '1', volume: '1',
notional: '100',
periodStart: '2022-11-01T15:49:00Z', periodStart: '2022-11-01T15:49:00Z',
}; };
return merge(defaultCandle, override); return merge(defaultCandle, override);