Skip to content

Commit 714ada5

Browse files
committed
fix(insights): when feeds aren't trading, show last valid price
1 parent 2887d6d commit 714ada5

File tree

4 files changed

+60
-26
lines changed

4 files changed

+60
-26
lines changed

apps/insights/src/components/LivePrices/index.tsx

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { PlusMinus } from "@phosphor-icons/react/dist/ssr/PlusMinus";
44
import type { PriceData, PriceComponent } from "@pythnetwork/client";
5+
import { PriceStatus } from "@pythnetwork/client";
56
import { Skeleton } from "@pythnetwork/component-library/Skeleton";
67
import type { ReactNode } from "react";
78
import { useMemo } from "react";
@@ -39,9 +40,13 @@ const LiveAggregatePrice = ({
3940
cluster: Cluster;
4041
}) => {
4142
const { prev, current } = useLivePriceData(cluster, feedKey);
42-
return (
43-
<Price current={current?.aggregate.price} prev={prev?.aggregate.price} />
44-
);
43+
if (current === undefined) {
44+
return <Price />;
45+
} else if (current.status === PriceStatus.Trading) {
46+
return <Price current={current.price} prev={prev?.price} />;
47+
} else {
48+
return <Price current={current.previousPrice} />;
49+
}
4550
};
4651

4752
const LiveComponentPrice = ({
@@ -101,7 +106,16 @@ const LiveAggregateConfidence = ({
101106
cluster: Cluster;
102107
}) => {
103108
const { current } = useLivePriceData(cluster, feedKey);
104-
return <Confidence confidence={current?.aggregate.confidence} />;
109+
return (
110+
<Confidence
111+
confidence={
112+
current &&
113+
(current.status === PriceStatus.Trading
114+
? current.confidence
115+
: current.previousConfidence)
116+
}
117+
/>
118+
);
105119
};
106120

107121
const LiveComponentConfidence = ({
@@ -153,7 +167,13 @@ export const LiveLastUpdated = ({
153167
});
154168
const formattedTimestamp = useMemo(() => {
155169
if (current) {
156-
const timestamp = new Date(Number(current.timestamp * 1000n));
170+
const timestamp = new Date(
171+
Number(
172+
(current.status === PriceStatus.Trading
173+
? current.timestamp
174+
: current.previousTimestamp) * 1000n,
175+
),
176+
);
157177
return isToday(timestamp)
158178
? formatterWithoutDate.format(timestamp)
159179
: formatterWithDate.format(timestamp);

apps/insights/src/components/PriceFeed/Chart/chart.tsx

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client";
22

3+
import { PriceStatus } from "@pythnetwork/client";
34
import { useLogger } from "@pythnetwork/component-library/useLogger";
45
import { useResizeObserver, useMountEffect } from "@react-hookz/web";
56
import {
@@ -81,28 +82,35 @@ const useChartElem = (symbol: string, feedId: string) => {
8182
return;
8283
}
8384

84-
// Update last data point
85-
const { price, confidence } = livePriceData.aggregate;
8685
const timestampMs = startOfResolution(
8786
new Date(Number(livePriceData.timestamp) * 1000),
8887
resolution,
8988
);
9089

9190
const time = (timestampMs / 1000) as UTCTimestamp;
9291

93-
const priceData: LineData = { time, value: price };
94-
const confidenceHighData: LineData = { time, value: price + confidence };
95-
const confidenceLowData: LineData = { time, value: price - confidence };
92+
if (livePriceData.status === PriceStatus.Trading) {
93+
// Update last data point
94+
const { price, confidence } = livePriceData.aggregate;
9695

97-
const lastDataPoint = chartRef.current.price.data().at(-1);
96+
const priceData: LineData = { time, value: price };
97+
const confidenceHighData: LineData = { time, value: price + confidence };
98+
const confidenceLowData: LineData = { time, value: price - confidence };
9899

99-
if (lastDataPoint && lastDataPoint.time > priceData.time) {
100-
return;
101-
}
100+
const lastDataPoint = chartRef.current.price.data().at(-1);
101+
102+
if (lastDataPoint && lastDataPoint.time > priceData.time) {
103+
return;
104+
}
102105

103-
chartRef.current.confidenceHigh.update(confidenceHighData);
104-
chartRef.current.confidenceLow.update(confidenceLowData);
105-
chartRef.current.price.update(priceData);
106+
chartRef.current.confidenceHigh.update(confidenceHighData);
107+
chartRef.current.confidenceLow.update(confidenceLowData);
108+
chartRef.current.price.update(priceData);
109+
} else {
110+
chartRef.current.price.update({ time, value: undefined });
111+
chartRef.current.confidenceHigh.update({ time, value: undefined });
112+
chartRef.current.confidenceLow.update({ time, value: undefined });
113+
}
106114
}, [livePriceData, resolution]);
107115

108116
function maybeResetVisibleRange() {

apps/insights/src/components/PriceFeedChangePercent/index.tsx

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client";
22

3+
import { PriceStatus } from "@pythnetwork/client";
34
import { StateType, useData } from "@pythnetwork/component-library/useData";
45
import type { ComponentProps } from "react";
56
import { createContext, use } from "react";
@@ -109,15 +110,19 @@ const PriceFeedChangePercentLoaded = ({
109110
}: PriceFeedChangePercentLoadedProps) => {
110111
const { current } = useLivePriceData(Cluster.Pythnet, feedKey);
111112

112-
return current === undefined ? (
113-
<ChangePercent className={className} isLoading />
114-
) : (
115-
<ChangePercent
116-
className={className}
117-
currentValue={current.aggregate.price}
118-
previousValue={priorPrice}
119-
/>
120-
);
113+
if (current === undefined) {
114+
return <ChangePercent className={className} isLoading />;
115+
} else if (current.status === PriceStatus.Trading) {
116+
return (
117+
<ChangePercent
118+
className={className}
119+
currentValue={current.aggregate.price}
120+
previousValue={priorPrice}
121+
/>
122+
);
123+
} else {
124+
return "-";
125+
}
121126
};
122127

123128
class YesterdaysPricesNotInitializedError extends Error {

apps/insights/src/services/clickhouse.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ export const getHistoricalPrices = async ({
377377
AND publisher = {publisher: String}
378378
AND symbol = {symbol: String}
379379
AND version = 2
380+
AND status = 1
380381
WHERE
381382
publishTime >= toDateTime({from: UInt32})
382383
AND publishTime < toDateTime({to: UInt32})

0 commit comments

Comments
 (0)