33#include <boost/algorithm/string.hpp>
34#include <ql/currencies/exchangeratemanager.hpp>
35#include <ql/math/functional.hpp>
36#include <ql/quotes/derivedquote.hpp>
37#include <ql/quotes/simplequote.hpp>
46 const Handle<YieldTermStructure>& targetYts, Natural fixingDays,
47 const Calendar& fixingCalendar)
48 : spotQuote_(spotQuote), sourceYts_(sourceYts), targetYts_(targetYts), fixingDays_(fixingDays),
49 fixingCalendar_(fixingCalendar) {
56 QL_ENSURE(
isValid(),
"invalid FxRateQuote");
73 const Handle<YieldTermStructure>& targetYts, Natural fixingDays,
74 const Calendar& fixingCalendar)
75 : todaysQuote_(todaysQuote), sourceYts_(sourceYts), targetYts_(targetYts), fixingDays_(fixingDays),
76 fixingCalendar_(fixingCalendar) {
83 QL_ENSURE(
isValid(),
"invalid FxSpotQuote");
101FxIndex::FxIndex(
const std::string& familyName, Natural fixingDays,
const Currency& source,
const Currency& target,
102 const Calendar& fixingCalendar,
const Handle<YieldTermStructure>& sourceYts,
103 const Handle<YieldTermStructure>& targetYts,
bool fixingTriangulation)
104 : familyName_(familyName), fixingDays_(fixingDays), sourceCurrency_(source), targetCurrency_(target),
105 sourceYts_(sourceYts), targetYts_(targetYts), useQuote_(false), fixingCalendar_(fixingCalendar),
106 fixingTriangulation_(fixingTriangulation) {
111FxIndex::FxIndex(
const std::string& familyName, Natural fixingDays,
const Currency& source,
const Currency& target,
112 const Calendar& fixingCalendar,
const Handle<Quote> fxSpot,
113 const Handle<YieldTermStructure>& sourceYts,
const Handle<YieldTermStructure>& targetYts,
114 bool fixingTriangulation)
115 : familyName_(familyName), fixingDays_(fixingDays), sourceCurrency_(source), targetCurrency_(target),
116 sourceYts_(sourceYts), targetYts_(targetYts), fxSpot_(fxSpot), useQuote_(true), fixingCalendar_(fixingCalendar),
117 fixingTriangulation_(fixingTriangulation) {
123 std::ostringstream tmp;
129 registerWith(IndexManager::instance().notifier(
name()));
142 Handle<Quote> tmpQuote;
144 tmpQuote = Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(
162 Date today = Settings::instance().evaluationDate();
164 Real result = Null<Real>();
166 if (adjustedFixingDate > today || (adjustedFixingDate == today && forecastTodaysFixing))
169 if (result == Null<Real>()) {
170 if (adjustedFixingDate < today || Settings::instance().enforcesTodaysHistoricFixings()) {
174 QL_REQUIRE(result != Null<Real>(),
"Missing " <<
name() <<
" fixing for " << adjustedFixingDate);
182 if (result == Null<Real>())
192 "FxIndex::forecastFixing(): null term structure set to this instance of " <<
name());
199 QL_REQUIRE(!
fxSpot_.empty(),
"FxIndex::forecastFixing(): fx quote required for " <<
name());
204 DayCounter dc = Actual365Fixed();
211 Real spotTime = dc.yearFraction(refDate, spotValueDate);
212 Real forwardTime = spotTime + fixingTime;
214 QL_REQUIRE(forwardTime > 0.0 ||
close_enough(forwardTime, 0.0),
215 "FxIndex::forecastFixing(" << fixingTime <<
"): forwardTime (" << forwardTime <<
") is negative for "
233 QL_REQUIRE(!
fxSpot_.empty(),
"FxIndex::forecastFixing(): fx quote required for " <<
name());
245 QL_REQUIRE(fixingValueDate >= refValueDate,
"value date for requested fixing as of "
247 <<
") must be greater or equal to today's fixing value date ("
248 << refValueDate <<
") for " <<
name());
251 Real forward = rate *
sourceYts_->discount(fixingValueDate) *
targetYts_->discount(refValueDate) /
257QuantLib::ext::shared_ptr<FxIndex>
FxIndex::clone(
const Handle<Quote> fxQuote,
const Handle<YieldTermStructure>& sourceYts,
258 const Handle<YieldTermStructure>& targetYts,
const string& familyName) {
260 Handle<YieldTermStructure> source = sourceYts.empty() ?
sourceYts_ : sourceYts;
261 Handle<YieldTermStructure> target = targetYts.empty() ?
targetYts_ : targetYts;
285 "FxIndex::valueDate(): " <<
fixingDate <<
" is not a valid fixing date for " <<
name()
296 if (
fixing != Null<Real>())
302 if (IndexManager::instance().hasHistoricalFixing(revName,
fixingDate))
303 return 1.0 / IndexManager::instance().getHistory(revName)[
fixingDate];
318 vector<string> availIndexes = IndexManager::instance().histories();
319 for (
auto i : availIndexes) {
323 if (
fixing != Null<Real>()) {
326 string keyDomestic = i.substr(l - 7, 3);
327 string keyForeign = i.substr(l - 3);
331 if (domestic == keyDomestic) {
334 string forName =
familyName_ +
" " + foreign +
"/" + keyForeign;
335 if (IndexManager::instance().hasHistoricalFixing(forName,
fixingDate)) {
336 Real forFixing = IndexManager::instance().getHistory(forName)[
fixingDate];
337 return fixing / forFixing;
341 forName =
familyName_ +
" " + keyForeign +
"/" + foreign;
342 if (IndexManager::instance().hasHistoricalFixing(forName,
fixingDate)) {
343 Real forFixing = IndexManager::instance().getHistory(forName)[
fixingDate];
344 return fixing * forFixing;
348 if (domestic == keyForeign) {
351 string forName =
familyName_ +
" " + foreign +
"/" + keyDomestic;
352 if (IndexManager::instance().hasHistoricalFixing(forName,
fixingDate)) {
353 Real forFixing = IndexManager::instance().getHistory(forName)[
fixingDate];
354 return 1 / (
fixing * forFixing);
358 forName =
familyName_ +
" " + keyDomestic +
"/" + foreign;
359 if (IndexManager::instance().hasHistoricalFixing(forName,
fixingDate)) {
360 Real forFixing = IndexManager::instance().getHistory(forName)[
fixingDate];
361 return forFixing /
fixing;
const Handle< Quote > fxQuote(bool withSettlementLag=false) const
fxQuote returns instantaneous Quote by default, otherwise settlement after fixingDays
QuantLib::ext::shared_ptr< FxIndex > clone(const Handle< Quote > fxQuote=Handle< Quote >(), const Handle< YieldTermStructure > &sourceYts=Handle< YieldTermStructure >(), const Handle< YieldTermStructure > &targetYts=Handle< YieldTermStructure >(), const std::string &familyName=std::string())
clone the index, the clone will be linked to the provided handles
virtual Real forecastFixing(const Time &fixingTime) const override
It can be overridden to implement particular conventions.
Calendar fixingCalendar() const override
const Handle< Quote > fxSpot_
bool fixingTriangulation_
const Handle< YieldTermStructure > targetYts_
std::string name() const override
FxIndex(const std::string &familyName, Natural fixingDays, const Currency &source, const Currency &target, const Calendar &fixingCalendar, const Handle< YieldTermStructure > &sourceYts=Handle< YieldTermStructure >(), const Handle< YieldTermStructure > &targetYts=Handle< YieldTermStructure >(), bool fixingTriangulation=false)
virtual Date valueDate(const Date &fixingDate) const
bool isValidFixingDate(const Date &fixingDate) const override
const Handle< YieldTermStructure > sourceYts_
Real pastFixing(const Date &fixingDate) const override
returns a past fixing at the given date
Date fixingDate(const Date &valueDate) const
std::string familyName() const
Real fixing(const Date &fixingDate, bool forecastTodaysFixing=false) const override
FxRateQuote(Handle< Quote > spotQuote, const Handle< YieldTermStructure > &sourceYts, const Handle< YieldTermStructure > &targetYts, Natural fixingDays, const Calendar &fixingCalendar)
if sourceYts, targetYts are not given, the non-discounted spot quote will be returned as a fallback
const Handle< Quote > spotQuote_
const Handle< YieldTermStructure > targetYts_
const Handle< YieldTermStructure > sourceYts_
Real value() const override
bool isValid() const override
FxSpotQuote(Handle< Quote > todaysQuote, const Handle< YieldTermStructure > &sourceYts, const Handle< YieldTermStructure > &targetYts, Natural fixingDays, const Calendar &fixingCalendar)
const Handle< YieldTermStructure > targetYts_
const Handle< Quote > todaysQuote_
const Handle< YieldTermStructure > sourceYts_
Real value() const override
bool isValid() const override
Filter close_enough(const RandomVariable &x, const RandomVariable &y)