19#include <boost/algorithm/string.hpp>
22#include <ql/quotes/derivedquote.hpp>
23#include <ql/quotes/simplequote.hpp>
30string invertFx(
const string& ccyPair) {
31 QL_REQUIRE(ccyPair.size() == 6,
"invertFx: Expected currency pair to be 6 characters but got: " << ccyPair);
32 return ccyPair.substr(3, 3) + ccyPair.substr(0, 3);
60 std::string sep(1, separator);
61 vector<string> tokens;
62 boost::split(tokens,
name, boost::is_any_of(sep));
64 QL_REQUIRE(tokens.size() == 2 || tokens.size() == 3,
65 "parseCorrelationFactor(" <<
name <<
"): expected 2 or 3 tokens separated by separator ('" << sep
66 <<
"'), e.g. 'IR" << sep <<
"USD' or 'INF" << sep <<
"UKRPI" << sep <<
"0'");
69 static_cast<Size
>(tokens.size() == 3 ?
parseInteger(tokens[3]) : 0)};
79 addCorrelation(f_1, f_2, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(correlation)));
83 const Handle<Quote>& correlation) {
90 const CorrelationFactor& f_2, Real correlation) {
91 addCorrelation(f_1, f_2, Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(correlation)));
95 const Handle<Quote>& correlation) {
103 QL_REQUIRE(correlation->value() >= -1.0 && correlation->value() <= 1.0,
"Correlation value, " <<
104 correlation->value() <<
", for key [" << ck.first <<
"," << ck.second <<
"] should be in [-1.0,1.0]");
106 DLOG(
"Added correlation: (" << f_1 <<
"," << f_2 <<
") = " << correlation->value() <<
".");
115 const vector<string>& infIndices) {
121 const vector<string>& infIndices,
const vector<string>& names) {
127 const vector<string>& infIndices,
const vector<string>& names,
const vector<string>& equities) {
136 vector<CorrelationFactor> factors;
137 for (
const auto& kv : processInfo) {
138 for (
const auto& p : kv.second) {
142 if (kv.first == CrossAssetModel::AssetType::FX) {
143 QL_REQUIRE(p.second == 1,
"CorrelationMatrixBuilder does not support multiple factors for FX. " <<
144 p.first <<
" is set up with " << p.second <<
" factors.");
148 for (Size i = 0; i < p.second; ++i) {
149 factors.push_back({ kv.first, p.first, i });
155 Matrix corr(dim, dim, 0.0);
156 for (Size i = 0; i < dim; i++)
160 for (Size i = 0; i < dim; ++i) {
161 for (Size j = 0; j < i; ++j) {
162 corr[i][j] = corr[j][i] =
getCorrelation(factors[i], factors[j])->value();
170 const vector<string>& ccys,
171 const std::vector<std::string>& inflationIndices,
172 const std::vector<std::string>& creditNames,
173 const std::vector<std::string>& equityNames) {
176 QL_REQUIRE(!ccys.empty(),
"At least one currency required to build correlation matrix");
177 for (
const string& ccy : ccys) {
178 QL_REQUIRE(ccy.size() == 3,
"Invalid currency code " << ccy);
186 for (
const string& ccy : ccys) {
187 result[CrossAssetModel::AssetType::IR].emplace_back(ccy, 1);
191 for (Size i = 1; i < ccys.size(); ++i) {
192 string ccyPair = ccys[i] + ccys[0];
193 result[CrossAssetModel::AssetType::FX].emplace_back(ccyPair, 1);
197 for (
const string& inflationIndex : inflationIndices) {
198 result[CrossAssetModel::AssetType::INF].emplace_back(inflationIndex, 1);
202 for (
const string& creditName : creditNames) {
203 result[CrossAssetModel::AssetType::CR].emplace_back(creditName, 1);
207 for (
const string& equityName : equityNames) {
208 result[CrossAssetModel::AssetType::EQ].emplace_back(equityName, 1);
216 case CrossAssetModel::AssetType::IR:
217 QL_REQUIRE(f.
name.size() == 3,
"Expected IR factor name to be 3 character currency code but got: " << f.
name);
219 case CrossAssetModel::AssetType::FX:
220 QL_REQUIRE(f.
name.size() == 6,
"Expected FX factor name to be 6 character currency pair but got: " << f.
name);
222 case CrossAssetModel::AssetType::INF:
223 case CrossAssetModel::AssetType::CR:
224 case CrossAssetModel::AssetType::EQ:
225 case CrossAssetModel::AssetType::COM:
226 case CrossAssetModel::AssetType::CrState:
227 QL_REQUIRE(!f.
name.empty(),
"Expected non-empty factor name for factor type " << f.
type);
230 QL_FAIL(
"Did not recognise factor type " <<
static_cast<int>(f.
type) <<
".");
237 QL_REQUIRE(f_1 != f_2,
"Correlation factors must be unique: " << f_1 <<
".");
240 return make_pair(f_1, f_2);
242 return make_pair(f_2, f_1);
265 typedef DerivedQuote<negate<Real>> InvQuote;
268 if (f_1.
type == CrossAssetModel::AssetType::FX) {
271 auto it =
corrs_.find(ck);
273 return Handle<Quote>(QuantLib::ext::make_shared<InvQuote>(it->second, negate<Real>()));
277 if (f_2.
type == CrossAssetModel::AssetType::FX) {
280 auto it =
corrs_.find(ck);
282 return Handle<Quote>(QuantLib::ext::make_shared<InvQuote>(it->second, negate<Real>()));
286 if (f_1.
type == CrossAssetModel::AssetType::FX && f_2.
type == CrossAssetModel::AssetType::FX) {
290 auto it =
corrs_.find(ck);
296 return Handle<Quote>(QuantLib::ext::make_shared<SimpleQuote>(0.0));
QuantLib::Matrix correlationMatrix(const std::vector< std::string > &ccys)
std::map< CorrelationKey, QuantLib::Handle< QuantLib::Quote > > corrs_
Store the correlation between two factors.
void addCorrelation(const std::string &factor1, const std::string &factor2, QuantLib::Real correlation)
QuantLib::Handle< QuantLib::Quote > lookup(const std::string &f1, const std::string &f2)
Get the correlation between two factors.
QuantLib::Handle< QuantLib::Quote > getCorrelation(const CorrelationFactor &f_1, const CorrelationFactor &f_2) const
Get the correlation between the factor f_1 and f_2.
CorrelationKey createKey(const CorrelationFactor &f_1, const CorrelationFactor &f_2) const
ProcessInfo createProcessInfo(const std::vector< std::string > &ccys, const std::vector< std::string > &inflationIndices={}, const std::vector< std::string > &creditNames={}, const std::vector< std::string > &equityNames={})
void checkFactor(const CorrelationFactor &f) const
Perform some basic checks on the factor names.
QuantLib::Matrix correlationMatrix(const std::vector< std::string > &ccys, const std::vector< std::string > &infIndices, const std::vector< std::string > &names, const std::vector< std::string > &equities)
void reset()
Clear all data.
std::map< QuantExt::CrossAssetModel::AssetType, std::vector< std::pair< std::string, QuantLib::Size > > > ProcessInfo
const std::map< CorrelationKey, QuantLib::Handle< QuantLib::Quote > > & correlations()
Get the raw correlation data.
configuration class for building correlation matrices
QuantExt::CrossAssetModel::AssetType parseCamAssetType(const string &s)
Integer parseInteger(const string &s)
Convert text to QuantLib::Integer.
#define DLOG(text)
Logging Macro (Level = Debug)
bool operator<(const Dividend &d1, const Dividend &d2)
bool operator!=(const Filter &a, const Filter &b)
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
bool operator==(const Dividend &d1, const Dividend &d)
std::pair< CorrelationFactor, CorrelationFactor > CorrelationKey
CorrelationFactor parseCorrelationFactor(const string &name, const char separator)
Serializable Credit Default Swap.
Map text representations to QuantLib/QuantExt types.
QuantExt::CrossAssetModel::AssetType type