react typescript, klinechart charting library. You need to access market data as here https://www.binance.com/ru/futures/DOGEUSDT
here is my code
import React, {useState, useEffect, ChangeEvent} from “react”;
import {
Badge, Box,
Button,
ButtonGroup,
Chip,
CircularProgress,
Grid,
Icon, IconButton, Skeleton, TextField,
Typography
} from “@mui/material”;
import ArrowUpwardRoundedIcon from ‘@mui/icons-material/ArrowUpwardRounded’;
import ArrowDownwardRoundedIcon from ‘@mui/icons-material/ArrowDownwardRounded’;
import {useAuthContext} from “…/…/AuthProvider/AuthProvider”;
import FormatPrice from “…/…/Common/FormatPrice”;
import {Order, readCandlesByTrade, readOrderByTrade, Trade, updateTrade} from “…/…/…/actions/cicap-diary-trades”;
import DataTable from “…/…/DataTable/DataTable”;
import {useSnackbar} from “notistack”;
import {CandleChart} from “…/CandleChart/CandleChart”;
import {TradeEntity} from “…/CandleChart/CandleChart.props”;
import {FormattedNumber} from “react-intl”;
import ImageIcon from “next/image”;
import {createTradeImage, deleteTradeImage, tradeImagesCollection, TradeImage} from “…/…/…/actions/cicap-diary-trades-images”;

const timezoneOffset = new Date().getTimezoneOffset() * 60;

interface SideTypeProps {
order: Order;
}

const SideType = ({order}: SideTypeProps) => {
let label = ‘’;
let color = ‘default’;
const icon = order?.side && ‘sell’ === order.side
? ArrowDownwardRoundedIcon
: ArrowUpwardRoundedIcon;

switch (order?.type) {
case ‘limit’:
label = ‘L’;
color = ‘success’
break;
case ‘market’:
label = ‘M’;
color = ‘warning’
break;
case ‘stop_market’:
label = ‘F’;
color = ‘primary’
break;
}

return <>
<Badge
badgeContent={label}
// @ts-ignore
color={color}
>
<Icon component={icon} color=“action” />
</Badge>
</>
}

interface CandlePrice {
timestamp: number;
open: number;
high: number;
low: number;
close: number;
volume: number;
}

interface TradeDetailsProps {
tradeId: string;
defaultChartInterval: string;
}

const TradeDetails = ({tradeId, defaultChartInterval}: TradeDetailsProps) => {
const [trade, setTrade] = useState<{orders: Array<Order>, data: Trade} | undefined>(undefined);
const [orders, setOrders] = useState<Array<TradeEntity>>([]);
const [chartInterval, setChartInterval] = useState(defaultChartInterval);
const [waiting, setWaiting] = useState(false);
const [candleData, setCandleData] = useState<Array<CandlePrice>>([]);
const [images, setImages] = useState<Array<TradeImage>>([]);
const [imageIdDeletion, setImageIdDeletion] = useState<string|null>(null);

const {diaryToken} = useAuthContext();
const [description, setDescription] = useState(‘’);
const [conclusion, setConclusion] = useState(‘’);
const [videoLink, setVideoLink] = useState(‘’);
const {enqueueSnackbar} = useSnackbar();
const ref = React.createRef<HTMLInputElement>();

const fetchTrade = () => {
if (!tradeId || !diaryToken) {
return;
}

setWaiting(true);
readOrderByTrade(tradeId, diaryToken)
.then(data => {
setWaiting(false);
if (!data) return;

const newOrders: Array<TradeEntity> = [];

data.orders.forEach(order => {
const timestamp = Math.floor(order.msTimestamp) - timezoneOffset;

newOrders.push({
time: timestamp,
position: order.side,
value: parseFloat(order.price),
});
});

setTrade(data);
setOrders(newOrders);
});
}

return <> <Box sx={{pr: 2}}>
{
trade?.data.id && candleData ? (<>
<CandleChart
images={images}
candles={candleData}
tradeId={trade?.data.id}
orders={orders}
interval={chartInterval}
openPrice={trade?.data.openPrice}
closePrice={trade?.data.closePrice}
pricePrecision={trade.data.pricePrecision}
quantityPrecision={trade.data.quantityPrecision}
createImage={createImage}
/>
</>) : (<>
<Skeleton variant=“rectangular” height={500} />
</>)
}
</Box>

</>
}

import React, {useEffect, useRef, useState} from “react”;
import {
init,
dispose,
Chart,
DeepPartial,
IndicatorFigureStylesCallbackData,
Indicator,
IndicatorStyle,
KLineData,
utils,
} from “klinecharts”;
import {CandleChartProps} from “./CandleChart.props”;
import CandleChartToolbar from “./CandleChartToolbar”;
import {Style} from “util”;
import {Box, Icon, IconButton, Stack} from “@mui/material”;
import getMinutesTickSizeByInterval from “./utils/getMinutesTickSizeByInterval.util”;
import drawTrade from “./utils/drawTrade.util”;
import drawTradeLines from “./utils/drawTradeLines.util”;
import {BasketIcon, ScreenIcon} from “…/…/icons”;
import {FullScreen, useFullScreenHandle} from “react-full-screen”;;

