Skip to content

Commit 82a5adf

Browse files
author
jenkins
committed
git subrepo pull (merge) ore
subrepo: subdir: "ore" merged: "f90154ee2d" upstream: origin: "git@gitlab.acadiasoft.net:qs/ore.git" branch: "master" commit: "e777f12010" git-subrepo: version: "0.4.6" origin: "https://github.com/ingydotnet/git-subrepo" commit: "73a0129"
2 parents caf407f + e777f12 commit 82a5adf

3 files changed

Lines changed: 35 additions & 24 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#TradeId,TradeType,Maturity,MaturityTime,NPV,NpvCurrency,NPV(Base),BaseCurrency,Notional,NotionalCurrency,Notional(Base),NettingSet,CounterParty
2-
Ascot,Ascot,2026-02-03,7.435616,996814.000699,EUR,1165610.845653,USD,1000000.00,EUR,1169336.35,,CPTY_C
3-
AssetSwap,Swap,2026-02-03,7.435616,-42567.908166,EUR,-49776.202381,USD,1000000.00,EUR,1169336.35,,CPTY_C
2+
Ascot,Ascot,2026-02-03,7.435616,34686.961931,EUR,40560.725473,USD,1000000.00,EUR,1169336.35,,CPTY_C
3+
AssetSwap,Swap,2026-02-03,7.435616,-4674.890778,EUR,-5466.519722,USD,1000000.00,EUR,1169336.35,,CPTY_C
44
ConvertibleBond,ConvertibleBond,2026-02-03,7.435616,1039381.908865,EUR,1215387.048035,USD,1.00,EUR,1.17,,CPTY_C

Examples/Example_48/Input/portfolio.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
<Index>EUR-EURIBOR-3M</Index>
5353
<!-- The recall spread goes here. -->
5454
<Spreads>
55-
<Spread>0.02</Spread>
55+
<Spread>0.025</Spread>
5656
</Spreads>
5757
</FloatingLegData>
5858
<ScheduleData>
@@ -143,7 +143,7 @@
143143
<Index>EUR-EURIBOR-3M</Index>
144144
<!-- The recall spread goes here. -->
145145
<Spreads>
146-
<Spread>0.02</Spread>
146+
<Spread>0.025</Spread>
147147
</Spreads>
148148
</FloatingLegData>
149149
<ScheduleData>

QuantExt/qle/pricingengines/intrinsicascotengine.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
*/
1818

1919
#include <algorithm>
20-
#include <qle/pricingengines/binomialconvertibleengine.hpp>
21-
#include <qle/pricingengines/intrinsicascotengine.hpp>
2220
#include <ql/cashflows/cashflows.hpp>
2321
#include <ql/cashflows/iborcoupon.hpp>
2422
#include <ql/cashflows/simplecashflow.hpp>
23+
#include <qle/pricingengines/binomialconvertibleengine.hpp>
24+
#include <qle/pricingengines/intrinsicascotengine.hpp>
2525

2626
namespace QuantExt {
2727

@@ -38,31 +38,42 @@ void IntrinsicAscotEngine::calculate() const {
3838
Real bondPrice = arguments_.bondQuantity * bond.NPV();
3939

4040
Date referenceDate = discountCurve_->referenceDate();
41+
Date settlementDate = bond.calendar().advance(referenceDate, bond.settlementDays(), QuantLib::Days);
4142

42-
Leg notional;
43-
auto coupon = boost::dynamic_pointer_cast<QuantLib::Coupon>(bond.cashflows()[0]);
44-
QL_REQUIRE(coupon, "expected non-coupon legs");
45-
double initFlowAmt = coupon->nominal();
46-
Date initDate = coupon->accrualStartDate();
47-
initDate = bond.calendar().adjust(initDate, Following);
48-
if (initFlowAmt != 0)
49-
notional.push_back(boost::shared_ptr<CashFlow>(new SimpleCashFlow(initFlowAmt, initDate)));
43+
Real currentNotional = Null<Real>();
44+
for (auto const& c : bond.cashflows()) {
45+
if (auto coupon = boost::dynamic_pointer_cast<QuantLib::Coupon>(c)) {
46+
currentNotional = coupon->nominal();
47+
if (c->date() > referenceDate)
48+
break;
49+
}
50+
}
5051

51-
Real upfrontPayment = CashFlows::npv(notional, **discountCurve_, false, referenceDate, referenceDate);
52+
QL_REQUIRE(currentNotional != Null<Real>(), "IntrinsicAscotEngine::calculate(): could not determine current "
53+
"notional, underlying bond must have at least one coupon");
54+
55+
Leg upfrontLeg;
56+
upfrontLeg.push_back(boost::make_shared<SimpleCashFlow>(currentNotional, settlementDate));
57+
Real upfrontLegNpv = CashFlows::npv(upfrontLeg, **discountCurve_, false, referenceDate, referenceDate);
5258

5359
// includes redemption flows
54-
Real assetLeg = CashFlows::npv(bond.cashflows(), **discountCurve_, false, referenceDate, referenceDate);
60+
Real assetLegNpv = CashFlows::npv(bond.cashflows(), **discountCurve_, false, referenceDate, referenceDate);
5561

56-
Real redemptionLeg = CashFlows::npv(bond.redemptions(), **discountCurve_, false, referenceDate, referenceDate);
62+
Real redemptionLegNpv = CashFlows::npv(bond.redemptions(), **discountCurve_, false, referenceDate, referenceDate);
5763

5864
// multiplied by bondNotional already
59-
Real fundingLeg = CashFlows::npv(arguments_.fundingLeg, **discountCurve_, true, referenceDate, referenceDate);
60-
61-
Real X = arguments_.bondQuantity * (upfrontPayment + assetLeg - redemptionLeg) - fundingLeg;
62-
63-
boost::shared_ptr<StrikedTypePayoff> payoff(new PlainVanillaPayoff(arguments_.callPut, X));
64-
65-
results_.value = (*payoff)(bondPrice);
65+
Real fundingLegNpv = CashFlows::npv(arguments_.fundingLeg, **discountCurve_, true, referenceDate, referenceDate);
66+
67+
Real strike = arguments_.bondQuantity * (upfrontLegNpv + assetLegNpv - redemptionLegNpv) - fundingLegNpv;
68+
69+
results_.value = PlainVanillaPayoff(arguments_.callPut, strike)(bondPrice);
70+
results_.additionalResults["bondPrice"] = bondPrice;
71+
results_.additionalResults["strike"] = strike;
72+
results_.additionalResults["fundingLegNpv"] = fundingLegNpv;
73+
results_.additionalResults["redemptionLegNpv"] = redemptionLegNpv * arguments_.bondQuantity;
74+
results_.additionalResults["assetLegNpv"] = assetLegNpv * arguments_.bondQuantity;
75+
results_.additionalResults["upfrontLegNpv"] = upfrontLegNpv * arguments_.bondQuantity;
76+
results_.additionalResults["bondQuantity"] = arguments_.bondQuantity;
6677
}
6778

6879
} // namespace QuantExt

0 commit comments

Comments
 (0)