Google Finance does not show last closing price after market hours. It just shows last *traded* price instead of *closing* - google-sheets

My query is on stock market of India where I fetch the quotes from =googlefinance function in my google sheet. I was very disappointed to know that the function does not show last closing price. Instead, it shows the last traded price.
Lets take an example of a stock RELIANCE:
=GoogleFinance("NSE:reliance", "price") result is 2498.00 which is incorrect.
Actual closing on Friday, 16 Sep 2022 was 2499.20 as per official National Stock Exchange of India. You may refer to this link for the Close price and the screenshot below
The incorrect quote 2498.00 is the last traded price before market closing
The correct quote is 2499.20 when the markets were closed.
This behavior is common across all stocks of Indian stock market. I have used almost all the parameters those are available in the =googlefinance function but I could not find a way to get the correct stock quote.
Then I decided to scrape the value from the official website using the following without success
<div id="closePrice">2,499.20</div>
//*[#id="closePrice"]
/html/body/div[2]/div[4]/div[2]/div[1]/div[4]/ul/li[6]/div[1]
document.querySelector("#closePrice")
I searched a lot of valuable articles on this site and also on google but could not find a solution which would fetch the desired result. Can someone help me with a way to get 2499.20 as a result for RELIANCE stock either using =googlefinance function or by scraping the value from office website?
Thank you.
Solution suggested by #TheMaster (Thank you so much!)
=LAMBDA(gf,INDEX(gf,ROWS(gf),2))(GOOGLEFINANCE("NSE:RELIANCE", "close",TODAY()-5,15))
Two other ways
=index(GOOGLEFINANCE("NSE:reliance","Close",today()-5,15),4,2)
=query(GOOGLEFINANCE("NSE:reliance","Close",today()-5,15),"select Col2 where Col1 < date '"&TEXT(today()+1, "YYYY-MM-DD")&"' order by Col1 desc limit 1",False)
I am also keen to know which one of these or other methods (if any) will get the results faster without crashes or any other processing issues as my googlesheet is loaded with thousands of stock quotes which will be refreshed every 1 minute.

Only historical prices support close attribute. Use the start date argument to get historical prices and get the last close:
=LAMBDA(gf,INDEX(gf,ROWS(gf),2))(GOOGLEFINANCE("NSE:RELIANCE", "close",TODAY()-5,15))

This is another way of achieving the result.
=query(GOOGLEFINANCE("NSE:reliance","Close",today()-5,15),"select Col2 where Col1 < date '"&TEXT(today()+1, "YYYY-MM-DD")&"' order by Col1 desc limit 1",False)
When I compared performance of both the solutions =LAMBDA and =QUERY on 2500+ stocks, I found query to be more faster than lambda.
Cheers!
However, my main query remains unresolved as no formula of google finance gives today's close until the actual day is over.

Related

Extracting year with max value for calendar day Google Sheets

I have a sheet with daily readings of lake level and temperature. I want to extract the max level for each day of the year, along with the year that the reading occurred. If it occurred more than once on the same day of the year, I'd like the first occurrence. It's easy enough to get the max for each day, but I haven't been able to also extract the year. I'm sure there are other people much more versed in GSheets than me who can figure this out. I also expect it's not that difficult, but I've yet to be able to find something that works.
Here's the sheet:
https://docs.google.com/spreadsheets/d/1kC3L0oDpnnJlFFuB76mUXiz3vGcfT5_fC3YbkE9Xgsg
UPDATE:
The layout you needed was a little different than what I'd first thought.
This QUERY will generate the maximum and minimums per day for your data.
link to sample sheet
=ARRAYFORMULA(QUERY({1*(TEXT('raw data'!A2:A,"mmm d ")&2020),IF('raw data'!B2:C=0,,'raw data'!B2:C)},"select Col1,MAX(Col2),MIN(Col2),MAX(Col3),MIN(Col3) where Col1 is not null group by Col1 order by Col1 label Col1'Day'"))
Then this formula will use those days and values to do a VLOOKUP back into the Raw Data to show the first year on which that value occurred for that day.
=ARRAYFORMULA(VLOOKUP(N(C4:D)&TEXT(B4:B,"mmm d"),{'raw data'!B:B&TEXT('raw data'!A:A,"mmm d"),YEAR('raw data'!A:A)},2,0))
This spreadsheet will be available forever.

Calculating average for more than one month of data

