"function generateTrade(stockQuant, stockPrice, action, assetClass, broker, user, date, tradeType) {
  return {
    shares: stockQuant,
    price: stockPrice,
    action: action,
    assetClass: assetClass,
    broker: broker,
    user: user,
    date: date,
    type: tradeType
  };
}

function generateFifo(type, date, security, actions, quantity, price, assetClass, broker, user) {
  let positionsMap = new Map();

  for (var i = 0; i < security.length; i++) {
    // Skip empty rows
    if (!security[i] && !actions[i] && !quantity[i] && !price[i]) {
      continue;
    }
    var currentType = type[i] ? type[i].toString().trim().toLowerCase() : '';
    var currentDate = date[i] ? new Date(date[i]) : new Date();
    var ticker = security[i] ? security[i].toString().trim() : '';
    var action = actions[i] ? actions[i].toString().trim().toLowerCase() : '';

    var stockQuant = Number(quantity[i]) || 0;
    var stockPrice = Number(price[i]) || 0;

    var currentAssetClass = assetClass && assetClass[i] ? assetClass[i] : 'Unknown';
    var currentBroker = broker && broker[i] ? broker[i] : 'Unknown';
    var currentUser = user && user[i] ? user[i] : 'Unknown';

    let tradeType = '';  // Will determine this based on action

    // Only process delivery trades
    if (currentType === 'delivery') {
      if (action === 'buy') {
        tradeType = 'Long';
        let key = `${ticker}|${currentBroker}|${currentUser}|${currentAssetClass}|${tradeType}`;
        let trade = generateTrade(stockQuant, stockPrice, action, currentAssetClass, currentBroker, currentUser, currentDate, tradeType);
        let activeTrades = positionsMap.get(key);
        if (!activeTrades) {
          positionsMap.set(key, [trade]);
        } else {
          activeTrades.push(trade);
        }
      } else if (action === 'sell') {
        tradeType = 'Long';  // Selling from Long positions
        let key = `${ticker}|${currentBroker}|${currentUser}|${currentAssetClass}|${tradeType}`;
        let activeTrades = positionsMap.get(key);
        if (activeTrades) {
          let sharesToProcess = stockQuant;
          activeTrades.sort((a, b) => new Date(a.date) - new Date(b.date)); // ensure FIFO
          let iTrade = 0;
          while (sharesToProcess > 0 && iTrade < activeTrades.length) {
            let trade = activeTrades[iTrade];
            if (trade.shares <= sharesToProcess) {
              sharesToProcess -= trade.shares;
              activeTrades.splice(iTrade, 1);
            } else {
              trade.shares -= sharesToProcess;
              sharesToProcess = 0;
            }
          }
          if (activeTrades.length == 0) {
            positionsMap.delete(key);
          }
        }
      } else if (action === 'sellshort') {
        tradeType = 'Short';
        let key = `${ticker}|${currentBroker}|${currentUser}|${currentAssetClass}|${tradeType}`;
        let trade = generateTrade(stockQuant, stockPrice, action, currentAssetClass, currentBroker, currentUser, currentDate, tradeType);
        let activeTrades = positionsMap.get(key);
        if (!activeTrades) {
          positionsMap.set(key, [trade]);
        } else {
          activeTrades.push(trade);
        }
      } else if (action === 'buytocover') {
        tradeType = 'Short';  // Covering Short positions
        let key = `${ticker}|${currentBroker}|${currentUser}|${currentAssetClass}|${tradeType}`;
        let activeTrades = positionsMap.get(key);
        if (activeTrades) {
          let sharesToProcess = stockQuant;
          activeTrades.sort((a, b) => new Date(a.date) - new Date(b.date)); // ensure FIFO
          let iTrade = 0;
          while (sharesToProcess > 0 && iTrade < activeTrades.length) {
            let trade = activeTrades[iTrade];
            if (trade.shares <= sharesToProcess) {
              sharesToProcess -= trade.shares;
              activeTrades.splice(iTrade, 1);
            } else {
              trade.shares -= sharesToProcess;
              sharesToProcess = 0;
            }
          }
          if (activeTrades.length == 0) {
            positionsMap.delete(key);
          }
        }
      }
    } else if (currentType === 'corp. action' && action === 'split') {
      // process split
      let splitRatioStr = quantity[i].toString();
      let ratioParts = splitRatioStr.split(':');
      let numerator = parseFloat(ratioParts[0]);
      let denominator = parseFloat(ratioParts[1]);
      let ratio = numerator / denominator;
      positionsMap.forEach((value, pKey) => {
        if (pKey.startsWith(`${ticker}|`)) {
          value.forEach(trade => {
            trade.shares *= ratio;
            trade.price /= ratio;
          });
        }
      });
    } else if (currentType === 'my action') {
      if (action === 'transferfrom') {
        // Assuming transfer applies to Long positions
        tradeType = 'Long';
        let transferKey = `${ticker}|${currentBroker}|${currentUser}|${currentAssetClass}|${tradeType}`;
        let newBroker = broker[i + 1] ? broker[i + 1] : 'Unknown';
        let newKey = `${ticker}|${newBroker}|${currentUser}|${currentAssetClass}|${tradeType}`;
        let activeTrades = positionsMap.get(transferKey);
        if (activeTrades) {
          let sharesToTransfer = stockQuant;
          let totalAvailableShares = activeTrades.reduce((sum, trade) => sum + trade.shares, 0);
          if (sharesToTransfer > totalAvailableShares) {
            continue; // Skip this transfer if not enough shares
          }
          let transferredTrades = [];
          activeTrades.sort((a, b) => new Date(a.date) - new Date(b.date)); // ensure FIFO
          while (sharesToTransfer > 0 && activeTrades.length > 0) {
            let trade = activeTrades[0];
            if (trade.shares <= sharesToTransfer) {
              sharesToTransfer -= trade.shares;
              transferredTrades.push({ ...trade }); // Copy trade to new broker
              activeTrades.splice(0, 1);
            } else {
              let transferredTrade = { ...trade, shares: sharesToTransfer };
              trade.shares -= sharesToTransfer;
              sharesToTransfer = 0;
              transferredTrades.push(transferredTrade);
            }
          }
          if (activeTrades.length == 0) {
            positionsMap.delete(transferKey);
          }
          // Add transferred trades to new broker
          let newActiveTrades = positionsMap.get(newKey);
          if (!newActiveTrades) {
            positionsMap.set(newKey, transferredTrades);
          } else {
            newActiveTrades.push(...transferredTrades);
          }
        }
      }
    }
  }
  return positionsMap;
}

