Prescott Nasser
2017-06-28 22:58:34 UTC
Hey all -
I'm struggling with something I think should be pretty basic. I'm actually using QLNet (the dotnet port), so the code is C# below, but hopefully that doesn't slow anyone down. Given a price, I'm attempting to calculate the Yield for each call date (and add maturity date as the final call date)
I have the following GetFixedRateBond method (taken from the docs):
public static FixedRateBond GetFixedRateBond(double redemption, double coupon,
Date datedDate, Date maturityDate, Date settlementDate,
DayCounter dayCounter, Frequency frequency)
{
Settings.setEvaluationDate(new TARGET().adjust(settlementDate));
var schedule = new Schedule(
datedDate,
maturityDate,
new Period(frequency),
new UnitedStates(UnitedStates.Market.GovernmentBond),
BusinessDayConvention.Unadjusted,
BusinessDayConvention.Unadjusted,
DateGeneration.Rule.Forward,
false);
var bondHelper = new FixedRateBondHelper(
new RelinkableHandle<Quote>(),
0,
_bondFaceAmount,
schedule,
new List<double>() { coupon / 100.0 },
dayCounter,
BusinessDayConvention.Unadjusted,
redemption);
var curve = new PiecewiseYieldCurve<Discount, LogLinear>(
settlementDate,
new List<RateHelper>() { bondHelper },
dayCounter);
var termStructure = new RelinkableHandle<YieldTermStructure>(curve);
var engine = new DiscountingBondEngine(termStructure);
var fixedRateBond = bondHelper.fixedRateBond();
fixedRateBond.setPricingEngine(engine);
return fixedRateBond;
}
Given above, I loop through a collection of call events ( Date, Call Redemption):
var e = new List<CalcEvent>();
foreach (var callEvent in _callEvents)
{
var bond = GetFixedRateBond((double)callEvent.Price, Coupon, IssueDate,
callEvent.Date, SettlementDate, DayCounter, Frequency);
var transform = new CalcEvent
{
Date = callEvent.Date,
RedemptionPrice = callEvent.Price,
};
//Here price is the given price we contemplate buying the bond for.
transform.Yield = bond.yield(price, DayCounter, _compounding, Frequency, SettlementDate, _precision) * 100;
e.Add(transform);
}
From the list of all the call events, I take the last call event (maturity) and put that yield as YTM - which seems to work consistently well. The YTW however (selecting the call with the lowest yield), fails when compared to Bloomberg, off by .03 or so.
Give the following:
Cusip: 24880ACS9
Price: 100.652
Expected YTW: .803 ***@100
YTM: 4.792
SettlementDate: 2017-07-03
Maturity: 2027-09-01
Issue: 2008-06-25
DayCount: Thirty360
Frequency: SemiAnnually
Test Case:
YTW Expected 0.803, was 0.815686458817721, diff: 0.0126864588177211
I'm not really sure where to look at this point, any help would be appreciated
Thanks for your time,
~Prescott
I'm struggling with something I think should be pretty basic. I'm actually using QLNet (the dotnet port), so the code is C# below, but hopefully that doesn't slow anyone down. Given a price, I'm attempting to calculate the Yield for each call date (and add maturity date as the final call date)
I have the following GetFixedRateBond method (taken from the docs):
public static FixedRateBond GetFixedRateBond(double redemption, double coupon,
Date datedDate, Date maturityDate, Date settlementDate,
DayCounter dayCounter, Frequency frequency)
{
Settings.setEvaluationDate(new TARGET().adjust(settlementDate));
var schedule = new Schedule(
datedDate,
maturityDate,
new Period(frequency),
new UnitedStates(UnitedStates.Market.GovernmentBond),
BusinessDayConvention.Unadjusted,
BusinessDayConvention.Unadjusted,
DateGeneration.Rule.Forward,
false);
var bondHelper = new FixedRateBondHelper(
new RelinkableHandle<Quote>(),
0,
_bondFaceAmount,
schedule,
new List<double>() { coupon / 100.0 },
dayCounter,
BusinessDayConvention.Unadjusted,
redemption);
var curve = new PiecewiseYieldCurve<Discount, LogLinear>(
settlementDate,
new List<RateHelper>() { bondHelper },
dayCounter);
var termStructure = new RelinkableHandle<YieldTermStructure>(curve);
var engine = new DiscountingBondEngine(termStructure);
var fixedRateBond = bondHelper.fixedRateBond();
fixedRateBond.setPricingEngine(engine);
return fixedRateBond;
}
Given above, I loop through a collection of call events ( Date, Call Redemption):
var e = new List<CalcEvent>();
foreach (var callEvent in _callEvents)
{
var bond = GetFixedRateBond((double)callEvent.Price, Coupon, IssueDate,
callEvent.Date, SettlementDate, DayCounter, Frequency);
var transform = new CalcEvent
{
Date = callEvent.Date,
RedemptionPrice = callEvent.Price,
};
//Here price is the given price we contemplate buying the bond for.
transform.Yield = bond.yield(price, DayCounter, _compounding, Frequency, SettlementDate, _precision) * 100;
e.Add(transform);
}
From the list of all the call events, I take the last call event (maturity) and put that yield as YTM - which seems to work consistently well. The YTW however (selecting the call with the lowest yield), fails when compared to Bloomberg, off by .03 or so.
Give the following:
Cusip: 24880ACS9
Price: 100.652
Expected YTW: .803 ***@100
YTM: 4.792
SettlementDate: 2017-07-03
Maturity: 2027-09-01
Issue: 2008-06-25
DayCount: Thirty360
Frequency: SemiAnnually
Test Case:
YTW Expected 0.803, was 0.815686458817721, diff: 0.0126864588177211
I'm not really sure where to look at this point, any help would be appreciated
Thanks for your time,
~Prescott