24#include <ql/cashflows/simplecashflow.hpp>
25#include <ql/event.hpp>
31 const Currency& domCcy,
const Handle<YieldTermStructure>& domCurve,
const Currency& forCcy,
32 const Handle<YieldTermStructure>& forCurve,
const Handle<Quote>& spotFx,
const std::vector<Time>& bucketTimes,
33 const bool computeDelta,
const bool computeGamma,
const bool linearInZero,
34 boost::optional<bool> includeSettlementDateFlows,
const Date& settlementDate,
const Date& npvDate,
35 const bool applySimmExemptions)
36 : domCcy_(domCcy), forCcy_(forCcy), domCurve_(domCurve), forCurve_(forCurve), spotFx_(spotFx),
37 bucketTimes_(bucketTimes), computeDelta_(computeDelta), computeGamma_(computeGamma), linearInZero_(linearInZero),
38 includeSettlementDateFlows_(includeSettlementDateFlows), settlementDate_(settlementDate), npvDate_(npvDate),
39 applySimmExemptions_(applySimmExemptions) {
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");
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)));
59 std::vector<Real> payer = {
arguments_.payCurrency1 ? -1.0 : 1.0,
arguments_.payCurrency1 ? 1.0 : -1.0};
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;
69 Real domFlow = 0, forFlow = 0, domNPV = 0, forNPV = 0;
70 for (Size i = 0; i < 2; ++i) {
72 Handle<YieldTermStructure> yts;
75 else if (currencies[i] ==
forCcy_)
78 QL_FAIL(
"ccy " << currencies[i] <<
" not handled.");
80 Real npv = 0.0, bps = 0.0, simpleCashFlowNpv = 0.0;
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()) {
92 domFlow = cf.amount();
94 forFlow = cf.amount();
98 results_.additionalResults[
"npvDom"] = npv;
99 results_.value += npv + simpleCashFlowNpv;
102 results_.additionalResults[
"npvFor"] = npv;
104 fxSpot[currencies[i]] =
spotFx_->value();
105 fxSpotDelta[currencies[i]] += npv;
107 }
catch (
const std::exception& e) {
108 QL_FAIL(
"DiscountingFxForwardEngineDeltaGamma, leg " << i <<
": " << e.what());
112 results_.additionalResults[
"fxSpot"] = fxSpot;
113 results_.additionalResults[
"deltaFxSpot"] = fxSpotDelta;
116 if (npvDate == Null<Date>()) {
120 if (settlementDate == Null<Date>()) {
121 settlementDate = npvDate;
127 for (std::map<Currency, std::map<Date, Real>,
CurrencyComparator>::const_iterator i = deltaDiscountRaw.begin();
128 i != deltaDiscountRaw.end(); ++i) {
130 deltaDiscount[i->first] =
133 results_.additionalResults[
"deltaDiscount"] = deltaDiscount;
139 std::map<Currency, Matrix, CurrencyComparator> gamma;
140 for (std::vector<Currency>::const_iterator i = currencies.begin(); i != currencies.end(); ++i) {
146 results_.additionalResults[
"gamma"] = gamma;
151 if (fabs(domNPV) > fabs(forNPV) *
spotFx_->value()) {
152 results_.additionalResults[
"currentNotional"] = domFlow;
155 results_.additionalResults[
"currentNotional"] = forFlow;
const Instrument::results * results_
const std::vector< Time > bucketTimes_
DiscountingFxForwardEngineDeltaGamma(const Currency &domCcy, const Handle< YieldTermStructure > &domCurve, const Currency &forCcy, const Handle< YieldTermStructure > &forCurve, const Handle< Quote > &spotFx, const std::vector< Time > &bucketTimes=std::vector< Time >(), const bool computeDelta=false, const bool computeGamma=false, const bool linearInZero=true, boost::optional< bool > includeSettlementDateFlows=boost::none, const Date &settlementDate=Date(), const Date &npvDate=Date(), const bool applySimmExemptions=false)
void calculate() const override
bool applySimmExemptions_
Handle< YieldTermStructure > forCurve_
Handle< YieldTermStructure > domCurve_
Compare currencies by currency code.
Engine to value an FX Forward off two yield curves.
Swap engine providing analytical deltas and gammas for vanilla swaps.
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_