tl;dr =ARRAYFORMULA(GOOGLEFINANCE({"AAPL"; "GOOG"}; "price")) returns a single row and not two. What am I doing wrong?
I'm trying to build a portfolio tracker in google sheets. I keep a trading history that tracks buys and sells, from which I derive the current portfolio.
I'd also like to calculate portfolio value at certain points in the past to visualize growth. As part of this exercise I FILTERed the trading history by date, and INDEXed just the ticker symbols:
This formula returns an array - now I want to run GOOGLEFINANCE over each of these cells to get the closing price at the date specified and this is where I am stuck. Simply wrapping this range in a GOOGLEFINANCE does not work as it will return only one cell, in this case, the price of AAPL:
Essentially I'm looking for some sort of map/reduce functionality. I have heard that ARRAYFUNCTION sort of does that but thruthfully I don't understand how it works and at least it seems like it doesn't do what I expect it to.
Temporary tables would of course do the trick but I would like to keep those to a minimum and just do everything in one massive formula.
GOOGLEFINANCE is not supported under ARRAYFORMULA. however, you can build an array like this:
={GOOGLEFINANCE("AAPL");
GOOGLEFINANCE("GOOG")}
So here is the situation. I have one spreadsheet in Google sheets that has a column for the names of TV stations. I have a second column that lists airing times for ads. This is the format the date and times are in.
14-12-22 08:06:05
I have a second sheet that has the same column for TV station names. I also have a column that has a time range in the format
09:00-16:00
Then there is a third column for Rate.
What I am trying to do is add a Rate column to the first spreadsheet and populate that my matching up the TV Station name and the time range on the second sheet. My first thought was a VLOOKUP but I'm trying to match 2 conditions with the second one being a bit tricky since I am using an exact time vs a time range.
Any ideas?
As it is permitted to parse the time intervals I would recommend doing so (say with something like =SPLIT(A1,"-") since the results might then be arranged into a compact matrix such as shown in the image in ColumnsF:J. The differences in the rates for different stations at different times are readily apparent.
I have left the above in the same sheet as one with a representation of your other data since I (am lazy and) don't know the relevant sheet names anyway - but prefix the relevant sheet name (and !) to the column references in the formula that are later in the alphabet than C:
=vlookup(A2,F:J,match(C2,$G$1:$J$1,1)+1,0)
With extraction of the time element (into ColumnC) of your data (from ColumnA) the formula attempts to find the time from C in the first row, but accepts an inexact comparison by defaulting to the next lower value where there is no exact match. Once found, the MATCH() function returns the position of the match relative to the start of the range searched.
This is then used in a VLOOKUP() function to determine how far across to return the result of a search for the exact A column value in ColumnF.
Details of the syntax of the functions may be found via Help > Function list.
For reference, please visit this Google Doc which is a simplified example of my problem, which is to determine total sales in Blue and Green markets each month.
Each month, I receive a new sales report from accounting for all of our markets and I add the sheet to the main workbook. My team is in charge of assigning "colors" to the markets and tracking this. As it's privileged information, we can't have accounting auto-tag these in the data they send over.
One solution would be, for each new monthly report that comes in, tag each city with the color. However, we have hundreds of markets and this isn't very practical to go through each time.
I assume that a SUMIFS function would work here, but am unsure how to set it up when there are values spread across multiple sheets.
You can use this function in B8 of February tab:
=SUM(IF(COUNTIFS($A$2:$A$5,Color!$A$2:$A$5,Color!$B$2:$B$5,'Sales February'!A8)>0,$B$2:$B$5,0))
COUNTIFS($A$2:$A$5,Color!$A$2:$A$5,Color!$B$2:$B$5,'Sales February'!A8)>0 gets an array of the countries that belong to the colour specified in A8 of the current tab (Would that be possible to put only Green and remove February Sales from that cell?).
If the country belongs to the particular colour, then return the array of corresponding values in column $B$2:$B$5.
Lastly, sum this array.
Note:
You need to array enter this formula in Excel (by holding Ctrl+Shift then hit Enter after typing in the formula).
In Google Spreadsheets, you array enter a formula by wrapping the formula around =ArrayFormula(), meaning you use:
=ArrayFormula(SUM(IF(COUNTIFS($A$2:$A$5,Color!$A$2:$A$5,Color!$B$2:$B$5,'Sales February'!A8)>0,$B$2:$B$5,0)))
In Excel you can use this "array formula"
=SUM(SUMIF(A$2:A$5,IF(Color!B$2:B$5=A8,Color!A$2:A$5),B$2:B$5))
confirmed with CTRL+SHIFT+ENTER
The same formula works in google docs if wrapped in arrayformula, i.e.
=arrayformula(SUM(SUMIF(A$2:A$5,IF(Color!B$2:B$5=A8,Color!A$2:A$5),B$2:B$5)))
or you can use FILTER as user3465711 suggests, i.e.
=SUM(filter(B$2:B$5,isnumber(match(A$2:A$5,IF(Color!B$2:B$5=A8,Color!A$2:A$5),0))))
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
I have essentially a log file in a Google Sheets. Columns are "Date/time", "user", "asset accessed", and there will be multiple entries for the same date, though usually not time.
I'd like to use the timeline graph to show user activity, but the graph requires an aggregate view with one date (no time) per row, with a numeric count in second col. Is there a way using functions within Google Sheets to generate an aggregate "view" of this data and pass this to the timeline graph?
Well, I guess you'll have to create an auxiliary sheet, or just some columns with the summarized values for you chart.
From your description, I'll assume you're using 3 columns (ABC). Let's use columns D, E and F with the following formulas:
=ArrayFormula(Trunc(A:A))
=Unique(D:D)
=ArrayFormula(CountIf(D:D;E:E))
Since date values are actually a number (qtt of days since the epoch), and hours are decimals, the Trunc formula gets rid of the "time" part and leaves only the date. Just format the cells (apparently numbers) as dates and you'll see. Then Unique and CountIf do the summarizing.
There's surely different ways of doing this, perhaps more "elegantly", in a single formula. But I think that in this way it's more easy to understand and learn from. Also, you'll probably need to adapt the ranges to your actual columns positions (I hope that's not a problem).