Riccardo Cambini
Dipartimento di Economia e Management
Università di Pisa,
Via Cosimo Ridolfi 10, 56124 Pisa, ITALY
E-mail: riccardo.cambini@unipi.it
1
1 Definizioni iniziali
F1 F2 F3 F4 ……. Fn-2 Fn-1 Fn
Si definisce operazione finanziaria un qualsiasi accordo che origina una movimentazione
di somme di denaro in epoche diverse. Una operazione finanziaria può essere descritta da
un diagramma temporale (Figura 1) nel quale: …….
0 1 2 3 4 n-2 n-1 n
• F1 , . . . , Fn , con n 2, sono i flussi di cassa corrispondenti agli istanti di tempo
T1 , . . . , Tn , rispettivamente;
Per comodità i flussi di cassa ed i corrispondenti istanti di tempo possono essere espressi
con i vettori F = [F1 , . . . , Fn ] e T = [T1 , . . . , Tn ].
…….
0 T1 T2 T3 T4 Tn-2 Tn-1 Tn
2
…….
0 1 2 3 4 n-2 n-1 n
F1 F2 F3 F4 k
X ……. Fn-2 Fn-1 Fn
Vk = Fh · c h
h=1
…….
0• T1
il Risultato T2
Economico T3 Attualizzato,
T4 Tn-2
indicato per brevità Tn-1 (detto
con R.E.A. Tn
anche Valore Attuale Netto, V.A.N., in inglese Net Present Value, N.P.V.), che
indica il valore attuale di tutti i flussi di cassa dell’operazione finanziaria, ovvero:
n
X
REA = Vn = Fh · c h
h=1
• la scadenza media (calcolata come media ponderata) dei flussi di cassa negativi e
di quelli positivi, ovvero:
F1 F2 FP3 F4 …….
P Fn-2 Fn-1 Fn
F <0 Tk · Fk F >0 Tk · Fk
µu = Pk , µe = Pk
i1 i2 i3 i Fk <0 Fk
4 ……. Fk >0 Fk in-1 in
0 T1 T2 T3 T4 Tn-2 Tn-1 Tn
2 Calcolo dei fattori di attualizzazione
2.1 Tasso di interesse costante
In questo caso il tasso di interesse si considera costante ed uguale ad i 0 per tutto
il periodo di tempo [0, Tn ] (vedasi Figura 2). Pertanto, i coefficienti di attualizzazione
risultano, per k = 1, . . . , n:
ck = (1 + i) Tk
i i i i ……. i i
0 T1 T2 T3 T4 Tn-2 Tn-1 Tn
In questo caso è utile esplicitare la dipendenza del valore attuale dei flussi di cassa dal
tasso di interesse i. In particolare, per k = 1, . . . , n verrà usata la seguente notazione:
X X
Th
Vk (i) = Fh · c h = Fh · (1 + i)
h:Th Tk h:Th Tk
3
…….
0 1 2 3 4 n-2 n-1 n
inoltre, risulta:
n
X
Th
REA(i) = Vn (i) = Fh · (1 + i)
h=1
Si osservi infine
F che vale
F la seguente
F proprietà:
F ……. Fn-2 Fn-1 Fn
1 2 3 4
i=0 () Sk = Vk (i) 8i 2 {1, . . . , n}
…….
0 mostra Tcome
che 1 T2 contabili
i saldi T3 ed i valori
T4 attualizzati coincidano T Tn-1nel caso
solamente
n-2 Tnin
cui il tasso i sia nullo. In questo caso risulta REA(0) = Vn (0) = Sn .
i1 i2 i3 i4 ……. in-1 in
0 T1 T2 T3 T4 Tn-2 Tn-1 Tn
In altri termini, per utilizzare una notazione classica della matematica finanziaria,
abbiamo che i1 = i (T0 , T1 ) e che ik = i (Tk 1 , Tk ) per ogni k 2 {2, . . . , n}.
I fattori di attualizzazione ck si calcolano come segue:
T1
c1 = (1 + i1 )
T1
c2 = (1 + i1 ) (1 + i2 )T1 T2
= c1 (1 + i2 )T1 T2
T1
c3 = (1 + i1 ) (1 + i2 )T1 T2
(1 + i3 )T2 T3
= c2 (1 + i3 )T2 T3
T1
c4 = (1 + i1 ) (1 + i2 )T1 T2
(1 + i3 )T2 T3
(1 + i4 )T3 T4
=
T3 T4
= c3 (1 + i4 )
...
3 Tipologie di investimenti/finanziamenti
Nel caso di operazioni finanziarie semplici (n = 2) si definisce come investimento una
operazione in cui il flusso di cassa iniziale F1 è negativo ed il successivo F2 è positivo,
mentre si definisce come finanziamento una operazione in cui il flusso di cassa iniziale F1 è
4
positivo ed il successivo F2 è negativo. Nel caso di operazioni finanziarie complesse (n > 2)
le definizioni sono invece molteplici.
In altre parole, ricordando che nel caso in cui il tasso sia costante risulta
n
X
Th
REA(i) = Vn (i) = Fh · (1 + i)
h=1
Esempio
Si considerino le quattro seguenti operazioni finanziarie:
A) T = [0, 1, 2] ed F = [ 100, 60, 30]
5
Per calcolare i T.I.R. occorre, in tutti e quattro i casi, risolvere l’equazione nonlineare:
1 2
REA(i) = F1 + F2 (1 + i) + F3 (1 + i) =0
Per chiarire ulteriormente il problema della esistenza ed unicità del T.I.R., in Figura 4
sono rappresentati i grafici delle funzioni REA(i) per le quattro operazioni considerate.
iii) F1 · Sn < 0;
iv) S1 · Sn < 0.
6
O restart; O T1:=0;T2:=1;T3:=2;
O T1:=0;T2:=1;T3:=2; F1:=-100;F2:=60;F3:=70;
F1:=-100;F2:=60;F3:=30; V:=i->F1*(1+i)^(-T1)+F2*(1+i)^(-T2)+F3*(1+i)^(-T3);
V:=i->F1*(1+i)^(-T1)+F2*(1+i)^(-T2)+F3*(1+i)^(-T3); plot(V(i),i=0..1);
plot(V(i),i=0..0.5,view = [0 .. 0.5, -50 .. 0]); fsolve(V(i)=0,i=0..0.5);
Delta:=F2^2-4*F1*F3; Delta:=F2^2-4*F1*F3;
i1:=evalf(-1+((-F2-sqrt(Delta))/(2*F1))); i1:=evalf(-1+((-F2-sqrt(Delta))/(2*F1)));
i2:=evalf(-1+((-F2+sqrt(Delta))/(2*F1))); i2:=evalf(-1+((-F2+sqrt(Delta))/(2*F1)));
T1 := 0 T1 := 0
T2 := 1 T2 := 1
T3 := 2 T3 := 2
F1 := K100 F1 := K100
F2 := 60 F2 := 60
F3 := 30 F3 := 70
KT1 KT2 KT3
V := i/F1 1 C i KT1
C F2 1 C i KT2
C F3 1 C i KT3 V := i/F1 1 C i C F2 1 C i C F3 1 C i
0 30
0.1 0.2 0.3 0.4 0.5
i
20
K10
10
0
K20 0.2 0.4 0.6 0.8 1
i
K10
i2 := K1.588819442 (2) (3)
O T1:=0;T2:=1;T3:=2;
F1:=-50;F2:=145;F3:=-100;
K30
V:=i->F1*(1+i)^(-T1)+F2*(1+i)^(-T2)+F3*(1+i)^(-T3); K20
plot(V(i),i=0..1);
fsolve(V(i)=0,i=0..0.5);
fsolve(V(i)=0,i=0.5..1); K30
Delta:=F2^2-4*F1*F3;
i1:=evalf(-1+((-F2-sqrt(Delta))/(2*F1)));
K40
i2:=evalf(-1+((-F2+sqrt(Delta))/(2*F1)));
T1 := 0 K40
T2 := 1
T3 := 2
F1 := K50
K50
K50
F2 := 145 0.1888194417
D := 15600
(a)
F3 := K100
i1 := K0.0755002002
(b)
D := 31600
KT1 KT2 KT3
V := i/F1 1 C i i2 :=C F2 1 C i
K1.324499800 C F3 1 C i (1) i1 := 0.1888194417
8 (2)
2
7
1
6
0 5
0.2 0.4 0.6 0.8 1
i
4
K1
3
K2
2
K3
1
K4 0
0.2 0.4 0.6 0.8 1
i
K5 K1
0.1298437881 0.2500000000
(c) (d)
0.6666666667
D := 400
i1 := 0.2500000000
Figura 4: Valore attuale dei flussi di cassa al variare del tasso di interesse i2 := 0.6666666667 (4)
(3)
h:Th >T1
Di conseguenza, essendo F1 < 0, esiste un tasso î > 0 sufficientemente grande tale che
P
F1 + h:Th >T1 Fh · (1 + î)T1 Th < 0 da cui si ha REA(î) < 0. La tesi segue quindi dalla
proprietà i) essendo REA(0) · REA(î) < 0. Il caso REA(0) < 0 ed F1 > 0 è analogo al
precedente.
iii) Segue direttamente dalla proprietà ii) essendo REA(0) = Sn .
iv) Segue direttamente dalla proprietà iii) essendo S1 = F1 .
7
Il seguente teorema fornisce alcune condizioni sufficienti per l’esistenza ed unicità del
T.I.R. nell’ambito delle operazioni finanziarie di investimento.
Si osservi che il risultato espresso dalla condizione i) è noto come Teorema di Levi, il
risultato espresso dalla condizione ii) è noto come Teorema di Norstrom.
Esempio
Si considerino le due seguenti operazioni finanziarie:
Per entrambe le due operazioni finanziarie risulta S5 = 2700 > 0 ed F1 = 2000 < 0.
Nessuna delle due operazioni finanziarie è un investimento in senso stretto poiché vi sono
flussi di cassa negativi successivi all’entrata F2 .
8
5 Analisi degli investimenti
5.1 Criterio del pay-back
Si supponga di dover analizzare una operazione finanziaria con F1 < 0, e quindi S1 < 0.
Sia quindi k̄ il più piccolo indice per cui Sk̄ 0. Se risulta Sk̄ = 0 allora P BP = Tk̄ ; se
invece Sk̄ > 0 allora il periodo di Pay-Back è un valore compreso nell’intervallo [Tk̄ 1 , Tk̄ ].
In quest’ultimo caso, per poter dare una stima del periodo di Pay-Back possiamo interpo-
lare con un segmento i due punti (Tk̄ 1 , Sk̄ 1 ) e (Tk̄ , Sk̄ ) e prendere come P.B.P. il valore
per cui la retta interpolante si annulla, cosı̀ come descritto in Figura 5.
Sk
Tk-1
PBP Tk
Sk-1
Figura 5: Stima del periodo di Pay-Back
Essendo l’equazione della retta passante per i punti (Tk̄ 1 , Sk̄ 1 ) e (Tk̄ , Sk̄ ) data da:
Sk̄ Sk̄ 1
S = Sk̄ + m (T Tk̄ ) con m=
Tk̄ Tk̄ 1
9
In un confronto tra investimenti si andrà a scegliere quella con il PBP minore. Debo-
lezza di questo criterio è l’uso dei saldi contabili, finanziariamente poco utili, ed il fatto
che non necessariamente pareggiare il prima possibile le entrate/uscite può risultare con-
veniente. Altro grande difetto è che non si considera minimamente quel che accade dopo
il tempo Tk̄ .
Si osservi come la formula precedente consideri implicitamente anche il caso “DP BP = Tk̄
se Vk̄ = 0”, permettendo quindi di riassumere il calcolo del PBP come segue:
8
>
< +1 se Vk < 0 per ogni k = 1, . . . , n
DP BP =
>
: T Vk̄ Vk̄ Vk̄ 1
k̄ m con m = Tk̄ Tk̄ se Vk̄ 0 e Vk < 0 8k < k̄
1
In un confronto tra investimenti si andrà a scegliere quella con il DPBP minore. De-
bolezza di questo criterio è che non necessariamente pareggiare il prima possibile il valore
attuale delle entrate/uscite risulta conveniente. Altro grande difetto è che non si considera
minimamente quel che accade dopo il tempo Tk̄ .
10
dove:
T1
c1 = (1 + i1 )
ch = ch 1 (1 + ih ) Th 1 Th
8h = 2, . . . , n
Nel caso di confronto tra operazioni finanziarie, si andrà a scegliere quella con il REA
maggiore. Rispetto ai criteri del P.B.P. e D.P.B.P. il criterio del R.E.A. considera l’ope-
razione finanziaria nella sua interezza. Debolezza di questo criterio è la necessità di dover
utilizzare una stima dei tassi di interesse futuri (operazione di per sé ai limiti della magia e
della veggenza); inoltre tale stima dei tassi di interesse risulta essere estremamente delica-
ta poiché a seconda del tasso di interesse scelto può risultare conveniente una operazione
finanziaria invece che un’altra, o viceversa.
Metodo Montecarlo
Si suddivide l’intervallo [ia , ib ] in m sottointervalli i0 , i1 , i2 , . . . , im , con i0 = ia , im = ib ,
ij 1 < ij 8j = 1, . . . , m. Si cerca quindi il valore j̄ tale che:
11
L’errore di approssimazione commesso prendendo il punto medio è:
1 1 ib ia
✏ < (ij̄ ij̄ 1) =
2 2 m
Se vogliamo calcolare il T.I.R. con circa p cifre decimali di precisione dobbiamo avere
✏ ⇡ 10 p da cui si ha 10 p ⇡ 12 ib mia e quindi:
1
m ⇡ (ib ia )10p
2
In altre parole, il metodo Montecarlo è molto semplice ma necessita di un numero enorme
di tassi da valutare.
Metodo di Bisezione
Si parte dall’intervallo [ia , ib ] e si scelgono i tassi ip , in 2 {ia , ib } in modo tale che sia
REA(ip ) > 0 e REA(in ) < 0. Sia ic il punto medio tra ip ed in , ovvero ic = 12 (ip + in );
se REA(ic ) > 0 si prende ic come nuovo tasso ip , se invece REA(ic ) < 0 si prende ic
come nuovo tasso in . L’intervallo è stato cosı̀ dimezzato e si ricomincia il procedimento
dall’inizio. Se troviamo che REA(ic ) = 0 allora possiamo prendere T IR = ic e concludere
il processo algoritmico; altrimenti, per non continuare all’infinito, ad un certo punto bi-
sogna interrompere la procedura iterativa e prendere come T.I.R. una delle due seguenti
approssimazioni:
Ogni volta che si calcola un nuovo tasso ic e lo si valuta, l’intervallo precedente viene
dimezzato. Di conseguenza, dopo m valutazioni l’intervallo iniziale di lunghezza ib ia è
stato ridotto ad un intervallo di lunghezza ib2mia . L’errore di approssimazione commesso
prendendo il punto medio risulta quindi:
1 ib ia
✏<
2 2m
Se vogliamo calcolare il T.I.R. con circa p cifre decimali di precisione dobbiamo avere
✏ ⇡ 10 p da cui si ha 10 p ⇡ i2bm+1
ia
e quindi:
12
Appendice – Implementazioni in MATLAB
(Live Script realizzato con MATLAB versione 2020a)
MF=Flussi;
T=Tempi;
I=Tassi;
Di seguito indicheremo con "F" dei vettori di flussi di cassa, ovvero singole colonne di "MF".
1
for i=1:numf % controllo non negatività di I
if not(I(i)>=0)
error('Componente %g di I negativa : %g',i,I(i));
end
end
ans = 1×26
-2000 -3000 -3200 -3300 -3100 -2800
2
scadmedianeg =
6.0667
scadmediapos =
12.376
function primoneg=PrimoNeg(v)
primoneg=NaN;
for h=1:length(v)
if v(h)<0
primoneg=h;
break;
end
end
end
function S=SaldiCont(F)
n=length(F);
S=zeros(n,1);
S(1)=F(1);
for h=2:n
S(h)=S(h-1)+F(h);
end
end
function scadmediapos=ScadMediaPos(F,T)
numer=0;
denom=0;
for h=1:length(F)
if F(h)>0
numer=numer+T(h)*F(h);
denom=denom+F(h);
end
end
3
scadmediapos=numer/denom;
end
function scadmedianeg=ScadMediaNeg(F,T)
numer=0;
denom=0;
for h=1:length(F)
if F(h)<0
numer=numer+T(h)*F(h);
denom=denom+F(h);
end
end
scadmedianeg=numer/denom;
end
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
S=SaldiCont(F);
S'
ans = 1×26
-2000 -3000 -3200 -3300 -3100 -2800
scadmedianeg=ScadMediaNeg(F,T)
scadmedianeg =
6.0667
scadmediapos=ScadMediaPos(F,T)
scadmediapos =
12.376
4
c'
ans = 1×26
1 0.97561 0.95181 0.9286 0.90595 0.88385
ans = 1×26
-2000 -2975.6 -3166 -3258.8 -3077.6 -2812.5
c=zeros(numf,1);
c(1)=(1+I(1))^(-T(1));
for i=2:numf
c(i)=c(i-1)*(1+I(i))^(T(i-1)-T(i));
end
c'
ans = 1×26
1 0.98039 0.95882 0.93089 0.89509 0.86274
Se i coefficienti di attualizzazione sono noti, allora il vettore dei saldi attualizzati si può determinare come di
seguito (occorrono i vettori F e c).
V=zeros(numf,1);
V(1)=F(1)*c(1);
for i=2:numf
V(i)=V(i-1)+F(i)*c(i);
end
V'
ans = 1×26
-2000 -2980.4 -3172.2 -3265.2 -3086.2 -2827.4
Se invece i coefficienti di attualizzazione non sono noti e non serve memorizzarli, allora il vettore dei saldi
attualizzati si può calcolare con il seguente codice (occorrono i vettori F, T ed I).
V=zeros(numf,1);
coeff=(1+I(1))^(-T(1));
V(1)=F(1)*coeff;
for i=2:numf
coeff=coeff*(1+I(i))^(T(i-1)-T(i));
5
V(i)=V(i-1)+F(i)*coeff;
end
V'
ans = 1×26
-2000 -2980.4 -3172.2 -3265.2 -3086.2 -2827.4
Anche in questo caso, è utile definire delle function per il calcolo dei coefficienti di attualizzazione e dei saldi
attualizzati.
function c=CoeffAtt(T,I)
n=length(T);
c=zeros(n,1);
c(1)=(1+I(1))^(-T(1));
for h=2:n
c(h)=c(h-1)*(1+I(h))^(T(h-1)-T(h));
end
end
function V=SaldiAtt(F,c)
n=length(F);
V=zeros(n,1);
V(1)=F(1)*c(1);
for h=2:n
V(h)=V(h-1)+F(h)*c(h);
end
end
c=CoeffAtt(T,I);
c'
ans = 1×26
1 0.98039 0.95882 0.93089 0.89509 0.86274
V=SaldiAtt(F,c);
V'
ans = 1×26
-2000 -2980.4 -3172.2 -3265.2 -3086.2 -2827.4
6
% calcolo REA al tasso fisso i0
rea=F(1)*(1+i0)^(-T(1));
for i=2:numf
rea=rea+F(i)*(1+i0)^(-T(i));
end
Di seguito invece abbiamo il calcolo del REA al tasso variabile, così come descritto dal vettore I:
coeff=(1+I(1))^(-T(1));
reaVAR=F(1)*coeff;
for i=2:numf
coeff=coeff*(1+I(i))^(T(i-1)-T(i));
reaVAR=reaVAR+F(i)*coeff;
end
Sarà talvolta utile avere delle function che calcolano direttamente il REA al tasso fisso i0 ed il REA al tasso
variabile.
function rea=ReaFisso(F,T,i0)
rea=F(1)*(1+i0)^(-T(1));
for h=2:length(F)
rea=rea+F(h)*(1+i0)^(-T(h));
end
end
function reavar=ReaVar(F,c)
reavar=F(1)*c(1);
for h=2:length(F)
reavar=reavar+F(h)*c(h);
end
end
Utilizzando queste function possiamo ad esempio calcolare i REA per tutte le operazioni finanziarie della
matrice MF.
REAfisso = 1×12
1888.7 1399.8 2454 1258.9 1404.4 1080.4
REAvar
REAvar = 1×12
2685.1 1751.3 3327.5 517.42 2055.2 1471
7
A5. Classificazione degli investimenti
Le seguenti function MATLAB forniscono un risultato del tipo vero/falso indicando se l’operazione finanziaria "F"
fornita come vettore in input è o meno un investimento in senso stretto, puro, in senso lato, in senso generale.
Queste function possono essere utilizzate anche per caratterizzare un finanziamento: è infatti sufficiente
passare alla function il vettore "–F" invece che "F" tenuto conto che "F" è un finanziamento se e solo se "–F" è
un investimento.
Le due seguenti function necessitano come input del solo vettore "F". Si ricordi che è richiesto avere almeno un
flusso di cassa positivo ed almeno un flusso di cassa negativo, inoltre il primo flusso di cassa non nullo deve
necessariamente essere negativo.
function puro=InvPuro(F)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
if primopos<primoneg
puro=false;
return;
end
S=SaldiCont(F);
primosaldopos=PrimoPos(S);
if isnan(primosaldopos)
puro=false;
return;
end
puro=true;
for h=(primosaldopos+1):length(F)
if S(h)<0
puro=false;
break;
end
end
end
function stretto=InvStretto(F)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
if primopos<primoneg
stretto=false;
return;
end
stretto=true;
for h=(primopos+1):length(F)
if F(h)<0
stretto=false;
break;
end
end
end
8
Si osservi come le precedenti function possano essere implementate anche utilizzando la subfunction
"PrimoNeg":
function puro=InvPuro(F)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
if primopos<primoneg
puro=false;
return;
end
S=SaldiCont(F);
primosaldopos=PrimoPos(S);
if isnan(primosaldopos)
puro=false;
return;
end
S2=S(primosaldopos+1:end);
primonegS2=PrimoNeg(S2);
puro=isnan(primonegS2);
end
function stretto=InvStretto(F)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
if primopos<primoneg
stretto=false;
return;
end
F2=F(primopos+1:end);
primonegF2=PrimoNeg(F2);
stretto=isnan(primonegF2);
end
function lato=InvLato(F,T)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
9
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
if ScadMediaNeg(F,T)<T(primopos)
lato=true;
else
lato=false;
end
end
Si osservi come queste function si possano implementare alternativamente utilizzando il calcolo booleano:
function generale=InvGenerale(F,T)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
generale = ( ScadMediaNeg(F,T)<ScadMediaPos(F,T) );
end
function lato=InvLato(F,T)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
lato = ( ScadMediaNeg(F,T)<T(primopos) );
end
Utilizzando queste function possiamo in modo estremamente semplice vedere che tipo di investimenti sono
raccolti nel file "OpFin.mat". Iniziamo con delle maschere:
maskPURO
maskLATO
10
1 0 1 0 1 0 1 0 0 1 1 0
maskGENERALE
listaSTRETTO=zeros(1,numinv);
numSTRETTO=0;
listaPURO=zeros(1,numinv);
numPURO=0;
listaLATO=zeros(1,numinv);
numLATO=0;
listaGENERALE=zeros(1,numinv);
numGENERALE=0;
for j=1:numinv
F=MF(:,j);
if InvStretto(F)
numSTRETTO=numSTRETTO+1;
listaSTRETTO(numSTRETTO)=j;
end
if InvPuro(F)
numPURO=numPURO+1;
listaPURO(numPURO)=j;
end
if InvLato(F,T)
numLATO=numLATO+1;
listaLATO(numLATO)=j;
end
if InvGenerale(F,T)
numGENERALE=numGENERALE+1;
listaGENERALE(numGENERALE)=j;
end
end
listaSTRETTO=listaSTRETTO(1:numSTRETTO)
listaSTRETTO = 1×3
3 7 11
listaPURO=listaPURO(1:numPURO)
listaPURO = 1×6
1 3 5 7 11 12
listaLATO=listaLATO(1:numLATO)
listaLATO = 1×6
1 3 5 7 10 11
listaGENERALE=listaGENERALE(1:numGENERALE)
listaGENERALE = 1×10
1 2 3 5 6 7 9 10 11 12
11
A6. Calcolo del PBP e del DPBP
Le seguenti function MATLAB calcolano il “Pay-Back Period” ed il “Discounted Pay-Back Period”
dell’operazione finanziaria fornita come input (vettori F, T e c).
Si ricordi che nel caso del PBP e del DPBP il primo flusso di cassa deve essere negativo (condizione non
particolarmente vincolante dal momento che questi valori sono rilevanti soltanto nel caso degli investimenti).
function primononneg=PrimoNonneg(v)
primononneg=NaN;
for h=1:length(v)
if v(h)>=0
primononneg=h;
break;
end
end
end
function pbp=PBP(F,T)
if not(F(1)<0)
error('Il vettore F non ha il primo flusso di cassa negativo');
end
S=SaldiCont(F);
k=PrimoNonneg(S);
if isnan(k)
pbp=+inf;
else
m=(S(k)-S(k-1))/(T(k)-T(k-1));
pbp=T(k)-(S(k)/m);
end
end
function dpbp=DPBP(F,T,c)
if not(F(1)<0)
error('Il vettore F non ha il primo flusso di cassa negativo');
end
V=SaldiAtt(F,c);
k=PrimoNonneg(V);
if isnan(k)
dpbp=+inf;
else
m=(V(k)-V(k-1))/(T(k)-T(k-1));
dpbp=T(k)-(V(k)/m);
end
end
Tramite queste function possiamo calcolare per le operazioni finanziarie in MF i valori dei PBP e DPBP:
c=CoeffAtt(T,I);
Pbp=zeros(1,numinv);
Dpbp=zeros(1,numinv);
for j=1:numinv
F=MF(:,j);
Pbp(j)=PBP(F,T);
Dpbp(j)=DPBP(F,T,c);
end
Pbp
12
Pbp = 1×12
13.75 7.2 13.636 4.3077 14.333 6.9444
Dpbp
Dpbp = 1×12
15.62 11.694 14.772 4.4536 15.862 17.776
Un modo immediato per verificare la correttezza dei valori calcolati per il PBP ed il DPBP è quello di
rappresentare graficamente i saldi contabili, i saldi di cassa attualizzati, il PBP ed il DPBP. In particolare,
PBP e DPBP altro non sono che il primo istante di tempo in cui i saldi contabili ed i saldi di cassa attualizzati,
rispettivamente, intersecano l'asse delle ascisse per la prima volta.
Siamo a questo punto in grado di rappresentare il grafico dei saldi di cassa e dei PBP e DPBP.
% grafico
figure("Name","PBP e DPBP");
xmin=0;
xmax=T(end);
dx=(xmax-xmin)*0.05;
yall=[0;S;V];
ymin=min(yall);
ymax=max(yall);
dy=(ymax-ymin)*0.05;
%
plot(T,S,'r-');
hold on;
plot(T,V,'g-');
plot(Pbp,0,'ks');
plot(Dpbp,0,'ks');
plot([xmin,xmax],[0,0],'b');
plot([0,0],[ymin,ymax],'b');
hold off;
%
xlim([xmin-dx,xmax+dx]);
ylim([ymin-dy,ymax+dy]);
title("Saldi di cassa, PBP e DPBP");
legend("Saldi Contabili","Saldi Cassa Attualizzati","Location","best");
xlabel("Tempi");
ylabel("Saldi");
13
grid on;
grid minor;
E’ opportuno osservare l’uso della function per il calcolo del REA a tasso fisso (precedentemente descritta) che
permette di semplificare notevolmente il codice.
Vediamo innanzi tutto una procedura per il calcolo del TIR tramite il "Metodo di Bisezione" (che si basa
sull'utilizzo di un ciclo iterativo "while").
function tir=TIR(F,T,i1,i2,precis)
R1=ReaFisso(F,T,i1);
R2=ReaFisso(F,T,i2);
if R1*R2>0
error('Esistenza del TIR non garantita')
elseif R1==0
tir=i1;
return
elseif R2==0
tir=i2;
return
end
if R1>0
14
ipos=i1;
reapos=R1;
ineg=i2;
reaneg=R2;
else
ipos=i2;
reapos=R2;
ineg=i1;
reaneg=R1;
end
while abs(ipos-ineg)>precis
itemp=(ipos+ineg)/2;
reatemp=ReaFisso(F,T,itemp);
if reatemp>0
ipos=itemp;
reapos=reatemp;
elseif reatemp<0
ineg=itemp;
reaneg=reatemp;
else
tir=itemp;
return;
end
end
m=(reapos-reaneg)/(ipos-ineg);
tir=ipos-(reapos/m);
end
Tramite questa function possiamo calcolare i TIR (i1=0%, i2=35%, precis=10^(-11)) delle operazioni finanziarie
descritte dalla matrice MF:
% calcoliamo i TIR
tir=zeros(1,numinv);
for j=1:numinv
F=MF(:,j);
tir(j)=TIR(F,T,i1,i2,precis);
end
tir
tir = 1×12
0.059164 0.063262 0.068078 0.29047 0.052469 0.052998
Un metodo immediato per verificare la correttezza del calcolo del TIR è quello di rappresentare graficamente
il REA al tasso fisso calcolato per i tassi nell'intervallo [0,0.35]. In questo caso, il TIR deve essere il punto di
intersezione del grafico del REA con l'asse delle ascisse.
15
i2=0.35;
precis=10^(-11);
step=0.01;
% calcoliamo il TIR
Tir=TIR(F,T,i1,i2,precis);
% grafico
figure("Name","TIR");
xmin=0;
xmax=i2;
dx=(xmax-xmin)*0.05;
yall=[0;Rea];
ymin=min(yall);
ymax=max(yall);
dy=(ymax-ymin)*0.05;
%
plot(tassi,Rea,'r-');
hold on;
plot(Tir,0,'ks');
plot([xmin,xmax],[0,0],'b');
plot([0,0],[ymin,ymax],'b');
hold off;
%
xlim([xmin-dx,xmax+dx]);
ylim([ymin-dy,ymax+dy]);
title("Rea al variare del tasso fisso e TIR");
legend("REA al variare del tasso fisso","Location","best");
xlabel("Tassi");
ylabel("REA");
grid on;
grid minor;
16
Vediamo adesso una procedura per il calcolo del TIR basata sul cosiddetto "Metodo Monte Carlo".
function tir=TIRmc(F,T,i1,i2,precis)
R1=ReaFisso(F,T,i1);
R2=ReaFisso(F,T,i2);
if R1*R2>0
error('Esistenza del TIR non garantita')
elseif R1==0
tir=i1;
return
elseif R2==0
tir=i2;
return
end
tassi=i1:precis:i2;
numtassi=length(tassi);
Rea=NaN(numtassi,1);
Rea(1)=R1;
for h=2:numtassi
Rea(h)=ReaFisso(F,T,tassi(h));
if Rea(h)==0
tir=tassi(h);
return;
elseif Rea(h-1)*Rea(h)<0
m=(Rea(h)-Rea(h-1))/(tassi(h)-tassi(h-1));
tir=tassi(h)-(Rea(h)/m);
return;
end
end
17
end
E’ utile ribadire con un test computazionale quanto il metodo di bisezione sia più veloce del metodo Monte-
Carlo.
Utilizzando i comandi “tic” e “toc” per la determinazione del tempo di esecuzione e richiedendo una precisione
di 10^(-8), per la determinazione del TIR il Metodo Monte Carlo necessita di circa 10 secondi di elaborazione
su un computer con processore i7 con 6-core a 2.6GHz, mentre il metodo di bisezione impiega sullo stesso
computer circa 2 millesimi di secondo.
ans =
0.063262
Elapsed time is 0.002135 seconds.
tic,TIRmc(F,T,i1,i2,precis),toc
ans =
0.063262
Elapsed time is 10.083986 seconds.
function primopos=PrimoPos(v)
primopos=NaN;
for h=1:length(v)
if v(h)>0
primopos=h;
break;
end
end
end
function primoneg=PrimoNeg(v)
primoneg=NaN;
for h=1:length(v)
if v(h)<0
primoneg=h;
break;
18
end
end
end
function c=CoeffAtt(T,I)
n=length(T);
c=zeros(n,1);
c(1)=(1+I(1))^(-T(1));
for h=2:n
c(h)=c(h-1)*(1+I(h))^(T(h-1)-T(h));
end
end
function S=SaldiCont(F)
n=length(F);
S=zeros(n,1);
S(1)=F(1);
for h=2:n
S(h)=S(h-1)+F(h);
end
end
function V=SaldiAtt(F,c)
n=length(F);
V=zeros(n,1);
V(1)=F(1)*c(1);
for h=2:n
V(h)=V(h-1)+F(h)*c(h);
end
end
function rea=ReaFisso(F,T,i0)
rea=F(1)*(1+i0)^(-T(1));
for h=2:length(F)
rea=rea+F(h)*(1+i0)^(-T(h));
end
end
function reavar=ReaVar(F,c)
reavar=F(1)*c(1);
for h=2:length(F)
reavar=reavar+F(h)*c(h);
end
end
function scadmediapos=ScadMediaPos(F,T)
numer=0;
denom=0;
for h=1:length(F)
if F(h)>0
numer=numer+T(h)*F(h);
denom=denom+F(h);
19
end
end
scadmediapos=numer/denom;
end
function scadmedianeg=ScadMediaNeg(F,T)
numer=0;
denom=0;
for h=1:length(F)
if F(h)<0
numer=numer+T(h)*F(h);
denom=denom+F(h);
end
end
scadmedianeg=numer/denom;
end
function generale=InvGenerale(F,T)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
generale = ( ScadMediaNeg(F,T)<ScadMediaPos(F,T) );
end
function lato=InvLato(F,T)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
lato = ( ScadMediaNeg(F,T)<T(primopos) );
end
function puro=InvPuro(F)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
if primopos<primoneg
puro=false;
return;
end
S=SaldiCont(F);
primosaldopos=PrimoPos(S);
if isnan(primosaldopos)
puro=false;
return;
end
S2=S(primosaldopos+1:end);
primonegS2=PrimoNeg(S2);
puro=isnan(primonegS2);
20
end
function stretto=InvStretto(F)
primopos=PrimoPos(F);
primoneg=PrimoNeg(F);
if isnan(primopos) || isnan(primoneg)
error('Nel vettore F i flussi sono tutti dello stesso segno');
end
if primopos<primoneg
stretto=false;
return;
end
F2=F(primopos+1:end);
primonegF2=PrimoNeg(F2);
stretto=isnan(primonegF2);
end
function primononneg=PrimoNonneg(v)
primononneg=NaN;
for h=1:length(v)
if v(h)>=0
primononneg=h;
break;
end
end
end
function pbp=PBP(F,T)
if not(F(1)<0)
error('Il vettore F non ha il primo flusso di cassa negativo');
end
S=SaldiCont(F);
k=PrimoNonneg(S);
if isnan(k)
pbp=+inf;
else
m=(S(k)-S(k-1))/(T(k)-T(k-1));
pbp=T(k)-(S(k)/m);
end
end
function dpbp=DPBP(F,T,c)
if not(F(1)<0)
error('Il vettore F non ha il primo flusso di cassa negativo');
end
V=SaldiAtt(F,c);
k=PrimoNonneg(V);
if isnan(k)
dpbp=+inf;
else
m=(V(k)-V(k-1))/(T(k)-T(k-1));
dpbp=T(k)-(V(k)/m);
21
end
end
% function tir
function tir=TIR(F,T,i1,i2,precis)
R1=ReaFisso(F,T,i1);
R2=ReaFisso(F,T,i2);
if R1*R2>0
error('Esistenza del TIR non garantita')
elseif R1==0
tir=i1;
return
elseif R2==0
tir=i2;
return
end
if R1>0
ipos=i1;
reapos=R1;
ineg=i2;
reaneg=R2;
else
ipos=i2;
reapos=R2;
ineg=i1;
reaneg=R1;
end
while abs(ipos-ineg)>precis
itemp=(ipos+ineg)/2;
reatemp=ReaFisso(F,T,itemp);
if reatemp>0
ipos=itemp;
reapos=reatemp;
elseif reatemp<0
ineg=itemp;
reaneg=reatemp;
else
tir=itemp;
return;
end
end
m=(reapos-reaneg)/(ipos-ineg);
tir=ipos-(reapos/m);
end
function tir=TIRmc(F,T,i1,i2,precis)
R1=ReaFisso(F,T,i1);
R2=ReaFisso(F,T,i2);
if R1*R2>0
error('Esistenza del TIR non garantita')
elseif R1==0
tir=i1;
return
22
elseif R2==0
tir=i2;
return
end
tassi=i1:precis:i2;
numtassi=length(tassi);
Rea=NaN(numtassi,1);
Rea(1)=R1;
for h=2:numtassi
Rea(h)=ReaFisso(F,T,tassi(h));
if Rea(h)==0
tir=tassi(h);
return;
elseif Rea(h-1)*Rea(h)<0
m=(Rea(h)-Rea(h-1))/(tassi(h)-tassi(h-1));
tir=tassi(h)-(Rea(h)/m);
return;
end
end
end
23