Login  Register

Redemption vs. Face Value

Posted by John Maiden on Nov 15, 2007; 7:09pm
URL: http://quantlib.414.s1.nabble.com/Redemption-vs-Face-Value-tp5218.html

In QuantLib, what is the difference between redemption
and face value for a fixed rate bond? I'm asking because
I thought I knew the difference, and have been getting
screwy answers. I'm working with a bond with the following
parameters:

Maturity: 5/3/2041
Coupon: 5.375%
Coupon Frequency: Quarterly
Coupon Type: Fixed
Redemption: $50
Credit Spread: 500 bps

If I use my code to price a bond with a $100 redemption
value, I get a present value of around $65. If I then
change it to a redemption of $50, I get a value of $62
(when I expected to get a present value of $65/2 = $32.5).
I don't understand how a bond could be worth more now than
at redemption. I tried my code with redemptions ranging
from $10 - $100, and received results around $58 - $65.
I don't know if this is a problem in my code, or some
misunderstanding I have between face value and redemption.
The code I used is below. Thanks in advance.

// TestQuantLib.cpp : Defines the entry point for the console
// application.
//
#include "stdafx.h"
#include <ql/quantlib.hpp>
#include <boost/timer.hpp>

using namespace std;
using namespace QuantLib;

#define LENGTH(a) (sizeof(a)/sizeof(a[0]))