interface Vol {
volume?: number
}

export const CandleChart = ({
images,
candles,
tradeId,
orders,
interval,
openPrice,
closePrice,
pricePrecision,
quantityPrecision,
createImage
}: CandleChartProps) => {
console.log(candles);

const chart = useRef<Chart|null>();
const paneId = useRef<string>(“”);
const [figureId, setFigureId] = useState<string>(“”)
const ref = useRef<HTMLDivElement>(null);
const handle = useFullScreenHandle();

useEffect(() => {
chart.current = init(chart-{tradeId}, {styles: chartStyles});

return () => dispose(chart-{tradeId});
}, [tradeId]);

useEffect(() => {
const onWindowResize = () => chart.current?.resize();
window.addEventListener(“resize”, onWindowResize);

return () => window.removeEventListener(“resize”, onWindowResize);
}, []);

useEffect(() => {
chart.current?.applyNewData(candles);
chart.current?.overrideIndicator({
name: “VOL”,
shortName: “Объем”,
calcParams: [],
figures: [
{
key: “volume”,
title: “”,
type: “bar”,
baseValue: 0,
styles: (data: IndicatorFigureStylesCallbackData<Vol>, indicator: Indicator, defaultStyles: IndicatorStyle) => {
const kLineData = data.current.kLineData as KLineData
let color: string
if (kLineData.close > kLineData.open) {
color = utils.formatValue(indicator.styles, “bars[0].upColor”, (defaultStyles.bars)[0].upColor) as string
} else if (kLineData.close < kLineData.open) {
color = utils.formatValue(indicator.styles, “bars[0].downColor”, (defaultStyles.bars)[0].downColor) as string
} else {
color = utils.formatValue(indicator.styles, “bars[0].noChangeColor”, (defaultStyles.bars)[0].noChangeColor) as string
}
return { color }
}
}
]
}, paneId.current);
chart.current?.createIndicator(“VOL”, false, { id: paneId.current });
chart.current?.setPriceVolumePrecision(+pricePrecision, +quantityPrecision);
}, [candles]);

useEffect(() => {
if (!orders || orders.length === 0 || candles.length === 0) return;

const minTime = orders[0].time;
const maxTime = orders[orders.length - 1].time;
const needleTime = minTime + (maxTime - minTime) / 2;

chart.current?.scrollToTimestamp(needleTime + 45 * getMinutesTickSizeByInterval(interval) * 60 * 1000);
drawTrade(chart, paneId, orders, interval);
if (openPrice && closePrice) {
let openTime = Infinity;
let closeTime = -Infinity;

orders.forEach(order => {
if (openTime > order.time) {
openTime = order.time;
}

if (closeTime < order.time) {
closeTime = order.time;
}
});

drawTradeLines(
chart,
openPrice,
openTime,
closePrice,
closeTime,
orders[0].position,
paneId,
pricePrecision,
quantityPrecision,
);
}
}, [orders, candles, tradeId]);
return (<> <Stack direction=“row” height={!handle.active ? 550 : “100%”} width=“100%”>
<CandleChartToolbar
setFigureId={setFigureId}
chart={chart} paneId={paneId}
handle={handle}
/>
<Box
ref={ref}
id={chart-${tradeId}}
width=“calc(100% - 55px)”
height={!handle.active ? 550 : “100%”}
sx={{ borderLeft: “1px solid #ddd” }}
>
{
figureId.length > 0 &&
<Stack
sx={{
backgroundColor: “#CBD4E3”,
borderRadius: 1,
position: “absolute”,
zIndex: 10,
right: 80,
top: 30,
border: “1px solid #697669”,
}}
spacing={2}
>
<IconButton sx={{ borderRadius: 1 }} onClick={removeFigure}>
<Icon component={BasketIcon} />
</IconButton>
</Stack>
}
</Box>
</Stack>
</>);
}

In those transactions where there is no closed order, you need to display real-time candles on the chart and calculate the percentage at the current price. This is necessary so that you can follow the transaction in real time. It is necessary that the chart reflects the current situation on the market, as here https://www.binance.com/ru/futures/DOGEUSDT
import { Options, WebSocketHook, JsonValue } from ‘./types’;
export declare const useWebSocket: <T extends JsonValue | null = JsonValue | null>(url: string | (() => string | Promise<string>) | null, options?: Options, connect?: boolean) => WebSocketHook<T, MessageEvent<any> | null>;
useWebSocket