45 {
46
47 QL_REQUIRE(!
domCurve_.empty(),
"domestic curve is empty");
48 QL_REQUIRE(!
forCurve_.empty(),
"foreign curve is empty");
49 QL_REQUIRE(!
spotFx_.empty(),
"FX quote is empty");
50
51
52
53 std::vector<Leg> legs;
54 legs.push_back(Leg(1, QuantLib::ext::make_shared<SimpleCashFlow>(
arguments_.nominal1,
arguments_.maturityDate)));
55 legs.push_back(Leg(1, QuantLib::ext::make_shared<SimpleCashFlow>(
arguments_.nominal2,
arguments_.maturityDate)));
56
58
59 std::vector<Real> payer = {
arguments_.payCurrency1 ? -1.0 : 1.0,
arguments_.payCurrency1 ? 1.0 : -1.0};
60
62
63 std::map<Currency, std::map<Date, Real>, CurrencyComparator> deltaDiscountRaw, gammaDiscountRaw;
64 std::map<Currency, Real, CurrencyComparator> fxSpot, fxSpotDelta;
65 std::map<Date, Real> empty;
66 std::map<std::pair<Date, Date>, Real> empty2;
67 Real empty3 = 0.0;
68
69 Real domFlow = 0, forFlow = 0, domNPV = 0, forNPV = 0;
70 for (Size i = 0; i < 2; ++i) {
71 try {
72 Handle<YieldTermStructure> yts;
75 else if (currencies[i] ==
forCcy_)
77 else {
78 QL_FAIL("ccy " << currencies[i] << " not handled.");
79 }
80 Real npv = 0.0, bps = 0.0, simpleCashFlowNpv = 0.0;
81 detail::NpvDeltaGammaCalculator calc(
83 empty, gammaDiscountRaw[currencies[i]], empty2, empty2, empty, empty3,
85 for (Size ii = 0; ii < legs[i].size(); ++ii) {
86 CashFlow& cf = *legs[i][ii];
87 if (cf.date() <= yts->referenceDate()) {
88 continue;
89 }
90 cf.accept(calc);
92 domFlow = cf.amount();
94 forFlow = cf.amount();
95 }
97 domNPV = npv;
98 results_.additionalResults[
"npvDom"] = npv;
99 results_.value += npv + simpleCashFlowNpv;
100 } else {
101 forNPV = npv;
102 results_.additionalResults[
"npvFor"] = npv;
104 fxSpot[currencies[i]] =
spotFx_->value();
105 fxSpotDelta[currencies[i]] += npv;
106 }
107 } catch (const std::exception& e) {
108 QL_FAIL("DiscountingFxForwardEngineDeltaGamma, leg " << i << ": " << e.what());
109 }
110 }
111
112 results_.additionalResults[
"fxSpot"] = fxSpot;
113 results_.additionalResults[
"deltaFxSpot"] = fxSpotDelta;
114
116 if (npvDate == Null<Date>()) {
118 }
120 if (settlementDate == Null<Date>()) {
121 settlementDate = npvDate;
122 }
123
124
126 std::map<Currency, std::vector<Real>, CurrencyComparator> deltaDiscount;
127 for (std::map<Currency, std::map<Date, Real>, CurrencyComparator>::const_iterator i = deltaDiscountRaw.begin();
128 i != deltaDiscountRaw.end(); ++i) {
130 deltaDiscount[i->first] =
132 }
133 results_.additionalResults[
"deltaDiscount"] = deltaDiscount;
135 }
136
137
139 std::map<Currency, Matrix, CurrencyComparator> gamma;
140 for (std::vector<Currency>::const_iterator i = currencies.begin(); i != currencies.end(); ++i) {
144 gamma[*i] = tmp;
145 }
146 results_.additionalResults[
"gamma"] = gamma;
148 }
149
150
151 if (fabs(domNPV) > fabs(forNPV) *
spotFx_->value()) {
152 results_.additionalResults[
"currentNotional"] = domFlow;
154 } else {
155 results_.additionalResults[
"currentNotional"] = forFlow;
157 }
158
159}
const Instrument::results * results_
Matrix rebucketGammas(const std::vector< Time > &gammaTimes, const std::map< Date, Real > &gammaDscRaw, std::map< std::pair< Date, Date >, Real > &gammaForward, std::map< std::pair< Date, Date >, Real > &gammaDscFwd, const bool forceFullMatrix, const Date &referenceDate, const DayCounter &dc, const bool linearInZero)
std::vector< Real > rebucketDeltas(const std::vector< Time > &deltaTimes, const std::map< Date, Real > &deltaRaw, const Date &referenceDate, const DayCounter &dc, const bool linearInZero)
Swap::arguments * arguments_