"function combinedUpdateAndRecordPnL() {

  const startTime = new Date(); // Start time for execution time logging

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Trade Log");
  if (!sheet) {
    console.error("Trade Log sheet not found. Please check the sheet name.");
    return;
  }

  let pnlSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PnL");
  if (!pnlSheet) {
    console.error("PnL sheet not found. Please create a sheet named 'PnL'.");
    return;
  }

  // Clear existing content and set headers
  pnlSheet.getRange('A4:K').clearContent();
  pnlSheet.getRange('A4:K4').setValues([["Sl No.", "Buy Date", "Sell Date", "Ticker", "Shares Sold/Bought", "Buy Price", "Sell Price", "Trade Type", "Asset Class", "Broker", "User"]]);

  var data = sheet.getDataRange().getValues();
  if (data.length <= 1) {
    console.error("No data found in Trade Log sheet.");
    return;
  }

  data.shift(); // Remove header row

  let portfolio = new Map();
  let startRow = 5; // Start writing data from row 5
  let pendingTransfers = {}; // Initialize pendingTransfers

  // Function to add positions to the portfolio
  function addToPortfolio(ticker, trade) {
    const key = `${ticker}_${trade.broker}_${trade.user}_${trade.assetClass}`;
    if (!portfolio.has(key)) {
      portfolio.set(key, []);
    }
    trade.ticker = ticker; // Add ticker to each position
    portfolio.get(key).push(trade);
  }

  // Function to remove positions from the portfolio
  function removeFromPortfolio(ticker, broker, user, assetClass, quantity, isShort) {
    const key = `${ticker}_${broker}_${user}_${assetClass}`;
    let positions = portfolio.get(key) || [];

    let remainingQuantity = quantity;
    let removedPositions = [];

    for (let i = 0; i < positions.length && remainingQuantity > 0; i++) {
      let pos = positions[i];
      if (pos.closed || pos.isShort !== isShort) continue;

      let qtyToRemove = Math.min(pos.quantity, remainingQuantity);
      if (qtyToRemove <= 0) continue;

      // Clone the position with the quantity to remove
      let removedPos = Object.assign({}, pos);
      removedPos.quantity = qtyToRemove;
      removedPositions.push(removedPos);

      // Update the original position
      pos.quantity -= qtyToRemove;
      if (pos.quantity <= 0) {
        pos.closed = true;
      }
      remainingQuantity -= qtyToRemove;
    }

    return removedPositions;
  }

  // Function to parse stock split ratio
  function parseSplitRatio(ratioStr) {
    let parts = ratioStr.split(':');
    if (parts.length === 2) {
      let numerator = parseFloat(parts[0]);
      let denominator = parseFloat(parts[1]);
      if (!isNaN(numerator) && !isNaN(denominator) && denominator !== 0) {
        return numerator / denominator;
      }
    }
    return 1; // Default no split
  }

  // Function to apply stock split to positions
  function applyStockSplit(ticker, ratio) {
    portfolio.forEach((positions, key) => {
      positions.forEach(pos => {
        if (pos.ticker === ticker) {
          pos.quantity *= ratio;
          pos.price /= ratio;
          pos.quantity = parseFloat(pos.quantity.toFixed(8));
          pos.price = parseFloat(pos.price.toFixed(8));
        }
      });
    });
  }

  let batchData = [];

  try {
    for (let index = 0; index < data.length; index++) {
      let row = data[index];
      let type = String(row[0]).toLowerCase().trim();
      let date = new Date(row[1]);
      let ticker = String(row[2]).trim();
      let action = String(row[3]).toLowerCase().trim();
      
      // Remove commas before parsing
      let stockQuant = parseFloat(row[4].toString().replace(/,/g, ''));
      let stockPrice = parseFloat(row[5].toString().replace(/,/g, ''));
      
      let assetClass = String(row[8]).trim();
      let broker = String(row[9]).trim();
      let user = String(row[10]).trim();

      let formattedDate = Utilities.formatDate(date, "Asia/Kolkata", "dd-MMM-yyyy");

      if (type === "corp. action" && action === "split") {
        let splitRatio = parseSplitRatio(row[4].toString());
        applyStockSplit(ticker, splitRatio);
      } else if (type === "delivery") {
        if (action === "buy" || action === "sellshort") {
          addToPortfolio(ticker, {
            date: formattedDate,
            quantity: stockQuant,
            price: stockPrice,
            assetClass: assetClass,
            broker: broker,
            user: user,
            closed: false,
            isShort: action === "sellshort"
          });
        } else if (action === "sell" || action === "buytocover") {
          const key = `${ticker}_${broker}_${user}_${assetClass}`;
          let positions = portfolio.get(key) || [];

          let sellQuantity = stockQuant;
          let remainingQuantity = sellQuantity;
          let isShort = action === "buytocover";

          for (let i = 0; i < positions.length && remainingQuantity > 0; i++) {
            let pos = positions[i];
            if (pos.closed || pos.isShort !== isShort) continue;

            let qtyToSell = Math.min(pos.quantity, remainingQuantity);
            if (qtyToSell <= 0) continue;

            let buyPrice = pos.price;
            let sellPrice = stockPrice;

            // Adjust dates and prices for short positions
            let buyDate = isShort ? formattedDate : pos.date;
            let sellDate = isShort ? pos.date : formattedDate;

            // For short positions, flip buy and sell prices
            if (isShort) {
              [buyPrice, sellPrice] = [sellPrice, buyPrice];
            }

            // Add to batchData with placeholder for serial number
            batchData.push([
              0, // Placeholder for serial number
              buyDate,
              sellDate,
              ticker,
              qtyToSell,
              buyPrice.toFixed(2),
              sellPrice.toFixed(2),
              isShort ? "Short" : "Long",
              assetClass,
              broker,
              user
            ]);

            // Update position
            pos.quantity -= qtyToSell;
            if (pos.quantity <= 0) {
              pos.closed = true; // Mark as closed if quantity is zero
            }
            remainingQuantity -= qtyToSell;
          }

          if (remainingQuantity > 0) {
            console.error(`Not enough positions to sell ${sellQuantity} shares of ${ticker} for ${broker} / ${user} / ${assetClass}`);
          }
        }
      } else if (type === "my action") {
        // Handling TransferFrom and TransferTo actions
        if (action === "transferfrom") {
          // Remove positions from the portfolio for this ticker, broker, user, assetClass
          let isShort = false; // Adjust if you have short positions to transfer
          let removedPositions = removeFromPortfolio(ticker, broker, user, assetClass, stockQuant, isShort);

          // Store the removed positions in pendingTransfers
          let transferKey = `${ticker}|${assetClass}|${stockQuant}|${formattedDate}`;
          pendingTransfers[transferKey] = {
            positions: removedPositions
          };
        } else if (action === "transferto") {
          // Retrieve the positions from pendingTransfers and add back to portfolio with new broker and user
          let transferKey = `${ticker}|${assetClass}|${stockQuant}|${formattedDate}`;
          let transferData = pendingTransfers[transferKey];

          if (transferData) {
            let transferredPositions = transferData.positions;

            // Update broker and user to the new ones
            transferredPositions.forEach(pos => {
              pos.broker = broker; // Update to the new broker
              pos.user = user;     // Update to the new user
              // pos.assetClass = assetClass; // assetClass remains the same
              addToPortfolio(ticker, pos);
            });

            // Remove transfer from pendingTransfers
            delete pendingTransfers[transferKey];
          } else {
            console.error(`No matching transferfrom found for transferto action: ${ticker}, ${stockQuant}, ${formattedDate}, ${broker}, ${user}, ${assetClass}`);
          }
        }
      }
    }

    // Assign serial numbers after sorting
    // Sort batchData by Sell Date first, then Buy Date to maintain chronological order
    batchData.sort((a, b) => {
      let dateA = new Date(a[2]); // Sell Date
      let dateB = new Date(b[2]); // Sell Date
      if (dateA - dateB !== 0) {
        return dateA - dateB; // Ascending order by Sell Date
      } else {
        let buyDateA = new Date(a[1]);
        let buyDateB = new Date(b[1]);
        return buyDateA - buyDateB;
      }
    });

    // Now assign serial numbers
    for (let i = 0; i < batchData.length; i++) {
      batchData[i][0] = i + 1; // Assign serial number
    }

    if (batchData.length > 0) {
      pnlSheet.getRange(startRow, 1, batchData.length, batchData[0].length).setValues(batchData);
    }

    // Format the "Buy Price" and "Sell Price" columns
    pnlSheet.getRange('F5:G').setNumberFormat('#,##0.00');

    // Record the last update date and time
    let now = new Date();
    let formattedNow = Utilities.formatDate(now, "Asia/Kolkata", "dd-MMM-yyyy HH:mm:ss");
    pnlSheet.getRange('E1').setValue(formattedNow);

  } catch (error) {
    console.error(`Error processing trades: ${error.message}`);
    console.error(`Stack trace: ${error.stack}`);
  }

  // Calculate and log execution time
  const endTime = new Date();
  const executionTime = (endTime - startTime) / 1000; // Time in seconds
  outputSheet.getRange('C3').setValue(`Execution time: ${executionTime} seconds`);

}"