I am writing some formulas that will make up a dashboard that allows for a dynamic look-up of change in waiting times for admission into a hospital. In this case, what I want to do is create a lookback period of 1 month, 3 months, 6 months, and 1 year to see how waiting times have changed during this time at a few locations. It's a bit of a complex issue, but the stripped down data and my example code can be found here (fully shared for editing).
I have successfully gotten the correct formulas for finding 1 month worth of change, but how to apprroach more than 1 month's worth of data eludes me and this is especially problamatic because the date formatting is not standard excel/google sheets data format. As this data will be continously fed into the spreadsheet, I don't think I have the option to modify it either so I think the only option is to come up with some pretty funky formulas that treat months as text. Alternatively, I guess I can also try to make a formula that reformats the text into valid google sheets dates and then use that to make calculations but then while I could probably write that formula, I'd still not know how to get multiple months worth of data processed. Can anyone help take a look at the sheet? (feel free to copy/edit the file if necessary).
try like this:
=QUERY({INDEX(SPLIT(Data!A3:A, "T"),,1), Data!B3:C},
"select avg(Col3)
where Col1 >= "&DATEVALUE(EOMONTH(TODAY(), -4)+1)&"
group by Col2
label avg(Col3)''")
spreadsheet demo

getting a count and sum total for the latest date by category in real time

My original data looks like this:
Original Data
I'm looking for a way for my query to return information ONLY for the latest date associated with each Test. For that date, I am looking to get the count number of customers and the $ Paid total. What's complicating my effort is the fact that multiple people could take the Test at a given date and across dates.
The ideal results should look like something like this:
Ideal Results
I am getting information submitted into this table via Google Forms in real-time hence row range will be dynamic & need a solution that can give me the info I am looking for at any given time.
Here is the one that came the closest for me (although still far off as it does not show the Count or the Total $):
=ARRAYFORMULA(VLOOKUP(QUERY({ROW(A2:A),SORT(A2:D)}, "SELECT MAX(Col1) WHERE Col3 IS NOT NULL GROUP BY Col3 LABEL MAX(Col1)''",0),{ROW(A2:A), SORT(A2:D)},{2,3,4,5},0))
Spreadsheet link for Original data and the results of the above query:
Google Spreadsheet with Original Data
I would really appreciate any insights or help from anybody.
Possible solution (based on your document)
https://docs.google.com/spreadsheets/d/1tADqNS4YtdDrMjToCNy2auKB_eNuMdMEA4ahmYJi_3M/edit?usp=sharing
Details:
Lastest date for a test could be found using FILTER MAX functions
Count for a test (at lastest date) could be found using COUNTIFS
Sum for a test (at lastest date) could be found using SUMIFS

Google Sheet: IMPORTXML from Yahoo Finance [duplicate]

This question already has answers here:
Scraping data to Google Sheets from a website that uses JavaScript
(2 answers)
Closed last month.
I'm trying to import current stock price from yahoo finance. I used a formula from some website and it partially work. I only know how to tell it to look for a specific query and it worked fine for some other data point I need but the price change query changes from
"Fw(500) Pstart(10px) Fz(24px) C($dataRed)"
to
"Fw(500) Pstart(10px) Fz(24px) C($dataGreen)"
depending if the price is up or down for the day.
How do I modify the formula I'm using below to use the "or" operator in this case? so that it will pull the price down whether the stock is up or down for the day. Thanks!
Formula I'm using:
=IMPORTXML("https://finance.yahoo.com/quote/IBM","//span[#class='Fw(500) Pstart(10px) Fz(24px) C($dataRed)']")
I noticed the other answers did not work for me (they may have worked in the past), so I decided to post this solution. Just put the ticker in cell A1 and one or both of the below formulas somewhere else.
Price:
=IFNA(VALUE(IMPORTXML("https://finance.yahoo.com/quote/" & A1, "//*[#class=""D(ib) Mend(20px)""]/span[1]")))
Change:
=IFNA(VALUE(REGEXEXTRACT(IMPORTXML("https://finance.yahoo.com/quote/" & A1,"//*[#class=""D(ib) Mend(20px)""]/span[2]"), "^.*?\s")))
Currently using googlefinance but find it does not update often enough even when updates set to every minute so currently testing if below will allow updates at least with an F5 press within the sheet
This brings in the price and other information (dated 2022/09/27)
=IMPORTXML("https://finance.yahoo.com/quote/SAVA/", "//*[#id=""quote-header-info""]/div[3]/div[1]/div[1]")
If you just want the price: =IFNA(VALUE(IMPORTXML("https://finance.yahoo.com/quote/" & $A1, "//*[#class=""D(ib) Mend(20px)""]/span[1]")))
You could use a more dynamic/generic xpath that doesnt require such specific paths such as this:
This one pulls in both the price and the change:
=ARRAY_CONSTRAIN(transpose(IMPORTXML("https://finance.yahoo.com/quote/IBM:,"//*[#class='Mt(6px)']//span")),1,2)
If you just want the price:
=trim(IMPORTXML("https://finance.yahoo.com/quote/IBM","//*[#class='Mt(6px)']//span"))
If you just want the change:
=IMPORTXML("https://finance.yahoo.com/quote/IBM","//*[#class='Mt(6px)']//span[2]")
Sadly Yahoo Finance changes the XML/HTML structure of its website quite often. The one that works for now is:
=IMPORTXML("https://finance.yahoo.com/quote/IBM/", "//*[#id=""quote-header-info""]/div[3]/div[1]/div/span[1]")
You may always open the HTML structure and use the developer tools to find and copy the X-path.
P.S.1. Though there seem to be a bug and the function can't retrieve data from URLs where there is a dot/point/period "." in the name.
P.S.2. The IMPORTHTML() function can't also fetch the latest price from Yahoo Finance because the information is neither in a table nor a list. You can try the scripts from this page and this page to list all the tables and lists.

On Google Spreadsheet how can you query 'GoogleFinance' for a past exchange rate?

I'd like to know if it is possible to query a past exchange rate on Google Spreadsheet.
For example; using formula =GoogleFinance("CURRENCY:USDEUR") will return the USD/EUR rate at this present moment. How can you retrieve a historic rate?
In order to retrieve the historical rate, you have to use the following formula:
=GoogleFinance("eurusd","price",today()-1,today())
where today()-1, today() is the desired time interval, which can be explicitly defined as the static pair of dates, or implicitly, as the dynamically calculated values, like in the example above. This expression returns a two-column array of the dates and close values. It is important to care about the suitable cell format (date/number), otherwise your data will be broken.
If you want to get the pure row with the date and currency exchange rate without column headers, wrap your formula with the INDEX() function:
=INDEX(GoogleFinance("eurusd","price",today()-1,today()),2,)
To retrieve the exchange rate value only, define the column number parameter:
=INDEX(GoogleFinance("eurusd","price",today()-1,today()),2,2)
To get today's currency exchange rates in Google Docs/Spreadsheet from Google Finance:
=GoogleFinance("eurusd","price",today())
A shorter way to get today's rates:
=GoogleFinance("currency:usdeur")
P.S. There is also the way to get live currency exchange rate in Microsoft Excel.
Try,
=GoogleFinance("usdeur","price",date(2013,12,1),date(2013,12,16))
Make sure that the dates are as per your spreadsheet settings.
Edit as comment, changed date for capturing single day data:-
Only with headers:
=INDEX(GoogleFinance("usdeur","price",date(2013,12,3),date(2013,12,4)),,2)
without headers:
=FILTER(INDEX(GoogleFinance("usdeur","price",date(2013,12,3),date(2013,12,4)),,2),INDEX(GoogleFinance("usdeur","price",date(2013,12,3),date(2013,12,4)),,2)<>"Close")
The instructions for all related to googlefinance are in here: https://support.google.com/docs/answer/3093281
Remember the actual Google Spreadsheets Formulas use semicolon (;) instead of comma (,).
Once made the replacement on some examples would look like this:
For a 30 day INDEX of USD vs EUR you should use (note that in the case of currencies they go together in the same first variable):
=INDEX(GoogleFinance(USDEUR;"price";today()-30;today());2;2)
TIP: You can get the graph over the entire size of the cell by simply changing INDEX for SPARKLINE, like this:
=SPARKLINE(GoogleFinance(USDEUR;"price";today()-30;today());2;2)
Vasim's answer is excellent, however notice if you want the exchange date on that day only, you can omit the range and just specify the day such as the following
=FILTER(INDEX(GoogleFinance("usdeur","price",today()),,2),INDEX(GoogleFinance("usdeur","price",today()),,2)<>"Close")
You may notice that GOOGLEFINANCE will return N/A for some dates, this is because the date is a day off (usually a weekend), what you can do is to get the last working from the specified date, e.g. Jun 21st 2015 is Sunday, so you should request the rate for Jun 19th (Friday), you can do this via WORKDAY function as was suggested here:
WORKDAY("6/21/2015"+1,-1)
So, the resulting formula will look something like that:
INDEX(GoogleFinance("CURRENCY:USDRUB", "price", WORKDAY("6/21/2015"+1,-1),1),2,2)
Additionally, you want to get the exchange rates for future dates you can additionally check if the date is in the future and if so, just use the today date:
WORKDAY(IF("6/21/2099">TODAY(),TODAY(),"6/21/2099")+1,-1)
For bigger spreadsheets, Google Sheets limitations usually will show randomly the following error:
Error Function INDEX parameter 2 value is 2. Valid values are between
0 and 1 inclusive.
Even modifying Index() and GoogleFinance() following the expected parameters GOOGLEFINANCE(ticker, [attribute], [start_date], [end_date|num_days], [interval]) the error will continue.
A workaround is to copy smaller parts into new spreadsheets but often it will fail.
As an alternative, I used ImportXML as web scraper for x-rates historical currency exchange data.
=index(IMPORTXML("https://www.x-rates.com/historical/?from="&N2&"&amount="&K2&"&date="&YEAR(B2)&"-"&TEXT(B2,"mm")&"-"&TEXT(B2,"dd")&"","//td[#class='rtRates']"),1)
I'm assuming column B are dates, K is for amounts and N for currencies.
Randomly it also will fail for a 2000+ rows spreadsheet but overall for my requirement, it worked too much better than GoogleFinance()
ImportXML examples
The ImportXML Guide for Google Docs from beginner to advanced
Other option is using the CurrencyConverter function from this Google Sheets add-on.
It is fast and and has simple syntax. For example,
=CurrencyConverter(100, "USD", "EUR", "2/28/2020")
returns 91.09957183

Resources