- Se avete bisogno di importare le quotazioni dei vostri titoli azionari o ETF in Google Sheets in modo che si aggiornino automaticamente, potete usare l’apps script qua sotto.
- Per farlo funzionare occorre semplicemente aprire un foglio di lavoro su https://docs.google.com/spreadsheets/ e andare su Estensioni e Apps Script.
- Cliccare sul + a fianco di File e selezionare Script.
- Dare un titolo a piacere al file (non implica nulla sul funzionamento).
- Elimina il contenuto già presente e incolla lo script che trovi qua di seguito.
- Salva cliccando sull’icona del floppydisk o premi ctrl+s.
- Ora torna nel tuo foglio di spreadsheets e utilizzando le varie funzioni di esempio, avrai il risultato voluto.
/**
* SCRIPT DEFINITIVO – Tutto in uno (2025)
* Funzioni disponibili in Google Sheets:
* =ULTIMO("SWDA.MI") → prezzo attuale
* =VARGIORN("SWDA.MI") → +1.24% (variazione odierna)
* =YTD("SWDA.MI") → +7.18
* =MAXVAL("SWDA.MI"; "2025-01-01") → massimo da data
* =MAXDATE("SWDA.MI"; "2025-01-01") → data massimo
* =MAXINFO("SWDA.MI") → tabella completa
*/
function ULTIMO(ticker) {
if (!ticker) return "Ticker?";
const url = `https://query1.finance.yahoo.com/v8/finance/chart/${ticker}`;
try {
const json = JSON.parse(UrlFetchApp.fetch(url, {muteHttpExceptions: true}).getContentText());
if (json.chart?.error) return "Errore";
return Number(json.chart.result[0].meta.regularMarketPrice.toFixed(4));
} catch (e) { return "—"; }
}
function VARGIORN(ticker) {
if (!ticker) return "Ticker?";
const url = `https://query1.finance.yahoo.com/v8/finance/chart/${ticker}`;
try {
const json = JSON.parse(UrlFetchApp.fetch(url, {muteHttpExceptions: true}).getContentText());
if (json.chart?.error) return "Errore";
const meta = json.chart.result[0].meta;
const cambio = meta.regularMarketPrice - meta.previousClose;
const perc = (cambio / meta.previousClose) * 100;
return Number(perc.toFixed(2));
} catch (e) { return "—"; }
}
function YTD(ticker) {
if (!ticker) return "Ticker?";
const url = `https://query1.finance.yahoo.com/v8/finance/chart/${ticker}?range=ytd&interval=1d`;
try {
const json = JSON.parse(UrlFetchApp.fetch(url, {muteHttpExceptions: true}).getContentText());
if (json.chart?.error) return "Errore";
const result = json.chart.result[0];
if (!result) return "No dati";
// Prova prima adjclose (aggiustati), fallback su quote.close
let prices = result.indicators?.adjclose?.[0]?.adjclose || result.indicators?.quote?.[0]?.close || [];
if (!prices || prices.length === 0) return "No prezzi";
let primo = null, ultimo = null;
for (let p of prices) {
if (p !== null && p !== undefined) {
if (primo === null) primo = p;
ultimo = p;
}
}
if (!primo || !ultimo) return "Dati incompleti";
return Number((((ultimo - primo) / primo) * 100).toFixed(2));
} catch (e) { return "Errore YTD: " + e.toString(); }
}
function MAXVAL(ticker, dataInizio = "") { return _getMaxInfo(ticker, dataInizio, "value"); }
function MAXDATE(ticker, dataInizio = "") { return _getMaxInfo(ticker, dataInizio, "date"); }
function MAXINFO(ticker, dataInizio = "") { return _getMaxInfo(ticker, dataInizio, "full"); }
function _getMaxInfo(ticker, dataInizio, mode) {
if (!ticker) return "Ticker?";
const range = dataInizio ? "5y" : "max";
const url = `https://query1.finance.yahoo.com/v8/finance/chart/${ticker}?range=${range}&interval=1d`;
try {
const json = JSON.parse(UrlFetchApp.fetch(url, {muteHttpExceptions: true}).getContentText());
if (json.chart?.error) return "Errore";
const r = json.chart.result[0];
const prices = r.indicators?.adjclose?.[0]?.adjclose || r.indicators?.quote?.[0]?.close;
const ts = r.timestamp;
const live = r.meta.regularMarketPrice;
const prevClose = r.meta.previousClose;
const cambioGiorno = live - prevClose;
const percGiorno = ((cambioGiorno / prevClose) * 100).toFixed(2);
let start = 0;
if (dataInizio) {
const d = (dataInizio instanceof Date) ? dataInizio : new Date(dataInizio);
if (isNaN(d.getTime())) return "Data errata";
start = Math.floor(d.getTime() / 1000);
}
let maxP = -Infinity, maxT = null;
for (let i = 0; i < prices.length; i++) {
if (prices[i] === null || ts[i] < start) continue;
if (prices[i] > maxP) { maxP = prices[i]; maxT = ts[i]; }
}
if (maxT === null) return "No dati";
const drawdown = ((live - maxP) / maxP * 100).toFixed(2);
switch (mode) {
case "value": return Number(maxP.toFixed(4));
case "date": return new Date(maxT * 1000);
case "full":
return [
["Ticker", ticker],
["Prezzo attuale", live.toFixed(4)],
["Var. oggi", (cambioGiorno > 0 ? "+" : "") + cambioGiorno.toFixed(4) + " (" + percGiorno + "%)"],
["Massimo", maxP.toFixed(4)],
["Data massimo", Utilities.formatDate(new Date(maxT * 1000), Session.getScriptTimeZone(), "dd/MM/yyyy")],
["Drawdown", drawdown + "%"],
["YTD 2025", YTD(ticker) + "%"],
["Periodo", dataInizio ? "dal " + Utilities.formatDate(new Date(start * 1000), Session.getScriptTimeZone(), "dd/MM/yyyy") : "storico"]
];
}
} catch (e) { return "Errore"; }
}
Trovate la mia pubblicazione anche su Reddit