QuantLib: a free/open-source library for quantitative finance
Fully annotated sources - version 1.32
Loading...
Searching...
No Matches
exchangeratemanager.cpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2004, 2005, 2006, 2007, 2008 StatPro Italia srl
5 Copyright (C) 2004 Decillion Pty(Ltd)
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21#include <ql/currencies/exchangeratemanager.hpp>
22#include <ql/currencies/europe.hpp>
23#include <ql/currencies/america.hpp>
24#include <ql/settings.hpp>
25#include <algorithm>
26
27namespace QuantLib {
28
29 namespace {
30
31 struct valid_at {
32 Date d;
33 explicit valid_at(const Date& d) : d(d) {}
34 bool operator()(const ExchangeRateManager::Entry& e) const {
35 return d >= e.startDate && d <= e.endDate;
36 }
37 };
38
39 }
40
43 }
44
46 const Date& startDate,
47 const Date& endDate) {
48 Key k = hash(rate.source(), rate.target());
49 data_[k].emplace_front(rate,startDate,endDate);
50 }
51
53 const Currency& target,
54 Date date,
55 ExchangeRate::Type type) const {
56
57 if (source == target)
58 return ExchangeRate(source,target,1.0);
59
60 if (date == Date())
62
63 if (type == ExchangeRate::Direct) {
64 return directLookup(source,target,date);
65 } else if (!source.triangulationCurrency().empty()) {
66 const Currency& link = source.triangulationCurrency();
67 if (link == target)
68 return directLookup(source,link,date);
69 else
70 return ExchangeRate::chain(directLookup(source,link,date),
71 lookup(link,target,date));
72 } else if (!target.triangulationCurrency().empty()) {
73 const Currency& link = target.triangulationCurrency();
74 if (source == link)
75 return directLookup(link,target,date);
76 else
77 return ExchangeRate::chain(lookup(source,link,date),
78 directLookup(link,target,date));
79 } else {
80 return smartLookup(source,target,date);
81 }
82 }
83
85 data_.clear();
87 }
88
90 const Currency& c1, const Currency& c2) const {
91 return Key(std::min(c1.numericCode(),c2.numericCode()))*1000
92 + Key(std::max(c1.numericCode(),c2.numericCode()));
93 }
94
96 const Currency& c) const {
97 return c.numericCode() == k % 1000 || c.numericCode() == k/1000;
98 }
99
101 // currencies obsoleted by Euro
103 Date(1,January,1999), Date::maxDate());
105 Date(1,January,1999), Date::maxDate());
107 Date(1,January,1999), Date::maxDate());
109 Date(1,January,1999), Date::maxDate());
111 Date(1,January,1999), Date::maxDate());
113 Date(1,January,1999), Date::maxDate());
115 Date(1,January,2001), Date::maxDate());
116 add(ExchangeRate(EURCurrency(), IEPCurrency(), 0.787564),
117 Date(1,January,1999), Date::maxDate());
119 Date(1,January,1999), Date::maxDate());
121 Date(1,January,1999), Date::maxDate());
123 Date(1,January,1999), Date::maxDate());
125 Date(1,January,1999), Date::maxDate());
126 // other obsoleted currencies
127 add(ExchangeRate(TRYCurrency(), TRLCurrency(), 1000000.0),
128 Date(1,January,2005), Date::maxDate());
130 Date(1,July,2005), Date::maxDate());
131 add(ExchangeRate(PENCurrency(), PEICurrency(), 1000000.0),
132 Date(1,July,1991), Date::maxDate());
134 Date(1,February,1985), Date::maxDate());
135 }
136
138 const Currency& target,
139 const Date& date) const {
140 if (const ExchangeRate* rate = fetch(source,target,date))
141 return *rate;
142 else
143 QL_FAIL("no direct conversion available from "
144 << source.code() << " to " << target.code()
145 << " for " << date);
146 }
147
149 const Currency& source,
150 const Currency& target,
151 const Date& date,
152 std::list<Integer> forbidden) const {
153 // direct exchange rates are preferred.
154 if (const ExchangeRate* direct = fetch(source,target,date))
155 return *direct;
156
157 // if none is found, turn to smart lookup. The source currency
158 // is forbidden to subsequent lookups in order to avoid cycles.
159 forbidden.push_back(source.numericCode());
160 std::map<Key, std::list<Entry> >::const_iterator i;
161 for (i = data_.begin(); i != data_.end(); ++i) {
162 // we look for exchange-rate data which involve our source
163 // currency...
164 if (hashes(i->first, source) && !(i->second.empty())) {
165 // ...whose other currency is not forbidden...
166 const Entry& e = i->second.front();
167 const Currency& other =
168 source == e.rate.source() ?
169 e.rate.target() : e.rate.source();
170 if (std::find(forbidden.begin(),forbidden.end(),
171 other.numericCode()) == forbidden.end()) {
172 // ...and which carries information for the requested date.
173 if (const ExchangeRate* head = fetch(source,other,date)) {
174 // if we can get to the target from here...
175 try {
176 ExchangeRate tail = smartLookup(other,target,date,
177 forbidden);
178 // ..we're done.
179 return ExchangeRate::chain(*head,tail);
180 } catch (Error&) {
181 // otherwise, we just discard this rate.
182 ;
183 }
184 }
185 }
186 }
187 }
188 // if the loop completed, we have no way to return the requested rate.
189 QL_FAIL("no conversion available from "
190 << source.code() << " to " << target.code()
191 << " for " << date);
192 }
193
195 const Currency& target,
196 const Date& date) const {
197 const std::list<Entry>& rates = data_[hash(source,target)];
198 auto i = std::find_if(rates.begin(), rates.end(), valid_at(date));
199 return i == rates.end() ? (const ExchangeRate*)nullptr : &(i->rate);
200 }
201
202}
203
Austrian shilling.
Definition: europe.hpp:330
Belgian franc.
Definition: europe.hpp:343
Currency specification
Definition: currency.hpp:36
const std::string & code() const
ISO 4217 three-letter code, e.g, "USD".
Definition: currency.hpp:142
bool empty() const
is this a usable instance?
Definition: currency.hpp:177
Integer numericCode() const
ISO 4217 numeric code, e.g, "840".
Definition: currency.hpp:147
const Currency & triangulationCurrency() const
currency used for triangulated exchange when required
Definition: currency.hpp:181
Deutsche mark.
Definition: europe.hpp:369
Concrete date class.
Definition: date.hpp:125
static Date maxDate()
latest allowed date
Definition: date.cpp:771
Spanish peseta.
Definition: europe.hpp:382
European Euro.
Definition: europe.hpp:123
Base error class.
Definition: errors.hpp:39
exchange rate between two currencies
const Currency & target() const
the target currency.
static ExchangeRate chain(const ExchangeRate &r1, const ExchangeRate &r2)
chain two exchange rates
const Currency & source() const
the source currency.
void add(const ExchangeRate &, const Date &startDate=Date::minDate(), const Date &endDate=Date::maxDate())
Add an exchange rate.
ExchangeRate lookup(const Currency &source, const Currency &target, Date date=Date(), ExchangeRate::Type type=ExchangeRate::Derived) const
ExchangeRate smartLookup(const Currency &source, const Currency &target, const Date &date, std::list< Integer > forbiddenCodes=std::list< Integer >()) const
std::map< Key, std::list< Entry > > data_
ExchangeRate directLookup(const Currency &source, const Currency &target, const Date &date) const
bool hashes(Key, const Currency &) const
Key hash(const Currency &, const Currency &) const
void clear()
remove the added exchange rates
const ExchangeRate * fetch(const Currency &source, const Currency &target, const Date &date) const
Finnish markka.
Definition: europe.hpp:395
French franc.
Definition: europe.hpp:408
Greek drachma.
Definition: europe.hpp:421
Italian lira.
Definition: europe.hpp:460
Luxembourg franc.
Definition: europe.hpp:473
Dutch guilder.
Definition: europe.hpp:499
Peruvian sol.
Definition: america.hpp:140
Peruvian inti.
Definition: america.hpp:126
Peruvian nuevo sol.
Definition: america.hpp:112
Portuguese escudo.
Definition: europe.hpp:512
Romanian leu.
Definition: europe.hpp:224
Romanian new leu.
Definition: europe.hpp:235
DateProxy & evaluationDate()
the date at which pricing is to be performed.
Definition: settings.hpp:147
static Settings & instance()
access to the unique instance
Definition: singleton.hpp:104
Turkish lira.
Definition: europe.hpp:292
New Turkish lira.
Definition: europe.hpp:303
@ January
Definition: date.hpp:57
@ July
Definition: date.hpp:63
@ February
Definition: date.hpp:58
Definition: any.hpp:35
ExchangeRate rate