const readOrderByTrade = (
  tradeId: string,
  token: string,
): Promise<{data:Trade,orders:Array<Order>}|undefined> => {
  return diaryClient(
    `/trades/${tradeId}/orders`,
    'get',
    token,
  );
}

  const [trade, setTrade] = useState<{orders: Array<Order>, data: Trade} | undefined>(undefined);
  const [orders, setOrders] = useState<Array<TradeEntity>>([]);
  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);
      });
  }
  const fetchCandleData = () => {
    if (!tradeId || !diaryToken) {
      return;
    }

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

        // @ts-ignore
        const candles = data.data;
        const dataLength = candles.length;
        const kLines = [];

        for (let i = 0; i < dataLength; i += 1) {
          const timestamp = Math.floor(candles[i][0]) - timezoneOffset;

          kLines.push({
            timestamp: timestamp,
            open: parseFloat(candles[i][1]),
            high: parseFloat(candles[i][2]),
            low: parseFloat(candles[i][3]),
            close: parseFloat(candles[i][4]),
            volume: parseFloat(candles[i][5]),
          });

        }
        setCandleData(kLines);
      })
  }
  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";;

// @ts-ignore
const chartStyles: DeepPartial<Style> = {
  candle: {
    bar: {
      upColor: "#4caf50",
      downColor: "#d32f2f",
      noChangeColor: ""
    },
    priceMark: {
      high: {
        textFamily: "Mont",
      },
      low: {
        textFamily: "Mont",
      },
      last: {
        text: {
          family: "Mont",
        }
      }
    },
    tooltip: {
      text: {
        family: "Mont",
        marginLeft: 10,
        marginTop: 8,
        marginRight: 10
      }
    }
  },
  indicator: {
    ohlc: {
      upColor: "red",
      downColor: "red",
      noChangeColor: "red"
    },
    bars: [{
      upColor: "#4caf50",
      downColor: "#d32f2f",
      noChangeColor: ""
    }],
    lastValueMark: {
      show: false,
      text: {
        family: "Mont",
      }
    },
    tooltip: {
      text: {
        family: "Mont",
      },
    },
  },
  xAxis: {
    tickText: {
      family: "Mont",
    }
  },
  yAxis: {
    type: "log",
    tickText: {
      family: "Mont",
    },
  },
  crosshair: {
    horizontal: {
      text: {
        family: "Mont",
      }
    },
    vertical: {
      text: {
        family: "Mont",
      }
    }
  },
  overlay: {
    text: {
      family: "Mont",
    },
    rectText: {
      family: "Mont",
      backgroundColor: "#686D76",
    }
  }
}

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>
  </>);
}

В тех сделках, где нет закрытого ордера нужно отображать на графике свечи в реальном времени и по текущей цене рассчитывать процент. Это нужно, чтобы можно было следить за сделкой в реальном времени. Нужно чтобы график отображал текущую ситуацию на рынке, как здесь https://www.binance.com/ru/futures/DOGEUSDT