int _tmain(int argc, _TCHAR* argv[])
{
        try {

                // parameters

                // schedule frequency
                int schedulefrequency = 52;
                // coupon frequency
                int couponFrequency = 4;
                // coupon
                double coupon = 0.05375;
                // redemption value
                double redemption = 50;
                // face value
                double faceValue = 100;
                // days between today and issue
                int issueDays = 0;
                // days between today and maturity
                int maturityDays = 12224;
                // number of points in interest rate curve
                int yLen = 10;
                // days between today and interest rate curve date
                int yieldDays[] = {92, 182, 366, 731, 1096, 1827, 3653,
7305, 10958, 12224};
                // interest yield curve points
                double yieldCurve[] = {0.034278, 0.037308, 0.036284,
0.035433, 0.034892,
0.038433, 0.042665, 0.046507,
0.046163, 0.046045};
                // number of points in credit spread curve
                int sLen = 1;
                // credit spread curve points
                double spreadCurve[] = {0.05};

                // set up interest rate points
                std::vector<Real> riskFree;
                std::vector<int> riskFreeDays;
                for(int i = 0; i < yLen; i++){
                        riskFree.push_back(yieldCurve[i]);
                        riskFreeDays.push_back(yieldDays[i]);
                }

                // set up credit spread points
                std::vector<Real> convSpread;
                for(int i = 0; i < sLen; i++)
                        convSpread.push_back(spreadCurve[i]);

                // set calendar and dates
                Calendar calendar_ = UnitedStates(UnitedStates::Market::NYSE);
                Date today = calendar_.adjust(Date::todaysDate());
                Settings::instance().evaluationDate() = today;

                DayCounter dayCount = Actual365Fixed();

                Date issueDate = today + issueDays;
                Date maturityDate = today + maturityDays;
                Date earlyDate;
                if(issueDate > today)
                        earlyDate = issueDate;
                else
                        earlyDate = today;

                Schedule schedule_(earlyDate, maturityDate,
Period(static_cast<QuantLib::Frequency>(schedulefrequency)),
                        calendar_, Unadjusted, Unadjusted, true, false);

                // put interest rate and credit spread points
// into yield term structure
                std::vector<Date> yDates;
                std::vector<Real> yRates;
                std::vector<Real> ySpreads;

                for(Size i=0; i<schedule_.size(); i++)
                        yDates.push_back(schedule_.at(i));

                boost::shared_ptr<YieldTermStructure> termStructure_;

                std::vector<Date> dates;

                dates.push_back(today);
                for(int i = 0; i < yLen; i++)
                        dates.push_back(today + riskFreeDays.at(i));

                std::vector<Real> yTemp = riskFree;
                riskFree.clear();
                riskFree.push_back(yTemp.at(0));
                for(Size i=0; i<yTemp.size(); i++)
                        riskFree.push_back(yTemp.at(i));

                //figures out yield curve, uses linear fit
                termStructure_ = boost::shared_ptr<YieldTermStructure>(new
                        InterpolatedZeroCurve<Linear>(dates, riskFree,
dayCount));

                for(Size i=0; i<yDates.size(); i++)
                        yRates.push_back(termStructure_->zeroRate(yDates.at(i),
dayCount, Continuous, NoFrequency));

                for(Size i=0; i<yDates.size(); i++)
                        ySpreads.push_back(convSpread.at(0));
               
                // risk-free rate + credit spread curve
                std::vector<Real> yTotal;

                for(Size i = 0; i < yRates.size(); i++)
                        yTotal.push_back(yRates.at(i) + ySpreads.at(i));

                Handle<YieldTermStructure> totalStructure
(boost::shared_ptr<YieldTermStructure>(new
                        InterpolatedZeroCurve<Linear>(yDates, yTotal,
dayCount)));

                // determine coupon schedule
                Frequency coupFreq = static_cast<QuantLib::Frequency>(couponFrequency);

                Date beforeMaturity = calendar_.advance(maturityDate,
-Period(coupFreq),
Unadjusted, true);
                if(beforeMaturity < earlyDate)
                        beforeMaturity = maturityDate;
                Date afterIssue = beforeMaturity;
                while(afterIssue > earlyDate)
                        afterIssue = calendar_.advance(afterIssue,
-Period(coupFreq), Unadjusted, true);
                while(afterIssue <= earlyDate)
                        afterIssue = calendar_.advance(afterIssue,
Period(coupFreq), Unadjusted, true);

                Schedule bondSchedule;
                if((afterIssue <= earlyDate) || (afterIssue >= maturityDate) ||
                        (beforeMaturity <= earlyDate) || (beforeMaturity >= maturityDate)) {
                                bondSchedule = Schedule(today, maturityDate, Period(coupFreq),
                                        calendar_, Unadjusted, Unadjusted, true, true);
                } else {
                        bondSchedule = Schedule(today, maturityDate, Period(coupFreq),
calendar_, Unadjusted, Unadjusted, true, true, afterIssue, beforeMaturity);
                }

                // set up bond
                boost::shared_ptr<Bond> bond_;

                DayCounter bondDayCount_ = Thirty360();

                std::vector<Real> coupons_(1, coupon);
               
                bond_ = boost::shared_ptr<FixedRateBond>(new FixedRateBond(0, faceValue,
bondSchedule, coupons_, bondDayCount_, Unadjusted, redemption,
issueDate, totalStructure));
       
                std::vector<Time> yTimes;

                //set up vector of times
                for(Size i=0; i<yDates.size(); i++)
                        yTimes.push_back(dayCount.yearFraction(earlyDate,
yDates.at(i)));

                //set up vector of bond amounts
                std::vector<Real> bondAmounts;

                for(Size k = 0; k < yDates.size(); k++){
                                bondAmounts.push_back(bond_->dirtyPrice(yTotal[k], Continuous, yDates[k]));
                }

                //send results to text file
                FILE * pFile;

                char timez[6] = "Time";
                char valuez[5] = "Bond";

                std::string filename = "straight_bond_values.txt";

                pFile = fopen (filename.c_str(),"w");

                fprintf (pFile, "%-10.10s \t %-10.10s \n", timez, valuez);

                for(Size j = 0; j < yTimes.size(); j++){
                        fprintf (pFile, "%f \t %f \n", yTimes.at(j), bondAmounts.at(j));
                }
                fclose (pFile);

                //end print job
               
                system("PAUSE");

        } catch (std::exception& e) {
                cout << e.what() << endl;

                system("PAUSE");
        }
                return 0;
}


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
QuantLib-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/quantlib-users