Main Content

Price Portfolio of Bond and Bond Option Instruments

This example shows the workflow to create and price a portfolio of bond and bond option instruments. You can use finportfolio and pricePortfolio to price FixedBond, FixedBondOption, OptionEmbeddedFixedBond, and FloatBond instruments using an IRTree pricing method.

Create ratecurve Object

Create a ratecurve object using ratecurve.

Settle = datetime(2018, 1, 1);
 ZeroTimes = calyears(1:4)';
 ZeroRates = [0.035; 0.042147; 0.047345; 0.052707];
 ZeroDates = Settle + ZeroTimes;
 Compounding = 1;
 ZeroCurve = ratecurve("zero",Settle,ZeroDates,ZeroRates, "Compounding",Compounding)
ZeroCurve = 
  ratecurve with properties:

                 Type: "zero"
          Compounding: 1
                Basis: 0
                Dates: [4×1 datetime]
                Rates: [4×1 double]
               Settle: 01-Jan-2018
         InterpMethod: "linear"
    ShortExtrapMethod: "next"
     LongExtrapMethod: "previous"

Create Bond and Option Instruments

Use fininstrument to create a FixedBond, FixedBondOption, OptionEmbeddedFixedBond, and FloatBond instrument objects.

CDates = datetime([2020,1,1 ; 2022,1,1]);
CRates = [.0425; .0750];
CouponRate = timetable(CDates,CRates);
Maturity = datetime(2022,1,1);
Period = 1;

% Vanilla FixedBond
VBond = fininstrument("FixedBond",'Maturity',Maturity,'CouponRate',0.0425,'Period',Period,'Name',"vanilla_fixed") 
VBond = 
  FixedBond with properties:

                  CouponRate: 0.0425
                      Period: 1
                       Basis: 0
                EndMonthRule: 1
                   Principal: 100
    DaycountAdjustedCashFlow: 0
       BusinessDayConvention: "actual"
                    Holidays: NaT
                   IssueDate: NaT
             FirstCouponDate: NaT
              LastCouponDate: NaT
                   StartDate: NaT
                    Maturity: 01-Jan-2022
                        Name: "vanilla_fixed"

 % Stepped coupon bond
SBond = fininstrument("FixedBond",'Maturity',Maturity,'CouponRate',CouponRate,'Period',Period,'Name',"stepped_coupon_bond") 
SBond = 
  FixedBond with properties:

                  CouponRate: [2×1 timetable]
                      Period: 1
                       Basis: 0
                EndMonthRule: 1
                   Principal: 100
    DaycountAdjustedCashFlow: 0
       BusinessDayConvention: "actual"
                    Holidays: NaT
                   IssueDate: NaT
             FirstCouponDate: NaT
              LastCouponDate: NaT
                   StartDate: NaT
                    Maturity: 01-Jan-2022
                        Name: "stepped_coupon_bond"

% FloatBond
Spread = 0;
Reset = 1;
Float = fininstrument("FloatBond",'Maturity',Maturity,'Spread',Spread,'Reset', Reset, ...
                      'ProjectionCurve',ZeroCurve,'Name',"floatbond")
Float = 
  FloatBond with properties:

                      Spread: 0
             ProjectionCurve: [1×1 ratecurve]
                 ResetOffset: 0
                       Reset: 1
                       Basis: 0
                EndMonthRule: 1
                   Principal: 100
    DaycountAdjustedCashFlow: 0
       BusinessDayConvention: "actual"
          LatestFloatingRate: NaN
                    Holidays: NaT
                   IssueDate: NaT
             FirstCouponDate: NaT
              LastCouponDate: NaT
                   StartDate: NaT
                    Maturity: 01-Jan-2022
                        Name: "floatbond"

% Call option
Strike = 100;
ExerciseDates = datetime(2020,1,1); 
OptionType ='call';
Period = 1;
CallOption = fininstrument("FixedBondOption",'Strike',Strike,'ExerciseDate',ExerciseDates, ...
                   'OptionType',OptionType,'ExerciseStyle',"american",'Bond', VBond,'Name',"fixed_bond_option")    
CallOption = 
  FixedBondOption with properties:

       OptionType: "call"
    ExerciseStyle: "american"
     ExerciseDate: 01-Jan-2020
           Strike: 100
             Bond: [1×1 fininstrument.FixedBond]
             Name: "fixed_bond_option"

