Skip to content

Commit fca5087

Browse files
committed
Merge branch 'master' into 'master'
update from master See merge request qs/ore-github!11
2 parents 30c365b + 81f0590 commit fca5087

42 files changed

Lines changed: 568 additions & 577 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/linux_build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
- name: Set up Boost
3232
run: |
3333
sudo apt update
34-
sudo apt install -y libboost-all-dev libboost-test-dev
34+
sudo apt install -y libboost-all-dev libboost-test-dev ninja-build
3535
- name: cmake configure
3636
run : mkdir build; cd build; cmake -DCMAKE_BUILD_TYPE=Release -DQL_BUILD_EXAMPLES=false -DQL_BUILD_TEST_SUITE=false -DQL_BUILD_BENCHMARK=false -DQL_ENABLE_SESSIONS=true -DORE_BUILD_DOC=false -G "Ninja" ..
3737
- name: cmake build

Docs/UserGuide/userguide.tex

Lines changed: 336 additions & 389 deletions
Large diffs are not rendered by default.

Examples/Example_8/Readme.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
5) Run Example
1818

1919
python run.py
20+

Examples/ore_examples_helper.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ def __init__(self, dry=False):
3636
self.dry = dry
3737
self.ax = None
3838
self.plot_name = ""
39-
self._locate_ore_exe()
39+
if 'ORE_EXAMPLES_USE_PYTHON' in os.environ.keys():
40+
self.use_python = os.environ['ORE_EXAMPLES_USE_PYTHON']=="1"
41+
self.ore_exe = ""
42+
else:
43+
self.use_python = False
44+
self._locate_ore_exe()
4045

4146
def _locate_ore_exe(self):
4247
if os.name == 'nt':
@@ -262,7 +267,11 @@ def save_plot_to_file(self, subdir="Output"):
262267

263268
def run(self, xml):
264269
if not self.dry:
265-
if subprocess.call([self.ore_exe, xml]) != 0:
270+
if(self.use_python):
271+
res = subprocess.call([sys.executable, os.path.join(os.pardir, "ore_wrapper.py"), xml])
272+
else:
273+
res = subprocess.call([self.ore_exe, xml])
274+
if res != 0:
266275
raise Exception("Return Code was not Null.")
267276

268277
def run_plus(self, xml):

Examples/ore_wrapper.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""
2+
Copyright (C) 2023 Quaternion Risk Management Ltd
3+
All rights reserved.
4+
"""
5+
6+
import os
7+
import argparse
8+
import ORE
9+
10+
if __name__ == "__main__":
11+
print("ORE Python Interface")
12+
parser = argparse.ArgumentParser(prog="ORE Python interface")
13+
parser.add_argument('path_to_ore_xml', default=".\Input\ore.xml")
14+
args = parser.parse_args()
15+
print ("Loading parameters...")
16+
params = ORE.Parameters()
17+
params.fromFile(args.path_to_ore_xml)
18+
print ("Creating OREApp...")
19+
ore = ORE.OREApp(params, True)
20+
print ("Running ORE process...");
21+
ore.run()
22+
print ("Running ORE process done");

OREAnalytics/orea/simm/crifloader.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ void CrifLoader::add(CrifRecord cr, const bool onDiffAmountCcy) {
175175
it->amount += cr.amount;
176176
updated = true;
177177
}
178+
if (cr.hasAmountResultCcy() && cr.hasResultCcy() && it->resultCurrency == cr.resultCurrency) {
179+
it->amountResultCcy += cr.amountResultCcy;
180+
updated = true;
181+
}
178182
if (updated)
179183
DLOG("Updated net CRIF records: " << cr);
180184
} else if (it->riskType == RiskType::AddOnNotionalFactor ||
@@ -210,6 +214,10 @@ void CrifLoader::add(CrifRecord cr, const bool onDiffAmountCcy) {
210214
it->amount += cr.amount;
211215
updated = true;
212216
}
217+
if (cr.hasAmountResultCcy() && cr.hasResultCcy() && it->resultCurrency == cr.resultCurrency) {
218+
it->amountResultCcy += cr.amountResultCcy;
219+
updated = true;
220+
}
213221
if (updated)
214222
DLOG("Updated net CRIF records: " << cr);
215223
} else {
@@ -559,7 +567,9 @@ void CrifLoader::fillAmountUsd(const boost::shared_ptr<ore::data::Market> market
559567
if (!cr.hasAmount() || !cr.hasAmountCcy()) {
560568
WLOG(ore::data::StructuredTradeWarningMessage(
561569
cr.tradeId, cr.tradeType, "Populating CRIF amount USD",
562-
"CRIF record is missing one of Amount and AmountCurrency: " + to_string(cr)));
570+
"CRIF record is missing one of Amount and AmountCurrency, and there is no amountUsd value to "
571+
"fall back to: " +
572+
to_string(cr)));
563573
} else {
564574
Real usdSpot = market->fxRate(cr.amountCurrency + "USD")->value();
565575
cr.amountUsd = cr.amount * usdSpot;

OREAnalytics/orea/simm/crifrecord.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ struct CrifRecord {
5757
std::string amountCurrency;
5858
mutable QuantLib::Real amount = QuantLib::Null<QuantLib::Real>();
5959
mutable QuantLib::Real amountUsd = QuantLib::Null<QuantLib::Real>();
60+
61+
// additional fields used exclusively by the SIMM calculator for handling amounts converted in a given result ccy
62+
std::string resultCurrency;
63+
mutable QuantLib::Real amountResultCcy = QuantLib::Null<QuantLib::Real>();
6064

6165
// optional data
6266
std::string tradeType;
@@ -102,6 +106,8 @@ struct CrifRecord {
102106
bool hasAmountCcy() const { return !amountCurrency.empty(); }
103107
bool hasAmount() const { return amount != QuantLib::Null<QuantLib::Real>(); }
104108
bool hasAmountUsd() const { return amountUsd != QuantLib::Null<QuantLib::Real>(); }
109+
bool hasResultCcy() const { return !resultCurrency.empty(); }
110+
bool hasAmountResultCcy() const { return amountResultCcy != QuantLib::Null<QuantLib::Real>(); }
105111

106112
// We use (and require) amountUsd for all risk types except for SIMM parameters AddOnNotionalFactor and
107113
// ProductClassMultiplier as these are multipliers and not amounts denominated in the amountCurrency

0 commit comments

Comments
 (0)