ye is script ka log h 

"5:36:29 PM	Notice	Execution started
5:36:31 PM	Error	Not enough positions to sell 532.09 shares of MUTF_IN:FRAN_INDI_FOCU_1D6ANMY for ICICI / YKM / Equity
5:36:31 PM	Error	Not enough positions to sell 213.15 shares of MUTF_IN:NIPP_INDI_GOLD_1B7Z70X for ICICI / YKM / Equity
5:36:32 PM	Error	Not enough positions to sell 3861.9 shares of MF:L&T_Merged for ICICI / YKM / Equity
5:36:35 PM	Error	
ReferenceError: outputSheet is not defined
combinedUpdateAndRecordPnL	@ 3. PnL_EachTrade_Delivery.gs:266"

is script me bhi floating point precision error h shyad isliye 

"5:36:31 PM	Error	Not enough positions to sell 532.09 shares of MUTF_IN:FRAN_INDI_FOCU_1D6ANMY for ICICI / YKM / Equity
5:36:31 PM	Error	Not enough positions to sell 213.15 shares of MUTF_IN:NIPP_INDI_GOLD_1B7Z70X for ICICI / YKM / Equity
5:36:32 PM	Error	Not enough positions to sell 3861.9 shares of MF:L&T_Merged for ICICI / YKM / Equity"

msg ara h jbki "PnL" me output shai ara h.

ek aur baat  "ReferenceError: outputSheet is not defined
combinedUpdateAndRecordPnL	@ 3. PnL_EachTrade_Delivery.gs:266"

iske liye reference sheet "PnL" hai

sahi kr do.

full corrected code likh do.

baki koi I repeat koi changes nhi krna. sb intact rakhna na km krna an add krna .

karo