Get average stock price in Google Sheets from a list - google-sheets

I'm trying to get average stock prices from a dynamic list.
In my example, I've made a bought stocks in a few different days. And I've sold some of them (not all). So, I have some stocks available that I want to find out the average price:
How to get an average price from stocks not sold, from the earlier to the latest date without changing manually the list?
Manually, the result must be: $19,82
I've built an example sheet.
Thanks! Any help will be appreciated!

use:
=AVERAGE.WEIGHTED(FILTER(E3:E6; B3:B6="buy"); FILTER(D3:D6; B3:B6="buy"))
update 1:
=INDEX(AVERAGE.WEIGHTED(FILTER(E3:E6; B3:B6="buy"); FILTER(D3:D6; B3:B6="buy")-
{SEQUENCE(COUNTIF(B3:B6; "buy")-1; 1; 0; 0); FILTER(D3:D6; B3:B6="sell")}))
update 2:
=ARRAYFORMULA(AVERAGE.WEIGHTED(FILTER(E3:E6; B3:B6="buy"); IF(0<FILTER(D3:D6; B3:B6="buy")+
IF(0>MMULT(TRANSPOSE((SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy")))>=
TRANSPOSE(SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy")))))*
QUERY({FILTER(D3:D6; B3:B6="buy");-SUM(FILTER(D3:D6; B3:B6="sell"))}; "offset 1"; 0));
SIGN(SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy")))));
MMULT(TRANSPOSE((SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy")))>=
TRANSPOSE(SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy")))))*
QUERY({FILTER(D3:D6; B3:B6="buy");-SUM(FILTER(D3:D6; B3:B6="sell"))}; "offset 1"; 0));
SIGN(SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy"))))); 0); FILTER(D3:D6; B3:B6="buy")+
IF(0>MMULT(TRANSPOSE((SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy")))>=
TRANSPOSE(SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy")))))*
QUERY({FILTER(D3:D6; B3:B6="buy");-SUM(FILTER(D3:D6; B3:B6="sell"))}; "offset 1"; 0));
SIGN(SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy")))));
MMULT(TRANSPOSE((SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy")))>=
TRANSPOSE(SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy")))))*
QUERY({FILTER(D3:D6; B3:B6="buy");-SUM(FILTER(D3:D6; B3:B6="sell"))}; "offset 1"; 0));
SIGN(SEQUENCE(COUNTA(FILTER(D3:D6; B3:B6="buy"))))); 0); 0)))

Related

Google Sheets Pivot Table Merge Empty by ID

So I know that empty cells are the worst for generating pivot tables however I have a huge csv that is generated like this:
ID
QTY
ITEM
DATE
800170
1
Donut
5/21/2022
800170
1
Bun
800170
1
Cake
800169
1
Sandwich
5/20/2022
800169
1
Cake
800169
2
Donut
800168
1
Donut
5/21/2022
800168
1
Cookie
800168
1
Tea
800167
1
Donut
5/22/2022
800167
1
Tea
and this is the pivot table that gets generated from it.
I am wondering if there is a way to have the dates "merged" by ID as an ID will always have the same Date?
Desired Output:
Here is a link to my test google sheet: https://docs.google.com/spreadsheets/d/1Loe3dCe4jqj14ZD7alYkb0IhkysOpArk5ZORtIahjdk/edit?usp=sharing
Unfortunately, the Pivot table has no function that will merge the data based on the ID. What you can do is to populate the date column of your raw data.
Here I created a script that will populate the data based on the previous value.
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('Fill Dates', 'fillDates').addToUi()
}
function fillDates(){
var sh = SpreadsheetApp.getActiveSpreadsheet();
var ss = sh.getSheetByName("Sheet1");//Change this to your sheet name
var dLastRow = ss.getRange("D"+(ss.getLastRow()+1)).getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
var startRow = 2;
var dateCol = 4
var range = ss.getRange(startRow, dateCol, dLastRow, 1);
var data = range.getValues();
var temp = '';
data.forEach(date =>{
if(date[0] != ''){
temp = date[0];
}else{
date[0] = temp
}
})
range.setValues(data)
}
To go to Apps Script, select Extensions > Apps Script. Copy paste the code above, save the script and refresh your spreadsheet. The script will create a custom menu in your spreadsheet and you can click that to run the script.
Demo:
Output:
Let me know if you have any issues or questions.
References:
Extending Google Sheets
Apps Script Spreadsheet Service
try:
=ARRAYFORMULA(QUERY({A2:C, VLOOKUP(ROW(D2:D), IF(D2:D<>"", {ROW(D2:D), D2:D}), 2)},
"select Col1,sum(Col2) where Col2>0 group by Col1 pivot Col4"))
or if you want totals:
=ARRAYFORMULA({QUERY({A:C, VLOOKUP(ROW(D:D), IF(D:D<>"", {ROW(D:D), D:D}), 2)},
"select Col1,sum(Col2) where Col2>0 group by Col1 pivot Col4"),
QUERY({A:B}, "select sum(Col2) where Col2>0 group by Col1 label sum(Col2)'Grand Total'");
{"Grand Total", TRANSPOSE(MMULT(TRANSPOSE(QUERY(QUERY({A:C,
VLOOKUP(ROW(D:D), IF(D:D<>"", {ROW(D:D), D:D}), 2)},
"select sum(Col2) where Col2>0 group by Col1 pivot Col4"), "offset 1", )*1),
SEQUENCE(COUNTUNIQUE(A2:A), 1, 1, ))), SUM(B:B)}})
or if you really love pivot table design:
demo sheet

Dynamically Add Sheets to a Query from a changing Range

On my spreadsheet, I have an "Organisation List" tab, "Schedule" tab and an increasing number of tabs per organisation, such as "BlueEdge Gym".
I have a QUERY formula that lists all dates from the different organisation's tabs schedules into one list on the "Schedule" tab. This makes a master schedule for me to view all organisations in chronological order, and I can see the next job.
Unfortunately, I have to manually add each organisations tab to this query in order to include them in the results.
I would like this to be dynamic from the organisation list, so that any organisation I add to my organisation tab list, will automatically/ dynamically be included into the list of sheets that the query on my schedule tab lists.
I would also like to have the Organisation name listed next to the date to which it corresponds, on the master schedule.
Here's the sheet:
https://docs.google.com/spreadsheets/d/1W3LSAjrshz3Mil6dsYVzKmR4fuL0Nojptl778ppTaEY/edit?usp=sharing
in A2 try:
=QUERY(SHEETNAMES(), "where not Col1 matches 'Schedule|Staff List|Organisation List'", 0)
and in E2:
=SORT(QUERY({
IFERROR(INDIRECT(IF(A2="", 0, A2)&"!D:F"), {"","",""});
IFERROR(INDIRECT(IF(A3="", 0, A3)&"!D:F"), {"","",""});
IFERROR(INDIRECT(IF(A4="", 0, A4)&"!D:F"), {"","",""});
IFERROR(INDIRECT(IF(A5="", 0, A5)&"!D:F"), {"","",""});
IFERROR(INDIRECT(IF(A6="", 0, A5)&"!D:F"), {"","",""});
IFERROR(INDIRECT(IF(A7="", 0, A7)&"!D:F"), {"","",""});
IFERROR(INDIRECT(IF(A8="", 0, A8)&"!D:F"), {"","",""});
IFERROR(INDIRECT(IF(A9="", 0, A9)&"!D:F"), {"","",""})},
"where Col3=FALSE", 0), 1, 1)
or try this more automated solution...
add script:
function onEdit() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Schedule");
var src = sheet.getRange("A2"); // The cell which holds the formula
var str = src.getValue();
var cell = sheet.getRange("E2"); // The cell where I want the results to be
cell.setFormula(str);
}
and use this formula in A2:
=INDEX("=SORT(QUERY({"&JOIN(";", "'"&QUERY(SHEETNAMES(),
"where not Col1 matches 'Schedule|Staff List|Organisation List'", 0)&"'!D:F")&
"}, ""where Col3 = FALSE"", 0), 1, 1)")

Google Sheets SUMIF Text Formula

Ok so, I will arleady say that im not that good with excel and even worse on google sheets.
I would like to know if there is a formula that checks for the name of someone and then sums the points said person got to his total. Thank you very much!
https://docs.google.com/spreadsheets/d/1D4M8Dlao8yFHJulNDff-i2jZJeVGGY_gejbAfzWdhFo/edit?usp=sharing is the link if you want to check it out.
I assume you want Punti tot. (R:R) column to have the sum of all TA Brawl (column C:C), Notte (L:L) and 50 Shades (H:H; in this case any of the two players should be checked, right?) for every player.
You can use put this in R2 (do not forget to remove everything below R2):
={
"Punti tot.";
ARRAYFORMULA(
IF(
P3:P = ""; ;
SUMIF(A3:A; P3:P; C3:C)
+ SUMIF(E3:E; P3:P; H3:H)
+ SUMIF(F3:F; P3:P; H3:H)
+ SUMIF(J3:J; P3:P; L3:L)
)
)
}
Update: here is another solution using QUERY which is also sorts players by total points:
=QUERY(
{
FILTER({A3:A\ C3:C}; A3:A <> "");
FILTER({E3:E\ H3:H}; E3:E <> "");
FILTER({F3:F\ H3:H}; F3:F <> "");
FILTER({J3:J\ L3:L}; J3:J <> "")
};
"
select Col1, SUM(Col2)
group by Col1
order by SUM(Col2) desc,
Col1
label Col1 'Player',
SUM(Col2) 'Punti tot.'
";
-1
)
And you might want to use this in O2 for ranking:
={
"Posizioni Finali";
ARRAYFORMULA(
RANK(
FILTER(Q3:Q; Q3:Q <> "");
FILTER(Q3:Q; Q3:Q <> "")
)
)
}
This way same amount of points gives players the same place. Otherwise hysen would get 9th place and Imurshh would be 10th just because h goes before i.

Summarizing data from multiple sheets

I have a google sheet like this example to track scores for disc golf:
https://docs.google.com/spreadsheets/d/1uxDFXg2kivZWKICeVklugyXH1OWqsq_s5qXZYzgHkt8/edit?usp=sharing
It works great for tracking day to day scores but it would be really awesome to have a single sheet at the beginning that could say everyones total scores that they have gotten. Also note that the names may not be the same in each sheet.
So in this example I would want to have a new sheet that would automatically calculate the scores from the other sheets and show:
Mike 67,71,65
George 83,70
Phillip 79,72,65
John 66,71
Henry 69
I am very unfamiliar with excel formulas and have been struggling to get this started. Any help would be greatly appreciated.
You can use a Google Apps Script to accomplish what you are looking for. The idea of the code is that it will iterate over every Sheet in your Spreadsheet, gather all the players and all their values, and finally create a summary and put it into the "Summary" sheet (that sheet must exist in your Spreadsheet, with strictly the same name):
function updateSummary() {
var sheets = SpreadsheetApp.getActive().getSheets();
var summarySheet = SpreadsheetApp.getActive().getSheetByName('Summary');
var allScores = {};
for (var i=0; i<sheets.length; i++) {
if (sheets[i].getName() == 'Summary') continue;
var nColumns = sheets[i].getLastColumn();
var names = sheets[i].getRange(1, 1, 1, nColumns).getValues()[0];
var scores = sheets[i].getRange(20, 1, 1, nColumns).getValues()[0];
for (var j=0; j<nColumns; j++) {
var currentName = names[j];
var currentScore = scores[j];
if (!allScores.hasOwnProperty(currentName))
allScores[currentName] = [];
allScores[currentName].push(currentScore);
}
}
summarySheet.clear();
for (var key in allScores) {
var row = [key].concat(allScores[key]);
summarySheet.appendRow(row);
}
}
This will create, with the data given, the following data in the "Summary" Sheet:
Instead, if you prefer to have two columns as you described in your question (with the second one holding every score separated by commas), you would simply need to replace the last for-loop in the code above for the following one:
for (var key in allScores) {
var row = [key].concat(allScores[key].join(','));
summarySheet.appendRow(row);
}
Finally, you can create an image in the "Summary" sheet which can serve as a button to run the script. To do so:
Within your Sheet, click on Insert>Image>Image over cells.
Select any image of your choice.
Select the newly created image and click on the three dots icon that appears on the top-right corner of the image.
Click on "Assign script" and put the function name (in this case, updateSummary) and click on OK.
try:
=QUERY(TRANSPOSE({
'MikeGeorgePhillipJohn 121519'!A1:D20,
'MikeGeorgePhillipJohn 122019'!A1:D20,
'MikeJosephPhillipHenry 122719'!A1:D20}),
"select Col1,sum(Col20)
where Col1 is not null
group by Col1
label sum(Col20)''", 0)
=ARRAYFORMULA(SPLIT(TRANSPOSE(QUERY(QUERY(TRANSPOSE({
'MikeGeorgePhillipJohn 121519'!A1:D20,
'MikeGeorgePhillipJohn 122019'!A1:D20,
'MikeJosephPhillipHenry 122719'!A1:D20}),
"select max(Col20)
where Col1 is not null
group by Col20
pivot Col1", 0),,999^99)), " "))

Is there a way to append a New Value at the end of every row in IMPORTRANGE?

I have multiple spreadsheets from which I am importing multiple sheets and then stacking the data vertically. The obstacle I am trying to move past is that every spreadsheet is a different company's information and when I query that information from another sheet that I made I am unable to differentiate the various sources of data from one another. Certainly, I could simply add a column to all of the original spreadsheets with the name of the company and include that in my query formulas, but I would rather use something more dynamic. Alternatively, maybe there is a way to ask a cell where it's value came from.
An example would be:
A2 = "San Diego" B2 = "$2.24" C2 = "Company 1"
A3 = "San Francisco" B3 = "$1.89" C3 = "Company 2"
A4 = "Indianapolis" B4 = "$4.21" C4 = "Company 2"
try something like:
=QUERY(QUERY(IMPORTRANGE("ID", "Sheet1!A:B"), "select Col1,Col2,'Company 1'", 0), "offset 1", 0)
then you could do array like:
={QUERY(QUERY(IMPORTRANGE("ID", "Sheet1!A:B"), "select Col1,Col2,'Company 1'", 0), "offset 1", 0);
QUERY(QUERY(IMPORTRANGE("ID", "Sheet5!C:D"), "select Col1,Col2,'Company 3'", 0), "offset 1", 0)}

Resources