Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
fxaverageforward.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2022 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19#include <boost/make_shared.hpp>
27#include <ql/cashflows/simplecashflow.hpp>
29
30namespace ore {
31namespace data {
32
33void FxAverageForward::build(const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory) {
34
35 // ISDA taxonomy
36 additionalData_["isdaAssetClass"] = string("Foreign Exchange");
37 additionalData_["isdaBaseProduct"] = string(settlement_ == "Cash" ? "NDF" : "Forward");
38 additionalData_["isdaSubProduct"] = string("");
39 additionalData_["isdaTransaction"] = string("");
40
41 LOG("FxAverageForward::build() called");
42 QL_REQUIRE(!settlementCurrency_.empty(), "settlement currency must not be blank");
43 QL_REQUIRE(!referenceCurrency_.empty(), "reference currency must not be blank");
44 QL_REQUIRE(!fxIndex_.empty(), "fx index must not be blank");
45 Currency refCcy = parseCurrency(referenceCurrency_);
46 Currency payCcy = parseCurrency(settlementCurrency_);
47 Date payDate = parseDate(paymentDate_);
48 Schedule observationSchedule = makeSchedule(observationDates_);
49 QL_REQUIRE(payDate >= observationSchedule.dates().back(),
50 "payment date >= last observation date required");
51
52 QL_REQUIRE(!fxIndex_.empty(), "FX settlement index must be specified for averaging forwards");
53 QuantLib::ext::shared_ptr<QuantExt::FxIndex> fxIndex = buildFxIndex(fxIndex_, payCcy.code(), refCcy.code(), engineFactory->market(),
54 engineFactory->configuration(MarketContext::pricing));
55 for (const auto& date : observationSchedule.dates()) {
56 if (date <= Settings::instance().evaluationDate())
58 }
59
60
61 // Set up Legs
62 inverted_ = parseFxIndex(fxIndex_)->targetCurrency() != payCcy;
63 legs_ = {{QuantLib::ext::make_shared<SimpleCashFlow>(settlementNotional_, payDate)},
64 {QuantLib::ext::make_shared<QuantExt::AverageFXLinkedCashFlow>(payDate, observationSchedule.dates(),
68
69 // Set up instrument and engine
70 QuantLib::ext::shared_ptr<QuantLib::Swap> swap(new QuantLib::Swap(legs_, legPayers_));
71 QuantLib::ext::shared_ptr<EngineBuilder> builder = engineFactory->builder("Swap");
72 QuantLib::ext::shared_ptr<SwapEngineBuilderBase> swapBuilder = QuantLib::ext::dynamic_pointer_cast<SwapEngineBuilderBase>(builder);
73 QL_REQUIRE(swapBuilder, "No Builder found for Swap " << id());
74 swap->setPricingEngine(swapBuilder->engine(payCcy, std::string(), std::string()));
75 setSensitivityTemplate(*swapBuilder);
76 instrument_.reset(new VanillaInstrument(swap));
77
81 maturity_ = payDate;
82
83 LOG("FxAverageForward::build() done");
84}
85
86const std::map<std::string, boost::any>& FxAverageForward::additionalData() const {
87 additionalData_.clear();
88 additionalData_["settlementNotional"] = settlementNotional_;
89 additionalData_["settlementCurrency"] = settlementCurrency_;
90 additionalData_["referenceCurrency"] = referenceCurrency_;
91 additionalData_["referenceNotional"] = referenceNotional_;
92 if (legs_.size() == 2 && !legs_[1].empty()) {
93 auto avg = QuantLib::ext::dynamic_pointer_cast<QuantExt::AverageFXLinkedCashFlow>(legs_[1].front());
94 if (avg) {
95 for (auto [date, value] : avg->fixings())
96 additionalData_["fixing_" + ore::data::to_string(date)] = value;
97 }
98 additionalData_["average rate"] = inverted_ ? 1.0 / avg->fxRate() : avg->fxRate();
99 additionalData_["effective rate"] = avg->fxRate();
100 }
101 return additionalData_;
102}
103
105 Trade::fromXML(node);
106 XMLNode* fxNode = XMLUtils::getChildNode(node, "FxAverageForwardData");
107 QL_REQUIRE(fxNode, "No FxAverageForwardData Node");
108 paymentDate_ = XMLUtils::getChildValue(fxNode, "PaymentDate", true);
109 XMLNode* tmp = XMLUtils::getChildNode(fxNode, "ObservationDates");
110 QL_REQUIRE(tmp, "No ObservationDates provided in FxAverageForwardData");
112 fixedPayer_ = XMLUtils::getChildValueAsBool(fxNode, "FixedPayer", true);
113 referenceCurrency_ = XMLUtils::getChildValue(fxNode, "ReferenceCurrency", true);
114 referenceNotional_ = XMLUtils::getChildValueAsDouble(fxNode, "ReferenceNotional", true);
115 settlementCurrency_ = XMLUtils::getChildValue(fxNode, "SettlementCurrency", true);
116 settlementNotional_ = XMLUtils::getChildValueAsDouble(fxNode, "SettlementNotional", true);
117 fxIndex_ = XMLUtils::getChildValue(fxNode, "FXIndex", true);
118 settlement_ = XMLUtils::getChildValue(fxNode, "Settlement", false);
119 if (settlement_ == "")
120 settlement_ = "Cash";
121}
122
124 XMLNode* node = Trade::toXML(doc);
125 XMLNode* fxNode = doc.allocNode("FxAverageForwardData");
126 XMLUtils::appendNode(node, fxNode);
127
128 XMLNode* schedNode = observationDates_.toXML(doc);
129 XMLUtils::setNodeName(doc, schedNode, "ObservationDates");
130 XMLUtils::appendNode(fxNode, schedNode);
131
132 XMLUtils::addChild(doc, fxNode, "PaymentDate", paymentDate_);
133 XMLUtils::addChild(doc, fxNode, "FixedPayer", std::to_string(fixedPayer_));
134 XMLUtils::addChild(doc, fxNode, "ReferenceCurrency", referenceCurrency_);
135 XMLUtils::addChild(doc, fxNode, "ReferenceNotional", referenceNotional_);
136 XMLUtils::addChild(doc, fxNode, "SettlementCurrency", settlementCurrency_);
137 XMLUtils::addChild(doc, fxNode, "SettlementNotional", settlementNotional_);
138 XMLUtils::addChild(doc, fxNode, "FXIndex", fxIndex_);
139 XMLUtils::addChild(doc, fxNode, "Settlement", settlement_);
140
141 return node;
142}
143} // namespace data
144} // namespace ore
Engine builder for Swaps.
virtual void fromXML(XMLNode *node) override
virtual XMLNode * toXML(XMLDocument &doc) const override
std::string fxIndex_
Needed for past fixings.
const std::string & fxIndex() const
void build(const QuantLib::ext::shared_ptr< EngineFactory > &) override
Build QuantLib/QuantExt instrument, link pricing engine.
const std::map< std::string, boost::any > & additionalData() const override
returns all additional data returned by the trade once built
void addFixingDate(const QuantLib::Date &fixingDate, const std::string &indexName, const QuantLib::Date &payDate=Date::maxDate(), const bool alwaysAddIfPaysOnSettlement=false, const bool mandatoryFixing=true)
virtual void fromXML(XMLNode *node) override
Definition: schedule.cpp:179
virtual XMLNode * toXML(XMLDocument &doc) const override
Definition: schedule.cpp:198
string npvCurrency_
Definition: trade.hpp:201
std::vector< bool > legPayers_
Definition: trade.hpp:200
std::vector< string > legCurrencies_
Definition: trade.hpp:199
std::vector< QuantLib::Leg > legs_
Definition: trade.hpp:198
QuantLib::Real notional_
Definition: trade.hpp:202
virtual void fromXML(XMLNode *node) override
Definition: trade.cpp:34
void setSensitivityTemplate(const EngineBuilder &builder)
Definition: trade.cpp:295
virtual XMLNode * toXML(XMLDocument &doc) const override
Definition: trade.cpp:46
RequiredFixings requiredFixings_
Definition: trade.hpp:223
QuantLib::ext::shared_ptr< InstrumentWrapper > instrument_
Definition: trade.hpp:197
string notionalCurrency_
Definition: trade.hpp:203
std::map< std::string, boost::any > additionalData_
Definition: trade.hpp:224
Vanilla Instrument Wrapper.
Small XML Document wrapper class.
Definition: xmlutils.hpp:65
XMLNode * allocNode(const string &nodeName)
util functions that wrap rapidxml
Definition: xmlutils.cpp:132
static Real getChildValueAsDouble(XMLNode *node, const string &name, bool mandatory=false, double defaultValue=0.0)
Definition: xmlutils.cpp:286
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
Definition: xmlutils.cpp:277
static bool getChildValueAsBool(XMLNode *node, const string &name, bool mandatory=false, bool defaultValue=true)
Definition: xmlutils.cpp:296
static XMLNode * getChildNode(XMLNode *n, const string &name="")
Definition: xmlutils.cpp:387
static void setNodeName(XMLDocument &doc, XMLNode *node, const string &name)
Definition: xmlutils.cpp:478
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
Definition: xmlutils.cpp:181
static void appendNode(XMLNode *parent, XMLNode *child)
Definition: xmlutils.cpp:406
SafeStack< ValueType > value
Pricing Engine Factory.
Fx Average Forward data model and serialization.
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.
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
Definition: parsers.cpp:51
Currency parseCurrency(const string &s)
Convert text to QuantLib::Currency.
Definition: parsers.cpp:290
Classes and functions for log message handling.
@ data
Definition: log.hpp:77
#define LOG(text)
Logging Macro (Level = Notice)
Definition: log.hpp:552
market data related utilties
std::string to_string(const LocationInfo &l)
Definition: ast.cpp:28
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)
Definition: marketdata.cpp:137
Schedule makeSchedule(const ScheduleDates &data)
Definition: schedule.cpp:263
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Map text representations to QuantLib/QuantExt types.
XML utility functions.