Estoy tratando de precio de un simple tesoro de los estados UNIDOS en QuantLib, utilizando dos métodos. El primer método llama a FixedRatebond.dirtyPrice(...), pasando de un YTM y otros parámetros.
El segundo método implica la construcción de una FlatForward YieldTermStructure con el mismo YTM y parámetros como el método #1.
Los dos métodos me dan ligeramente diferente sucio de los precios, y espero que sean de la misma. ¿Alguien puede explicar lo que he hecho mal, o explicar por qué el sucio es el precio que debe ser diferente utilizando los dos métodos?
Aquí está el código de ejemplo (full disclosure: este código fue plagiado de aquí):
try {
// date set up
Calendar calendar = TARGET();
Date settlementDate(28, January, 2011);
// the settlement date must be a business day
settlementDate = calendar.adjust(settlementDate);
// Evaluation date
Integer fixingDays = 1;
Natural settlementDays = 1;
Date todaysDate = calendar.advance(settlementDate, -fixingDays, Days);
Settings::instance().evaluationDate() = todaysDate;
// bond set up
Real faceAmount = 100.0;
Real redemption = 100.0;
Date issueDate(27, January, 2011);
Date maturity(31, August, 2020);
Real couponRate = 0.03625;
Real yield = 0.034921;
RelinkableHandle<YieldTermStructure> discountingTermStructure;
boost::shared_ptr<YieldTermStructure> flatTermStructure(
new FlatForward(
settlementDate,
yield,
ActualActual(ActualActual::Bond),
Compounding::Compounded,
Semiannual));
discountingTermStructure.linkTo(flatTermStructure);
// Pricing engine
boost::shared_ptr<PricingEngine> bondEngine(
new DiscountingBondEngine(discountingTermStructure));
// Rate
Schedule fixedBondSchedule(
issueDate,
maturity,
Period(Semiannual),
UnitedStates(UnitedStates::GovernmentBond),
BusinessDayConvention::Unadjusted,
BusinessDayConvention::Unadjusted,
DateGeneration::Rule::Backward,
false);
FixedRateBond fixedRateBond(
settlementDays,
faceAmount,
fixedBondSchedule,
std::vector<Rate>(1, couponRate),
ActualActual(ActualActual::Bond),
BusinessDayConvention::Unadjusted,
redemption,
issueDate);
//Calculate pricing without term structure
Real cp = fixedRateBond.cleanPrice(yield, fixedRateBond.dayCounter(), Compounding::Compounded, Semiannual);
Real dp = fixedRateBond.dirtyPrice(yield, fixedRateBond.dayCounter(), Compounding::Compounded, Semiannual);
Rate ytm = fixedRateBond.yield(cp, fixedRateBond.dayCounter(), Compounding::Compounded, Semiannual);
Real accrued = fixedRateBond.accruedAmount();
fixedRateBond.setPricingEngine(bondEngine);
// write column headings
Size widths[] = { 18, 15, 15};
std::cout << std::setw(widths[0]) << " "
<< std::setw(widths[1]) << "Without TS"
<< std::setw(widths[2]) << "With TS"
<< std::endl;
Size width = widths[0]
+ widths[1]
+ widths[2];
std::string rule(width, '-'), dblrule(width, '=');
std::cout << rule << std::endl;
std::cout << std::setw(widths[0]) << "Clean Price"
<< std::setw(widths[1]) << std::setprecision (8) << cp
<< std::setw(widths[2]) << std::setprecision (8) << fixedRateBond.cleanPrice()
<< std::endl;
std::cout << std::setw(widths[0]) << "Dirty Price"
<< std::setw(widths[1]) << std::setprecision (8) << dp
<< std::setw(widths[2]) << std::setprecision (8) << fixedRateBond.dirtyPrice()
<< std::endl;
std::cout << std::setw(widths[0]) << "Accrued"
<< std::setw(widths[1]) << std::setprecision (8) << accrued
<< std::setw(widths[2]) << std::setprecision (8) << fixedRateBond.accruedAmount()
<< std::endl;
return 0;
} catch (std::exception& e) {
std::cerr << e.what() << std::endl;
return 1;
} catch (...) {
std::cerr << "unknown error" << std::endl;
return 1;
}
}