66#include <ql/cashflow.hpp>
67#include <ql/cashflows/averagebmacoupon.hpp>
68#include <ql/cashflows/capflooredcoupon.hpp>
69#include <ql/cashflows/capflooredinflationcoupon.hpp>
70#include <ql/cashflows/cashflowvectors.hpp>
71#include <ql/cashflows/cpicoupon.hpp>
72#include <ql/cashflows/cpicouponpricer.hpp>
73#include <ql/cashflows/digitalcmscoupon.hpp>
74#include <ql/cashflows/fixedratecoupon.hpp>
75#include <ql/cashflows/iborcoupon.hpp>
76#include <ql/cashflows/simplecashflow.hpp>
77#include <ql/errors.hpp>
78#include <ql/experimental/coupons/digitalcmsspreadcoupon.hpp>
79#include <ql/experimental/coupons/strippedcapflooredcoupon.hpp>
80#include <ql/utilities/vectors.hpp>
82#include <boost/algorithm/string.hpp>
83#include <boost/make_shared.hpp>
84#include <boost/range/adaptor/transformed.hpp>
92bool lessThan(
const string& s1,
const string& s2) {
return s1 < s2; }
100 XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Cashflow",
"Amount",
"date",
dates_, &
parseReal,
false);
135 "Compounding method " <<
compounding_ <<
" not supported");
137 if (subtractNotionalNode)
156 spreads_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Spreads",
"Spread",
"startDate",
spreadDates_,
184 caps_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Caps",
"Cap",
"startDate",
capDates_, &
parseReal);
186 XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Floors",
"Floor",
"startDate",
floorDates_, &
parseReal);
187 gearings_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Gearings",
"Gearing",
"startDate",
gearingDates_,
205 vector<std::string> histFixingDates;
206 vector<QuantLib::Real> histFixingValues = XMLUtils::getChildrenValuesWithAttributes<Real>(
207 node,
"HistoricalFixings",
"Fixing",
"fixingDate", histFixingDates,
210 QL_REQUIRE(histFixingDates.size() == histFixingValues.size(),
"Mismatch Fixing values and dates");
211 for (
size_t i = 0; i < histFixingDates.size(); ++i) {
272 "can not have both Interpolated and Interpolation node in CPILegData");
292 caps_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Caps",
"Cap",
"startDate",
capDates_, &
parseReal);
294 XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Floors",
"Floor",
"startDate",
floorDates_, &
parseReal);
348 gearings_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Gearings",
"Gearing",
"startDate",
gearingDates_,
350 spreads_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Spreads",
"Spread",
"startDate",
spreadDates_,
352 caps_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Caps",
"Cap",
"startDate",
capDates_, &
parseReal);
354 XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Floors",
"Floor",
"startDate",
floorDates_, &
parseReal);
407 spreads_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Spreads",
"Spread",
"startDate",
spreadDates_,
418 caps_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Caps",
"Cap",
"startDate",
capDates_, &
parseReal);
420 XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Floors",
"Floor",
"startDate",
floorDates_, &
parseReal);
421 gearings_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Gearings",
"Gearing",
"startDate",
gearingDates_,
449 spreads_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Spreads",
"Spread",
"startDate",
spreadDates_,
457 caps_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Caps",
"Cap",
"startDate",
capDates_, &
parseReal);
459 XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Floors",
"Floor",
"startDate",
floorDates_, &
parseReal);
460 gearings_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Gearings",
"Gearing",
"startDate",
gearingDates_,
498 underlying_ = QuantLib::ext::make_shared<CMSLegData>();
502 callStrikes_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"CallStrikes",
"Strike",
"startDate",
508 callPayoffs_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"CallPayoffs",
"Payoff",
"startDate",
512 putStrikes_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"PutStrikes",
"Strike",
"startDate",
518 putPayoffs_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"PutPayoffs",
"Payoff",
"startDate",
546 spreads_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Spreads",
"Spread",
"startDate",
spreadDates_,
557 caps_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Caps",
"Cap",
"startDate",
capDates_, &
parseReal);
559 XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Floors",
"Floor",
"startDate",
floorDates_, &
parseReal);
560 gearings_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Gearings",
"Gearing",
"startDate",
gearingDates_,
593 underlying_ = QuantLib::ext::make_shared<CMSSpreadLegData>();
597 callStrikes_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"CallStrikes",
"Strike",
"startDate",
603 callPayoffs_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"CallPayoffs",
"Payoff",
"startDate",
607 putStrikes_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"PutStrikes",
"Strike",
"startDate",
613 putPayoffs_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"PutPayoffs",
"Payoff",
"startDate",
649 WLOG(
"EquityLegData::fromXML, node FXIndexFixingDays has been deprecated, fixing days are "
650 "taken from conventions.");
653 WLOG(
"EquityLegData::fromXML, node FXIndexCalendar has been deprecated, fixing calendar is "
654 "taken from conventions.");
713 if (
value_ != Null<Real>())
726 QL_REQUIRE(
type_ ==
"LinearToMaturity" ||
value_ != Null<Real>(),
"AmortizationData requires Value");
727 QL_REQUIRE(
type_ ==
"LinearToMaturity" ||
value_ != Null<Real>(),
"AmortizationData requires Underflow");
730LegData::LegData(
const QuantLib::ext::shared_ptr<LegAdditionalData>& concreteLegData,
bool isPayer,
const string& currency,
731 const ScheduleData& scheduleData,
const string& dayCounter,
const std::vector<double>& notionals,
732 const std::vector<string>& notionalDates,
const string& paymentConvention,
733 const bool notionalInitialExchange,
const bool notionalFinalExchange,
734 const bool notionalAmortizingExchange,
const bool isNotResetXCCY,
const string& foreignCurrency,
735 const double foreignAmount,
const string& fxIndex,
736 const std::vector<AmortizationData>& amortizationData,
const string& paymentLag,
737 const string& notionalPaymentLag,
const string& paymentCalendar,
const vector<string>& paymentDates,
738 const std::vector<Indexing>& indexing,
const bool indexingFromAssetLeg,
739 const string& lastPeriodDayCounter)
740 : concreteLegData_(concreteLegData), isPayer_(isPayer), currency_(currency), schedule_(scheduleData),
741 dayCounter_(dayCounter), notionals_(notionals), notionalDates_(notionalDates),
742 paymentConvention_(paymentConvention), notionalInitialExchange_(notionalInitialExchange),
743 notionalFinalExchange_(notionalFinalExchange), notionalAmortizingExchange_(notionalAmortizingExchange),
744 isNotResetXCCY_(isNotResetXCCY), foreignCurrency_(foreignCurrency), foreignAmount_(foreignAmount),
745 fxIndex_(fxIndex), amortizationData_(amortizationData), paymentLag_(paymentLag),
746 notionalPaymentLag_(notionalPaymentLag), paymentCalendar_(paymentCalendar), paymentDates_(paymentDates),
747 indexing_(indexing), indexingFromAssetLeg_(indexingFromAssetLeg), lastPeriodDayCounter_(lastPeriodDayCounter) {
770 notionals_ = XMLUtils::getChildrenValuesWithAttributes<Real>(node,
"Notionals",
"Notional",
"startDate",
785 WLOG(
"LegData::fromXML, node FixingDays has been deprecated, fixing days are "
786 "taken from conventions.");
789 WLOG(
"LegData::fromXML, node FixingCalendar has been deprecated, fixing calendar is "
790 "taken from conventions.");
805 if (amortizationParentNode) {
807 for (
auto const& a : adNodes) {
818 WLOG(
"Usage of PaymentDates is deprecated, use PaymentSchedule instead.");
825 QL_REQUIRE(
paymentDates_.empty(),
"Both PaymentDates and PaymentSchedule is given. Remove one of them. "
826 "PaymentDates is deprecated, so preferably use PaymentSchedule.");
836 for (
auto const& i : indexings) {
851 auto legData = LegDataFactory::instance().build(
legType);
852 QL_REQUIRE(legData,
"Leg type " <<
legType <<
" has not been registered with the leg data factory.");
858 QL_REQUIRE(node,
"Failed to create LegData node");
898 if (amort.initialized()) {
935 QuantLib::ext::shared_ptr<CashflowData> cashflowData = QuantLib::ext::dynamic_pointer_cast<CashflowData>(
data.concreteLegData());
936 QL_REQUIRE(cashflowData,
"Wrong LegType, expected CashFlow, got " <<
data.legType());
938 const vector<double>& amounts = cashflowData->amounts();
939 const vector<string>& dates = cashflowData->dates();
940 QL_REQUIRE(amounts.size() == dates.size(),
"Amounts / Date size mismatch in makeSimpleLeg."
941 <<
"Amounts:" << amounts.size() <<
", Dates:" << dates.size());
943 for (Size i = 0; i < dates.size(); i++) {
945 leg.push_back(QuantLib::ext::shared_ptr<CashFlow>(
new SimpleCashFlow(amounts[i], d)));
952 QuantLib::ext::shared_ptr<FixedLegData> fixedLegData = QuantLib::ext::dynamic_pointer_cast<FixedLegData>(
data.concreteLegData());
953 QL_REQUIRE(fixedLegData,
"Wrong LegType, expected Fixed, got " <<
data.legType());
958 Schedule paymentSchedule;
960 scheduleBuilder.
add(schedule,
data.schedule());
961 scheduleBuilder.
add(paymentSchedule,
data.paymentSchedule());
966 vector<Date> paymentDates;
968 if (!paymentSchedule.empty()) {
969 paymentDates = paymentSchedule.dates();
970 }
else if (!
data.paymentDates().empty()) {
971 BusinessDayConvention paymentDatesConvention =
973 Calendar paymentDatesCalendar =
975 paymentDates = parseVectorOfValues<Date>(
data.paymentDates(), &
parseDate);
976 for (Size i = 0; i < paymentDates.size(); i++)
977 paymentDates[i] = paymentDatesCalendar.adjust(paymentDates[i], paymentDatesConvention);
982 Calendar paymentCalendar;
983 if (!
data.paymentCalendar().empty())
985 else if (!paymentSchedule.calendar().empty())
986 paymentCalendar = paymentSchedule.calendar();
987 else if (!schedule.calendar().empty())
988 paymentCalendar = schedule.calendar();
997 vector<double> rates =
buildScheduledVector(fixedLegData->rates(), fixedLegData->rateDates(), schedule);
1010 if (!
data.strictNotionalDates()) {
1014 Leg leg = FixedRateLeg(schedule)
1015 .withNotionals(notionals)
1016 .withCouponRates(rates, dc)
1017 .withPaymentAdjustment(bdc)
1019 .withPaymentCalendar(paymentCalendar)
1020 .withLastPeriodDayCounter(
data.lastPeriodDayCounter().empty()
1023 .withPaymentDates(paymentDates);
1030 std::vector<Date> notionalDatesAsDates;
1031 std::vector<Date> rateDatesAsDates;
1033 for (
auto const& d :
data.notionalDates()) {
1035 notionalDatesAsDates.push_back(
parseDate(d));
1038 for (
auto const& d : fixedLegData->rateDates()) {
1040 rateDatesAsDates.push_back(
parseDate(d));
1044 fixedLegData->rates(), rateDatesAsDates,
data.strictNotionalDates(), dc,
1045 paymentCalendar, bdc, boost::apply_visitor(
PaymentLagPeriod(), paymentLag));
1050 QuantLib::ext::shared_ptr<ZeroCouponFixedLegData> zcFixedLegData =
1051 QuantLib::ext::dynamic_pointer_cast<ZeroCouponFixedLegData>(
data.concreteLegData());
1052 QL_REQUIRE(zcFixedLegData,
"Wrong LegType, expected Zero Coupon Fixed, got " <<
data.legType());
1056 Calendar paymentCalendar;
1057 if (
data.paymentCalendar().empty())
1058 paymentCalendar = schedule.calendar();
1068 Size numNotionals =
data.notionals().size();
1069 Size numRates = zcFixedLegData->rates().size();
1070 Size numDates = schedule.size();
1072 QL_REQUIRE(numDates >= 2,
"Incorrect number of schedule dates entered, expected at least 2, got " << numDates);
1073 QL_REQUIRE(numNotionals >= 1,
1074 "Incorrect number of notional values entered, expected at least1, got " << numNotionals);
1075 QL_REQUIRE(numRates >= 1,
"Incorrect number of rate values entered, expected at least 1, got " << numRates);
1077 vector<Date> dates = schedule.dates();
1079 vector<double> rates =
buildScheduledVector(zcFixedLegData->rates(), zcFixedLegData->rateDates(), schedule);
1083 QL_REQUIRE(comp == QuantLib::Compounded || comp == QuantLib::Simple,
1084 "Compounding method " << zcFixedLegData->compounding() <<
" not supported");
1087 vector<Date> cpnDates;
1088 cpnDates.push_back(dates.front());
1090 for (Size i = 0; i < numDates - 1; i++) {
1092 double currentNotional = i < notionals.size() ? notionals[i] : notionals.back();
1093 double currentRate = i < rates.size() ? rates[i] : rates.back();
1094 cpnDates.push_back(dates[i + 1]);
1095 Date paymentDate = paymentCalendar.advance(dates[i + 1], paymentLagDays, Days, payConvention);
1096 leg.push_back(QuantLib::ext::make_shared<ZeroFixedCoupon>(paymentDate,
currentNotional, currentRate, dc, cpnDates, comp,
1097 zcFixedLegData->subtractNotional()));
1103 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory,
const bool attachPricer,
1104 const QuantLib::Date& openEndDateReplacement) {
1106 QuantLib::ext::shared_ptr<FloatingLegData> floatData = QuantLib::ext::dynamic_pointer_cast<FloatingLegData>(
data.concreteLegData());
1107 QL_REQUIRE(floatData,
"Wrong LegType, expected Floating, got " <<
data.legType());
1112 Schedule fixingSchedule;
1113 Schedule resetSchedule;
1114 Schedule paymentSchedule;
1116 scheduleBuilder.
add(schedule,
data.schedule());
1117 scheduleBuilder.
add(fixingSchedule, floatData->fixingSchedule());
1118 scheduleBuilder.
add(resetSchedule, floatData->resetSchedule());
1119 scheduleBuilder.
add(paymentSchedule,
data.paymentSchedule());
1124 vector<Date> paymentDates;
1126 if (!paymentSchedule.empty()) {
1127 paymentDates = paymentSchedule.dates();
1128 }
else if (!
data.paymentDates().empty()) {
1129 BusinessDayConvention paymentDatesConvention =
1131 Calendar paymentDatesCalendar =
1133 paymentDates = parseVectorOfValues<Date>(
data.paymentDates(), &
parseDate);
1134 for (Size i = 0; i < paymentDates.size(); i++)
1135 paymentDates[i] = paymentDatesCalendar.adjust(paymentDates[i], paymentDatesConvention);
1140 Calendar paymentCalendar;
1141 if (!
data.paymentCalendar().empty())
1143 else if (!paymentSchedule.calendar().empty())
1144 paymentCalendar = paymentSchedule.calendar();
1145 else if (!schedule.calendar().empty())
1146 paymentCalendar = schedule.calendar();
1155 bool hasCapsFloors = floatData->caps().size() > 0 || floatData->floors().size() > 0;
1160 vector<double> spreads =
1162 vector<double> gearings =
1167 Size fixingDays = floatData->fixingDays() == Null<Size>() ? index->fixingDays() : floatData->fixingDays();
1168 bool isInArrears = floatData->isInArrears() ? *floatData->isInArrears() :
false;
1176 if (!
data.amortizationData().empty()) {
1179 LOG(
"Build floating annuity notional schedule");
1180 QL_REQUIRE(
data.amortizationData().size() == 1,
1181 "Can have one AmortizationData block only for floating leg annuities");
1182 QL_REQUIRE(!hasCapsFloors,
"Caps/Floors not supported in floating annuity coupons");
1183 QL_REQUIRE(floatData->gearings().size() == 0,
"Gearings not supported in floating annuity coupons");
1184 DayCounter dc = index->dayCounter();
1185 Date startDate =
data.amortizationData().front().startDate().empty()
1188 double annuity =
data.amortizationData().front().value();
1189 bool underflow =
data.amortizationData().front().underflow();
1190 vector<QuantLib::ext::shared_ptr<Coupon>> coupons;
1191 for (Size i = 0; i < schedule.size() - 1; i++) {
1192 Date paymentDate = paymentCalendar.adjust(schedule[i + 1], bdc);
1193 if (schedule[i] < startDate || i == 0) {
1194 QuantLib::ext::shared_ptr<FloatingRateCoupon> coupon;
1195 if (!floatData->hasSubPeriods()) {
1196 coupon = QuantLib::ext::make_shared<IborCoupon>(paymentDate, notionals[i], schedule[i], schedule[i + 1],
1197 fixingDays, index, gearings[i], spreads[i], Date(),
1198 Date(), dc, isInArrears);
1199 coupon->setPricer(QuantLib::ext::make_shared<BlackIborCouponPricer>());
1201 coupon = QuantLib::ext::make_shared<QuantExt::SubPeriodsCoupon1>(
1202 paymentDate, notionals[i], schedule[i], schedule[i + 1], index,
1205 index->businessDayConvention(), spreads[i], dc, floatData->includeSpread(), gearings[i]);
1206 coupon->setPricer(QuantLib::ext::make_shared<QuantExt::SubPeriodsCouponPricer1>());
1208 coupons.push_back(coupon);
1209 LOG(
"FloatingAnnuityCoupon: " << i <<
" " << coupon->nominal() <<
" " << coupon->amount());
1211 QL_REQUIRE(coupons.size() > 0,
1212 "FloatingAnnuityCoupon needs at least one predecessor, e.g. a plain IborCoupon");
1213 LOG(
"FloatingAnnuityCoupon, previous nominal/coupon: " << i <<
" " << coupons.back()->nominal()
1214 <<
" " << coupons.back()->amount());
1215 QuantLib::ext::shared_ptr<QuantExt::FloatingAnnuityCoupon> coupon =
1216 QuantLib::ext::make_shared<QuantExt::FloatingAnnuityCoupon>(
1217 annuity, underflow, coupons.back(), paymentDate, schedule[i], schedule[i + 1], fixingDays,
1218 index, gearings[i], spreads[i], Date(), Date(), dc, isInArrears);
1219 coupons.push_back(coupon);
1220 LOG(
"FloatingAnnuityCoupon: " << i <<
" " << coupon->nominal() <<
" " << coupon->amount());
1224 for (Size i = 0; i < coupons.size(); i++)
1225 leg.push_back(coupons[i]);
1226 LOG(
"Floating annuity notional schedule done");
1233 if (floatData->hasSubPeriods()) {
1234 QL_REQUIRE(floatData->caps().empty() && floatData->floors().empty(),
1235 "SubPeriodsLegs does not support caps or floors");
1236 QL_REQUIRE(!isInArrears,
"SubPeriodLegs do not support in arrears fixings");
1259 if (!
data.strictNotionalDates() && fixingSchedule.empty() && resetSchedule.empty()) {
1263 IborLeg iborLeg = IborLeg(schedule, index)
1264 .withNotionals(notionals)
1265 .withSpreads(spreads)
1266 .withPaymentCalendar(paymentCalendar)
1267 .withPaymentDayCounter(dc)
1268 .withPaymentAdjustment(bdc)
1269 .withFixingDays(fixingDays)
1270 .inArrears(isInArrears)
1271 .withGearings(gearings)
1273 .withPaymentDates(paymentDates);
1274 if (floatData->caps().size() > 0)
1276 if (floatData->floors().size() > 0)
1277 iborLeg.withFloors(
buildScheduledVector(floatData->floors(), floatData->floorDates(), schedule));
1280 isNonStandard =
false;
1286 QL_REQUIRE(!hasCapsFloors,
"Ibor leg with strict notional or reset dates, explicit fixing or reset schedule "
1287 "does not support cap / floors");
1289 std::vector<Date> notionalDatesAsDates;
1290 std::vector<Date> spreadDatesAsDates;
1291 std::vector<Date> gearingDatesAsDates;
1293 for (
auto const& d :
data.notionalDates()) {
1295 notionalDatesAsDates.push_back(
parseDate(d));
1298 for (
auto const& d : floatData->spreadDates()) {
1300 spreadDatesAsDates.push_back(
parseDate(d));
1303 for (
auto const& d : floatData->gearingDates()) {
1305 gearingDatesAsDates.push_back(
parseDate(d));
1309 resetSchedule.dates(), fixingDays,
data.notionals(), notionalDatesAsDates,
1310 floatData->spreads(), spreadDatesAsDates, floatData->gearings(),
1311 gearingDatesAsDates,
data.strictNotionalDates(), dc, paymentCalendar, bdc,
1314 isNonStandard =
true;
1317 if (attachPricer && (hasCapsFloors || isInArrears || isNonStandard)) {
1318 auto builder = engineFactory->builder(
"CapFlooredIborLeg");
1319 QL_REQUIRE(builder,
"No builder found for CapFlooredIborLeg");
1320 auto cappedFlooredIborBuilder = QuantLib::ext::dynamic_pointer_cast<CapFlooredIborLegEngineBuilder>(builder);
1321 auto couponPricer = cappedFlooredIborBuilder->engine(IndexNameTranslator::instance().oreName(index->name()));
1322 QuantLib::setCouponPricer(tmpLeg, couponPricer);
1327 if (floatData->nakedOption()) {
1328 tmpLeg = StrippedCappedFlooredCouponLeg(tmpLeg);
1337 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory,
const bool attachPricer,
1338 const QuantLib::Date& openEndDateReplacement) {
1339 QuantLib::ext::shared_ptr<FloatingLegData> floatData = QuantLib::ext::dynamic_pointer_cast<FloatingLegData>(
data.concreteLegData());
1340 QL_REQUIRE(floatData,
"Wrong LegType, expected Floating, got " <<
data.legType());
1342 auto tmp =
data.schedule();
1349 for (
auto& r : tmp.modifyRules()) {
1350 if (r.tenor() ==
"1D") {
1351 r.modifyCalendar() =
to_string(index->fixingCalendar());
1352 r.modifyConvention() =
"F";
1353 r.modifyTermConvention() =
"F";
1357 Schedule schedule =
makeSchedule(tmp, openEndDateReplacement);
1363 vector<Date> paymentDates;
1364 if (!
data.paymentDates().empty()) {
1365 BusinessDayConvention paymentDatesConvention =
1367 Calendar paymentDatesCalendar =
1369 paymentDates = parseVectorOfValues<Date>(
data.paymentDates(), &
parseDate);
1370 for (Size i = 0; i < paymentDates.size(); i++)
1371 paymentDates[i] = paymentDatesCalendar.adjust(paymentDates[i], paymentDatesConvention);
1375 Period rateComputationPeriod = 0 * Days;
1376 if (!tmp.rules().empty() && !tmp.rules().front().tenor().empty())
1377 rateComputationPeriod =
parsePeriod(tmp.rules().front().tenor());
1378 else if (!tmp.dates().empty() && !tmp.dates().front().tenor().empty())
1379 rateComputationPeriod =
parsePeriod(tmp.dates().front().tenor());
1381 Calendar paymentCalendar;
1382 if (
data.paymentCalendar().empty())
1383 paymentCalendar = index->fixingCalendar();
1388 vector<double> spreads =
1390 vector<double> gearings =
1392 bool isInArrears = floatData->isInArrears() ? *floatData->isInArrears() :
true;
1396 if (floatData->isAveraged()) {
1398 QuantLib::ext::shared_ptr<QuantExt::AverageONIndexedCouponPricer> couponPricer =
1399 QuantLib::ext::make_shared<QuantExt::AverageONIndexedCouponPricer>();
1401 QuantLib::ext::shared_ptr<QuantExt::CapFlooredAverageONIndexedCouponPricer> cfCouponPricer;
1402 if (attachPricer && (floatData->caps().size() > 0 || floatData->floors().size() > 0)) {
1403 auto builder = QuantLib::ext::dynamic_pointer_cast<CapFlooredAverageONIndexedCouponLegEngineBuilder>(
1404 engineFactory->builder(
"CapFlooredAverageONIndexedCouponLeg"));
1405 QL_REQUIRE(builder,
"No builder found for CapFlooredAverageONIndexedCouponLeg");
1406 cfCouponPricer = QuantLib::ext::dynamic_pointer_cast<CapFlooredAverageONIndexedCouponPricer>(
1407 builder->engine(IndexNameTranslator::instance().oreName(index->name()), rateComputationPeriod));
1408 QL_REQUIRE(cfCouponPricer,
"internal error, could not cast to CapFlooredAverageONIndexedCouponPricer");
1426 .
withRateCutoff(floatData->rateCutoff() == Null<Size>() ? 0 : floatData->rateCutoff())
1428 .
withCaps(buildScheduledVectorNormalised<Real>(floatData->caps(), floatData->capDates(), schedule,
1430 .
withFloors(buildScheduledVectorNormalised<Real>(floatData->floors(), floatData->capDates(), schedule,
1443 QuantLib::ext::shared_ptr<QuantExt::OvernightIndexedCouponPricer> couponPricer =
1444 QuantLib::ext::make_shared<QuantExt::OvernightIndexedCouponPricer>();
1446 QuantLib::ext::shared_ptr<QuantExt::CappedFlooredOvernightIndexedCouponPricer> cfCouponPricer;
1447 if (attachPricer && (floatData->caps().size() > 0 || floatData->floors().size() > 0)) {
1448 auto builder = QuantLib::ext::dynamic_pointer_cast<CapFlooredOvernightIndexedCouponLegEngineBuilder>(
1449 engineFactory->builder(
"CapFlooredOvernightIndexedCouponLeg"));
1450 QL_REQUIRE(builder,
"No builder found for CapFlooredOvernightIndexedCouponLeg");
1451 cfCouponPricer = QuantLib::ext::dynamic_pointer_cast<QuantExt::CappedFlooredOvernightIndexedCouponPricer>(
1452 builder->engine(IndexNameTranslator::instance().oreName(index->name()), rateComputationPeriod));
1453 QL_REQUIRE(cfCouponPricer,
"internal error, could not cast to CapFlooredAverageONIndexedCouponPricer");
1472 .
withRateCutoff(floatData->rateCutoff() == Null<Size>() ? 0 : floatData->rateCutoff())
1473 .
withCaps(buildScheduledVectorNormalised<Real>(floatData->caps(), floatData->capDates(), schedule,
1475 .
withFloors(buildScheduledVectorNormalised<Real>(floatData->floors(), floatData->capDates(),
1476 schedule, Null<Real>()))
1485 QuantLib::ext::shared_ptr<BRLCdi> brlCdiIndex = QuantLib::ext::dynamic_pointer_cast<BRLCdi>(index);
1493Leg
makeBMALeg(
const LegData& data,
const QuantLib::ext::shared_ptr<QuantExt::BMAIndexWrapper>& indexWrapper,
1494 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory,
const QuantLib::Date& openEndDateReplacement) {
1495 QuantLib::ext::shared_ptr<FloatingLegData> floatData = QuantLib::ext::dynamic_pointer_cast<FloatingLegData>(
data.concreteLegData());
1496 QL_REQUIRE(floatData,
"Wrong LegType, expected Floating, got " <<
data.legType());
1497 QuantLib::ext::shared_ptr<BMAIndex> index = indexWrapper->bma();
1502 Calendar paymentCalendar;
1504 if (
data.paymentCalendar().empty())
1505 paymentCalendar = schedule.calendar();
1510 vector<Real> spreads =
1512 vector<Real> gearings =
1516 vector<Real> floors =
1521 Leg leg = AverageBMALeg(schedule, index)
1522 .withNotionals(notionals)
1523 .withSpreads(spreads)
1524 .withPaymentDayCounter(dc)
1525 .withPaymentCalendar(paymentCalendar)
1526 .withPaymentAdjustment(bdc)
1527 .withGearings(gearings);
1531 Period rateComputationPeriod = 0 * Days;
1532 if (!
data.schedule().rules().empty() && !
data.schedule().rules().front().tenor().empty())
1533 rateComputationPeriod =
parsePeriod(
data.schedule().rules().front().tenor());
1534 else if (!
data.schedule().dates().empty() && !
data.schedule().dates().front().tenor().empty())
1535 rateComputationPeriod =
parsePeriod(
data.schedule().dates().front().tenor());
1539 if (floatData->caps().size() > 0 || floatData->floors().size() > 0) {
1541 QuantLib::ext::shared_ptr<QuantExt::CapFlooredAverageBMACouponPricer> cfCouponPricer;
1542 auto builder = QuantLib::ext::dynamic_pointer_cast<CapFlooredAverageBMACouponLegEngineBuilder>(
1543 engineFactory->builder(
"CapFlooredAverageBMACouponLeg"));
1544 QL_REQUIRE(builder,
"No builder found for CapFlooredAverageBMACouponLeg");
1545 cfCouponPricer = QuantLib::ext::dynamic_pointer_cast<CapFlooredAverageBMACouponPricer>(
1546 builder->engine(IndexNameTranslator::instance().oreName(index->name()), rateComputationPeriod));
1547 QL_REQUIRE(cfCouponPricer,
"internal error, could not cast to CapFlooredAverageBMACouponPricer");
1549 for (Size i = 0; i < leg.size(); ++i) {
1550 auto bmaCpn = QuantLib::ext::dynamic_pointer_cast<AverageBMACoupon>(leg[i]);
1551 QL_REQUIRE(bmaCpn,
"makeBMALeg(): internal error, exepcted AverageBMACoupon. Contact dev.");
1552 if (caps[i] != Null<Real>() || floors[i] != Null<Real>()) {
1553 auto cpn = QuantLib::ext::make_shared<CappedFlooredAverageBMACoupon>(
1554 bmaCpn, caps[i], floors[i], floatData->nakedOption(), floatData->includeSpread());
1555 cpn->setPricer(cfCouponPricer);
1566Leg
makeNotionalLeg(
const Leg& refLeg,
const bool initNomFlow,
const bool finalNomFlow,
const bool amortNomFlow,
1567 const Natural notionalPaymentLag,
const BusinessDayConvention paymentConvention,
1568 const Calendar paymentCalendar,
const bool excludeIndexing) {
1576 auto coupon = QuantLib::ext::dynamic_pointer_cast<QuantLib::Coupon>(refLeg[0]);
1577 QL_REQUIRE(coupon,
"makeNotionalLeg does not support non-coupon legs");
1579 Date initDate = coupon->accrualStartDate();
1580 initDate = paymentCalendar.advance(initDate, notionalPaymentLag, Days, paymentConvention);
1581 if (initFlowAmt != 0)
1582 leg.push_back(QuantLib::ext::shared_ptr<CashFlow>(
new SimpleCashFlow(-initFlowAmt, initDate)));
1587 for (Size i = 1; i < refLeg.size(); i++) {
1588 auto coupon = QuantLib::ext::dynamic_pointer_cast<QuantLib::Coupon>(refLeg[i]);
1589 QL_REQUIRE(coupon,
"makeNotionalLeg does not support non-coupon legs");
1590 auto coupon2 = QuantLib::ext::dynamic_pointer_cast<QuantLib::Coupon>(refLeg[i - 1]);
1591 QL_REQUIRE(coupon,
"makeNotionalLeg does not support non-coupon legs");
1592 Date flowDate = coupon->accrualStartDate();
1593 flowDate = paymentCalendar.advance(flowDate, notionalPaymentLag, Days, paymentConvention);
1596 Real flow = initNom - newNom;
1598 leg.push_back(QuantLib::ext::shared_ptr<CashFlow>(
new SimpleCashFlow(flow, flowDate)));
1604 auto coupon = QuantLib::ext::dynamic_pointer_cast<QuantLib::Coupon>(refLeg.back());
1605 QL_REQUIRE(coupon,
"makeNotionalLeg does not support non-coupon legs");
1606 double finalNomFlow = (excludeIndexing ?
unpackIndexedCoupon(coupon) : coupon)->nominal();
1607 Date finalDate = coupon->accrualEndDate();
1608 finalDate = paymentCalendar.advance(finalDate, notionalPaymentLag, Days, paymentConvention);
1609 if (finalNomFlow != 0)
1610 leg.push_back(QuantLib::ext::shared_ptr<CashFlow>(
new SimpleCashFlow(finalNomFlow, finalDate)));
1617 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory,
const QuantLib::Date& openEndDateReplacement) {
1619 QuantLib::ext::shared_ptr<CPILegData> cpiLegData = QuantLib::ext::dynamic_pointer_cast<CPILegData>(
data.concreteLegData());
1620 QL_REQUIRE(cpiLegData,
"Wrong LegType, expected CPI, got " <<
data.legType());
1624 Calendar paymentCalendar;
1626 if (
data.paymentCalendar().empty())
1627 paymentCalendar = schedule.calendar();
1632 QuantLib::ext::shared_ptr<InflationSwapConvention> cpiSwapConvention =
nullptr;
1634 auto inflationConventions = InstrumentConventions::instance().conventions()->get(
1637 if (inflationConventions.first)
1638 cpiSwapConvention = QuantLib::ext::dynamic_pointer_cast<InflationSwapConvention>(inflationConventions.second);
1640 Period observationLag;
1641 if (cpiLegData->observationLag().empty()) {
1642 QL_REQUIRE(cpiSwapConvention,
1643 "observationLag is not specified in legData and couldn't find convention for "
1644 << cpiLegData->index() <<
". Please add field to trade xml or add convention");
1645 DLOG(
"Build CPI Leg and use observation lag from standard inflationswap convention");
1646 observationLag = cpiSwapConvention->observationLag();
1648 observationLag =
parsePeriod(cpiLegData->observationLag());
1651 CPI::InterpolationType interpolationMethod;
1652 if (cpiLegData->interpolation().empty()) {
1653 QL_REQUIRE(cpiSwapConvention,
1654 "Interpolation is not specified in legData and couldn't find convention for "
1655 << cpiLegData->index() <<
". Please add field to trade xml or add convention");
1656 DLOG(
"Build CPI Leg and use observation lag from standard inflationswap convention");
1657 interpolationMethod = cpiSwapConvention->interpolated() ? CPI::Linear : CPI::Flat;
1662 vector<double> rates =
buildScheduledVector(cpiLegData->rates(), cpiLegData->rateDates(), schedule);
1664 bool couponCap = cpiLegData->caps().size() > 0;
1665 bool couponFloor = cpiLegData->floors().size() > 0;
1666 bool couponCapFloor = cpiLegData->caps().size() > 0 || cpiLegData->floors().size() > 0;
1667 bool finalFlowCapFloor = cpiLegData->finalFlowCap() != Null<Real>() || cpiLegData->finalFlowFloor() != Null<Real>();
1674 engineFactory->market()->discountCurve(
data.currency(),
1676 cpiLegData->baseCPI(), observationLag)
1690 const string& start = cpiLegData->startDate();
1691 if (schedule.size() < 2) {
1692 QL_REQUIRE(!start.empty(),
"makeCPILeg(): only one schedule date, a 'StartDate' must be given.");
1694 }
else if (!start.empty()) {
1695 DLOG(
"Schedule with more than 2 dates was provided. The first schedule date "
1697 << io::iso_date(schedule.dates().front()) <<
" is used as the start date. The 'StartDate' of " << start
1698 <<
" is not used.");
1706 if (cpiLegData->finalFlowCap() != Null<Real>())
1709 if (cpiLegData->finalFlowFloor() != Null<Real>())
1712 Leg leg = cpiLeg.operator Leg();
1713 Size n = leg.size();
1714 QL_REQUIRE(n > 0,
"Empty CPI Leg");
1716 if (couponCapFloor || finalFlowCapFloor) {
1718 string indexName = cpiLegData->index();
1721 QuantLib::ext::shared_ptr<EngineBuilder> cpBuilder = engineFactory->builder(
"CappedFlooredCpiLegCoupons");
1722 QL_REQUIRE(cpBuilder,
"No builder found for CappedFlooredCpiLegCoupons");
1723 QuantLib::ext::shared_ptr<CapFlooredCpiLegCouponEngineBuilder> cappedFlooredCpiCouponBuilder =
1724 QuantLib::ext::dynamic_pointer_cast<CapFlooredCpiLegCouponEngineBuilder>(cpBuilder);
1725 QuantLib::ext::shared_ptr<InflationCouponPricer> couponPricer = cappedFlooredCpiCouponBuilder->engine(indexName);
1728 QuantLib::ext::shared_ptr<EngineBuilder> cfBuilder = engineFactory->builder(
"CappedFlooredCpiLegCashFlows");
1729 QL_REQUIRE(cfBuilder,
"No builder found for CappedFlooredCpiLegCashFLows");
1730 QuantLib::ext::shared_ptr<CapFlooredCpiLegCashFlowEngineBuilder> cappedFlooredCpiCashFlowBuilder =
1731 QuantLib::ext::dynamic_pointer_cast<CapFlooredCpiLegCashFlowEngineBuilder>(cfBuilder);
1732 QuantLib::ext::shared_ptr<InflationCashFlowPricer> cashFlowPricer = cappedFlooredCpiCashFlowBuilder->engine(indexName);
1735 for (Size i = 0; i < leg.size(); i++) {
1739 QuantLib::ext::shared_ptr<CappedFlooredCPICoupon> cfCpiCoupon =
1740 QuantLib::ext::dynamic_pointer_cast<CappedFlooredCPICoupon>(leg[i]);
1741 if (cfCpiCoupon && couponCapFloor) {
1742 cfCpiCoupon->setPricer(couponPricer);
1745 QuantLib::ext::shared_ptr<CappedFlooredCPICashFlow> cfCpiCashFlow =
1746 QuantLib::ext::dynamic_pointer_cast<CappedFlooredCPICashFlow>(leg[i]);
1747 if (cfCpiCashFlow && finalFlowCapFloor && i == (leg.size() - 1)) {
1748 cfCpiCashFlow->setPricer(cashFlowPricer);
1754 if (!
data.notionalFinalExchange()) {
1759 if ((couponCapFloor || finalFlowCapFloor) && cpiLegData->nakedOption()) {
1767 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory,
const QuantLib::Date& openEndDateReplacement) {
1768 QuantLib::ext::shared_ptr<YoYLegData> yoyLegData = QuantLib::ext::dynamic_pointer_cast<YoYLegData>(
data.concreteLegData());
1769 QL_REQUIRE(yoyLegData,
"Wrong LegType, expected YoY, got " <<
data.legType());
1774 Calendar paymentCalendar;
1776 QuantLib::ext::shared_ptr<InflationSwapConvention> cpiSwapConvention =
nullptr;
1778 auto inflationConventions = InstrumentConventions::instance().conventions()->get(
1781 if (inflationConventions.first)
1782 cpiSwapConvention = QuantLib::ext::dynamic_pointer_cast<InflationSwapConvention>(inflationConventions.second);
1784 Period observationLag;
1785 if (yoyLegData->observationLag().empty()) {
1786 QL_REQUIRE(cpiSwapConvention,
1787 "observationLag is not specified in legData and couldn't find convention for "
1788 << yoyLegData->index() <<
". Please add field to trade xml or add convention");
1789 DLOG(
"Build CPI Leg and use observation lag from standard inflationswap convention");
1790 observationLag = cpiSwapConvention->observationLag();
1792 observationLag =
parsePeriod(yoyLegData->observationLag());
1795 if (
data.paymentCalendar().empty())
1796 paymentCalendar = schedule.calendar();
1800 vector<double> gearings =
1802 vector<double> spreads =
1806 bool irregularYoY = yoyLegData->irregularYoY();
1807 bool couponCap = yoyLegData->caps().size() > 0;
1808 bool couponFloor = yoyLegData->floors().size() > 0;
1809 bool couponCapFloor = yoyLegData->caps().size() > 0 || yoyLegData->floors().size() > 0;
1810 bool addInflationNotional = yoyLegData->addInflationNotional();
1814 if (!irregularYoY) {
1815 auto yoyIndex = QuantLib::ext::dynamic_pointer_cast<YoYInflationIndex>(index);
1816 QL_REQUIRE(yoyIndex,
"Need a YoY Inflation Index");
1835 leg = yoyLeg.operator Leg();
1837 if (couponCapFloor) {
1839 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder(
"CapFlooredYYLeg");
1840 QL_REQUIRE(builder,
"No builder found for CapFlooredYYLeg");
1841 QuantLib::ext::shared_ptr<CapFlooredYoYLegEngineBuilder> cappedFlooredYoYBuilder =
1842 QuantLib::ext::dynamic_pointer_cast<CapFlooredYoYLegEngineBuilder>(builder);
1843 string indexname = yoyLegData->index();
1844 QuantLib::ext::shared_ptr<InflationCouponPricer> couponPricer =
1845 cappedFlooredYoYBuilder->engine(IndexNameTranslator::instance().oreName(indexname));
1849 for (Size i = 0; i < leg.size(); i++) {
1850 QuantLib::ext::dynamic_pointer_cast<QuantExt::CappedFlooredYoYInflationCoupon>(leg[i])->setPricer(
1851 QuantLib::ext::dynamic_pointer_cast<QuantLib::YoYInflationCouponPricer>(couponPricer));
1855 if (yoyLegData->nakedOption()) {
1857 for (
auto const& t : leg) {
1858 auto s = QuantLib::ext::dynamic_pointer_cast<StrippedCappedFlooredYoYInflationCoupon>(t);
1863 QuantLib::CPI::InterpolationType interpolation = QuantLib::CPI::Flat;
1864 if (cpiSwapConvention && cpiSwapConvention->interpolated()) {
1865 interpolation = QuantLib::CPI::Linear;
1867 auto zcIndex = QuantLib::ext::dynamic_pointer_cast<ZeroInflationIndex>(index);
1868 QL_REQUIRE(zcIndex,
"Need a Zero Coupon Inflation Index");
1888 leg = yoyLeg.operator Leg();
1890 if (couponCapFloor) {
1892 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder(
"CapFlooredNonStdYYLeg");
1893 QL_REQUIRE(builder,
"No builder found for CapFlooredNonStdYYLeg");
1894 QuantLib::ext::shared_ptr<CapFlooredNonStandardYoYLegEngineBuilder> cappedFlooredYoYBuilder =
1895 QuantLib::ext::dynamic_pointer_cast<CapFlooredNonStandardYoYLegEngineBuilder>(builder);
1896 string indexname = zcIndex->name();
1897 QuantLib::ext::shared_ptr<InflationCouponPricer> couponPricer =
1898 cappedFlooredYoYBuilder->engine(IndexNameTranslator::instance().oreName(indexname));
1902 for (Size i = 0; i < leg.size(); i++) {
1903 QuantLib::ext::dynamic_pointer_cast<QuantExt::NonStandardCappedFlooredYoYInflationCoupon>(leg[i])->setPricer(
1904 QuantLib::ext::dynamic_pointer_cast<QuantExt::NonStandardYoYInflationCouponPricer>(couponPricer));
1908 if (yoyLegData->nakedOption()) {
1910 for (
auto const& t : leg) {
1911 auto s = QuantLib::ext::dynamic_pointer_cast<StrippedCappedFlooredYoYInflationCoupon>(t);
1920 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory,
const bool attachPricer,
1921 const QuantLib::Date& openEndDateReplacement) {
1922 QuantLib::ext::shared_ptr<CMSLegData> cmsData = QuantLib::ext::dynamic_pointer_cast<CMSLegData>(
data.concreteLegData());
1923 QL_REQUIRE(cmsData,
"Wrong LegType, expected CMS, got " <<
data.legType());
1928 Calendar paymentCalendar;
1931 if (
data.paymentCalendar().empty())
1932 paymentCalendar = schedule.calendar();
1936 vector<double> spreads =
1938 vector<double> gearings =
1941 Size fixingDays = cmsData->fixingDays() == Null<Size>() ? swapIndex->fixingDays() : cmsData->fixingDays();
1945 CmsLeg cmsLeg = CmsLeg(schedule, swapIndex)
1946 .withNotionals(notionals)
1947 .withSpreads(spreads)
1948 .withGearings(gearings)
1949 .withPaymentCalendar(paymentCalendar)
1950 .withPaymentDayCounter(dc)
1951 .withPaymentAdjustment(bdc)
1953 .withFixingDays(fixingDays)
1954 .inArrears(cmsData->isInArrears());
1956 if (cmsData->caps().size() > 0)
1959 if (cmsData->floors().size() > 0)
1966 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder(
"CMS");
1967 QL_REQUIRE(builder,
"No builder found for CmsLeg");
1968 QuantLib::ext::shared_ptr<CmsCouponPricerBuilder> cmsSwapBuilder =
1969 QuantLib::ext::dynamic_pointer_cast<CmsCouponPricerBuilder>(builder);
1970 QuantLib::ext::shared_ptr<FloatingRateCouponPricer> couponPricer =
1971 cmsSwapBuilder->engine(IndexNameTranslator::instance().oreName(swapIndex->iborIndex()->name()));
1974 Leg tmpLeg = cmsLeg;
1975 QuantLib::setCouponPricer(tmpLeg, couponPricer);
1978 if (cmsData->nakedOption()) {
1979 tmpLeg = StrippedCappedFlooredCouponLeg(tmpLeg);
1984Leg
makeCMBLeg(
const LegData& data,
const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory,
const bool attachPricer,
1985 const QuantLib::Date& openEndDateReplacement) {
1986 QuantLib::ext::shared_ptr<CMBLegData> cmbData = QuantLib::ext::dynamic_pointer_cast<CMBLegData>(
data.concreteLegData());
1987 QL_REQUIRE(cmbData,
"Wrong LegType, expected CMB, got " <<
data.legType());
1989 std::string bondIndexName = cmbData->genericBond();
1992 std::vector<string> tokens;
1993 split(tokens, bondIndexName, boost::is_any_of(
"-"));
1994 QL_REQUIRE(tokens.size() >= 2,
1995 "Generic Bond Index with at least two tokens separated by - expected, found " << bondIndexName);
1996 std::string securityFamily = tokens[0];
1997 for (Size i = 1; i < tokens.size() - 1; ++i)
1998 securityFamily = securityFamily +
"-" + tokens[i];
1999 string underlyingTerm = tokens.back();
2000 Period underlyingPeriod =
parsePeriod(underlyingTerm);
2001 LOG(
"Generic bond id " << bondIndexName <<
" has family " << securityFamily <<
" and term " << underlyingPeriod);
2004 Calendar
calendar = schedule.calendar();
2005 int fixingDays = cmbData->fixingDays();
2006 BusinessDayConvention convention = schedule.businessDayConvention();
2007 bool creditRisk = cmbData->hasCreditRisk();
2010 BondData bondData(securityFamily, 1.0, creditRisk);
2012 DLOG(
"Bond data for security id " << securityFamily <<
" loaded");
2013 QL_REQUIRE(bondData.
coupons().size() == 1,
2014 "multiple reference bond legs not covered by the CMB leg");
2015 QL_REQUIRE(bondData.
coupons().front().schedule().rules().size() == 1,
2016 "multiple bond schedule rules not covered by the CMB leg");
2017 QL_REQUIRE(bondData.
coupons().front().schedule().dates().size() == 0,
2018 "dates based bond schedules not covered by the CMB leg");
2022 QuantLib::ext::shared_ptr<BondYieldConvention> conv;
2024 conv = QuantLib::ext::dynamic_pointer_cast<BondYieldConvention>(ret.second);
2026 conv = QuantLib::ext::make_shared<BondYieldConvention>();
2027 ALOG(
"BondYield conventions not found for security " << securityFamily <<
", falling back on defaults:"
2028 <<
" compounding=" << conv->compoundingName()
2029 <<
", priceType=" << conv->priceTypeName()
2030 <<
", accuracy=" << conv->accuracy()
2031 <<
", maxEvaluations=" << conv->maxEvaluations()
2032 <<
", guess=" << conv->guess());
2040 BusinessDayConvention bondConvention = bondSchedule.businessDayConvention();
2041 bool bondEndOfMonth = bondSchedule.endOfMonth();
2042 Frequency bondFrequency = bondSchedule.tenor().frequency();
2047 DLOG(
"Create Constant Maturity Bond Indices for each period");
2048 std::vector<QuantLib::ext::shared_ptr<QuantExt::ConstantMaturityBondIndex>> bondIndices;
2049 for (Size i = 0; i < schedule.dates().
size() - 1; ++i) {
2052 Date refDate = cmbData->isInArrears() ? schedule[i+1] : schedule[i];
2053 Date start =
calendar.advance(refDate, -fixingDays, Days, Preceding);
2054 std::string startDate =
to_string(start);
2055 std::string endDate =
to_string(start + underlyingPeriod);
2058 bondTrade.
build(engineFactory);
2059 auto bond = QuantLib::ext::dynamic_pointer_cast<QuantLib::Bond>(bondTrade.
instrument()->qlInstrument());
2060 QuantLib::ext::shared_ptr<QuantExt::ConstantMaturityBondIndex> bondIndex
2061 = QuantLib::ext::make_shared<QuantExt::ConstantMaturityBondIndex>(securityFamily, underlyingPeriod,
2063 bondSettlementDays, bondCurrency, bondCalendar, bondDayCounter, bondConvention, bondEndOfMonth,
2067 conv->compounding(), bondFrequency, conv->accuracy(), conv->maxEvaluations(), conv->guess(), conv->priceType());
2068 bondIndices.push_back(bondIndex);
2072 DLOG(
"Create CMB leg");
2078 QL_REQUIRE(bondIndices.size() == schedule.size() - 1,
2079 "vector size mismatch between schedule (" << schedule.size() <<
") "
2080 <<
"and bond indices (" << bondIndices.size() <<
")");
2082 for (Size i = 0; i < schedule.size() - 1; i++) {
2083 Date paymentDate =
calendar.adjust(schedule[i + 1], convention);
2084 DLOG(
"Coupon " << i <<
": "
2085 << io::iso_date(paymentDate) <<
" "
2086 << notionals[i] <<
" "
2087 << io::iso_date(schedule[i]) <<
" "
2088 << io::iso_date(schedule[i+1]) <<
" "
2089 << cmbData->fixingDays() <<
" "
2090 << gearings[i] <<
" "
2091 << spreads[i] <<
" "
2092 << dayCounter.name());
2093 QuantLib::ext::shared_ptr<CmbCoupon> coupon
2094 = QuantLib::ext::make_shared<CmbCoupon>(paymentDate, notionals[i], schedule[i], schedule[i + 1],
2095 cmbData->fixingDays(), bondIndices[i], gearings[i], spreads[i], Date(), Date(),
2096 dayCounter, cmbData->isInArrears());
2097 auto pricer = QuantLib::ext::make_shared<CmbCouponPricer>();
2098 coupon->setPricer(pricer);
2099 leg.push_back(coupon);
2106 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory,
const bool attachPricer,
2107 const QuantLib::Date& openEndDateReplacement) {
2108 auto digitalCmsData = QuantLib::ext::dynamic_pointer_cast<DigitalCMSLegData>(
data.concreteLegData());
2109 QL_REQUIRE(digitalCmsData,
"Wrong LegType, expected DigitalCMS");
2111 auto cmsData = QuantLib::ext::dynamic_pointer_cast<CMSLegData>(digitalCmsData->underlying());
2112 QL_REQUIRE(cmsData,
"Incomplete DigitalCms Leg, expected CMS data");
2118 vector<double> spreads =
2120 vector<double> gearings =
2125 vector<double> callStrikes =
2128 for (Size i = 0; i < callStrikes.size(); i++) {
2129 if (std::fabs(callStrikes[i]) < eps / 2) {
2130 callStrikes[i] = eps / 2;
2134 vector<double> callPayoffs =
2137 vector<double> putStrikes =
2139 vector<double> putPayoffs =
2142 Size fixingDays = cmsData->fixingDays() == Null<Size>() ? swapIndex->fixingDays() : cmsData->fixingDays();
2146 DigitalCmsLeg digitalCmsLeg = DigitalCmsLeg(schedule, swapIndex)
2147 .withNotionals(notionals)
2148 .withSpreads(spreads)
2149 .withGearings(gearings)
2151 .withPaymentDayCounter(dc)
2152 .withPaymentAdjustment(bdc)
2153 .withFixingDays(fixingDays)
2154 .inArrears(cmsData->isInArrears())
2155 .withCallStrikes(callStrikes)
2156 .withLongCallOption(digitalCmsData->callPosition())
2157 .withCallATM(digitalCmsData->isCallATMIncluded())
2158 .withCallPayoffs(callPayoffs)
2159 .withPutStrikes(putStrikes)
2160 .withLongPutOption(digitalCmsData->putPosition())
2161 .withPutATM(digitalCmsData->isPutATMIncluded())
2162 .withPutPayoffs(putPayoffs)
2163 .withReplication(QuantLib::ext::make_shared<DigitalReplication>())
2164 .withNakedOption(cmsData->nakedOption());
2166 if (cmsData->caps().size() > 0 || cmsData->floors().size() > 0)
2167 QL_FAIL(
"caps/floors not supported in DigitalCMSOptions");
2170 return digitalCmsLeg;
2173 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder(
"CMS");
2174 QL_REQUIRE(builder,
"No CMS builder found for CmsLeg");
2175 QuantLib::ext::shared_ptr<CmsCouponPricerBuilder> cmsBuilder = QuantLib::ext::dynamic_pointer_cast<CmsCouponPricerBuilder>(builder);
2176 auto cmsPricer = QuantLib::ext::dynamic_pointer_cast<CmsCouponPricer>(
2177 cmsBuilder->engine(IndexNameTranslator::instance().oreName(swapIndex->iborIndex()->name())));
2178 QL_REQUIRE(cmsPricer,
"Expected CMS Pricer");
2181 Leg tmpLeg = digitalCmsLeg;
2182 QuantLib::setCouponPricer(tmpLeg, cmsPricer);
2188 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory,
const bool attachPricer,
2189 const QuantLib::Date& openEndDateReplacement) {
2190 QuantLib::ext::shared_ptr<CMSSpreadLegData> cmsSpreadData =
2191 QuantLib::ext::dynamic_pointer_cast<CMSSpreadLegData>(
data.concreteLegData());
2192 QL_REQUIRE(cmsSpreadData,
"Wrong LegType, expected CMSSpread, got " <<
data.legType());
2197 Calendar paymentCalendar;
2198 if (
data.paymentCalendar().empty())
2199 paymentCalendar = schedule.calendar();
2206 cmsSpreadData->spreadDates(), schedule, 0.0);
2208 cmsSpreadData->gearingDates(), schedule, 1.0);
2211 cmsSpreadData->fixingDays() == Null<Size>() ? swapSpreadIndex->fixingDays() : cmsSpreadData->fixingDays();
2215 CmsSpreadLeg cmsSpreadLeg = CmsSpreadLeg(schedule, swapSpreadIndex)
2216 .withNotionals(notionals)
2217 .withSpreads(spreads)
2218 .withGearings(gearings)
2219 .withPaymentCalendar(paymentCalendar)
2220 .withPaymentDayCounter(dc)
2221 .withPaymentAdjustment(bdc)
2223 .withFixingDays(fixingDays)
2224 .inArrears(cmsSpreadData->isInArrears());
2226 if (cmsSpreadData->caps().size() > 0)
2227 cmsSpreadLeg.withCaps(
buildScheduledVector(cmsSpreadData->caps(), cmsSpreadData->capDates(), schedule));
2229 if (cmsSpreadData->floors().size() > 0)
2230 cmsSpreadLeg.withFloors(
buildScheduledVector(cmsSpreadData->floors(), cmsSpreadData->floorDates(), schedule));
2233 return cmsSpreadLeg;
2236 auto builder1 = engineFactory->builder(
"CMS");
2237 QL_REQUIRE(builder1,
"No CMS builder found for CmsSpreadLeg");
2238 auto cmsBuilder = QuantLib::ext::dynamic_pointer_cast<CmsCouponPricerBuilder>(builder1);
2239 auto cmsPricer = QuantLib::ext::dynamic_pointer_cast<CmsCouponPricer>(cmsBuilder->engine(
2240 IndexNameTranslator::instance().oreName(swapSpreadIndex->swapIndex1()->iborIndex()->name())));
2241 QL_REQUIRE(cmsPricer,
"Expected CMS Pricer");
2242 auto builder2 = engineFactory->builder(
"CMSSpread");
2243 QL_REQUIRE(builder2,
"No CMS Spread builder found for CmsSpreadLeg");
2244 auto cmsSpreadBuilder = QuantLib::ext::dynamic_pointer_cast<CmsSpreadCouponPricerBuilder>(builder2);
2245 auto cmsSpreadPricer = cmsSpreadBuilder->engine(swapSpreadIndex->currency(), cmsSpreadData->swapIndex1(),
2246 cmsSpreadData->swapIndex2(), cmsPricer);
2247 QL_REQUIRE(cmsSpreadPricer,
"Expected CMS Spread Pricer");
2250 Leg tmpLeg = cmsSpreadLeg;
2251 QuantLib::setCouponPricer(tmpLeg, cmsSpreadPricer);
2254 if (cmsSpreadData->nakedOption()) {
2255 tmpLeg = StrippedCappedFlooredCouponLeg(tmpLeg);
2261 const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory,
2262 const QuantLib::Date& openEndDateReplacement) {
2263 auto digitalCmsSpreadData = QuantLib::ext::dynamic_pointer_cast<DigitalCMSSpreadLegData>(
data.concreteLegData());
2264 QL_REQUIRE(digitalCmsSpreadData,
"Wrong LegType, expected DigitalCMSSpread");
2266 auto cmsSpreadData = QuantLib::ext::dynamic_pointer_cast<CMSSpreadLegData>(digitalCmsSpreadData->underlying());
2267 QL_REQUIRE(cmsSpreadData,
"Incomplete DigitalCmsSpread Leg, expected CMSSpread data");
2273 Calendar paymentCalendar;
2274 if (
data.paymentCalendar().empty())
2275 paymentCalendar = schedule.calendar();
2280 cmsSpreadData->spreadDates(), schedule, 0.0);
2282 cmsSpreadData->gearingDates(), schedule, 1.0);
2287 digitalCmsSpreadData->callStrikeDates(), schedule);
2289 for (Size i = 0; i < callStrikes.size(); i++) {
2290 if (std::fabs(callStrikes[i]) < eps / 2) {
2291 callStrikes[i] = eps / 2;
2296 digitalCmsSpreadData->callPayoffDates(), schedule);
2299 digitalCmsSpreadData->putStrikeDates(), schedule);
2301 digitalCmsSpreadData->putPayoffDates(), schedule);
2304 cmsSpreadData->fixingDays() == Null<Size>() ? swapSpreadIndex->fixingDays() : cmsSpreadData->fixingDays();
2308 DigitalCmsSpreadLeg digitalCmsSpreadLeg = DigitalCmsSpreadLeg(schedule, swapSpreadIndex)
2309 .withNotionals(notionals)
2310 .withSpreads(spreads)
2311 .withGearings(gearings)
2312 .withPaymentDayCounter(dc)
2313 .withPaymentCalendar(paymentCalendar)
2314 .withPaymentAdjustment(bdc)
2315 .withFixingDays(fixingDays)
2316 .inArrears(cmsSpreadData->isInArrears())
2317 .withCallStrikes(callStrikes)
2318 .withLongCallOption(digitalCmsSpreadData->callPosition())
2319 .withCallATM(digitalCmsSpreadData->isCallATMIncluded())
2320 .withCallPayoffs(callPayoffs)
2321 .withPutStrikes(putStrikes)
2322 .withLongPutOption(digitalCmsSpreadData->putPosition())
2323 .withPutATM(digitalCmsSpreadData->isPutATMIncluded())
2324 .withPutPayoffs(putPayoffs)
2325 .withReplication(QuantLib::ext::make_shared<DigitalReplication>())
2326 .withNakedOption(cmsSpreadData->nakedOption());
2328 if (cmsSpreadData->caps().size() > 0 || cmsSpreadData->floors().size() > 0)
2329 QL_FAIL(
"caps/floors not supported in DigitalCMSSpreadOptions");
2332 auto builder1 = engineFactory->builder(
"CMS");
2333 QL_REQUIRE(builder1,
"No CMS builder found for CmsSpreadLeg");
2334 auto cmsBuilder = QuantLib::ext::dynamic_pointer_cast<CmsCouponPricerBuilder>(builder1);
2335 auto cmsPricer = QuantLib::ext::dynamic_pointer_cast<CmsCouponPricer>(cmsBuilder->engine(
2336 IndexNameTranslator::instance().oreName(swapSpreadIndex->swapIndex1()->iborIndex()->name())));
2337 QL_REQUIRE(cmsPricer,
"Expected CMS Pricer");
2338 auto builder2 = engineFactory->builder(
"CMSSpread");
2339 QL_REQUIRE(builder2,
"No CMS Spread builder found for CmsSpreadLeg");
2340 auto cmsSpreadBuilder = QuantLib::ext::dynamic_pointer_cast<CmsSpreadCouponPricerBuilder>(builder2);
2341 auto cmsSpreadPricer = cmsSpreadBuilder->engine(swapSpreadIndex->currency(), cmsSpreadData->swapIndex1(),
2342 cmsSpreadData->swapIndex2(), cmsPricer);
2343 QL_REQUIRE(cmsSpreadPricer,
"Expected CMS Spread Pricer");
2346 Leg tmpLeg = digitalCmsSpreadLeg;
2347 QuantLib::setCouponPricer(tmpLeg, cmsSpreadPricer);
2353 const QuantLib::ext::shared_ptr<QuantExt::FxIndex>& fxIndex,
const QuantLib::Date& openEndDateReplacement) {
2354 QuantLib::ext::shared_ptr<EquityLegData> eqLegData = QuantLib::ext::dynamic_pointer_cast<EquityLegData>(
data.concreteLegData());
2355 QL_REQUIRE(eqLegData,
"Wrong LegType, expected Equity, got " <<
data.legType());
2358 if (
data.dayCounter().empty())
2359 dc = Actual365Fixed();
2364 Real dividendFactor = eqLegData->dividendFactor();
2365 Real initialPrice = eqLegData->initialPrice();
2366 bool initialPriceIsInTargetCcy =
false;
2368 if (!eqLegData->initialPriceCurrency().empty()) {
2372 Currency eqCurrency;
2374 if (!eqLegData->eqCurrency().empty())
2376 else if (!equityCurve->currency().empty())
2377 eqCurrency = equityCurve->currency();
2379 TLOG(
"Cannot find currency for equity " << equityCurve->name());
2382 QL_REQUIRE(initialPriceCurrency == dataCurrency || initialPriceCurrency == eqCurrency || eqCurrency.empty(),
2383 "initial price ccy (" << initialPriceCurrency <<
") must match either leg ccy (" << dataCurrency
2384 <<
") or equity ccy (if given, got '" << eqCurrency <<
"')");
2385 initialPriceIsInTargetCcy = initialPriceCurrency == dataCurrency;
2389 bool notionalReset = eqLegData->notionalReset();
2390 Natural fixingDays = eqLegData->fixingDays();
2397 scheduleBuilder.
add(schedule, scheduleData);
2399 ScheduleData valuationData = eqLegData->valuationSchedule();
2400 Schedule valuationSchedule;
2402 scheduleBuilder.
add(valuationSchedule, valuationData);
2408 Calendar paymentCalendar;
2409 if (
data.paymentCalendar().empty())
2410 paymentCalendar = schedule.calendar();
2415 Leg leg =
EquityLeg(schedule, equityCurve, fxIndex)
2430 QL_REQUIRE(leg.size() > 0,
"Empty Equity Leg");
2436 Date today = Settings::instance().evaluationDate();
2439 for (
auto cf : leg) {
2440 if (cf->date() > today) {
2441 QuantLib::ext::shared_ptr<Coupon> coupon = QuantLib::ext::dynamic_pointer_cast<QuantLib::Coupon>(cf);
2443 return coupon->nominal();
2452 if (leg.size() > 0) {
2453 QuantLib::ext::shared_ptr<Coupon> coupon = QuantLib::ext::dynamic_pointer_cast<QuantLib::Coupon>(leg.front());
2455 return coupon->nominal();
2462 DLOG(
"Build fixed amortization notional schedule");
2464 Date startDate =
data.startDate().empty() ? Date::minDate() :
parseDate(
data.startDate());
2465 Date endDate =
data.endDate().empty() ? Date::maxDate() :
parseDate(
data.endDate());
2466 bool underflow =
data.underflow();
2468 double amort =
data.value();
2469 Date lastAmortDate = Date::minDate();
2470 for (Size i = 0; i < schedule.size() - 1; i++) {
2471 if (i > 0 && (lastAmortDate == Date::minDate() || schedule[i] > lastAmortDate + amortPeriod - 4 * Days) &&
2472 schedule[i] >= startDate && schedule[i] < endDate) {
2473 nominals[i] = nominals[i - 1] - amort;
2474 lastAmortDate = schedule[i];
2475 }
else if (i > 0 && lastAmortDate > Date::minDate()) {
2476 nominals[i] = nominals[i - 1];
2478 if (amort > nominals[i] && underflow ==
false)
2479 amort = std::max(nominals[i], 0.0);
2481 DLOG(
"Fixed amortization notional schedule done");
2486 const Schedule& schedule,
2488 DLOG(
"Build notional schedule with amortizations expressed as percentages of initial notional");
2490 Date startDate =
data.startDate().empty() ? Date::minDate() :
parseDate(
data.startDate());
2491 Date endDate =
data.endDate().empty() ? Date::maxDate() :
parseDate(
data.endDate());
2492 bool underflow =
data.underflow();
2494 double amort =
data.value() * nominals.front();
2495 Date lastAmortDate = Date::minDate();
2496 for (Size i = 0; i < schedule.size() - 1; i++) {
2497 if (i > 0 && (lastAmortDate == Date::minDate() || schedule[i] > lastAmortDate + amortPeriod - 4 * Days) &&
2498 schedule[i] >= startDate && schedule[i] < endDate) {
2499 nominals[i] = nominals[i - 1] - amort;
2500 lastAmortDate = schedule[i];
2501 }
else if (i > 0 && lastAmortDate > Date::minDate())
2502 nominals[i] = nominals[i - 1];
2503 if (amort > nominals[i] && underflow ==
false) {
2504 amort = std::max(nominals[i], 0.0);
2507 DLOG(
"Fixed amortization notional schedule done");
2512 const Schedule& schedule,
2514 DLOG(
"Build notional schedule with amortizations expressed as percentages of previous notionals");
2516 Date startDate =
data.startDate().empty() ? Date::minDate() :
parseDate(
data.startDate());
2517 Date endDate =
data.endDate().empty() ? Date::maxDate() :
parseDate(
data.endDate());
2519 double fraction =
data.value();
2520 QL_REQUIRE(fraction < 1.0 ||
close_enough(fraction, 1.0),
2521 "amortization fraction " << fraction <<
" expected to be <= 1");
2522 Date lastAmortDate = Date::minDate();
2523 for (Size i = 0; i < schedule.size() - 1; i++) {
2524 if (i > 0 && (lastAmortDate == Date::minDate() || schedule[i] > lastAmortDate + amortPeriod - 4 * Days) &&
2525 schedule[i] >= startDate && schedule[i] < endDate) {
2526 nominals[i] = nominals[i - 1] * (1.0 - fraction);
2527 lastAmortDate = schedule[i];
2528 }
else if (i > 0 && lastAmortDate > Date::minDate())
2529 nominals[i] = nominals[i - 1];
2531 DLOG(
"Fixed amortization notional schedule done");
2537 const DayCounter& dc) {
2538 DLOG(
"Build fixed annuity notional schedule");
2540 Date startDate =
data.startDate().empty() ? Date::minDate() :
parseDate(
data.startDate());
2541 Date endDate =
data.endDate().empty() ? Date::maxDate() :
parseDate(
data.endDate());
2542 bool underflow =
data.underflow();
2543 double annuity =
data.value();
2545 Date lastAmortDate = Date::minDate();
2546 for (Size i = 0; i < schedule.size() - 1; i++) {
2547 if (i > 0 && schedule[i] >= startDate && schedule[i] < endDate) {
2548 nominals[i] = nominals[i - 1] - amort;
2549 lastAmortDate = schedule[i];
2550 }
else if (i > 0 && lastAmortDate > Date::minDate())
2551 nominals[i] = nominals[i - 1];
2552 Real dcf = dc.yearFraction(schedule[i], schedule[i + 1]);
2553 Real rate = i < rates.size() ? rates[i] : rates.back();
2554 amort = annuity - rate * nominals[i] * dcf;
2555 if (amort > nominals[i] && underflow ==
false) {
2556 amort = std::max(nominals[i], 0.0);
2559 DLOG(
"Fixed Annuity notional schedule done");
2565 DLOG(
"Build linear-to-maturity notional schedule");
2567 Date startDate =
data.startDate().empty() ? Date::minDate() :
parseDate(
data.startDate());
2568 Date endDate =
data.endDate().empty() ? Date::maxDate() :
parseDate(
data.endDate());
2570 Date lastAmortDate = Date::minDate();
2571 Real periodAmortization = Null<Real>();
2572 Real accumulatedAmortization = 0.0;
2573 for (Size i = 0; i < schedule.size() - 1; ++i) {
2574 if (schedule[i] >= startDate && periodAmortization == Null<Real>()) {
2575 periodAmortization = nominals[i] /
static_cast<Real
>(schedule.size() - i);
2577 if (i > 0 && schedule[i] >= startDate && schedule[i] < endDate) {
2578 accumulatedAmortization += periodAmortization;
2580 if (i > 0 && (lastAmortDate == Date::minDate() || schedule[i] > lastAmortDate + amortPeriod - 4 * Days) &&
2581 schedule[i] >= startDate && schedule[i] < endDate) {
2582 nominals[i] = nominals[i - 1] - accumulatedAmortization;
2583 accumulatedAmortization = 0.0;
2584 lastAmortDate = schedule[i];
2585 }
else if (i > 0 && lastAmortDate > Date::minDate()) {
2586 nominals[i] = nominals[i - 1];
2589 DLOG(
"Linear-to-maturity notional schedule done");
2594 const bool annuityAllowed,
const std::vector<Real>& rates) {
2595 Date lastEndDate = Date::minDate();
2596 for (Size i = 0; i <
data.amortizationData().
size(); ++i) {
2600 QL_REQUIRE(i == 0 || !amort.
startDate().empty(),
2601 "All AmortizationData blocks except the first require a StartDate");
2603 QL_REQUIRE(startDate >= lastEndDate,
"Amortization start date ("
2604 << startDate <<
") is earlier than last end date (" << lastEndDate
2615 QL_REQUIRE(annuityAllowed,
"Amortization type Annuity not allowed for leg type " <<
data.legType());
2622 QL_FAIL(
"AmortizationType " << amort.
type() <<
" not supported");
2627 QL_REQUIRE(
data.amortizationData().size() == 1,
2628 "Floating Leg supports only one amortisation block of type Annuity");
2634 RequiredFixings& requiredFixings,
const QuantLib::Date& openEndDateReplacement,
2635 const bool useXbsCurves) {
2636 for (
auto const& indexing :
data.indexing()) {
2637 if (indexing.hasData()) {
2638 DLOG(
"apply indexing (index='" << indexing.index() <<
"') to leg of type " <<
data.legType());
2639 QL_REQUIRE(engineFactory,
"applyIndexing: engineFactory required");
2643 QuantLib::ext::shared_ptr<Index> index;
2645 if (boost::starts_with(indexing.index(),
"EQ-")) {
2646 string eqName = indexing.index().substr(3);
2647 index = *engineFactory->market()->equityCurve(eqName, config);
2648 }
else if (boost::starts_with(indexing.index(),
"FX-")) {
2650 Currency ccy1 = tmp->targetCurrency();
2651 Currency ccy2 = tmp->sourceCurrency();
2652 QL_REQUIRE(ccy1.code() ==
data.currency() || ccy2.code() ==
data.currency(),
2653 "applyIndexing: fx index '" << indexing.index() <<
"' ccys do not match leg ccy ("
2654 <<
data.currency() <<
")");
2655 std::string domestic =
data.currency();
2656 std::string foreign = ccy1.code() == domestic ? ccy2.code() : ccy1.code();
2657 index =
buildFxIndex(indexing.index(), domestic, foreign, engineFactory->market(),
2660 }
else if (boost::starts_with(indexing.index(),
"COMM-")) {
2663 engineFactory->market()->commodityPriceCurve(tmp->underlyingName(), config),
2664 tmp->fixingCalendar());
2665 }
else if (boost::starts_with(indexing.index(),
"BOND-")) {
2667 QuantLib::ext::shared_ptr<BondIndex> bi =
parseBondIndex(indexing.index());
2668 QL_REQUIRE(!(QuantLib::ext::dynamic_pointer_cast<BondFuturesIndex>(bi)),
2669 "BondFuture Legs are not yet supported");
2670 BondData bondData(bi->securityName(), 1.0);
2671 BondIndexBuilder bondIndexBuilder(bondData, indexing.indexIsDirty(), indexing.indexIsRelative(),
2673 indexing.indexIsConditionalOnSurvival(), engineFactory);
2677 QL_FAIL(
"invalid index '" << indexing.index()
2678 <<
"' in indexing data, expected EQ-, FX-, COMM-, BOND- index");
2681 QL_REQUIRE(index,
"applyIndexing(): index is null, this is unexpected");
2688 if (
data.notionalInitialExchange())
2692 if (indexing.valuationSchedule().hasData())
2694 if (!indexing.fixingCalendar().empty())
2696 if (!indexing.fixingConvention().empty())
2705 Size lastLeg = Null<Size>();
2706 for (Size i = 0; i < legs.size(); ++i) {
2708 if (legs[i].empty())
2711 if (lastLeg != Null<Size>()) {
2712 auto lcpn = QuantLib::ext::dynamic_pointer_cast<Coupon>(legs[lastLeg].back());
2713 auto fcpn = QuantLib::ext::dynamic_pointer_cast<Coupon>(legs[i].front());
2714 QL_REQUIRE(lcpn,
"joinLegs: expected coupon as last cashflow in leg #" << lastLeg);
2715 QL_REQUIRE(fcpn,
"joinLegs: expected coupon as first cashflow in leg #" << i);
2716 QL_REQUIRE(lcpn->accrualEndDate() == fcpn->accrualStartDate(),
2717 "joinLegs: accrual end date of last coupon in leg #"
2718 << lastLeg <<
" (" << lcpn->accrualEndDate()
2719 <<
") is not equal to accrual start date of first coupon in leg #" << i <<
" ("
2720 << fcpn->accrualStartDate() <<
")");
2724 masterLeg.insert(masterLeg.end(), legs[i].begin(), legs[i].end());
2730 const QuantLib::ext::shared_ptr<Market>& market,
const std::string& configuration) {
2732 if (!
data.isNotResetXCCY()) {
2734 DLOG(
"Building Resetting XCCY Notional leg");
2735 Real foreignNotional =
data.foreignAmount();
2737 QL_REQUIRE(!
data.fxIndex().empty(),
"buildNotionalLeg(): need fx index for fx resetting leg");
2742 Natural payLagInteger = boost::apply_visitor(
PaymentLagInteger(), notionalPayLag);
2747 for (Size j = 0; j < leg.size(); j++) {
2749 QuantLib::ext::shared_ptr<Coupon> c = QuantLib::ext::dynamic_pointer_cast<Coupon>(leg[j]);
2750 QL_REQUIRE(c,
"Expected each cashflow in FX resetting leg to be of type Coupon");
2752 const Date& initFlowDate = payCalendar.advance(c->accrualStartDate(), payLagInteger, Days, payConvention);
2753 const Date& finalFlowDate = payCalendar.advance(c->accrualEndDate(), payLagInteger, Days, payConvention);
2757 QuantLib::ext::shared_ptr<CashFlow> outCf;
2758 QuantLib::ext::shared_ptr<CashFlow> inCf;
2765 if (
data.notionals().size() == 0) {
2766 fixingDate = fxIndex->fixingDate(c->accrualStartDate());
2767 if (
data.notionalInitialExchange()) {
2768 outCf = QuantLib::ext::make_shared<FXLinkedCashFlow>(initFlowDate,
fixingDate, -foreignNotional,
2773 if (leg.size() > 1 ||
data.notionalFinalExchange()) {
2774 inCf = QuantLib::ext::make_shared<FXLinkedCashFlow>(finalFlowDate,
fixingDate, foreignNotional,
2778 if (
data.notionalInitialExchange()) {
2779 outCf = QuantLib::ext::make_shared<SimpleCashFlow>(-c->nominal(), initFlowDate);
2781 if (leg.size() > 1 ||
data.notionalFinalExchange()) {
2782 inCf = QuantLib::ext::make_shared<SimpleCashFlow>(c->nominal(), finalFlowDate);
2786 fixingDate = fxIndex->fixingDate(c->accrualStartDate());
2788 QuantLib::ext::make_shared<FXLinkedCashFlow>(initFlowDate,
fixingDate, -foreignNotional, fxIndex);
2790 if (j < leg.size() - 1 ||
data.notionalFinalExchange()) {
2792 QuantLib::ext::make_shared<FXLinkedCashFlow>(finalFlowDate,
fixingDate, foreignNotional, fxIndex);
2798 resettingLeg.push_back(outCf);
2803 resettingLeg.push_back(inCf);
2809 if (
data.notionalAmortizingExchange()) {
2810 QL_FAIL(
"Cannot have an amortizing notional with FX reset");
2813 return resettingLeg;
2815 }
else if ((
data.notionalInitialExchange() ||
data.notionalFinalExchange() ||
data.notionalAmortizingExchange()) &&
2816 (
data.legType() !=
"CPI")) {
2821 Natural notionalPayLagInteger = boost::apply_visitor(
PaymentLagInteger(), notionalPayLag);
2824 data.notionalAmortizingExchange(), notionalPayLagInteger,
2833std::string getCmbLegSecurity(
const std::string& genericBond) {
2834 return genericBond.substr(0, genericBond.find_last_of(
'-'));
2837QuantLib::ext::shared_ptr<BondReferenceDatum> getCmbLegRefData(
const CMBLegData& cmbData,
2838 const QuantLib::ext::shared_ptr<ReferenceDataManager>& refData) {
2839 QL_REQUIRE(refData,
"getCmbLegCreditQualifierMapping(): reference data is null");
2840 std::string security = getCmbLegSecurity(cmbData.genericBond());
2842 auto bondRefData = QuantLib::ext::dynamic_pointer_cast<ore::data::BondReferenceDatum>(
2844 QL_REQUIRE(bondRefData !=
nullptr,
"getCmbLegRefData(): internal error, could not cast to BondReferenceDatum");
2852 if (
auto bondRefData = getCmbLegRefData(ld, refData)) {
2853 std::string security = getCmbLegSecurity(ld.
genericBond());
2858 return std::string();
2861std::pair<std::string, SimmCreditQualifierMapping>
2863 const std::string& tradeId,
const std::string& tradeType) {
2866 std::string security = getCmbLegSecurity(ld.
genericBond());
2867 if (
auto bondRefData = getCmbLegRefData(ld, refData)) {
2870 target.
creditGroup = bondRefData->bondData().creditGroup;
2874 "Could not set mapping for CMB Leg security '" +
2876 "'. Check security name and reference data.")
2879 return std::make_pair(source, target);
Bond trade data model and serialization.
Interface for building a bond index.
builder that returns an engine to price capped floored avg BMA legs
builder that returns an engine to price capped floored ibor legs
builder that returns an engine to price capped floored ibor legs
builder that returns an engine to price capped floored yoy inflation legs
AverageONLeg & withLastRecentPeriod(const boost::optional< Period > &lastRecentPeriod)
AverageONLeg & withPaymentDates(const std::vector< QuantLib::Date > &paymentDates)
AverageONLeg & withPaymentDayCounter(const DayCounter &dayCounter)
AverageONLeg & includeSpreadInCapFloors(bool includeSpread)
AverageONLeg & withPaymentLag(Natural lag)
AverageONLeg & withLookback(const Period &lookback)
AverageONLeg & withRateCutoff(Natural rateCutoff)
AverageONLeg & withLastRecentPeriodCalendar(const Calendar &lastRecentPeriodCalendar)
AverageONLeg & withPaymentCalendar(const Calendar &calendar)
AverageONLeg & withNakedOption(const bool nakedOption)
AverageONLeg & withLocalCapFloor(const bool localCapFloor)
AverageONLeg & withTelescopicValueDates(bool telescopicValueDates)
AverageONLeg & withPaymentAdjustment(BusinessDayConvention convention)
AverageONLeg & withCapFlooredAverageONIndexedCouponPricer(const boost::shared_ptr< CapFlooredAverageONIndexedCouponPricer > &couponPricer)
AverageONLeg & withNotionals(const std::vector< Real > ¬ionals)
AverageONLeg & withSpreads(const std::vector< Spread > &spreads)
AverageONLeg & withInArrears(const bool inArrears)
AverageONLeg & withCaps(Rate cap)
AverageONLeg & withFloors(Rate floor)
AverageONLeg & withFixingDays(const Size fixingDays)
AverageONLeg & withAverageONIndexedCouponPricer(const boost::shared_ptr< AverageONIndexedCouponPricer > &couponPricer)
AverageONLeg & withGearings(const std::vector< Real > &gearings)
CPILeg & withNotionals(Real notional)
CPILeg & withPaymentAdjustment(BusinessDayConvention)
CPILeg & withFinalFlowCap(Rate cap)
CPILeg & withSubtractInflationNominal(bool)
CPILeg & withFixedRates(Real fixedRate)
CPILeg & withFinalFlowFloor(Rate floor)
CPILeg & withCaps(Rate cap)
CPILeg & withPaymentDayCounter(const DayCounter &)
CPILeg & withStartDate(const Date &startDate)
CPILeg & withPaymentCalendar(const Calendar &)
CPILeg & withFloors(Rate floor)
CPILeg & withSubtractInflationNominalAllCoupons(bool subtractInflationNominalAllCoupons)
CPILeg & withObservationInterpolation(CPI::InterpolationType)
EquityLeg & withInitialPriceIsInTargetCcy(bool)
EquityLeg & withDividendFactor(Real)
EquityLeg & withPaymentCalendar(const Calendar &calendar)
EquityLeg & withFixingDays(Natural)
EquityLeg & withNotionalReset(bool)
EquityLeg & withQuantity(Real)
EquityLeg & withNotionals(const std::vector< Real > ¬ionals)
EquityLeg & withInitialPrice(Real)
EquityLeg & withPaymentDayCounter(const DayCounter &dayCounter)
EquityLeg & withValuationSchedule(const Schedule &valuationSchedule)
EquityLeg & withPaymentAdjustment(BusinessDayConvention convention)
EquityLeg & withPaymentLag(Natural paymentLag)
EquityLeg & withReturnType(EquityReturnType)
IndexedCouponLeg & withInitialNotionalFixing(const Real initialNotionalFixing)
IndexedCouponLeg & withFixingCalendar(const Calendar &fixingCalendar)
IndexedCouponLeg & inArrearsFixing(const bool inArrearsFixing=true)
IndexedCouponLeg & withInitialFixing(const Real initialFixing)
IndexedCouponLeg & withFixingDays(const Size fixingDays)
IndexedCouponLeg & withValuationSchedule(const Schedule &valuationSchedule)
IndexedCouponLeg & withFixingConvention(const BusinessDayConvention &fixingConvention)
NonStandardYoYInflationLeg & withPaymentAdjustment(BusinessDayConvention)
NonStandardYoYInflationLeg & withFloors(Rate floor)
NonStandardYoYInflationLeg & withFixingDays(Natural fixingDays)
NonStandardYoYInflationLeg & withRateCurve(const Handle< YieldTermStructure > &rateCurve)
NonStandardYoYInflationLeg & withSpreads(Spread spread)
NonStandardYoYInflationLeg & withPaymentDayCounter(const DayCounter &)
NonStandardYoYInflationLeg & withGearings(Real gearing)
NonStandardYoYInflationLeg & withNotionals(Real notional)
NonStandardYoYInflationLeg & withObservationInterpolation(QuantLib::CPI::InterpolationType interpolation)
NonStandardYoYInflationLeg & withCaps(Rate cap)
NonStandardYoYInflationLeg & withInflationNotional(bool addInflationNotional_)
OvernightLeg & withLookback(const Period &lookback)
OvernightLeg & withGearings(Real gearing)
OvernightLeg & withPaymentCalendar(const Calendar &)
OvernightLeg & withLastRecentPeriod(const boost::optional< Period > &lastRecentPeriod)
OvernightLeg & withFloors(Rate floor)
OvernightLeg & withCapFlooredOvernightIndexedCouponPricer(const boost::shared_ptr< CappedFlooredOvernightIndexedCouponPricer > &couponPricer)
OvernightLeg & withTelescopicValueDates(bool telescopicValueDates)
OvernightLeg & withPaymentAdjustment(BusinessDayConvention)
OvernightLeg & withNakedOption(const bool nakedOption)
OvernightLeg & withFixingDays(const Natural fixingDays)
OvernightLeg & withNotionals(Real notional)
OvernightLeg & withOvernightIndexedCouponPricer(const boost::shared_ptr< OvernightIndexedCouponPricer > &couponPricer)
OvernightLeg & withRateCutoff(const Natural rateCutoff)
OvernightLeg & withCaps(Rate cap)
OvernightLeg & withPaymentDayCounter(const DayCounter &)
OvernightLeg & withInArrears(const bool inArrears)
OvernightLeg & withSpreads(Spread spread)
OvernightLeg & withPaymentDates(const std::vector< Date > &paymentDates)
OvernightLeg & withLocalCapFloor(const bool localCapFloor)
OvernightLeg & includeSpread(bool includeSpread)
OvernightLeg & withPaymentLag(Natural lag)
OvernightLeg & withLastRecentPeriodCalendar(const Calendar &lastRecentPeriodCalendar)
SubPeriodsLeg1 & withPaymentDayCounter(const DayCounter &dayCounter)
SubPeriodsLeg1 & withType(SubPeriodsCoupon1::Type type)
SubPeriodsLeg1 & withSpreads(const std::vector< Spread > &spreads)
SubPeriodsLeg1 & includeSpread(bool includeSpread)
SubPeriodsLeg1 & withGearings(const std::vector< Real > &gearings)
SubPeriodsLeg1 & withNotionals(const std::vector< Real > ¬ionals)
SubPeriodsLeg1 & withPaymentAdjustment(BusinessDayConvention convention)
yoyInflationLeg & withRateCurve(const Handle< YieldTermStructure > &rateCurve)
yoyInflationLeg & withSpreads(Spread spread)
yoyInflationLeg & withFloors(Rate floor)
yoyInflationLeg & withPaymentAdjustment(BusinessDayConvention)
yoyInflationLeg & withNotionals(Real notional)
yoyInflationLeg & withGearings(Real gearing)
yoyInflationLeg & withPaymentDayCounter(const DayCounter &)
yoyInflationLeg & withCaps(Rate cap)
yoyInflationLeg & withInflationNotional(bool addInflationNotional_)
yoyInflationLeg & withFixingDays(Natural fixingDays)
Serializable object holding amortization rules.
const string & endDate() const
Amortization end date.
const string & startDate() const
Amortization start date.
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
const string & type() const
FixedAmount, RelativeToInitialNotional, RelativeToPreviousNotional, Annuity.
const string & currency() const
const std::vector< LegData > & coupons() const
void populateFromBondReferenceData(const QuantLib::ext::shared_ptr< BondReferenceDatum > &referenceDatum, const std::string &startDate="", const std::string &endDate="")
populate data from reference datum and check data for completeness
const string & settlementDays() const
const string & calendar() const
virtual void build(const QuantLib::ext::shared_ptr< EngineFactory > &) override
Trade interface.
QuantLib::ext::shared_ptr< QuantExt::BondIndex > bondIndex() const
void addRequiredFixings(RequiredFixings &requiredFixings, Leg leg={})
static constexpr const char * TYPE
Serializable Constant Maturity Bond Yield Leg Data.
vector< string > gearingDates_
vector< double > gearings_
const string & genericBond() const
vector< string > floorDates_
virtual void fromXML(XMLNode *node) override
vector< double > spreads_
virtual XMLNode * toXML(XMLDocument &doc) const override
vector< string > capDates_
vector< string > spreadDates_
vector< string > gearingDates_
vector< double > gearings_
vector< string > floorDates_
virtual void fromXML(XMLNode *node) override
vector< double > spreads_
virtual XMLNode * toXML(XMLDocument &doc) const override
vector< string > capDates_
vector< string > spreadDates_
vector< string > gearingDates_
vector< double > gearings_
vector< string > floorDates_
virtual void fromXML(XMLNode *node) override
vector< double > spreads_
virtual XMLNode * toXML(XMLDocument &doc) const override
vector< string > capDates_
vector< string > spreadDates_
vector< string > floorDates_
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
vector< string > rateDates_
bool subtractInflationNominalCoupons_
vector< string > capDates_
bool subtractInflationNominal_
void fromXML(XMLNode *node) override
XMLNode * toXML(XMLDocument &doc) const override
vector< double > amounts_
Position::Type callPosition_
vector< double > callPayoffs_
vector< double > callStrikes_
Position::Type putPosition_
vector< string > callStrikeDates_
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
vector< string > putPayoffDates_
QuantLib::ext::shared_ptr< CMSLegData > underlying_
vector< double > putPayoffs_
vector< string > putStrikeDates_
vector< string > callPayoffDates_
vector< double > putStrikes_
Position::Type callPosition_
vector< double > callPayoffs_
vector< double > callStrikes_
Position::Type putPosition_
vector< string > callStrikeDates_
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
vector< string > putPayoffDates_
vector< double > putPayoffs_
vector< string > putStrikeDates_
vector< string > callPayoffDates_
QuantLib::ext::shared_ptr< CMSSpreadLegData > underlying_
vector< double > putStrikes_
Serializable object holding generic trade data, reporting dimensions.
string initialPriceCurrency_
ScheduleData valuationSchedule_
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
EquityReturnType returnType_
EquityUnderlying equityUnderlying_
void fromXML(XMLNode *node) override
XMLNode * toXML(XMLDocument &doc) const override
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
vector< string > rateDates_
vector< string > gearingDates_
std::map< QuantLib::Date, double > historicalFixings_
vector< double > gearings_
ScheduleData resetSchedule_
QuantLib::Size rateCutoff_
vector< string > floorDates_
boost::optional< Period > lastRecentPeriod_
boost::optional< bool > isInArrears_
virtual void fromXML(XMLNode *node) override
vector< double > spreads_
virtual XMLNode * toXML(XMLDocument &doc) const override
std::string lastRecentPeriodCalendar_
ScheduleData fixingSchedule_
QuantLib::Size fixingDays_
vector< string > capDates_
QuantLib::Period lookback_
vector< string > spreadDates_
Serializable object holding indexing data.
void log() const
generate Boost log record to pass to corresponding sinks
std::set< std::string > indices_
const string & legNodeName() const
Serializable object holding leg data.
std::set< std::string > indices_
string notionalPaymentLag_
bool notionalFinalExchange_
vector< double > notionals_
LegData()
Default constructor.
bool indexingFromAssetLeg_
bool notionalInitialExchange_
const std::vector< Indexing > & indexing() const
std::vector< std::string > paymentDates_
virtual QuantLib::ext::shared_ptr< LegAdditionalData > initialiseConcreteLegData(const string &)
QuantLib::ext::shared_ptr< LegAdditionalData > concreteLegData_
virtual void fromXML(XMLNode *node) override
ScheduleData paymentSchedule_
virtual XMLNode * toXML(XMLDocument &doc) const override
const string & legType() const
std::vector< Indexing > indexing_
bool strictNotionalDates_
std::string paymentCalendar_
vector< string > notionalDates_
string lastPeriodDayCounter_
string paymentConvention_
std::vector< AmortizationData > amortizationData_
bool notionalAmortizingExchange_
void addFixingDate(const QuantLib::Date &fixingDate, const std::string &indexName, const QuantLib::Date &payDate=Date::maxDate(), const bool alwaysAddIfPaysOnSettlement=false, const bool mandatoryFixing=true)
void makeSchedules(const QuantLib::Date &openEndDateReplacement=QuantLib::Null< QuantLib::Date >())
void add(QuantLib::Schedule &schedule, const ScheduleData &scheduleData)
Serializable schedule data.
bool hasData() const
Check if has any dates/rules/derived schedules.
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
Utility class for Structured Trade errors, contains the Trade ID and Type.
const QuantLib::ext::shared_ptr< InstrumentWrapper > & instrument() const
Small XML Document wrapper class.
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
static void addChildren(XMLDocument &doc, XMLNode *n, const string &names, const string &name, const vector< T > &values)
static void checkNode(XMLNode *n, const string &expectedName)
static vector< XMLNode * > getChildrenNodes(XMLNode *node, const string &name)
Returns all the children with a given name.
static Real getChildValueAsDouble(XMLNode *node, const string &name, bool mandatory=false, double defaultValue=0.0)
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
static bool getChildValueAsBool(XMLNode *node, const string &name, bool mandatory=false, bool defaultValue=true)
static XMLNode * getChildNode(XMLNode *n, const string &name="")
static void addChildrenWithOptionalAttributes(XMLDocument &doc, XMLNode *n, const string &names, const string &name, const vector< T > &values, const string &attrName, const vector< string > &attrs)
static string getNodeValue(XMLNode *node)
Get a node's value.
static int getChildValueAsInt(XMLNode *node, const string &name, bool mandatory=false, int defaultValue=0)
static vector< string > getChildrenValues(XMLNode *node, const string &names, const string &name, bool mandatory=false)
static void setNodeName(XMLDocument &doc, XMLNode *node, const string &name)
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
static void appendNode(XMLNode *parent, XMLNode *child)
bool addInflationNotional_
vector< string > gearingDates_
vector< double > gearings_
vector< string > floorDates_
virtual void fromXML(XMLNode *node) override
vector< double > spreads_
virtual XMLNode * toXML(XMLDocument &doc) const override
vector< string > capDates_
vector< string > spreadDates_
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
vector< string > rateDates_
builder that returns an engine to price capped floored ibor legs
builder that returns a cms spread coupon pricer
void setCouponPricer(const Leg &leg, const boost::shared_ptr< FloatingRateCouponPricer > &)
Calendar parseCalendar(const string &s)
Convert text to QuantLib::Calendar.
QuantLib::ext::shared_ptr< FxIndex > parseFxIndex(const string &s, const Handle< Quote > &fxSpot, const Handle< YieldTermStructure > &sourceYts, const Handle< YieldTermStructure > &targetYts, const bool useConventions)
Convert std::string to QuantExt::FxIndex.
Currency parseCurrencyWithMinors(const string &s)
Convert text to QuantLib::Currency.
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
string internalIndexName(const string &indexName)
QuantLib::Real convertMinorToMajorCurrency(const std::string &s, QuantLib::Real value)
Convert a value from a minor ccy to major.
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
QuantLib::ext::shared_ptr< BondIndex > parseBondIndex(const string &name)
Convert std::string to QuantExt::BondIndex.
Position::Type parsePositionType(const std::string &s)
Convert text to QuantLib::Position::Type.
BusinessDayConvention parseBusinessDayConvention(const string &s)
Convert text to QuantLib::BusinessDayConvention.
QuantLib::CPI::InterpolationType parseObservationInterpolation(const std::string &s)
Convert string to observation interpolation.
Period parsePeriod(const string &s)
Convert text to QuantLib::Period.
bool parseBool(const string &s)
Convert text to bool.
Compounding parseCompounding(const string &s)
Convert text to QuantLib::Compounding;.
PaymentLag parsePaymentLag(const string &s)
Convert text to PaymentLag.
Real parseReal(const string &s)
Convert text to Real.
void apply_permutation_in_place(std::vector< T > &vec, const std::vector< std::size_t > &p)
Integer parseInteger(const string &s)
Convert text to QuantLib::Integer.
std::vector< std::size_t > sort_permutation(const std::vector< T > &vec, Compare &compare)
DayCounter parseDayCounter(const string &s)
Convert text to QuantLib::DayCounter.
translates between QuantLib::Index::name() and ORE names
leg data model and serialization
Classes and functions for log message handling.
#define LOG(text)
Logging Macro (Level = Notice)
#define DLOG(text)
Logging Macro (Level = Debug)
#define ALOG(text)
Logging Macro (Level = Alert)
#define WLOG(text)
Logging Macro (Level = Warning)
#define TLOG(text)
Logging Macro (Level = Data)
make functions for non-standard ibor and fixed legs
market data related utilties
QuantLib::Date fixingDate(const QuantLib::Date &d, const QuantLib::Period obsLag, const QuantLib::Frequency freq, bool interpolated)
Filter close_enough(const RandomVariable &x, const RandomVariable &y)
boost::shared_ptr< Coupon > unpackIndexedCoupon(const boost::shared_ptr< Coupon > &c)
EquityReturnType parseEquityReturnType(const std::string &str)
Leg makeOISLeg(const LegData &data, const QuantLib::ext::shared_ptr< OvernightIndex > &index, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const bool attachPricer, const QuantLib::Date &openEndDateReplacement)
vector< T > normaliseToSchedule(const vector< T > &values, const Schedule &schedule, const T &defaultValue)
vector< T > buildScheduledVectorNormalised(const vector< T > &values, const vector< string > &dates, const Schedule &schedule, const T &defaultValue, const bool checkAllValuesAppearInResult=false)
Leg makeDigitalCMSLeg(const LegData &data, const QuantLib::ext::shared_ptr< QuantLib::SwapIndex > &swapIndex, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const bool attachPricer, const QuantLib::Date &openEndDateReplacement)
Leg makeSimpleLeg(const LegData &data)
vector< double > buildAmortizationScheduleLinearToMaturity(const vector< double > ¬ionals, const Schedule &schedule, const AmortizationData &data)
vector< double > buildAmortizationScheduleFixedAmount(const vector< double > ¬ionals, const Schedule &schedule, const AmortizationData &data)
vector< double > buildAmortizationScheduleRelativeToInitialNotional(const vector< double > ¬ionals, const Schedule &schedule, const AmortizationData &data)
Real currentNotional(const Leg &leg)
std::pair< std::string, SimmCreditQualifierMapping > getCmbLegCreditQualifierMapping(const CMBLegData &ld, const QuantLib::ext::shared_ptr< ReferenceDataManager > &refData, const std::string &tradeId, const std::string &tradeType)
void applyAmortization(std::vector< Real > ¬ionals, const LegData &data, const Schedule &schedule, const bool annuityAllowed, const std::vector< Real > &rates)
vector< double > buildAmortizationScheduleRelativeToPreviousNotional(const vector< double > ¬ionals, const Schedule &schedule, const AmortizationData &data)
void applyIndexing(Leg &leg, const LegData &data, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, RequiredFixings &requiredFixings, const QuantLib::Date &openEndDateReplacement, const bool useXbsCurves)
Leg makeBMALeg(const LegData &data, const QuantLib::ext::shared_ptr< QuantExt::BMAIndexWrapper > &indexWrapper, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const QuantLib::Date &openEndDateReplacement)
Size size(const ValueType &v)
vector< double > buildAmortizationScheduleFixedAnnuity(const vector< double > ¬ionals, const vector< double > &rates, const Schedule &schedule, const AmortizationData &data, const DayCounter &dc)
Leg buildNotionalLeg(const LegData &data, const Leg &leg, RequiredFixings &requiredFixings, const QuantLib::ext::shared_ptr< Market > &market, const std::string &configuration)
Real originalNotional(const Leg &leg)
Leg makeCMBLeg(const LegData &data, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const bool attachPricer, const QuantLib::Date &openEndDateReplacement)
Leg makeYoYLeg(const LegData &data, const QuantLib::ext::shared_ptr< InflationIndex > &index, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const QuantLib::Date &openEndDateReplacement)
std::string to_string(const LocationInfo &l)
vector< T > buildScheduledVector(const vector< T > &values, const vector< string > &dates, const Schedule &schedule, const bool checkAllValuesAppearInResult=false)
Leg makeCMSSpreadLeg(const LegData &data, const QuantLib::ext::shared_ptr< QuantLib::SwapSpreadIndex > &swapSpreadIndex, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const bool attachPricer, const QuantLib::Date &openEndDateReplacement)
Leg makeDigitalCMSSpreadLeg(const LegData &data, const QuantLib::ext::shared_ptr< QuantLib::SwapSpreadIndex > &swapSpreadIndex, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const QuantLib::Date &openEndDateReplacement)
Leg makeCPILeg(const LegData &data, const QuantLib::ext::shared_ptr< ZeroInflationIndex > &index, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const QuantLib::Date &openEndDateReplacement)
Leg makeCMSLeg(const LegData &data, const QuantLib::ext::shared_ptr< QuantLib::SwapIndex > &swapIndex, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const bool attachPricer, const QuantLib::Date &openEndDateReplacement)
AmortizationType parseAmortizationType(const std::string &s)
QuantLib::ext::shared_ptr< QuantExt::CommodityIndex > parseCommodityIndex(const string &name, bool hasPrefix, const Handle< PriceTermStructure > &ts, const Calendar &cal, const bool enforceFutureIndex)
Leg makeEquityLeg(const LegData &data, const QuantLib::ext::shared_ptr< EquityIndex2 > &equityCurve, const QuantLib::ext::shared_ptr< QuantExt::FxIndex > &fxIndex, const QuantLib::Date &openEndDateReplacement)
std::string getCmbLegCreditRiskCurrency(const CMBLegData &ld, const QuantLib::ext::shared_ptr< ReferenceDataManager > &refData)
Leg makeZCFixedLeg(const LegData &data, const QuantLib::Date &openEndDateReplacement)
Leg makeIborLeg(const LegData &data, const QuantLib::ext::shared_ptr< IborIndex > &index, const QuantLib::ext::shared_ptr< EngineFactory > &engineFactory, const bool attachPricer, const QuantLib::Date &openEndDateReplacement)
bool lessThan(const string &s1, const string &s2)
Leg makeFixedLeg(const LegData &data, const QuantLib::Date &openEndDateReplacement)
boost::variant< QuantLib::Period, QuantLib::Natural > PaymentLag
Leg makeNotionalLeg(const Leg &refLeg, const bool initNomFlow, const bool finalNomFlow, const bool amortNomFlow, const Natural notionalPaymentLag, const BusinessDayConvention paymentConvention, const Calendar paymentCalendar, const bool excludeIndexing)
QuantLib::ext::shared_ptr< QuantExt::FxIndex > buildFxIndex(const string &fxIndex, const string &domestic, const string &foreign, const QuantLib::ext::shared_ptr< Market > &market, const string &configuration, bool useXbsCurves)
Leg joinLegs(const std::vector< Leg > &legs)
Leg makeNonStandardIborLeg(const QuantLib::ext::shared_ptr< IborIndex > &index, const std::vector< Date > &calcDates, const std::vector< Date > &payDatesInput, const std::vector< Date > &fixingDatesInput, const std::vector< Date > &resetDatesInput, const Size fixingDays, const std::vector< Real > ¬ionals, const std::vector< Date > ¬ionalDatesInput, const std::vector< Real > &spreadsInput, const std::vector< Date > &spreadDatesInput, const std::vector< Real > &gearingsInput, const std::vector< Date > &gearingDatesInput, const bool strictNotionalDates, const DayCounter &dayCounter, const Calendar &payCalendar, const BusinessDayConvention payConv, const Period &payLag, const bool isInArrears)
std::string securitySpecificCreditCurveName(const std::string &securityId, const std::string &creditCurveId)
Schedule makeSchedule(const ScheduleDates &data)
Leg makeNonStandardFixedLeg(const std::vector< Date > &calcDates, const std::vector< Date > &payDatesInput, const std::vector< Real > ¬ionals, const std::vector< Date > ¬ionalDatesInput, const std::vector< Real > &rates, const std::vector< Date > &rateDatesInput, const bool strictNotionalDates, const DayCounter &dayCounter, const Calendar &payCalendar, const BusinessDayConvention payConv, const Period &payLag)
@ RelativeToPreviousNotional
@ RelativeToInitialNotional
Serializable Credit Default Swap.
Reference data model and serialization.
std::string targetQualifier
Structured Trade Error class.
string conversion utilities
Utilities for sorting vectors using permutations.