Tasso interno di rendimento (tvm.irr)¶
Trova il tasso per periodo al quale il valore attuale netto di una serie di flussi di cassa
periodici è nullo. L'algoritmo è deterministico: esplora una griglia fissa di tassi, rifiuta
gli input per i quali più di un tasso risolve l'equazione e dichiara se l'unicità del tasso
restituito è dimostrata. Per flussi in date di calendario usa tvm.xirr; per
dichiarare in modo esplicito i tassi di finanziamento e di reinvestimento usa
tvm.mirr.
Versione del metodo: 2. La versione 2 aggiunge la scansione su griglia, la verifica di
unicità, l'output uniqueness_verified e l'errore FM-E011. Gli input con un solo cambio di
segno e un TIR compreso nella griglia danno lo stesso risultato della versione 1; gli input il
cui unico tasso è fuori dalla griglia mentre i flussi cambiano segno più di una volta ora
restituiscono FM-E011, e i risultati a tassi negativi possono differire nelle ultime cifre (i
fattori di sconto sono calcolati dal reciproco della base).
Formula¶
Trova \(r\) tale che
Il primo flusso avviene in \(t = 0\), come in tvm.npv.
Esempio¶
from decimal import Decimal
import fairmark as fm
r = fm.tvm.irr([-1000, 300, 400, 500])
print(r.irr) # 0.0889633946933499353177656797
print(r.uniqueness_verified) # True: un solo cambio di segno nei flussi
print(r.solver, r.iterations) # newton 5
assert abs(r.irr - Decimal("0.088963394693")) < Decimal("0.000000000001")
# I flussi -100, 230, -132 hanno due TIR, 10% e 20%: il motore rifiuta di sceglierne uno.
try:
fm.tvm.irr([-100, 230, -132])
except fm.FairmarkError as err:
assert err.code == "FM-E011"
print(err.message) # ... in the intervals {0.10}, {0.20}; the result is ambiguous
# Tre cambi di segno, un tasso isolato sulla griglia (50%); un'ulteriore coppia non si può escludere.
# Qui una coppia esiste (11% e 12%), quindi il risultato è segnalato.
flagged = fm.tvm.irr(["-1", "3.73", "-4.5882", "1.8648"])
assert not flagged.uniqueness_verified
print(flagged.conventions[-1]) # uniqueness not verified: the flows change sign 3 times; ...
Algoritmo¶
- Scansione su griglia. Il VAN è valutato su una griglia fissa di tassi: −0.99, −0.95, poi da −0.90 a 1.00 con passo 0.05, poi da 1.25 a 10 con passo 0.25 (ADR 0008). Un punto della griglia in cui il calcolo va in overflow viene saltato. Ogni cambio di segno tra punti consecutivi della griglia, e ogni punto della griglia in cui il VAN è esattamente zero, è una radice trovata.
-
Verifica di unicità. Le radici trovate sono confrontate con il numero \(s\) di cambi di segno nei flussi. Per la regola dei segni di Cartesio, il numero di tassi superiori a −100% è pari a \(s\) meno un numero pari. Quindi:
Radici trovate sulla griglia Cambi di segno \(s\) Risultato più di una qualsiasi FM-E011, con gli intervalliuna \(s - 1\) dispari FM-E011: esiste almeno un altro tassonessuna \(s > 1\) FM-E011: esistono zero o più tassiuna \(s - 1\) pari e positivo tasso restituito, uniqueness_verified = falseuna o nessuna \(s = 1\) tasso restituito, uniqueness_verified = true -
Raffinamento. Con un solo intervallo, il metodo di Newton parte da
guess(predefinito0.10) e il suo risultato è accettato solo all'interno dell'intervallo; altrimenti si applica la bisezione all'interno dell'intervallo. Una radice che cade esattamente su un punto della griglia è restituita così com'è (algoritmogrid (exact root)). Senza intervalli e con \(s = 1\), il risultato del metodo di Newton a partire daguessè accettato solo se converge; altrimentiFM-E005. - Criterio di arresto. Le iterazioni si fermano quando il passo sul tasso è inferiore a \(10^{-18}\), al massimo 200 iterazioni per fase.
Il limite residuo è lo scarto pari: quando viene trovato un tasso e \(s - 1\) è pari e positivo,
possono esistere ulteriori tassi a coppie (due radici nello stesso intervallo della griglia,
oppure fuori dalla griglia). Non possono essere esclusi, e il risultato lo dichiara con
uniqueness_verified = false e una convenzione. Quando il tasso è ambiguo, per la decisione
preferisci il VAN al costo del capitale, oppure tvm.mirr.
Input¶
| Campo | Significato | Default |
|---|---|---|
cash_flows |
Flussi di cassa, il primo in \(t = 0\); almeno uno positivo e uno negativo | obbligatorio |
guess |
Punto di partenza del metodo di Newton, frazione decimale per periodo | 0.10 |
Output¶
| Campo | Significato |
|---|---|
irr |
Tasso interno di rendimento per periodo, frazione decimale |
uniqueness_verified |
true quando nessun altro tasso può risolvere l'equazione; false quando non si possono escludere ulteriori tassi a coppie |
npv_at_irr |
VAN al tasso restituito (circa zero) |
solver |
newton, bisection oppure grid (exact root) |
iterations |
Iterazioni dell'algoritmo che ha prodotto il risultato |
tolerance |
Criterio di arresto sul passo del tasso, \(10^{-18}\) |
Convenzioni (esplicite, riportate in explain.conventions)¶
| Convenzione | Valore | Default |
|---|---|---|
| Origine dei tempi | cash_flows[0] in \(t = 0\) |
fissa |
| Griglia dell'algoritmo | −0.99, −0.95, da −0.90 a 1.00 passo 0.05, da 1.25 a 10 passo 0.25 | fissa |
| Ordine degli algoritmi | metodo di Newton all'interno dell'intervallo della radice, bisezione come alternativa | fisso |
| Criterio di arresto | passo sul tasso inferiore a \(10^{-18}\), al massimo 200 iterazioni | fisso |
| Punto di partenza del metodo di Newton | guess, riportato come fornito o come default |
0.10 |
| Unicità | dimostrata, oppure non verificata con il motivo | riportata in ogni risultato |
Errori¶
| Codice | Quando |
|---|---|
FM-E001 |
Un campo è mancante o sconosciuto |
FM-E002 |
cash_flows è vuoto |
FM-E005 |
Nessuna radice è stata isolata sulla griglia e il metodo di Newton a partire da guess non converge |
FM-E006 |
I flussi non presentano cambi di segno |
FM-E008 |
Overflow aritmetico durante il raffinamento della radice |
FM-E011 |
Più di un tasso annulla il VAN, oppure è noto che esiste un altro tasso; il messaggio elenca gli intervalli |
Precisione¶
Ogni valutazione del VAN usa solo potenze intere; rispetto a un calcolo indipendente a 60 cifre, queste operazioni concordano entro circa \(10^{-24}\) in termini relativi o meglio. La tolleranza di \(10^{-18}\) è un criterio di arresto sul passo del tasso, non un limite all'errore: per una radice semplice il tasso restituito è preciso all'incirca entro quel passo, mentre vicino a una radice doppia (due tassi molto vicini tra loro) la precisione è minore. I casi di riferimento sono verificati entro \(10^{-12}\).
Verificato con¶
- Casi di riferimento (golden case) in
tests/golden/tvm.irr/, compreso un caso con due tassi ricavato dalle radici del polinomio (\(10\%\) e \(20\%\)). - Concorda con la funzione
IRRdei fogli di calcolo (Excel, LibreOffice),numpy_financial.irrepyxirr.irrsugli input con un solo tasso.