You are on page 1of 20

Fixed Income Mathematics in Quantlib

Part II
Mauricio Bedoya
javierma36@gmail.com
February 2014
In this blog, we will replicate Exhibit 24.2 and create two additional classes: FixedPassThrough
and AccrualCMO. The FixedPassThrough class will create the cash ows that allow to make
payment in the AccrualCMO. In other words, FixedPassThrough works as the collateral of
AccrualCMO structure. Before we continue, I have to give some bad news. Exhibits 24.3 and
24.5 are wrong in the book. Contrast the last paragraph of page 447 with bond class A principal
payment.
Something that I forget to mentioned in the previous blogs, is that I didnt assert proper input
valuation. For example, if you provide a negative amount to class FixedRateMortgagePSA, the
program should prompt an error and this is not the case. I assume that you provide reasonable
inputs. At the same time, previous and current les arent part of QuantLib. Once I check that
everything works correctly, I will sent them to QuantLib to proper assessment.
1. Fixed Passthrough (page 474)
FixedPassThrough will be inherited from FixedRateMortgagePSA. The .hpp and .cpp les of
FixedPassThrowugh are:
1
1 / mode : c++; tabwi dth : 4; i ndent tabsmode : n i l ; cbas i c o f f s e t : 4 /
3 /
Copyri ght (C) 2014 Mauri ci o Bedoya
5
Thi s f i l e i s not yet part of QuantLib , a f r e e s of t war e /opens our ce l i br a r y
7 f or f i n a n c i a l quant i t at i ve anal ys t s and de ve l ope r s http : // quant l i b . org /
/
9
#i f nde f quant l i b f i xe dpas s t hr ough hpp
11 #de f i ne quant l i b f i xe dpas s t hr ough hpp
13 #i nc l ude f i xedratemortgagePSA . hpp
#i nc l ude <i ostream>
15 #i nc l ude <vector >
#i nc l ude <ql /ti me / daycounters / ac t ual ac t ual . hpp>
17 #i nc l ude <ql / i n t e r e s t r a t e . hpp>
19 namespace QuantLib{
21 c l a s s FixedPassThrough : publ i c FixedRateMortgagePSA{
publ i c :
23 FixedPassThrough ( cons t Date& i ssueDate , cons t Cal endar& cal endar , cons t
Real& amount , cons t I nt e r e s t Rat e& passthrowghRate , cons t I nt e r e s t Rat e& NetWAC
, cons t Real& WAM, Rate& f ee , cons t I nt e ge r& yearPayments , cons t Real& PSA,
cons t I nt e ge r& seasoned = 0) ;
v i r t ua l FixedPassThrough ( ) ;
25 //@{
/ Others /
27 Leg Ne t I nt e r e s t ( ) ;
29 //@}
pr i vat e :
31 Real term ;
I nt e ge r yearPayments , s eas oned ;
33 I nt e r e s t Rat e passthroughRate , NetWAC ;
/ Hel per s /
35 Time t = ( 1. 0/ yearPayments ) ;
Real compoundFactor = passthroughRate . compoundFactor ( t ) ;
37 I nt e ge r numberOfPayments = ( term yearPayments s eas oned ) ;
39 };
}
41
#e ndi f / def i ne d ( h h Fi l e ) /
2
/ mode : c++; tabwi dth : 4; i ndent tabsmode : n i l ; cbas i c o f f s e t : 4 /
2
/
4 Copyri ght (C) 2014 Mauri ci o Bedoya
6 Thi s f i l e i s not yet part of QuantLib , a f r e e s of t war e /opens our ce l i br a r y
f or f i n a n c i a l quant i t at i ve anal ys t s and de ve l ope r s http : // quant l i b . org /
8 /
10 #i nc l ude f i xedpas s t hr ough . hpp
12 namespace QuantLib {
14 FixedPassThrough : : FixedPassThrough ( cons t Date& i ssueDate , cons t Cal endar&
cal endar , cons t Real& amount , cons t I nt e r e s t Rat e& passthroughRate , cons t
I nt e r e s t Rat e& NetWAC, cons t Real& WAM, Rate& f ee , cons t I nt e ge r& yearPayments
, cons t Real& PSA, cons t I nt e ge r& seasoned ) : FixedRateMortgagePSA( i ssueDate ,
cal endar , amount , NetWAC, f ee , WAM, yearPayments , PSA, seasoned ) ,
passthroughRate ( passthroughRate ) , NetWAC (NetWAC) , yearPayments (
yearPayments ) , term (WAM) , s eas oned ( seasoned ) {}
16 FixedPassThrough : : FixedPassThrough ( ) {}
18 //@{
/ Others /
20
Leg FixedPassThrough : : Ne t I nt e r e s t ( )
22 {
Leg i n t e r e s t ;
24 f o r ( i nt i = 0; i < numberOfPayments ; i ++)
{
26 boost : : s har ed pt r <CashFlow> I ( new SimpleCashFlow( t hi s >
FixedRateMortgagePSA : : Begi ni ngBal ance ( ) [ i ]>amount ( ) ( compoundFactor 1)
, ( t hi s ) . FixedRateMortgagePSA : : Begi ni ngBal ance ( ) [ i ]>date ( ) ) ) ;
i n t e r e s t . push back ( I ) ;
28 }
30 r et ur n i n t e r e s t ;
}
32 }
The implementation in main, to replicar Exhibit 24.2:
3
/
2 Fi xed Income Mathematics Four Edi t i on
pag ( 474)
4 Anal yzi ng s e c ur i t i z e d products .
/
6 #i nc l ude <i ostream>
#i nc l ude <ql / quant l i b . hpp>
8 #i nc l ude <vector >
#i nc l ude <boost / as s i gn / st d/ vect or . hpp>
10 #i nc l ude <boost /f ormat . hpp>
#i nc l ude f i xedpas s t hr ough . hpp
12
us i ng namespace QuantLib ;
14 us i ng namespace std ;
us i ng namespace boost : : as s i gn ;
16
boost : : f ormat FORMATER1 ( %20d % 12.10d % 12.3d % 12.8d % 12.8d % 12.8d %
12s %12s %12s ) ;
18
i nt main ( )
20 {
t r y {
22 Rate BondRate = 0. 075;
Rate WAC = 0. 08125;
24 Rate f e e = 0 . 0 ;
DayCounter DC= Actual Actual ( Actual Actual : : ISDA) ;
26 Cal endar cal endar = Nul l Cal endar ( ) ;
Compounding compounded = Si mpl e ;
28 Frequency f r equency = Annual ;
30 I nt e r e s t Rat e bondRate ( BondRate , DC, compounded , f r equency ) ;
I nt e r e s t Rat e netWAC(WAC, DC, compounded , f r equency ) ;
32 Date i s s ue ( 1 , Jan , 2000) ;
i s s ue = cal endar . adj us t ( i s s ue ) ;
34 I nt e ge r YearPayments = 12;
I nt e ge r Seasoned = 3;
36 Real Remai ningYears = 30;
FixedPassThrough FPT( i s s ue , cal endar , 400000000 , bondRate , netWAC,
RemainingYears , f ee , YearPayments , 1. 65 , Seasoned ) ;
38
cout << FORMATER1 % Date % BMB % SMM % MP % NI % SP % PREP
% TP % TCF << endl ;
40 Real BB, SMM, MP, NI , SP, PREP, TP, TCF;
f o r ( i nt i= 0; i <357; i ++) {
42 BB = FPT. FixedRateMortgagePSA : : Begi ni ngBal ance ( ) [ i ]>amount ( ) ;
SMM = FPT. FixedRateMortgagePSA : :SMM( ) [ i ]>amount ( ) ;
44 MP = FPT. FixedRateMortgagePSA : : Payment ( ) [ i ]>amount ( ) ;
NI = FPT. Ne t I nt e r e s t ( ) [ i ]>amount ( ) ;
46 SP = FPT. FixedRateMortgagePSA : : ProyectedPri nci pal Payment ( ) [ i ]>
amount ( ) ;
4
PREP = FPT. FixedRateMortgagePSA : : Pri nci pal Repayment ( ) [ i ]>amount ( ) ;
2 TP = SP + PREP;
TCF = NI + TP;
4
cout << FORMATER1 %FPT. FixedRateMortgagePSA : : Begi ni ngBal ance ( ) [ i ]>
date ( )
6 %BB %SMM %MP % NI %SP %PREP %TP %TCF << endl ;
}
8 }
10 catch ( st d : : except i on& e ) {
c e r r << e . what ( ) << endl ;
12 }
}
2. Accrual CMO structure (page 477)
AccrualCMO has dierent inspectors. You can retrieve Balance, Principal and Interest for each
bond in the structure.
1 / mode : c++; tabwi dth : 4; i ndent tabsmode : n i l ; cbas i c o f f s e t : 4 /
3 /
Copyri ght (C) 2014 Mauri ci o Bedoya
5
Thi s f i l e i s not yet part of QuantLib , a f r e e s of t war e /opens our ce l i br a r y
7 f or f i n a n c i a l quant i t at i ve anal ys t s and de ve l ope r s http : // quant l i b . org /
9 /
11 #i f nde f quantl i b accrual CMO hpp
#de f i ne quantl i b accrual CMO hpp
13
#i nc l ude FixedPassThrough . hpp
15
namespace QuantLib{
17 c l a s s AccrualCMO{
/ Types Names
19 Accrual Z
Normal A through X ( excl udi ng F, I , Q, R and S)
21 /
publ i c :
23 AccrualCMO( cons t std : : vector <Real>& ParAmount , cons t st d : : vector <
I nt er es t Rat e >& CouponRate , cons t std : : vector <st d : : s t r i ng >& type , cons t
FixedPassThrough& PassThrough ) ;
v i r t ua l AccrualCMO( ) ;
25 //@{
/ I ns pe c t or s /
27 st d : : vector <Real> parAmount ( ) cons t ;
st d : : vector <I nt er es t Rat e > couponRate ( ) cons t ;
5
st d : : vector <st d : : s t r i ng > type ( ) cons t ;
2 st d : : vector <st d : : vector <Real> > Bal ance ( ) cons t ;
st d : : vector <st d : : vector <Real> > Pr i nc i pal ( ) cons t ;
4 st d : : vector <st d : : vector <Real> > I nt e r e s t ( ) cons t ;
6 / Others /
Real WAM( ) cons t ;
8 st d : : vector <Real> VectorWAM( ) cons t ;
Real GrossWAC( ) cons t ;
10 Real Total Outstandi ng ( ) cons t ;
Real Ac c r ue I nt e r e s t ( ) ;
12 voi d ParAmountUpdate ( ) ;
voi d GenerateCashFlow ( ) ;
14
//@}
16 pr i vat e :
FixedPassThrough PassThrough ;
18 mutable std : : vector <Real> ParAmount ;
st d : : vector <Real> ParAmountCopy = ParAmount ;
20 st d : : vector <i nt > I nt er es t Rat eHel per ( ) ;
st d : : vector <I nt er es t Rat e > CouponRate ;
22 st d : : vector <st d : : s t r i ng > t ype ;
st d : : vector <I nt eger > Months ;
24 st d : : vector <st d : : vector <Real> > Bal ance , Pr i nc i pal , I n t e r e s t ;
26 };
28 / I nl i ne f unc t i ons /
i n l i n e Real Total Outstandi ng ( cons t st d : : vector <boost : : s har ed pt r <
FixedRateMortgagePSA> >& Mortgages )
30 {
Real Total = 0;
32 f o r ( i nt i = 0; i < Mortgages . s i z e ( ) ; i ++) {
Total += Mortgages [ i ]>amount ( ) ;
34 }
36 r et ur n Total ;
}
38
i n l i n e Real WAM( cons t std : : vector <boost : : s har ed pt r <FixedRateMortgagePSA> >&
Mortgages , boost : : s har ed pt r <AccrualCMO>& Tranches )
40 {
Real wam;
42 st d : : vector <st d : : vector <Real> > bal ance = Tranches>Bal ance ( ) ;
f o r ( i nt i = 0; i < Mortgages . s i z e ( ) ; i ++)
44 {
46 wam += ( Mortgages [ i ]>amount ( ) / Total Outstandi ng ( Mortgages ) ) (1 +
bal ance [ i ] . s i z e ( ) ) ;
}
48
r et ur n wam;
50 }
6
i n l i n e Real GrossWAC( cons t std : : vector <boost : : s har ed pt r <
FixedRateMortgagePSA> >& Mortgages )
2 {
Real wac ;
4 f o r ( i nt i = 0; i < Mortgages . s i z e ( ) ; i ++)
{
6 wac += ( Mortgages [ i ]>amount ( ) / Total Outstandi ng ( Mortgages ) )
Mortgages [ i ]>r at e ( ) ;
}
8
r et ur n wac ;
10 }
12 i n l i n e Real NetWAC( cons t std : : vector <boost : : s har ed pt r <FixedRateMortgagePSA>
>& Mortgages )
{
14 / f e e must i nc l ude : s e r v i c i ng f ee , t r us t e e f e e and payment f o r c r e di t
support /
Real netwac ;
16 f o r ( i nt i = 0; i < Mortgages . s i z e ( ) ; i ++)
{
18 netwac += ( Mortgages [ i ]>amount ( ) / Total Outstandi ng ( Mortgages ) ) (
Mortgages [ i ]>r at e ( ) Mortgages [ i ]>f e e ( ) ) ;
}
20
r et ur n netwac ;
22 }
24 }
#e ndi f / def i ne d ( hh Accrual CMO ) /
Im only going to concentrate in extension and contraction risk. As PSA increase, the average
life of each bond in the structure reduce, but no in equal proportion. Just play with the PSA
or create an additional Accrue type bond and evaluate the behaviour.
1 /
Fi xed Income Mathematics Four Edi t i on
3 pag ( 474)
Anal yzi ng s e c ur i t i z e d products .
5 /
#i nc l ude <i ostream>
7 #i nc l ude <ql / quant l i b . hpp>
#i nc l ude <vector >
9 #i nc l ude <boost / as s i gn / st d/ vect or . hpp>
#i nc l ude <boost /f ormat . hpp>
11 #i nc l ude f i xedpas s t hr ough . hpp
#i nc l ude AccrualCMO. hpp
13
us i ng namespace QuantLib ;
15 us i ng namespace std ;
7
1 us i ng namespace boost : : as s i gn ;
3 boost : : f ormat FORMATER1 ( %20d % 12.10d % 12.3d % 12.8d % 12.8d % 12.8d %
12s %12s %12s ) ;
boost
5 : : f ormat FORMATER2 ( %10.4d % 10.4d % 10.4d % 10.4d % 10.4d ) ;
i nt main ( )
7 {
t r y {
9 Rate BondRate = 0. 075;
Rate WAC = 0. 08125;
11 Rate f e e = 0 . 0 ;
DayCounter DC= Actual Actual ( Actual Actual : : ISDA) ;
13 Cal endar cal endar = Nul l Cal endar ( ) ;
Compounding compounded = Si mpl e ;
15 Frequency f r equency = Annual ;
17 I nt e r e s t Rat e bondRate ( BondRate , DC, compounded , f r equency ) ;
I nt e r e s t Rat e netWAC(WAC, DC, compounded , f r equency ) ;
19 Date i s s ue ( 1 , Jan , 2000) ;
i s s ue = cal endar . adj us t ( i s s ue ) ;
21 I nt e ge r YearPayments = 12;
I nt e ge r Seasoned = 3;
23 vector <Rate> PSA;
PSA += 0 . 5 , 1 , 1 . 6 5 , 2 , 3 , 4 , 5;
25 Real RemainingYears = 30;
27 cout << FORMATER2 % PSA % A % B % C % Z << endl ;
st d : : vector <Real> ParAmount ;
29 ParAmount += 194500000 , 36000000 , 96500000 , 73000000;
st d : : vector <I nt er es t Rat e > CouponRate ;
31 f o r ( i nt i = 0; i < 4; i ++)
{
33 I nt e r e s t Rat e r ( 0. 075 ,DC, compounded , f r equency ) ;
CouponRate += r ;
35 }
st d : : vector <s t r i ng > type ;
37 type += A , B , C , Accrue ;
39 st d : : vector <Real> Vwam;
f o r ( i nt i = 0; i < PSA. s i z e ( ) ; i ++)
41 {
FixedPassThrough FPT( i s s ue , cal endar , 400000000 , bondRate , netWAC,
RemainingYears , f ee , YearPayments , PSA[ i ] , Seasoned ) ;
43 AccrualCMO CMO( ParAmount , CouponRate , type , FPT) ;
Vwam = CMO. VectorWAM( ) ;
45 cout << FORMATER2 %PSA[ i ] %Vwam[ 0 ] %Vwam[ 1 ] %Vwam[ 2 ] %Vwam[ 3 ]
<< endl ;
47 Vwam. c l e a r ( ) ;
}
49 }
8
1 catch ( st d : : except i on& e ) {
c e r r << e . what ( ) << endl ;
3 }
}
Its not possible to replicate Exhibit 24.3, because is wrong. Read last two paragraphs of page
477 for an explanation.
3. Prepayment Models (Chapter 23)
Now imagine that you want to consider any prepayment model, not only PSA. What you can
do is to create a class prepaymentxedratemortgage that accept as an input a vector of SMM
or CPR values. Im not going to publish this, but if you have diculties, comment this blog.
4. PAC bonds
Now, I will create a class PACBonds (FIM-3 in book), that allow to generate the corresponding
cashows and determinate the average life of the elements that integrate the structure. Before
we continue, I must say that Fabozzi book has another error in the table of page 489. For
dierent values of prepayment, is not possible to have the same average life for the support
bond. At the same time, for prepayment value 50, I get dierent (close) average life for PAC
and support bond.
/ mode : c++; tabwi dth : 4; i ndent tabsmode : n i l ; cbas i c o f f s e t : 4 /
2
/
4 Copyri ght (C) 2014 Mauri ci o Bedoya
6 Thi s f i l e i s not yet part of QuantLib , a f r e e s of t war e /opens our ce l i br a r y
f or f i n a n c i a l quant i t at i ve anal ys t s and de ve l ope r s http : // quant l i b . org /
8
QuantLib i s f r e e s of t war e : you can r e di s t r i but e i t and/ or modi fy i t
10 under the terms of the QuantLib l i c e n s e . You shoul d have r e c e i ve d a
copy of the l i c e n s e al ong wi th t hi s program ; i f not , pl e as e emai l
12 <quant l i bde v@l i s t s . s f . net >. The l i c e n s e i s al s o a va i l a bl e onl i ne at
<http : // quant l i b . org / l i c e n s e . shtml >.
14
Thi s program i s di s t r i but e d i n the hope that i t wi l l be us e f ul , but WITHOUT
16 ANY WARRANTY; wi thout even the i mpl i ed warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the l i c e n s e f o r more d e t a i l s .
18 /
20 #i f nde f quantlib PACBonds hpp
#de f i ne quantlib PACBonds hpp
9
1 #i nc l ude f i xedpas s t hr ough . hpp
3 namespace QuantLib {
5 c l a s s PacBonds{
publ i c :
7 PacBonds ( cons t st d : : vector <Real>& ParAmount , cons t st d : : vector <
I nt er es t Rat e >& CouponRate , cons t std : : vector <st d : : s t r i ng >& type , cons t Real&
capPSA, cons t Real& fl oorPSA , cons t FixedPassThrough& PassThrough ) ;
v i r t ua l PacBonds ( ) ;
9
//@{
11 / I ns pe c t or s /
st d : : vector <Real> ParAmount ( ) cons t ;
13 st d : : vector <I nt er es t Rat e > CouponRate ( ) cons t ;
st d : : vector <st d : : s t r i ng > Type ( ) cons t ;
15 st d : : vector <st d : : vector <Real> > Bal ance ( ) cons t ;
st d : : vector <st d : : vector <Real> > Pr i nc i pal ( ) cons t ;
17 st d : : vector <st d : : vector <Real> > I nt e r e s t ( ) cons t ;
19 / Others /
st d : : vector <Real> PAC AverageLife ( ) cons t ;
21 Real Support AverageLi f e ( ) cons t ;
Real GrossWAC( ) cons t ;
23 Real Total Outstandi ng ( ) cons t ;
25 //@}
27 pr i vat e :
//PAC I nf or mat i on
29 mutable std : : vector <Real> ParAmount ;
st d : : vector <Real> ParAmountCopy = ParAmount ;
31 st d : : vector <I nt er es t Rat e > CouponRate ;
st d : : vector <st d : : s t r i ng > t ype ;
33 Real capPSA , f l oorPSA ;
Real PSA ;
35 FixedPassThrough PassThrough ;
st d : : vector <st d : : vector <Real> > Bal ance , Pr i nc i pal , I n t e r e s t ;
37 st d : : vector <Real> SupportBal ance , Suppor t Pr i nci pal , Suppor t I nt e r e s t ;
39 //@{
// Hel per s
41 voi d SupportBal anceUpdate ( cons t Real& amount ) ;
Real SupportBal ance ( ) ;
43 st d : : vector <i nt > I nt er es t Rat eHel per ( ) ;
voi d GenerateCashFlow ( ) ;
45 //@}
};
47 }
49 #e ndi f / def i ne d ( quantlib PACBonds hpp ) /
10
1 / mode : c++; tabwi dth : 4; i ndent tabsmode : n i l ; cbas i c o f f s e t : 4 /
3 /
Copyri ght (C) 2014 Mauri ci o Bedoya
5
Thi s f i l e i s not yet part of QuantLib , a f r e e s of t war e /opens our ce l i br a r y
7 f or f i n a n c i a l quant i t at i ve anal ys t s and de ve l ope r s http : // quant l i b . org /
9 QuantLib i s f r e e s of t war e : you can r e di s t r i but e i t and/ or modi fy i t
under the terms of the QuantLib l i c e n s e . You shoul d have r e c e i ve d a
11 copy of the l i c e n s e al ong wi th t hi s program ; i f not , pl e as e emai l
<quant l i bde v@l i s t s . s f . net >. The l i c e n s e i s al s o a va i l a bl e onl i ne at
13 <http : // quant l i b . org / l i c e n s e . shtml >.
15 Thi s program i s di s t r i but e d i n the hope that i t wi l l be us e f ul , but WITHOUT
ANY WARRANTY; wi thout even the i mpl i ed warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the l i c e n s e f o r more d e t a i l s .
/
19
#i nc l ude PACBonds . hpp
21
namespace QuantLib {
23 PacBonds : : PacBonds ( cons t std : : vector <Real>& ParAmount , cons t st d : : vector <
I nt er es t Rat e >& CouponRate , cons t std : : vector <st d : : s t r i ng >& type , cons t Real&
capPSA, cons t Real& fl oorPSA , cons t FixedPassThrough& PassThrough ) : ParAmount
( ParAmount ) , CouponRate ( CouponRate ) , t ype ( type ) , capPSA ( capPSA) , f l oorPSA
( f l oorPSA) , PassThrough ( PassThrough )
{
25 QL REQUIRE( ( PassThrough . FixedRateMortgagePSA : : amount ( ) ==
Total Outstandi ng ( ) ) , Error : ParAmount and PassThrough amount d i f f e r . ) ;
QL REQUIRE( ( capPSA >= 0 | | f l oorPSA >= 0 | | capPSA > f l oorPSA) , Error :
PSA val ues must be po s i t i v e . ) ;
27
GenerateCashFlow ( ) ;
29 }
31 PacBonds : : PacBonds ( ) {}
33 //@{
/ I ns pe c t or s /
35 st d : : vector <Real> PacBonds : : ParAmount ( ) cons t { r et ur n ParAmountCopy ; }
st d : : vector <I nt er es t Rat e > PacBonds : : CouponRate ( ) cons t { r et ur n CouponRate ; }
37 st d : : vector <st d : : s t r i ng > PacBonds : : Type ( ) cons t { r et ur n t ype ; }
st d : : vector <st d : : vector <Real> > PacBonds : : Bal ance ( ) cons t { r et ur n Bal ance ; }
39 st d : : vector <st d : : vector <Real> > PacBonds : : Pr i nc i pal ( ) cons t { r et ur n
Pr i nc i pa l ; }
st d : : vector <st d : : vector <Real> > PacBonds : : I nt e r e s t ( ) cons t { r et ur n I n t e r e s t
; }
11
/ Others /
2 st d : : vector <Real> PacBonds : : PAC AverageLife ( ) cons t
{
4 st d : : vector <Real> l i f e ;
6 f o r ( i nt i = 0; i < Pr i nc i pa l . s i z e ( ) ; i ++)
{
8 Real M = 0;
f o r ( i nt j = 0; j < Pr i nc i pa l [ i ] . s i z e ( ) ; j ++)
10 {
M += ( ( j + 1) Pr i nc i pa l [ i ] [ j ] ) / 12;
12 }
14 l i f e . push back (M / ParAmountCopy [ i ] ) ;
}
16
r et ur n l i f e ;
18 }
20 Real PacBonds : : Support AverageLi f e ( ) cons t
{
22 i nt support = ParAmountCopy . s i z e ( ) 1;
Real M = 0;
24 f o r ( i nt j = 0; j < Suppor t Pr i nci pal . s i z e ( ) ; j ++)
{
26 M += ( ( j + 1) Suppor t Pr i nci pal [ j ] ) / 12;
}
28
r et ur n (M / ParAmountCopy [ support ] ) ;
30 }
32 Real PacBonds : : GrossWAC( ) cons t
{
34 Real wac = 0;
Real Total = Total Outstandi ng ( ) ;
36 f o r ( i nt i = 0; i < ParAmount . s i z e ( ) ; i ++)
{
38 wac += ( ParAmount [ i ] / Total ) CouponRate [ i ] ;
}
40
r et ur n wac ;
42 }
44 Real PacBonds : : Total Outstandi ng ( ) cons t
{
46 Real Total = 0;
f o r ( i nt i = 0; i < ParAmount . s i z e ( ) ; i ++)
48 {
Total += ParAmount [ i ] ;
50 }
52 r et ur n Total ;
}
12
1 Real PacBonds : : SupportBal ance ( )
{
3 Real t o t a l = 0;
f o r ( i nt i = 0; i < ParAmount . s i z e ( ) ; i ++)
5 {
t o t a l += I nt er es t Rat eHel per ( ) [ i ] ParAmount [ i ] ;
7 }
9 r et ur n t o t a l ;
}
11
voi d PacBonds : : SupportBal anceUpdate ( cons t Real& amount )
13 {
f o r ( i nt i = 0; i < ParAmount . s i z e ( ) ; i ++)
15 {
ParAmount [ i ] = I nt er es t Rat eHel per ( ) [ i ] amount ;
17 }
}
19 //@}
21 //@{ Hel per s de f i ne d pr i vat e
st d : : vector <i nt > PacBonds : : I nt er es t Rat eHel per ( )
23 {
st d : : vector <i nt > he l pe r ;
25 f o r ( i nt i = 0; i < ParAmount . s i z e ( ) ; i ++)
{
27 i f ( t ype [ i ]==Support )
{
29 he l pe r . push back ( 1) ;
}
31 e l s e
{
33 he l pe r . push back ( 0) ;
}
35 }
37 r et ur n he l pe r ;
}
39
voi d PacBonds : : GenerateCashFlow ( )
41 {
i nt N = PassThrough . FixedRateMortgagePSA : : ProyectedPri nci pal Payment ( ) .
s i z e ( ) ;
43 // Set vector s s i z e
st d : : vector <Real> begi ni ngbal ance (N) , pr i nc i pa l (N) , i n t e r e s t (N) ;
45 Suppor t Pr i nci pal . r e s i z e (N) , SupportBal ance . r e s i z e (N) , Suppor t I nt e r e s t
. r e s i z e (N) ;
47 Real e xc e s s ; // Excess amount over PAC /
Support bal ance
i nt j = 0; // St ar t Counter
49 i nt support = ParAmount . s i z e ( ) 1; // I de nt i f y Support vect or
ONLY.
13
1 f o r ( i nt i = 0; i < ParAmount . s i z e ( ) ; ++i )
{
3 st d : : f i l l ( begi ni ngbal ance . begi n ( ) , begi ni ngbal ance . end ( ) , 0) ;
st d : : f i l l ( pr i nc i pa l . begi n ( ) , pr i nc i pa l . end ( ) , 0) ;
5 st d : : f i l l ( i n t e r e s t . begi n ( ) , i n t e r e s t . end ( ) , 0) ;
7 whi l e ( ParAmount [ i ] > 0. 0001)
{
9 //PSA Value
PassThrough . setPSA( PassThrough . getPSA( ) ) ;
11 Real PSA Pri nci pal Payment = PassThrough . FixedRateMortgagePSA : :
ProyectedPri nci pal Payment ( ) [ j ]>amount ( ) +
PassThrough . FixedRateMortgagePSA : : Pri nci pal Repayment ( ) [ j ]>
amount ( ) ;
13 // Fl oor Value
PassThrough . setPSA( f l oorPSA ) ;
15 Real Fl oor Pr i nc i pal = PassThrough . FixedRateMortgagePSA : :
ProyectedPri nci pal Payment ( ) [ j ]>amount ( ) +
PassThrough . FixedRateMortgagePSA : : Pri nci pal Repayment ( ) [ j ]>
amount ( ) ;
17 //Cap Value
PassThrough . setPSA( capPSA ) ;
19 Real Cap Pr i nci pal = PassThrough . FixedRateMortgagePSA : :
ProyectedPri nci pal Payment ( ) [ j ]>amount ( ) +PassThrough . FixedRateMortgagePSA : :
Pri nci pal Repayment ( ) [ j ]>amount ( ) ;
21 Real Pri nci pal Payment = 0;
Real Absorb = 0;
23
/
25 Support Sect i on
/
27 //
i f ( SupportBal ance ( ) > 0)
29 {
i f ( PassThrough . getPSA( ) < f l oorPSA )
31 {
Pri nci pal Payment = PSA Pri nci pal Payment ;
33 }
e l s e
35 {
Pri nci pal Payment = ( Cap Pr i nci pal >= Fl oor Pr i nc i pal ) ?
Fl oor Pr i nc i pal : Cap Pr i nci pal ;
37 }
39 i f ( i < support )
{
41 // To absorb
Absorb = PSA Pri nci pal Payment Pri nci pal Payment +
e xc e s s ;
43 }
14
1 e l s e
{
3 // To absorb
Absorb = PSA Pri nci pal Payment + e xc e s s ;
5 }
e xc e s s = 0;
7
i f ( SupportBal ance ( ) > Absorb )
9 {
// Update support
11 SupportBal ance [ j ] = ParAmount [ support ] ;
Suppor t Pr i nci pal [ j ] = Absorb ;
13 Suppor t I nt e r e s t [ j ] = ParAmount [ support ] ( CouponRate
[ support ] . compoundFactor ( 1. 0/12) 1) ;
SupportBal anceUpdate ( Absorb ) ;
15 }
e l s e
17 {
// Absorb support bal ance
19 Absorb = SupportBal ance ( ) ;
SupportBal ance [ j ] = ParAmount [ support ] ;
21 Suppor t Pr i nci pal [ j ] = Absorb ;
Suppor t I nt e r e s t [ j ] = ParAmount [ support ] ( CouponRate
[ support ] . compoundFactor ( 1. 0/12) 1) ;
23 e xc e s s = PSA Pri nci pal Payment Pri nci pal Payment
SupportBal ance ( ) ;
SupportBal anceUpdate ( Absorb ) ;
25 }
}
27
/
29 PAC s e c t i on
/
31 e l s e
{
33 Pri nci pal Payment = PSA Pri nci pal Payment ;
}
35
i f ( i < support )
37 {
// Pac i nf or mat i on
39 begi ni ngbal ance [ j ] = ParAmount [ i ] ;
i n t e r e s t [ j ] = ParAmount [ i ] ( CouponRate [ i ] . compoundFactor
( 1. 0/12) 1) ;
41
i f ( ParAmount [ i ] > Pri nci pal Payment )
43 {
// Update PAC
45 pr i nc i pa l [ j ] = Pri nci pal Payment + e xc e s s ;
ParAmount [ i ] = ( Pri nci pal Payment + e xc e s s ) ;
47 e xc e s s = 0;
}
15
e l s e
2 {
// Absorb PAC bal ance
4 pr i nc i pa l [ j ] = ParAmount [ i ] ;
e xc e s s = Pri nci pal Payment ParAmount [ i ] ;
6 ParAmount [ i ] = ParAmount [ i ] ;
}
8 }
j ++;
10 }
/
12 Pac bal ance , pr i nc i pa l and i n t e r e s t
/
14 i f ( i < support )
{
16 Bal ance . push back ( begi ni ngbal ance ) ;
Pr i nc i pa l . push back ( pr i nc i pa l ) ;
18 I n t e r e s t . push back ( i n t e r e s t ) ;
}
20
}
22 }
//@}
24 }
Code to replicate table in page 489.
/
2 Fi xed Income Mathematics Four Edi t i on
pag ( 489)
4 Anal yzi ng s e c ur i t i z e d products .
/
6 #i nc l ude <i ostream>
#i nc l ude <al gori thm>
8 #i nc l ude <ql / quant l i b . hpp>
#i nc l ude <vector >
10 #i nc l ude <boost / as s i gn / st d/ vect or . hpp>
#i nc l ude <boost /f ormat . hpp>
12 #i nc l ude f i xedpas s t hr ough . hpp
#i nc l ude AccrualCMO. hpp
14 #i nc l ude PACBonds . hpp
16 us i ng namespace QuantLib ;
us i ng namespace std ;
18 us i ng namespace boost : : as s i gn ;
20 boost : : f ormat FORMATER2 ( %10.4d % 10.4d % 10.4d ) ;
16
i nt main ( )
2 {
t r y {
4 Rate BondRate = 0. 075;
Rate WAC = 0. 08125;
6 Rate f e e = 0 . 0 ;
DayCounter DC= Actual Actual ( Actual Actual : : ISDA) ;
8 Cal endar cal endar = Nul l Cal endar ( ) ;
Compounding compounded = Si mpl e ;
10 Frequency f r equency = Annual ;
12 I nt e r e s t Rat e bondRate ( BondRate , DC, compounded , f r equency ) ;
I nt e r e s t Rat e netWAC(WAC, DC, compounded , f r equency ) ;
14 Date i s s ue ( 1 , Jan , 2000) ;
i s s ue = cal endar . adj us t ( i s s ue ) ;
16 I nt e ge r YearPayments = 12;
I nt e ge r Seasoned = 3;
18 Real RemainingYears = 30;
20 st d : : vector <Real> ParAmount ;
ParAmount += 243800000 , 156200000;
22 st d : : vector <I nt er es t Rat e > CouponRate ;
f o r ( i nt i = 0; i < ParAmount . s i z e ( ) ; i ++)
24 {
I nt e r e s t Rat e r ( 0. 075 ,DC, compounded , f r equency ) ;
26 CouponRate += r ;
}
28 st d : : vector <s t r i ng > type ;
type += PAC1 , Support ;
30
st d : : vector <Real> PSA;
32 Real Cap , Fl oor ;
PSA += 0. 0 , 0. 5 , 0. 9 , 1. 0 , 1. 5 , 1. 65 , 2. 0 , 2. 5 , 3. 0 , 3. 5 , 4. 0 , 4. 5 , 5. 0 ,
7 . 0 ;
34 Cap = 3 . 0 ;
Fl oor = 0 . 9 ;
36
cout << Average Li f e or I nstruments i ns i de the s t r uc t ur e << endl ;
38 cout << FORMATER2 % PSA % PAC1 % Support << endl ;
40 f o r ( i nt i = 0; i < PSA. s i z e ( ) ; i ++)
{
42 // PassThrough
FixedPassThrough FPT( i s s ue , cal endar , 400000000 , bondRate , netWAC,
RemainingYears , f ee , YearPayments , PSA[ i ] , Seasoned ) ;
44 // PAC
PacBonds PAC( ParAmount , CouponRate , type , Cap , Fl oor , FPT) ;
46
// Average l i f e i nf or mat i on
48 st d : : vector <Real> PAC aver agel i f e = PAC. PAC AverageLife ( ) ;
Real Suppor t ave r age l i f e = PAC. Suppor t AverageLi f e ( ) ;
17
1 cout << FORMATER2 %FPT. getPSA( ) % PAC aver agel i f e [ 0 ] %
Suppor t ave r age l i f e << endl ;
}
3
}
5
catch ( st d : : except i on& e ) {
7 c e r r << e . what ( ) << endl ;
}
9 }
5. Agency Mortgage Strips
In FixedPassThrough class, you can nd NetInterest and TotalPrincipal inspectors (inherited
from FixedPassThroughPSA). These are the Legs (cashow) that you need.
6. Pricing
Once you have the corresponding Leg (cash ow), what is left to determinate the price of an
instrument (bonds from the structure), is the corresponding yield curve. In previous blogs I
show how to set a at yield curve (atforward class). Next, Im going to determinate the price
of the pass-through found in exhibit 22.8 (page 437), and the IO and PO bond class. The results
should correspond to those found in illustration 25.7 (page 501). Results dier because in the
book, they use approximate data.
/
2 Fi xed Income Mathematics Four Edi t i on
pag ( 489)
4 Anal yzi ng s e c ur i t i z e d products .
/
6 #i nc l ude <i ostream>
#i nc l ude <al gori thm>
8 #i nc l ude <ql / quant l i b . hpp>
#i nc l ude <vector >
10 #i nc l ude <boost / as s i gn / st d/ vect or . hpp>
#i nc l ude <boost /f ormat . hpp>
12 #i nc l ude f i xedpas s t hr ough . hpp
14 us i ng namespace QuantLib ;
us i ng namespace std ;
16 us i ng namespace boost : : as s i gn ;
18 boost : : f ormat FORMATER ( %12.7d % 10.7d ) ;
i nt main ( )
20 {
18
t r y {
2 Rate BondRate = 0. 075;
Rate WAC = 0. 0 95;
4 Rate f e e = 0. 005 ;
DayCounter DC= Actual Actual ( Actual Actual : : ISDA) ;
6 Cal endar cal endar = Nul l Cal endar ( ) ;
Compounding compounded = Si mpl e ;
8 Frequency f r equency = Annual ;
10 I nt e r e s t Rat e bondRate ( BondRate , DC, compounded , f r equency ) ;
I nt e r e s t Rat e netWAC(WAC, DC, compounded , f r equency ) ;
12 Date i s s ue ( 1 , Jan , 2000) ;
i s s ue = cal endar . adj us t ( i s s ue ) ;
14 I nt e ge r YearPayments = 12;
I nt e ge r Seasoned = 0;
16 Real RemainingYears = 30;
18 // PassThrough
FixedPassThrough FPT( i s s ue , cal endar , 100000 , bondRate , netWAC,
RemainingYears , f ee , YearPayments , 1. 0 , Seasoned ) ;
20 // Yi el dCurve
Rate yi e l d= 0. 0989564;
22 I nt e r e s t Rat e Yi el d ( yi el d , DC, compounded , f r equency ) ;
24 Real NPV Passthrough = CashFlows : : npv(FPT. TotalCashFlow ( ) , Yi el d , true ,
i s s ue , i s s ue ) ; // Passthrough
Real NPV IO = CashFlows : : npv(FPT. FixedRateMortgagePSA : : Ne t I nt e r e s t ( ) ,
Yi el d , true , i s s ue , i s s ue ) ; //IO
26 Real NPV PO = CashFlows : : npv(FPT. FixedRateMortgagePSA : : Tot al Pr i nc i pal ( ) ,
Yi el d , true , i s s ue , i s s ue ) ; //PO
28 cout << Pr i ce << endl ;
cout << FORMATER % PassThrough : % NPV Passthrough << endl ;
30 cout << FORMATER % IO: %NPV IO << endl ;
cout << FORMATER % PO: %NPV PO << endl ;
32
cout << \n ;
34 cout << FORMATER % TIR: %FPT. CashFl owYi el d ( NPV Passthrough ) << endl ;
cout << FORMATER % BEY: %FPT.BEY( Yi el d ) <<endl ;
36
cout << FORMATER % Durati on : %FPT. Ef f e c t i ve Dur at i on ( NPV Passthrough
, 0 . 7 5 , 1 . 0 ) << endl ;
38 cout << FORMATER % Convexi ty : %FPT. Ef f ect i veConvexi t y (
NPV Passthrough , 0 . 7 5 , 1 . 0 ) << endl ;
}
40
catch ( st d : : except i on& e ) {
42 c e r r << e . what ( ) << endl ;
}
44 }
19
In this case, duration and convexity approach diers from book. To estimate eective convexity
and duration, FixedPassThrough class increase (reduce) the yield
1
.
Clases may have suer changes, during the development. You can found them in the blog as
c++ les. I will send these to QuantLib in June 2014. Next blog will implement option pricing
examples and exercises found in Jhon C. Hull book: Option, Futures and Other Derivatives
sixth edition.
1
In the book, they increase (reduce) BEY.
20

You might also like