fewmath

YAHOO_PRICE_ON_DATE

Nov 4th, 2025 (edited)
141
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  // var url = 'https://query2.finance.yahoo.com/v8/finance/chart/0P0001BM48.F?symbol=0P0001BM48.F&period1=1733961600&period2=1734393600&interval=5d'
  2. /**
  3.  * Fetches the closing price for a Yahoo Finance symbol on a specific date.
  4.  *
  5.  * @param {string} symbol The Yahoo Finance ticker symbol (e.g., "0P00008W4T.F").
  6.  * @param {Date} date The target date (e.g., a cell reference like A2).
  7.  * @return {number} The closing price, or an error message if not found.
  8.  * @customfunction
  9.  */
  10. function checkDataStructure(result) {
  11.     // 1. Check if the 'result' object is falsy (null, undefined, etc.)
  12.     if (!result) {
  13.       return "ERROR: The data object itself is missing or empty.";
  14.     }
  15.  
  16.     // 2. Check for the 'timestamp' property
  17.     if (!result.timestamp) {
  18.       return "ERROR: 'timestamp' property is missing or invalid in the data.";
  19.     }
  20.  
  21.     // 3. Check for the nested structure step-by-step
  22.     const quoteData = result.indicators?.quote;
  23.  
  24.     // Check for 'indicators' or 'quote' array
  25.     if (!quoteData) {
  26.       return "ERROR: The 'indicators.quote' array is missing or empty.";
  27.     }
  28.  
  29.     // Check if the 'quote' array has at least one element
  30.     if (quoteData.length === 0) {
  31.       return "ERROR: 'indicators.quote' array is empty.";
  32.     }
  33.  
  34.     const firstQuote = quoteData[0];
  35.  
  36.     // Check for the 'close' property on the first element
  37.     if (!firstQuote.close) {
  38.       return "ERROR: The 'close' price is missing or invalid in the first quote element.";
  39.     }
  40.  
  41.     // If all checks pass, the data structure is valid
  42.     return null; // Or return the data if you prefer
  43. }
  44.  
  45. function YAHOO_PRICE_ON_DATE(symbol, date) {
  46.   // Use the date components to create a new Date object at UTC midnight.
  47.   // This is the most reliable way to handle dates passed from Google Sheets.
  48.   const targetDateUTC = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
  49.   const targetTimestamp = Math.floor(targetDateUTC.getTime() / 1000); // Target day's midnight UTC
  50.  
  51.   // Set a range (e.g., 10 days before to 1 day after)
  52.   const oneDay = 24 * 60 * 60; // seconds
  53.   const period1 = targetTimestamp - (10 * oneDay);
  54.   const period2 = targetTimestamp + (1 * oneDay);
  55.   // 2. Construct the URL with a DAILY interval
  56.   const url = `https://query2.finance.yahoo.com/v8/finance/chart/${symbol}?symbol=${symbol}&period1=${period1}&period2=${period2}&interval=1d`;
  57.  
  58.   try {
  59.     const response = UrlFetchApp.fetch(url, {muteHttpExceptions: true});
  60.     const data = JSON.parse(response.getContentText());
  61.    
  62.     const result = data?.chart?.result?.[0];
  63.  
  64.     const validationError = checkDataStructure(result);
  65.     if (validationError) {
  66.       // The checkDataStructure function returned an error string, so we return it.
  67.       return validationError;
  68.     }
  69.  
  70.     const timestamps = result.timestamp;
  71.     const closePrices = result.indicators.quote[0].close;
  72.  
  73.     // 3. Find the matching price
  74.     for (let i = 0; i < timestamps.length; i++) {
  75.       // API timestamps are usually midnight UTC for the end of the trading day.
  76.       if (timestamps[i] === targetTimestamp) {
  77.         const price = closePrices[i];
  78.         if (price !== null) {
  79.           return price;
  80.         }
  81.       }
  82.     }
  83.  
  84.     // Fallback: if the exact timestamp isn't found, return the most recent price
  85.     // *before* the target date, as market data may be delayed or unavailable for the exact day.
  86.     for (let i = timestamps.length - 1; i >= 0; i--) {
  87.         if (timestamps[i] <= targetTimestamp && closePrices[i] !== null) {
  88.             return closePrices[i];
  89.         }
  90.     }
  91.  
  92.  
  93.     return "Price not found for date.";
  94.  
  95.   } catch (e) {
  96.     return `ERROR: ${e.toString()}`;
  97.   }
  98. }
Advertisement
Comments
  • fewmath
    17 hours
    # text 0.28 KB | 0 0
    1. You must fetch the Yahoo Finance code for each stock to use it in this function. It very often coincides with the standard ticker, but it can sometimes be different. There is a daily query limit for yahoo finance, so use this function wisely.
    2.  
    3. Usage: =YAHOO_PRICE_ON_DATE('GOOG', TODAY())
Add Comment
Please, Sign In to add comment