> To:
[hidden email]> From:
[hidden email]> Date: Thu, 15 Nov 2007 19:09:46 +0000
> Subject: [Quantlib-users] Redemption vs. Face Value
>
> 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