Core Utilities


The following core utility functions are required by almost every technical indicator in this library. You must copy these into your script editor alongside any individual indicators you choose to use.

GetData.js

This function handles the ingestion of spreadsheet ranges, normalizing date formats and ensuring that header rows are processed correctly. It is compatible with both static ranges and dynamic outputs like =GOOGLEFINANCE().

GetData.js
/**
 * Processes a 2D array of cell values, handling headers and converting data types.
 * This version is compatible with both direct ranges and function outputs (e.g., GOOGLEFINANCE).
 *
 * @param {Array<Array>} data - A 2D array of cell values to process.
 * @returns {Array<Array>} - A 2D array where the first row contains headers and subsequent rows contain processed data.
 * @customfunction
 */
function getData(data) {
  if (!Array.isArray(data) || data.length === 0) {
    throw new Error("Input data must be a non-empty array.");
  }

  const nonEmptyRows = data.filter(row => Array.isArray(row) && row.some(cell => cell !== null && cell !== undefined && cell !== ""));
  if (nonEmptyRows.length === 0) {
      throw new Error("Input range is empty or contains no data.");
  }

  const headers = nonEmptyRows[0].every(item => typeof item === 'string') ? nonEmptyRows[0] : null;
  const dataToProcess = headers ? nonEmptyRows.slice(1) : nonEmptyRows;

  if (dataToProcess.length === 0 && headers) {
      throw new Error("Input range contains only a header row.");
  }

  const processedData = dataToProcess.map(row => {
    return row.map((cell, index) => {
      if (index === 0) {
        if (cell instanceof Date) return cell;
        const date = new Date(cell);
        if (isNaN(date.getTime())) throw new Error(`Invalid date format in cell: "${cell}"`);
        return date;
      }
      const value = parseFloat(cell);
      return isNaN(value) ? 0 : value;
    });
  });

  return headers ? [headers, ...processedData] : processedData;
}

Utility Functions

The following mathematical alignment and smoothing functions are used by indicators like MACD and RSI to ensure data consistency across multiple periods.

utils.js
/**
 * Aligns the lengths of two 2D arrays based on their date values (first column).
 * Used when comparing indicators with different calculation lag.
 */
function alignLENGTHS(data1, data2) {
  const dates1 = data1.map(row => new Date(row[0]).getTime());
  const dates2 = data2.map(row => new Date(row[0]).getTime());
  
  const commonDates = dates1.filter(d => dates2.includes(d));
  
  const aligned1 = data1.filter(row => commonDates.includes(new Date(row[0]).getTime()));
  const aligned2 = data2.filter(row => commonDates.includes(new Date(row[0]).getTime()));
  
  return [aligned1, aligned2];
}