const marginForOrders = 40;

const cupDrawer = {
  clear: (ctx: CanvasRenderingContext2D, size: CanvasSize) => {
    ctx.clearRect(0, 0, size.width, size.height);
  },
  draw: (
    ctx: CanvasRenderingContext2D,
    size: CanvasSize,
    dpiScale: number,
    bestBidPrice: number,
    bestAskPrice: number,
    maxVolume: number,
    pricePrecision: number,
    quantityPrecision: number,
    priceStep: number,
    zoom: number,
    rowCount: number,
    camera: number,
    cellHeight: number,
    zoomedBestMicroPrice: any,
    darkMode: boolean,
    volumeAsDollars: boolean,
    cup: {[key: number]: CupItem},
    history: CupHistory,
    positions: Record<string, AccountPosition>,
    openOrders: Record<string, AccountOpenOrder>,
    symbol: string,
  ) => {
    const zoomedTickSize = priceStep * zoom;
    const startMicroPrice = camera + rowCount / 2 * zoomedTickSize - zoomedTickSize;
    const quantityDivider = Math.pow(10, quantityPrecision);
    const priceDivider = Math.pow(10, pricePrecision);
    const fullWidthAsMarginForOrders = size.width - (marginForOrders * dpiScale);

    for (let index = 0; index <= rowCount; index++) {
      const microPrice = startMicroPrice - index * zoomedTickSize;

      if (microPrice < 0) continue;

      const item = cup[microPrice] || {};
      let side = "undefined" !== typeof item?.bid
        ? "bid"
        : "undefined" !== typeof item?.ask ? "ask" : "";

      if ("" === side || (!item?.bid && !item.ask)) {
        side = (microPrice >= (zoomedBestMicroPrice?.buy || zoomedBestMicroPrice?.sell || 0) ? "ask" : "bid");
      }

      const historyItemAsk = history.ask[microPrice] || {};
      const historyItemBid = history.bid[microPrice] || {};

      let historyItem: CupHistoryItem;

      side === "ask"
        ? historyItem = historyItemAsk
        : historyItem = historyItemBid;

      const yPosition = cellHeight * index;
      const quantity = volumeAsDollars
        ? ((side === "bid" ? item?.bid || 0 : item?.ask || 0) / quantityDivider) * (microPrice / priceDivider)
        : (side === "bid" ? item?.bid || 0 : item?.ask || 0) / quantityDivider;

      const isBestPrice = cupTools.isBestPrice(
        side,
        microPrice,
        zoomedBestMicroPrice,
      );

      if ((microPrice / zoomedTickSize) % 5 === 0) {
        ctx.beginPath();
        ctx.strokeStyle = darkMode ? "#232425" : "#dddedf";
        ctx.lineWidth = Math.max(1, dpiScale);
        ctx.moveTo((marginForOrders * dpiScale), yPosition);
        ctx.lineTo(size.width, yPosition);
        ctx.stroke();
      }

      if (Object.keys(historyItem).length !== 0) {
        cupDrawer.drawHistoryTcks(
          ctx,
          historyItem.tcks,
          cupTools.microPriceToReal(microPrice, pricePrecision),
          quantity,
          side,
          maxVolume,
          isBestPrice,
          yPosition,
          cellHeight,
          fullWidthAsMarginForOrders,
          dpiScale,
          quantityDivider,
          darkMode
        );
      }

      cupDrawer.drawCell(
        ctx,
        quantity,
        side,
        maxVolume,
        isBestPrice,
        yPosition,
        cellHeight,
        fullWidthAsMarginForOrders,
        dpiScale,
        darkMode
      );

      if (isBestPrice) {
        cupDrawer.drawFill(
          ctx,
          quantity,
          side,
          maxVolume,
          yPosition,
          cellHeight,
          fullWidthAsMarginForOrders,
          dpiScale,
          darkMode
        );
      }

      cupDrawer.drawPrice(
        ctx,
        cupTools.microPriceToReal(microPrice, pricePrecision),
        side,
        isBestPrice,
        yPosition,
        cellHeight,
        fullWidthAsMarginForOrders,
        dpiScale,
        darkMode
      );

      cupDrawer.drawQuantity(
        ctx,
        cupTools.abbreviateNumber(quantity),
        side,
        isBestPrice,
        yPosition,
        cellHeight,
        fullWidthAsMarginForOrders,
        dpiScale,
        darkMode
      );

    }

    if(openOrders) {
      let filteredOrders = Object.values(openOrders).filter(o => o.symbol === symbol);

      if(filteredOrders.length > 0) {
        filteredOrders.forEach(order => {
          return cupDrawer.drawOpenOrder(
            ctx,
            order,
            Object.keys(cup),
            priceDivider,
            cellHeight,
            dpiScale,
            darkMode
          );
        });
      }
    }

    if(positions && positions[symbol]) {
      const position = positions[symbol];

      cupDrawer.drawPosition(
        ctx,
        position,
        priceDivider,
        Object.keys(cup),
        bestBidPrice,
        bestAskPrice,
        cellHeight,
        size,
        dpiScale,
        darkMode
      );
    }
  },

нужно оптимизировать код, сделай это, оптимизируй