function myPositions(type, date, security, actions, quantity, price, assetClass, broker, user) {
  let positionsMap = generateFifo(type, date, security, actions, quantity, price, assetClass, broker, user);
  let returnArry = [['SN.', 'Ticker', 'Type', '# Shares', 'Avg. Buy @', 'Asset Class', 'Broker', 'User']];
  let sn = 1;
  let sortedKeys = Array.from(positionsMap.keys()).sort();
  sortedKeys.forEach(key => {
    let value = positionsMap.get(key);
    let totalShares = 0;
    let totalCost = 0;
    let avgPrice = 0;
    let [ticker, currentBroker, currentUser, currentAssetClass, longOrShort] = key.split('|');
    value.forEach(trade => {
      totalShares += trade.shares;
      totalCost += trade.shares * trade.price;
    });
    avgPrice = totalShares > 0 ? totalCost / totalShares : 0;

    returnArry.push([
      sn++,
      ticker,
      longOrShort,
      Number(totalShares.toFixed(2)), // **Shares as Number**
      avgPrice.toFixed(2),             // Avg. Buy @ remains as String
      currentAssetClass,
      currentBroker,
      currentUser
    ]);
  });
  return returnArry;
}"

this code is based on 

"function updateOpenPortfolio() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Trade Log");
  if (!sheet) {
    Logger.log("Trade Log sheet not found. Please check the sheet name.");
    return;
  }

  var portfolioSheet = ss.getSheetByName("Portfolio");
  if (!portfolioSheet) {
    portfolioSheet = ss.insertSheet("Portfolio");
  }

  // Set headers if they are not already set
  var headerRange = portfolioSheet.getRange('A3:H3');
  var currentHeaders = headerRange.getValues()[0];
  var newHeaders = ["SN.", "Ticker", "Type", "# Shares", "Avg. Buy @", "Asset Class", "Broker", "User"];

  // Only set headers if they are different
  if (JSON.stringify(currentHeaders) !== JSON.stringify(newHeaders)) {
    headerRange.setValues([newHeaders]);
  }

  // Clear existing data in columns A to H starting from row 4
  var lastRow = portfolioSheet.getLastRow();
  if (lastRow > 3) {
    portfolioSheet.getRange(4, 1, lastRow - 3, 8).clearContent(); // Clear only columns A to H
  }

  // Batch read data from the Trade Log
  var dataRange = sheet.getRange(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn());
  var data = dataRange.getValues();

  if (data.length === 0) {
    Logger.log("No data found in Trade Log sheet.");
    return;
  }

  // Process header row
  var headers = data[0].map(header => header.toString().trim().toLowerCase());
  var expectedHeaders = {
    "type": ["type"],
    "date": ["date"],
    "security": ["security"],
    "action": ["action"],
    "quantity": ["quantity"],
    "@price": ["@price", "price"],
    "asset class": ["asset class"],
    "broker": ["broker"],
    "user": ["user"]
  };

  var headerIndices = {};
  var missingHeaders = [];

  for (var key in expectedHeaders) {
    var found = false;
    for (var i = 0; i < expectedHeaders[key].length; i++) {
      var possibleHeader = expectedHeaders[key][i].toLowerCase();
      var idx = headers.indexOf(possibleHeader);
      if (idx !== -1) {
        headerIndices[key] = idx;
        found = true;
        break;
      }
    }
    if (!found) {
      missingHeaders.push(key);
    }
  }

  if (missingHeaders.length > 0) {
    Logger.log("Missing Headers:", missingHeaders.join(", "));
    throw new Error("One or more required columns are missing in Trade Log sheet.");
  }

  var positionsMap = new Map();
  var pendingTransfers = {};

  function addPosition(ticker, assetClass, broker, user, position) {
    var key = `${ticker}|${assetClass}|${broker}|${user}`; // Changed delimiter to '|'
    if (!positionsMap.has(key)) {
      positionsMap.set(key, []);
    }
    positionsMap.get(key).push(position);
  }

  function removePositions(ticker, assetClass, broker, user, quantity) {
    var key = `${ticker}|${assetClass}|${broker}|${user}`; // Changed delimiter to '|'
    var remainingQuantity = quantity;
    var removedPositions = [];

    if (positionsMap.has(key)) {
      var positions = positionsMap.get(key);
      positions.sort((a, b) => new Date(a.date) - new Date(b.date)); // FIFO
      positionsMap.set(key, positions.filter(pos => {
        if (remainingQuantity <= 0) return true;
        if (pos.quantity <= remainingQuantity) {
          removedPositions.push({ ...pos });
          remainingQuantity -= pos.quantity;
          return false;
        } else {
          var splitPos = { ...pos, quantity: remainingQuantity };
          removedPositions.push(splitPos);
          pos.quantity -= remainingQuantity;
          remainingQuantity = 0;
          return true;
        }
      }));
    }
    return removedPositions;
  }

  for (var i = 1; i < data.length; i++) {
    var row = data[i];

    // Check if the row is empty
    if (row.every(cell => cell === "")) {
      continue; // Skip empty rows
    }

    var type = row[headerIndices["type"]].toString().trim().toLowerCase();
    var date = new Date(row[headerIndices["date"]]);
    var action = row[headerIndices["action"]].toString().trim().toLowerCase();
    var ticker = row[headerIndices["security"]].toString().trim();
    var quantity = parseFloat(row[headerIndices["quantity"]]) || 0;
    var price = parseFloat(row[headerIndices["@price"]]) || 0.0;
    var assetClass = row[headerIndices["asset class"]].toString().trim();
    var broker = row[headerIndices["broker"]].toString().trim();
    var user = row[headerIndices["user"]].toString().trim();

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

    if (type === "delivery") {
      if (action === "buy" || action === "sellshort") {
        addPosition(ticker, assetClass, broker, user, {
          date: formattedDate,
          quantity: quantity,
          price: price,
          tradeType: action === "buy" ? "Long" : "Short"
        });
      } else if (action === "sell" || action === "buytocover") {
        removePositions(ticker, assetClass, broker, user, quantity);
      }
    } else if (type === "my action") {
      if (action === "transferfrom") {
        var transferKey = `${ticker}|${assetClass}|${quantity}|${formattedDate}|${broker}|${user}`; // Changed delimiter to '|'
        pendingTransfers[transferKey] = removePositions(ticker, assetClass, broker, user, quantity);
      } else if (action === "transferto") {
        var transferKey = `${ticker}|${assetClass}|${quantity}|${formattedDate}`; // Changed delimiter to '|'
        var matchingTransfer = Object.keys(pendingTransfers).find(key => key.startsWith(transferKey));
        if (matchingTransfer) {
          pendingTransfers[matchingTransfer].forEach(pos =>
            addPosition(ticker, assetClass, broker, user, pos)
          );
          delete pendingTransfers[matchingTransfer];
        } else {
          Logger.log(`Warning: No matching transfer found for TransferTo action: ${ticker}, ${quantity}, ${formattedDate}`);
        }
      }
    } else if (type === "corp. action" && action === "split") {
      var splitRatio = eval(quantity.toString().replace(":", "/")); // Convert "2:1" to 2/1
      for (var key of positionsMap.keys()) {
        // Check if the key starts with the ticker (ignoring asset class)
        if (key.startsWith(`${ticker}|`)) { // Changed delimiter to '|'
          positionsMap.get(key).forEach(function(pos) {
            if (pos.tradeType === "Long") {
              pos.quantity *= splitRatio; // Adjust quantity for long positions
              pos.price /= splitRatio; // Adjust price for long positions
            } else if (pos.tradeType === "Short") {
              pos.quantity *= splitRatio; // Adjust quantity for short positions
              pos.price /= splitRatio; // Adjust price for short positions
            }
          });
        }
      }
    }
  }

  // Prepare data for output
  var consolidatedPositions = {};

  for (var key of positionsMap.keys()) {
    var [ticker, assetClass, broker, user] = key.split('|'); // Changed delimiter to '|'
    var totalQuantity = 0;
    var totalValue = 0;

    positionsMap.get(key).forEach(function(pos) {
      if (pos.quantity > 0) {
        totalQuantity += pos.quantity;
        totalValue += pos.quantity * pos.price;
      }
    });

    if (totalQuantity > 0) {
      var avgPrice = totalValue / totalQuantity;
      var consolidationKey = `${ticker}|${assetClass}|${broker}|${user}`; // Changed delimiter to '|'
      consolidatedPositions[consolidationKey] = {
        ticker: ticker,
        type: positionsMap.get(key)[0].tradeType,
        quantity: totalQuantity,
        avgPrice: avgPrice,
        assetClass: assetClass,
        broker: broker,
        user: user
      };
    }
  }

  // Convert consolidated positions to array and sort by ticker
  var output = Object.values(consolidatedPositions);
  output.sort((a, b) => a.ticker.localeCompare(b.ticker));

  // Add Sl No. and prepare final sorted output
  var sortedOutput = output.map((item, index) => [
    index + 1, // SN.
    item.ticker,
    item.type,
    item.quantity.toFixed(2), // Format quantity
    item.avgPrice.toFixed(2), // Format average price
    item.assetClass,
    item.broker,
    item.user
  ]);

  // Output to "Portfolio" sheet without affecting formatting
  if (sortedOutput.length > 0) {
    portfolioSheet.getRange(4, 1, sortedOutput.length, sortedOutput[0].length).setValues(sortedOutput);
    portfolioSheet.getRange(4, 4, sortedOutput.length, 2).setNumberFormat('#,##0.00');
  } else {
    Logger.log("No open positions to display.");
  }

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

  Logger.log("Open portfolio updated successfully.");
}"

both give same output but 1st one is custom function which is realtime and 2nd is script which is to be run manually.

both take data in order "Type	Date	Security	Action	Quantity	@Price	Fees	Total ₹ (In/Out)	Asset Class	Broker	User"

so when populating portfolio both codes are not taking "Fees" into concideration i think for calculation of average price of ticker. 

i want it to take "Fees" into consideration for calculation of average price of ticker when they output portfolio.

only want this addition functionality. dont interfear or change any other things . keep all other things intact.