Come si calcola il rendimento mensile
Scopri come misurare il rendimento mensile di un titolo analizzando prezzi di chiusura, dividendi e l'impatto dei split sugli ETF e le azioni.
Chiedendo quale sia stato l'andamento di un'azione a giugno, si otterranno numeri diversi a seconda della fonte, ma tutti corretti. Il rendimento mensile di un titolo è definito da scelte che la maggior parte delle persone non vede: quali due prezzi delimitano il mese, se i dividendi sono inclusi e se la serie dei prezzi è stata adjusted per i split. Questa pagina confronta le diverse convenzioni applicandole ai dati reali, rendendo così comprensibili le differenze.
Close-to-close: la convenzione standard
La convenzione utilizzata dai provider di indici, dalle schede informative dei fondi e dalla maggior parte delle pagine di quotazione: il rendimento mensile parte dalla chiusura della sessione regolare del mese precedente fino alla chiusura finale di questo mese. L'ultima chiusura di maggio è il punto di partenza per giugno. Il calcolo è lineare: prezzo finale meno prezzo iniziale, diviso per il prezzo iniziale. Un esempio semplice: un titolo che chiude maggio a $50.00 e chiude giugno a $53.50 ha reso (53.50 − 50.00) ÷ 50.00 = 0.07, ovvero il 7%, per il mese. Ogni convenzione descritta in questa pagina fornisce input diversi alla stessa formula. Ecco l'applicazione sui dati reali di giugno 2026, accanto alla principale alternativa:
L'esatto SQL dietro ogni numero
SELECT ticker,
round(argMaxIf(cl, day, day <= '2026-05-31'), 2) AS may_final_close,
round(argMinIf(op, day, day >= '2026-06-01'), 2) AS june_first_open,
round(argMaxIf(cl, day, day <= '2026-06-30'), 2) AS june_final_close,
round(100 * (argMaxIf(cl, day, day <= '2026-06-30') - argMaxIf(cl, day, day <= '2026-05-31'))
/ argMaxIf(cl, day, day <= '2026-05-31'), 2) AS close_to_close_pct,
round(100 * (argMaxIf(cl, day, day <= '2026-06-30') - argMinIf(op, day, day >= '2026-06-01'))
/ argMinIf(op, day, day >= '2026-06-01'), 2) AS open_to_close_pct,
round(abs(100 * (argMaxIf(cl, day, day <= '2026-06-30') - argMinIf(op, day, day >= '2026-06-01'))
/ argMinIf(op, day, day >= '2026-06-01')
- 100 * (argMaxIf(cl, day, day <= '2026-06-30') - argMaxIf(cl, day, day <= '2026-05-31'))
/ argMaxIf(cl, day, day <= '2026-05-31')), 2) AS convention_gap_points
FROM (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS day,
argMinIf(toFloat64(open), window_start, rth) AS op,
argMaxIf(toFloat64(close), window_start, rth) AS cl
FROM (
SELECT ticker, window_start, open, close,
toTimeZone(window_start, 'America/New_York') >= toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 09:30:00'), 'America/New_York')
AND toTimeZone(window_start, 'America/New_York') < toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 16:00:00'), 'America/New_York') AS rth
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('NVDA', 'SPY')
AND window_start >= '2026-05-28 04:00:00'
AND window_start < '2026-07-01 08:00:00'
)
GROUP BY ticker, day
)
GROUP BY ticker
ORDER BY tickerIl mese di giugno di NVDA è stato del -5.39% close-to-close — ma del -7.4% misurato dalla prima apertura della sessione regolare di giugno alla sua ultima chiusura. Stesso titolo, stesso mese, 2.01 punti percentuali di differenza tra le due risposte corrette. L'intera differenza è dovuta a una finestra overnight+weekend: NVDA ha chiuso maggio a $211.15 ed è aperta giugno a $215.73 — quel salto appartiene a "giugno" nella convenzione open-to-close e al limite di confine nella convenzione close-to-close. SPY mostra la stessa struttura in modo più contenuto: -1.33% close-to-close rispetto a -1.2% open-to-close.
Nessuno dei due numeri è errato. Il close-to-close risponde alla domanda: "cosa ha sperimentato chi ha mantenuto la posizione durante il passaggio al mese successivo?". L'open-to-close risponde alla domanda: "cosa ha generato il trading del mese per chi ha acquistato all'apertura di giugno?". I due valori differiscono ogni volta che il mercato presenta un gap al passaggio del mese — e i gap overnight sono comuni, non rari.
Dividendi: price return vs total return
La seconda opzione: il contante distribuito da un'azione durante il mese viene conteggiato? Un price return lo ignora; un total return lo reintegra. Per la maggior parte dei singoli mesi la differenza è minima — un pagatore trimestrale distribuisce circa un quarto del proprio yield ogni trimestre — ma nel corso degli anni l'effetto composto crea un divario enorme, e il mese di giugno 2026 è stato un mese di pagamento per SPY:
L'esatto SQL dietro ogni numero
WITH px AS (
SELECT argMaxIf(cl, day, day <= '2026-05-31') AS may_close,
argMaxIf(cl, day, day <= '2026-06-30') AS jun_close
FROM (
SELECT ticker,
toDate(toTimeZone(window_start, 'America/New_York')) AS day,
argMinIf(toFloat64(open), window_start, rth) AS op,
argMaxIf(toFloat64(close), window_start, rth) AS cl
FROM (
SELECT ticker, window_start, open, close,
toTimeZone(window_start, 'America/New_York') >= toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 09:30:00'), 'America/New_York')
AND toTimeZone(window_start, 'America/New_York') < toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 16:00:00'), 'America/New_York') AS rth
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker IN ('NVDA', 'SPY')
AND window_start >= '2026-05-28 04:00:00'
AND window_start < '2026-07-01 08:00:00'
)
GROUP BY ticker, day
)
WHERE ticker = 'SPY'
),
dv AS (
SELECT sum(cash_amount) AS div_per_share
FROM global_markets.stocks_dividends
WHERE ticker = 'SPY'
AND ex_dividend_date >= '2026-06-01'
AND ex_dividend_date <= '2026-06-30'
)
SELECT round(may_close, 2) AS may_final_close,
round(jun_close, 2) AS june_final_close,
round(div_per_share, 4) AS june_dividend_per_share,
round(100 * (jun_close - may_close) / may_close, 2) AS price_return_pct,
round(100 * div_per_share / may_close, 2) AS dividend_contribution_pct,
round(100 * ((jun_close + div_per_share) - may_close) / may_close, 2) AS total_return_pct
FROM px CROSS JOIN dvIl price return di SPY per giugno è stato del -1.33%; aggiungendo la distribuzione di $1.9035 per azione andata ex-dividend durante il mese, il total return sale al -1.08% — un contributo del 0.25% derivante dal cash. Le famiglie di indici pubblicano entrambe le versioni (l' "S&P 500" che si vede quotato è solitamente il price index), le pagine sulle performance dei fondi sono obbligate a mostrare il total return, e gli screener utilizzano entrambi liberamente. Quando due fonti divergono di alcune decimi su un mese di un pagatore di dividendi, il dividendo è il primo sospetto — la data ex-dividend determina a quale mese appartiene un pagamento.
Un singolo mese di giugno rappresenta frazioni di punto percentuale. L'orizzonte temporale è ciò che separa le due convenzioni — ecco lo stesso calcolo esteso su cinque anni:
L'esatto SQL dietro ogni numero
WITH daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS day,
argMaxIf(toFloat64(close), window_start,
toTimeZone(window_start, 'America/New_York') >= toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 09:30:00'), 'America/New_York')
AND toTimeZone(window_start, 'America/New_York') < toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 16:00:00'), 'America/New_York')) AS cl
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND ((window_start >= '2021-06-28 04:00:00' AND window_start < '2021-07-01 08:00:00')
OR (window_start >= '2026-06-26 04:00:00' AND window_start < '2026-07-01 08:00:00'))
GROUP BY day
),
px AS (
SELECT argMaxIf(cl, day, day <= '2021-06-30') AS start_close,
argMaxIf(cl, day, day <= '2026-06-30') AS end_close
FROM daily
),
dv AS (
SELECT round(sum(cash_amount), 2) AS divs_per_share,
count() AS payments
FROM global_markets.stocks_dividends
WHERE ticker = 'SPY'
AND ex_dividend_date >= '2021-07-01'
AND ex_dividend_date <= '2026-06-30'
)
SELECT round(start_close, 2) AS june_2021_close,
round(end_close, 2) AS june_2026_close,
divs_per_share AS dividends_paid_per_share,
payments AS dividend_payments,
round(100 * (end_close - start_close) / start_close, 2) AS five_year_price_return_pct,
round(100 * ((end_close + divs_per_share) - start_close) / start_close, 2) AS five_year_return_with_divs_pct,
round(100 * divs_per_share / start_close, 2) AS dividend_points_added
FROM px CROSS JOIN dvDalla chiusura di giugno 2021 a $428.07 alla chiusura di giugno 2026 a $746.32, il price return quinquennale di SPY misura il 74.35%. Nello stesso periodo ha pagato 20 distribuzioni per un totale di $34.07 per azione; includendo quel cash, la cifra sale al 82.3% — 7.96 punti di scarto prima del reinvestimento di un singolo dividendo. Un vero indice total-return reinveste ogni pagamento alla sua ex-date, e le azioni reinvestite ampliano ulteriormente il divario. Per un pagatore maturo, "margini ampi" non è un modo di dire; è il risultato standard di anni di cash trimestrale.
Adjusted close vs. raw close: la trappola dello split
La maggior parte degli strumenti di analisi grafica — Yahoo Finance, Google Finance, la maggior parte delle app dei broker — riporta un adjusted close: una serie storica di prezzi in cui i valori passati sono stati divisi in base agli split (e, su alcune piattaforme, corretti anche per i dividendi) affinché la linea sia confrontabile nel tempo. Il nostro database memorizza i dati esattamente come sono stati registrati. In un mese ordinario i due valori coincidono. In un mese che include uno stock split, i dati mostrano risultati completamente diversi — lo split 10-for-1 di NVDA avvenuto il 10 giugno 2024, durante il mese:
L'esatto SQL dietro ogni numero
WITH px AS (
SELECT argMaxIf(cl, day, day <= '2024-05-31') AS may_close,
argMaxIf(cl, day, day <= '2024-06-30') AS jun_close
FROM (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS day,
argMaxIf(toFloat64(close), window_start,
toTimeZone(window_start, 'America/New_York') >= toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 09:30:00'), 'America/New_York')
AND toTimeZone(window_start, 'America/New_York') < toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 16:00:00'), 'America/New_York')) AS cl
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'NVDA'
AND window_start >= '2024-05-29 04:00:00'
AND window_start < '2024-07-01 08:00:00'
GROUP BY day
)
),
sp AS (
SELECT split_to / split_from AS ratio
FROM global_markets.stocks_splits
WHERE ticker = 'NVDA'
AND execution_date >= '2024-06-01'
AND execution_date <= '2024-06-30'
)
SELECT round(may_close, 2) AS may_final_close_raw,
round(jun_close, 2) AS june_final_close_raw,
toInt32(ratio) AS shares_after_split_per_old_share,
round(100 * (jun_close - may_close) / may_close, 2) AS raw_price_change_pct,
round(may_close / ratio, 2) AS may_close_split_adjusted,
round(100 * (jun_close - may_close / ratio) / (may_close / ratio), 2) AS adjusted_return_pct
FROM px CROSS JOIN spLeggendo i dati raw, NVDA è "scesa" da $1097.46 a $123.41 in quel giugno — un crollo del -88.75%. Non è successo nulla di simile: alla data di esecuzione ogni vecchia azione è diventata 10 nuove azioni e il prezzo è stato diviso proporzionalmente, mantenendo invariato il valore in dollari per ogni azionista. Dividendo la chiusura di maggio per lo stesso rapporto — $109.75 su base split-adjusted — il giugno 2024 misura 12.45%, un mese positivo. Qualsiasi fonte che riporti dati adjusted indicherà un valore vicino alla seconda cifra; un calcolo ingenuo sui dati raw riporterà la prima. L'adjusted close è la causa più comune per cui due fonti divergono drasticamente su un rendimento mensile storico — quando un dato appare improbabilmente elevato in una qualsiasi direzione, consultate il calendario degli split prima di qualsiasi altra cosa.
Quale "close" è quello ufficiale?
Un'ulteriore distinzione risiede nelle convenzioni: il prezzo di chiusura stesso. Il valore utilizzato in ogni fact sheet è il prezzo ufficiale dell'auction di chiusura — l'unico prezzo stabilito dalla closing auction alle 16:00 ET. Tuttavia, il trading continua dopo l'orario regolare e l'ultimo prezzo dell'extended session può differire dalla chiusura ufficiale:
L'esatto SQL dietro ogni numero
SELECT round(argMaxIf(toFloat64(close), window_start, rth), 2) AS regular_session_close,
round(argMax(toFloat64(close), window_start), 2) AS last_extended_print,
round(100 * (argMax(toFloat64(close), window_start) - argMaxIf(toFloat64(close), window_start, rth))
/ argMaxIf(toFloat64(close), window_start, rth), 3) AS after_hours_drift_pct
FROM (
SELECT window_start, close,
toTimeZone(window_start, 'America/New_York') >= toDateTime('2026-06-30 09:30:00', 'America/New_York')
AND toTimeZone(window_start, 'America/New_York') < toDateTime('2026-06-30 16:00:00', 'America/New_York') AS rth
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= '2026-06-30 04:00:00'
AND window_start < '2026-07-01 08:00:00'
)Il 30 giugno la differenza era di -0.003% — un valore contenuto per quella sera, ma durante una notte di pubblicazione degli earnings su un singolo titolo, l'extended session può registrare variazioni percentuali che il rendimento mensile ufficiale assegnerà al mese successivo. Il trading after-hours e premarket approfondisce questo aspetto. Un caso limite correlato: i limiti mensili possono cadere occasionalmente in una sessione ridotta per festività, dove la giornata regolare termina alle 13:00 ET e la chiusura ufficiale avviene tramite una closing auction anticipata — il market holiday schedule elenca tali date.
Capitalizzazione di dodici mesi in un anno
Il rendimento annuale non è la somma di dodici rendimenti mensili, ma il loro prodotto. La formula di collegamento consiste nel convertire ogni mese in un fattore di crescita (1 + rendimento), moltiplicare tra loro i dodici fattori e sottrarre 1. Un mese con un rendimento del −5% seguito da un mese con un rendimento del +5% produce una somma pari a zero, ma il calcolo composto risulta in 0,95 × 1,05 − 1 = −0,25%. Ecco l'andamento mensile effettivo di SPY nei dodici mesi conclusi a giugno 2026:
L'esatto SQL dietro ogni numero
WITH daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS day,
argMaxIf(toFloat64(close), window_start,
toTimeZone(window_start, 'America/New_York') >= toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 09:30:00'), 'America/New_York')
AND toTimeZone(window_start, 'America/New_York') < toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 16:00:00'), 'America/New_York')) AS cl
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= '2025-06-24 04:00:00'
AND window_start < '2026-07-01 08:00:00'
GROUP BY day
),
monthly AS (
SELECT toStartOfMonth(day) AS month_start,
argMax(cl, day) AS month_close
FROM daily
GROUP BY month_start
),
rets AS (
SELECT month_start,
formatDateTime(month_start, '%Y-%m') AS month,
round(month_close, 2) AS month_final_close,
100 * (month_close / lagInFrame(month_close) OVER (ORDER BY month_start) - 1) AS r
FROM monthly
)
SELECT month,
month_final_close,
round(r, 2) AS simple_return_pct,
round(100 * log(1 + r / 100), 2) AS log_return_pct
FROM rets
WHERE isFinite(r)
ORDER BY month_startDodici mesi con prezzi di chiusura, da 2.28% in 2025-07 a -1.33% in 2026-06 — l'ultima riga corrisponde al valore di SPY a giugno 2026 misurato nel primo pannello. Calcolate correttamente il collegamento tra i dodici mesi e confrontatelo con la scorciatoia della semplice somma delle percentuali:
L'esatto SQL dietro ogni numero
WITH daily AS (
SELECT toDate(toTimeZone(window_start, 'America/New_York')) AS day,
argMaxIf(toFloat64(close), window_start,
toTimeZone(window_start, 'America/New_York') >= toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 09:30:00'), 'America/New_York')
AND toTimeZone(window_start, 'America/New_York') < toDateTime(concat(toString(toDate(toTimeZone(window_start, 'America/New_York'))), ' 16:00:00'), 'America/New_York')) AS cl
FROM global_markets.delayed_stocks_minute_aggs
WHERE ticker = 'SPY'
AND window_start >= '2025-06-24 04:00:00'
AND window_start < '2026-07-01 08:00:00'
GROUP BY day
),
monthly AS (
SELECT toStartOfMonth(day) AS month_start,
argMax(cl, day) AS month_close
FROM daily
GROUP BY month_start
),
rets AS (
SELECT month_start,
100 * (month_close / lagInFrame(month_close) OVER (ORDER BY month_start) - 1) AS r
FROM monthly
),
ends AS (
SELECT argMin(month_close, month_start) AS base_close,
argMax(month_close, month_start) AS final_close
FROM monthly
)
SELECT count() AS months_linked,
round(sum(r), 2) AS simple_sum_pct,
round(100 * (exp(sum(log(1 + r / 100))) - 1), 2) AS geometric_compound_pct,
round(100 * (any(final_close) / any(base_close) - 1), 2) AS direct_twelve_month_pct,
round(100 * (exp(sum(log(1 + r / 100))) - 1) - sum(r), 2) AS compounding_gap_points,
round(sum(100 * log(1 + r / 100)), 2) AS sum_of_monthly_log_returns_pct,
round(100 * log(any(final_close) / any(base_close)), 2) AS twelve_month_log_return_pct
FROM rets CROSS JOIN ends
WHERE isFinite(r)La somma dei dodici mesi è 19.83%, ma il rendimento composto è 20.79% — il calcolo diretto, dalla chiusura di giugno 2025 alla chiusura di giugno 2026, fornisce 20.79%, che coincide con il valore composto invece che con la somma. Lo scarto è di 0.96 punti in un anno relativamente stabile; lo scarto aumenta con l'aumentare della volatilità e dell'orizzonte temporale. Sommare le percentuali mensili è un'abitudine comune nei fogli di calcolo, ma è un errore.
Le ultime due colonne mostrano la convenzione utilizzata per la somma: il log return, ovvero il logaritmo naturale del fattore di crescita, ln(1 + rendimento). I log return mensili sommati danno 18.89% — valore identico al log return di dodici mesi di 18.89%, ed è esattamente questo il motivo per cui analisti e modelli di rischio li utilizzano. Per mesi con variazioni contenute le due convenzioni differiscono poco (2025-11: 0.21% semplice, 0.21% log); maggiore è la variazione mensile, maggiore è la divergenza (2026-04: 10.49% semplice, 9.97% log). Le schede informative dei fondi riportano i rendimenti semplici; i log return sono utilizzati nei documenti di ricerca e nei calcoli della volatilità.
La checklist per riconciliare due fonti diverse
Quando due dati sul rendimento mensile non coincidono, la differenza dipende quasi sempre da uno di questi quattro fattori:
- Endpoints — close-to-close (lo standard) o open-to-close (il trading del mese stesso). I valori differiscono ogni volta che si verifica un gap sul limite temporale.
- Dividends — price return o total return. I valori differiscono in ogni mese che include una data ex-dividend.
- Adjustment — prezzi grezzi o serie adjusted-close. I valori differiscono drasticamente in ogni mese che include uno split.
- Il close stesso — prezzo ufficiale dell'asta (lo standard) rispetto all'ultimo trade che può includere l'extended hours.
Applicando gli stessi parametri a entrambe le fonti, la discrepanza scompare. Un confronto fund-versus-index è valido solo se entrambi i dati utilizzano le stesse quattro impostazioni; se se ne sbaglia anche solo una, il confronto misurerà il parametro scelto invece della performance. Il nostro riepilogo di giugno 2026 specifica la propria convenzione fin dall'inizio proprio per questo motivo: ogni dato mensile è close-to-close, basato su official prints e price return.
FAQ sui rendimenti mensili
Cos'è un rendimento close-to-close?
La variazione percentuale tra il prezzo di chiusura della sessione regolare del periodo precedente e la chiusura finale del periodo attuale. È la convenzione standard per i rendimenti azionari giornalieri, mensili e annuali nelle schede informative e nei report degli indici.
Perché due siti web mostrano rendimenti diversi per lo stesso titolo e lo stesso mese?
Quasi sempre dipende da una di quattro convenzioni: diversi endpoint (close-to-close rispetto a open-to-close), inclusione o esclusione dei dividendi, prezzi lordi rispetto a prezzi adjusted per lo split, o una diversa fonte per il prezzo di chiusura. Per NVDA, nel giugno 2026, si misurano -5.39% o -7.4% solo considerando il primo switch.
Uno stock split cambia il calcolo del rendimento mensile?
Non dovrebbe — uno split modifica contemporaneamente il numero di azioni e il prezzo, lasciando invariato il valore della posizione — ma invalida qualsiasi calcolo effettuato sui prezzi lordi. Il dato di NVDA per giugno 2024 appare come -88.75% sui prezzi di chiusura lordi e misura 12.45% una volta applicato l'adjustment per lo split di dieci per uno.
I rendimenti mensili azionari includono i dividendi?
Solo i total returns li includono. I rendimenti del prezzo — incluso il livello principale dell'indice S&P 500 — li escludono. Nel giugno 2026, il dividendo ha aggiunto 0.25% al rendimento mensile di SPY, ovvero il divario tra il suo prezzo e il total return.
Il rendimento mensile del mio portafoglio personale è calcolato nello stesso modo?
Non appena avvengono flussi di cassa in entrata o in uscita. I rendimenti di singoli titoli come quelli presenti in questa pagina sono time-weighted; un conto con depositi e prelievi richiede un calcolo money-weighted (internal-rate-of-return), altrimenti i flussi di cassa possono falsare la performance. La maggior parte dei broker riporta un dato time-weighted proprio per escludere i depositi dal calcolo.
Ogni dato sopra riportato è una query memorizzata e versionata sul tape reale — espandi la SQL di qualsiasi pannello, o misura il mese di qualsiasi ticker secondo qualsiasi convenzione sulla terminale Strasmore.