fix(market-depth): fix depth chart data upate, use market depth as mid price source (#3242)
This commit is contained in:
parent
faa359e2fb
commit
9f3026aa4b
@ -74,7 +74,7 @@ describe('updateLevels', () => {
|
||||
|
||||
const updates = [{ price: '132', volume: '200' }];
|
||||
|
||||
expect(updateLevels(priceLevels, updates, 2, 0, true)).toEqual([
|
||||
expect(updateLevels(priceLevels, updates, 2, 0, false)).toEqual([
|
||||
{ price: 1.35, volume: 200 },
|
||||
{ price: 1.32, volume: 200 },
|
||||
{ price: 1.28, volume: 100 },
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { addDecimal } from '@vegaprotocol/utils';
|
||||
import uniqBy from 'lodash/uniqBy';
|
||||
import reverse from 'lodash/reverse';
|
||||
|
||||
interface PriceLevel {
|
||||
price: number;
|
||||
@ -41,9 +43,9 @@ export const updateLevels = (
|
||||
updates: RawPriceLevel[],
|
||||
decimalPlaces: number,
|
||||
positionDecimalPlaces: number,
|
||||
reverse = false
|
||||
ascending = true
|
||||
) => {
|
||||
updates.forEach((update) => {
|
||||
uniqBy(reverse(updates || []), 'price').forEach((update) => {
|
||||
const updateLevel = parseLevel(
|
||||
update,
|
||||
decimalPlaces,
|
||||
@ -63,9 +65,9 @@ export const updateLevels = (
|
||||
}
|
||||
} else if (update.volume !== '0') {
|
||||
index = levels.findIndex((level) =>
|
||||
reverse
|
||||
? level.price < updateLevel.price
|
||||
: level.price > updateLevel.price
|
||||
ascending
|
||||
? level.price > updateLevel.price
|
||||
: level.price < updateLevel.price
|
||||
);
|
||||
if (index !== -1) {
|
||||
levels.splice(index, 0, updateLevel);
|
||||
|
@ -9,6 +9,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||
import type { MarketData } from '@vegaprotocol/market-list';
|
||||
import type {
|
||||
MarketDepthQuery,
|
||||
MarketDepthUpdateSubscription,
|
||||
PriceLevelFieldsFragment,
|
||||
} from './__generated__/MarketDepth';
|
||||
@ -22,6 +23,18 @@ interface DepthChartManagerProps {
|
||||
const formatMidPrice = (midPrice: string, decimalPlaces: number) =>
|
||||
Number(addDecimal(midPrice, decimalPlaces));
|
||||
|
||||
const getMidPrice = (
|
||||
sell: PriceLevelFieldsFragment[] | null | undefined,
|
||||
buy: PriceLevelFieldsFragment[] | null | undefined,
|
||||
decimalPlaces: number
|
||||
) =>
|
||||
buy?.length && sell?.length
|
||||
? formatMidPrice(
|
||||
((BigInt(buy[0].price) + BigInt(sell[0].price)) / BigInt(2)).toString(),
|
||||
decimalPlaces
|
||||
)
|
||||
: undefined;
|
||||
|
||||
type DepthData = Pick<DepthChartProps, 'data' | 'midPrice'>;
|
||||
|
||||
export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
@ -30,6 +43,7 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
const [depthData, setDepthData] = useState<DepthData | null>(null);
|
||||
const dataRef = useRef<DepthData | null>(null);
|
||||
const marketDataRef = useRef<MarketData | null>(null);
|
||||
const rawDataRef = useRef<MarketDepthQuery['market'] | null>(null);
|
||||
const deltaRef = useRef<{
|
||||
sell: PriceLevelFieldsFragment[];
|
||||
buy: PriceLevelFieldsFragment[];
|
||||
@ -56,28 +70,28 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
}
|
||||
dataRef.current = {
|
||||
...dataRef.current,
|
||||
midPrice: marketDataRef.current?.staticMidPrice
|
||||
? formatMidPrice(
|
||||
marketDataRef.current?.staticMidPrice,
|
||||
market.decimalPlaces
|
||||
)
|
||||
: undefined,
|
||||
midPrice: getMidPrice(
|
||||
rawDataRef.current?.depth.sell,
|
||||
rawDataRef.current?.depth.buy,
|
||||
market.decimalPlaces
|
||||
),
|
||||
data: {
|
||||
buy: deltaRef.current.buy
|
||||
buy: deltaRef.current.buy.length
|
||||
? updateLevels(
|
||||
dataRef.current.data.buy,
|
||||
deltaRef.current.buy,
|
||||
market.decimalPlaces,
|
||||
market.positionDecimalPlaces,
|
||||
true
|
||||
false
|
||||
)
|
||||
: dataRef.current.data.buy,
|
||||
sell: deltaRef.current.sell
|
||||
sell: deltaRef.current.sell.length
|
||||
? updateLevels(
|
||||
dataRef.current.data.sell,
|
||||
deltaRef.current.sell,
|
||||
market.decimalPlaces,
|
||||
market.positionDecimalPlaces
|
||||
market.positionDecimalPlaces,
|
||||
true
|
||||
)
|
||||
: dataRef.current.data.sell,
|
||||
},
|
||||
@ -85,16 +99,23 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
deltaRef.current.buy = [];
|
||||
deltaRef.current.sell = [];
|
||||
setDepthData(dataRef.current);
|
||||
}, 1000),
|
||||
}, 250),
|
||||
[market]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
deltaRef.current.buy = [];
|
||||
deltaRef.current.sell = [];
|
||||
}, [marketId]);
|
||||
|
||||
// Apply updates to the table
|
||||
const update = useCallback(
|
||||
({
|
||||
delta: deltas,
|
||||
data: rawData,
|
||||
}: {
|
||||
delta?: MarketDepthUpdateSubscription['marketsDepthUpdate'];
|
||||
delta?: MarketDepthUpdateSubscription['marketsDepthUpdate'] | null;
|
||||
data: NonNullable<MarketDepthQuery['market']> | null;
|
||||
}) => {
|
||||
if (!dataRef.current) {
|
||||
return false;
|
||||
@ -109,6 +130,7 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
if (delta.buy) {
|
||||
deltaRef.current.buy.push(...delta.buy);
|
||||
}
|
||||
rawDataRef.current = rawData;
|
||||
updateDepthData();
|
||||
}
|
||||
return true;
|
||||
@ -116,7 +138,11 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
[marketId, updateDepthData]
|
||||
);
|
||||
|
||||
const { data, error, loading } = useDataProvider({
|
||||
const { data, error, loading } = useDataProvider<
|
||||
NonNullable<MarketDepthQuery['market']> | null,
|
||||
MarketDepthUpdateSubscription['marketsDepthUpdate'],
|
||||
{ marketId: string }
|
||||
>({
|
||||
dataProvider: marketDepthProvider,
|
||||
update,
|
||||
variables,
|
||||
@ -155,9 +181,11 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
return;
|
||||
}
|
||||
dataRef.current = {
|
||||
midPrice: marketData.staticMidPrice
|
||||
? formatMidPrice(marketData.staticMidPrice, market.decimalPlaces)
|
||||
: undefined,
|
||||
midPrice: getMidPrice(
|
||||
data.depth.sell,
|
||||
data.depth.buy,
|
||||
market.decimalPlaces
|
||||
),
|
||||
data: {
|
||||
buy:
|
||||
data.depth.buy?.map((priceLevel) =>
|
||||
@ -177,8 +205,12 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
) ?? [],
|
||||
},
|
||||
};
|
||||
rawDataRef.current = data;
|
||||
setDepthData(dataRef.current);
|
||||
}, [data, marketData, market]);
|
||||
return () => {
|
||||
updateDepthData.cancel();
|
||||
};
|
||||
}, [data, marketData, market, updateDepthData]);
|
||||
|
||||
const volumeFormat = useCallback(
|
||||
(volume: number) =>
|
||||
|
@ -75,6 +75,11 @@ export const OrderbookManager = ({ marketId }: OrderbookManagerProps) => {
|
||||
}, 250)
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
deltaRef.current.buy = [];
|
||||
deltaRef.current.sell = [];
|
||||
}, [marketId]);
|
||||
|
||||
const update = useCallback(
|
||||
({
|
||||
delta: deltas,
|
||||
|
Loading…
Reference in New Issue
Block a user