% Option for embedded bond (callable bond)
CDates = datetime([2020,1,1 ; 2022,1,1]);
CRates = [.0425; .0750];
CouponRate = timetable(CDates,CRates);
StrikeOE = [100; 100];
ExerciseDatesOE = [datetime(2020,1,1); datetime(2021,1,1)];
CallSchedule =  timetable(ExerciseDatesOE,StrikeOE,'VariableNames',{'Strike Schedule'}); 
CallableBond = fininstrument("OptionEmbeddedFixedBond", 'Maturity',Maturity, ...
                              'CouponRate',CouponRate,'Period', Period, ...
                              'CallSchedule',CallSchedule,'Name',"option_embedded_fixedbond")
CallableBond = 
  OptionEmbeddedFixedBond with properties:

                  CouponRate: [2×1 timetable]
                      Period: 1
                       Basis: 0
                EndMonthRule: 1
                   Principal: 100
    DaycountAdjustedCashFlow: 0
       BusinessDayConvention: "actual"
                    Holidays: NaT
                   IssueDate: NaT
             FirstCouponDate: NaT
              LastCouponDate: NaT
                   StartDate: NaT
                    Maturity: 01-Jan-2022
                   CallDates: [2×1 datetime]
                    PutDates: [0×1 datetime]
                CallSchedule: [2×1 timetable]
                 PutSchedule: [0×0 timetable]
           CallExerciseStyle: "american"
            PutExerciseStyle: [0×0 string]
                        Name: "option_embedded_fixedbond"

Create HullWhite Model

Use finmodel to create a HullWhite model object.

VolCurve = 0.01;
AlphaCurve = 0.1;

HWModel = finmodel("hullwhite",'alpha',AlphaCurve,'sigma',VolCurve)
HWModel = 
  HullWhite with properties:

    Alpha: 0.1000
    Sigma: 0.0100

Create IRTree Pricer for HullWhite Model

Use finpricer to create an IRTree pricer object for a HullWhite model and use the ratecurve object for the 'DiscountCurve' name-value pair argument.

HWTreePricer = finpricer("IRTree",'Model',HWModel,'DiscountCurve',ZeroCurve,'TreeDates',ZeroDates)
HWTreePricer = 
  HWBKTree with properties:

             Tree: [1×1 struct]
        TreeDates: [4×1 datetime]
            Model: [1×1 finmodel.HullWhite]
    DiscountCurve: [1×1 ratecurve]

Create finportfolio Object and Add Callable Bond Instrument

Create a finportfolio object with the vanilla bond, stepped coupon bond, float bond, and the call option.

myportfolio = finportfolio([VBond,SBond,Float,CallOption],HWTreePricer, [1,2,2,1])
myportfolio = 
  finportfolio with properties:

    Instruments: [4×1 fininstrument.FinInstrument]
        Pricers: [1×1 finpricer.irtree.HWBKTree]
    PricerIndex: [4×1 double]
       Quantity: [4×1 double]

Use addInstrument to add the callable bond instrument to the existing portfolio.

myportfolio = addInstrument(myportfolio,CallableBond,HWTreePricer,1)
myportfolio = 
  finportfolio with properties:

    Instruments: [5×1 fininstrument.FinInstrument]
        Pricers: [1×1 finpricer.irtree.HWBKTree]
    PricerIndex: [5×1 double]
       Quantity: [5×1 double]

myportfolio.PricerIndex
ans = 5×1

     1
     1
     1
     1
     1

The PricerIndex property has a length equal to the length of instrument objects in the finportfolio object and stores the index of which pricer is used for each instrument object. In this case, because there is only one pricer, each instrument must use that pricer.

Price Portfolio

Use pricePortfolio to compute the price and sensitivities for the portfolio and the bond and option instruments in the portfolio.

format bank
[PortPrice,InstPrice,PortSens,InstSens] = pricePortfolio(myportfolio)
PortPrice = 
        600.55

InstPrice = 5×1

         96.59
        204.14
        200.00
          0.05
         99.77

PortSens=1×4 table
    Price      Delta       Gamma      Vega 
    ______    ________    _______    ______

    600.55    -1297.48    5759.65    -63.40

InstSens=5×4 table
                                 Price      Delta      Gamma      Vega 
                                 ______    _______    _______    ______

    vanilla_fixed                 96.59    -344.81    1603.49     -0.00
    stepped_coupon_bond          204.14    -725.96    3364.60      0.00
    floatbond                    200.00       0.00      -0.00     -0.00
    fixed_bond_option              0.05      -3.69      24.15     12.48
    option_embedded_fixedbond     99.77    -223.03     767.41    -75.88