Skip to content

Commit b3850cd

Browse files
Merge remote-tracking branch 'origin/master' into github_modules
2 parents 72f4eee + 4fffaf0 commit b3850cd

15 files changed

Lines changed: 285 additions & 75 deletions

App/ore.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ int main(int argc, char** argv) {
8282
string tmp = params->get("setup", "useAnalytics", false);
8383
if (tmp != "")
8484
useAnalytics = parseBool(tmp);
85-
return ore.run(useAnalytics);
85+
ore.run(useAnalytics);
86+
return 0;
8687
} catch (const exception& e) {
8788
cout << endl << "an error occurred: " << e.what() << endl;
8889
return -1;

Docs/UserGuide/userguide.tex

Lines changed: 183 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
%\title{Open Source Risk Engine \\ User Guide }
129129
\title{ORE User Guide}
130130
\author{Acadia Inc.}
131-
\date{3 March 2023}
131+
\date{13 March 2023}
132132
\maketitle
133133

134134
\newpage
@@ -149,7 +149,7 @@ \section*{Document History}
149149
30 June 2021 & Acadia & updates for release 6\\
150150
16 September 2022 & Acadia & updates for release 7\\
151151
6 December 2022 & Acadia & updates for release 8\\
152-
3 March 2023 & Acadia & updates for release 9\\
152+
13 March 2023 & Acadia & updates for release 9\\
153153
\hline
154154
\end{supertabular}
155155
\end{center}
@@ -865,7 +865,7 @@ \subsection{Building ORE-SWIG}\label{sec:oreswig}
865865
\hspace{1cm} {\tt -D ORE=<ORE Root Directory> $\backslash$} \\
866866
\hspace{1cm} {\tt -D BOOST\_ROOT=<Top level boost include directory> $\backslash$}\\
867867
\hspace{1cm} {\tt -D BOOST\_LIBRARYDIR=<Location of the compiled boost libraries> $\backslash$}\\
868-
\hspace{1cm} {\tt -D PYTHON\_LIBRARY=<Full name including path to the 'libpython*' library> $\backslash$} \\
868+
\hspace{1cm} {\tt -D PYTHON\_LIBRARY=<Full name including path to the 'libpython*' library>$\backslash$} \\
869869
\hspace{1cm} {\tt -D PYTHON\_INCLUDE\_DIR=<Directory that contains Python.h> $\backslash$} \\
870870
\hspace{1cm} {\tt ..} \\
871871
{\tt ninja} \\
@@ -888,7 +888,7 @@ \subsection{Building ORE-SWIG}\label{sec:oreswig}
888888
\hspace{1cm} {\tt -D BOOST\_ROOT=C:$\backslash$dev$\backslash$boost $\backslash$}\\
889889
\hspace{1cm} {\tt -S OREAnalytics-SWIG/Python $\backslash$}\\
890890
\hspace{1cm} {\tt -B build $\backslash$}\\
891-
{\tt cmake --build build -v}
891+
{\tt cmake -{}-build build -v}
892892
}
893893

894894
\medskip
@@ -918,6 +918,185 @@ \subsection{Building ORE-SWIG}\label{sec:oreswig}
918918

919919
\end{enumerate}
920920

921+
\subsection{How to build ORE Python Wheels on Windows}
922+
923+
This section is a stand-alone HOWTO for building ore and oreswig, including Python wrappers and wheels, at the DOS command line using cmake and VS 2022.
924+
925+
\subsubsection*{Prerequisites}
926+
927+
\begin{itemize}
928+
\item python: The following tools need to be up to date: \\
929+
{\tt python -m ensurepip } \\
930+
{\tt pip install build }
931+
\item boost: Download the binaries from the link below. This release was tested against boost version 1.72. It is important to download these precompiled binaries (rather than compiling yourself from source code) because the binaries include ZLIB support which this build requires. \\
932+
\url{https://sourceforge.net/projects/boost/files/boost-binaries}
933+
\item swig: You need to either install the binaries, or install the source code and build yourself
934+
\item ore and oreswig: You need to install the source code. Instructions for building with cmake are provided below.
935+
\end{itemize}
936+
937+
\subsubsection*{Environment variables}
938+
939+
Set the following environment variables to the paths where the above items live on your machine, e.g:
940+
941+
{\tt set DEMO\_BOOST\_ROOT=C:{\bs}repos{\bs}boost{\bs}boost\_1\_81\_0} \\
942+
{\tt set DEMO\_BOOST\_LIB=C:{\bs}repos{\bs}boost{\bs}boost\_1\_81\_0{\bs}lib{\bs}x64{\bs}lib} \\
943+
{\tt set DEMO\_SWIG\_DIR=C:{\bs}repos{\bs}swigwin-4.1.1} \\
944+
{\tt set DEMO\_ORE\_DIR=C:{\bs}repos{\bs}ore } \\
945+
{\tt set DEMO\_ORE\_SWIG\_DIR=C:{\bs}repos{\bs}oreswig}
946+
947+
\subsubsection*{Build ORE}
948+
949+
Generate the project files:
950+
951+
\medskip
952+
{\tt cd \%DEMO\_ORE\_DIR\%} \\
953+
{\tt mkdir build }\\
954+
{\tt cd \%DEMO\_ORE\_DIR\%{\bs}build} \\
955+
{\tt set BOOST\_INCLUDEDIR=\%DEMO\_BOOST\_ROOT\%} \\
956+
{\tt set BOOST\_LIBRARYDIR=\%DEMO\_BOOST\_LIB\%} \\
957+
%{\tt "C:{\bs}Program Files{\bs}CMake{\bs}bin{\bs}cmake.exe" .. $\backslash$\\
958+
{\tt cmake .. $\backslash$\\
959+
\hspace{1cm} -DBoost\_NO\_WARN\_NEW\_VERSIONS=1 $\backslash$\\
960+
\hspace{1cm} -Wno-dev -G "Visual Studio 17 2022" $\backslash$ \\
961+
\hspace{1cm} -A x64 $\backslash$\\
962+
\hspace{1cm} -DMSVC\_LINK\_DYNAMIC\_RUNTIME=OFF}
963+
964+
\medskip
965+
This will create \%DEMO\_ORE\_DIR\%{\bs}build{\bs}ORE.sln
966+
967+
\medskip
968+
Build:
969+
970+
\medskip
971+
{\tt cd \%DEMO\_ORE\_DIR\%{\bs}build} \\
972+
%{\tt "C:{\bs}Program Files{\bs}CMake{\bs}bin{\bs}cmake.exe" -{}-build . -{}-config Release}
973+
{\tt cmake -{}-build . -{}-config Release}
974+
975+
\medskip
976+
This will create \%DEMO\_ORE\_DIR\%{\bs}build{\bs}OREAnalytics{\bs}orea{\bs}Release{\bs}OREAnalytics-x64-mt.lib
977+
978+
\subsubsection*{Build ORE-SWIG Wrapper and Wheel}
979+
980+
In contrast to the generic cmake-based SWIG build in section \ref{sec:oreswig}, we are now resorting to python's setup.py.
981+
982+
\medskip
983+
{\tt cd \%DEMO\_ORE\_SWIG\_DIR\%{\bs}OREAnalytics-SWIG{\bs}Python} \\
984+
{\tt set BOOST\_ROOT=\%DEMO\_BOOST\_ROOT\%} \\
985+
{\tt set BOOST\_LIB=\%DEMO\_BOOST\_LIB\%} \\
986+
{\tt set ORE\_DIR=\%DEMO\_ORE\_DIR\%} \\
987+
{\tt set PATH=\%PATH\%;\%DEMO\_SWIG\_DIR\%} \\
988+
{\tt set ORE\_STATIC\_RUNTIME=1} \\
989+
{\tt python setup.py wrap} \\
990+
{\tt python setup.py build} \\
991+
{\tt python setup.py test} \\
992+
{\tt python -m build -{}-wheel}
993+
994+
\medskip
995+
This will create
996+
\begin{itemize}
997+
\item the Python module and static library in folder {\tt <PATH>{\bs}build{\bs}lib.win-amd64-cpython-310} (the directory name depends on the machine and python version)
998+
\item the wheel file (filename.whl) in folder {\tt <PATH>{\bs}dist}
999+
\end{itemize}
1000+
where {\tt <PATH>} stands for {\tt \%DEMO\_ORE\_SWIG\_DIR\%{\bs}OREAnalytics-SWIG{\bs}Python}.
1001+
1002+
\medskip
1003+
To use the wrapper directly: \\
1004+
\medskip
1005+
{\tt cd <PATH>{\bs}Examples} \\
1006+
{\tt set PYTHONPATH=<PATH>{\bs}build{\bs}lib.win-amd64-cpython-310} \\
1007+
{\tt python commodityforward.py}
1008+
1009+
\medskip
1010+
To use the wheel:
1011+
1012+
{\tt cd <PATH>{\bs}Examples} \\
1013+
{\tt python -m venv env1} \\
1014+
{\tt .{\bs}env1{\bs}Scripts{\bs}activate.bat} \\
1015+
{\tt pip install <PATH>{\bs}dist{\bs}filename.whl} \\
1016+
{\tt python commodityforward.py} \\
1017+
{\tt deactivate} \\
1018+
{\tt rmdir /s /q env1} \\
1019+
1020+
\subsection{How to build ORE Python Wheels on Linux and macOS}
1021+
1022+
This section is a stand-alone HOWTO for building and using a python wheel for OREAnalytics on Linux or macOS.
1023+
1024+
\subsubsection*{Prerequisites}
1025+
1026+
\begin{itemize}
1027+
\item python: Ensure that python3, pip and virtualenv are installed and up to date\\
1028+
{\tt pip install build}
1029+
\item boost and swig: You need to either install the binaries, or install the source code and build yourself
1030+
\item ore and oreswig: You need to install the source code. Instructions for building with cmake are provided below.
1031+
\end{itemize}
1032+
1033+
\subsubsection*{Environment variables}
1034+
1035+
Set the following environment variables to the paths where the above items live on your machine, e.g:
1036+
1037+
\medskip
1038+
{\tt export DEMO\_BOOST\_DIR=/home/username/quaternion/boost\_1\_81\_0} \\
1039+
{\tt export DEMO\_ORE\_DIR=/home/username/quaternion/ore} \\
1040+
{\tt export DEMO\_ORE\_SWIG\_DIR=/home/username/quaternion/oreswig}
1041+
1042+
\subsubsection*{Build ORE}
1043+
1044+
Use cmake to generate the project Makefiles
1045+
1046+
\medskip
1047+
{\tt cd \$DEMO\_ORE\_DIR} \\
1048+
{\tt mkdir build} \\
1049+
{\tt cd \$DEMO\_ORE\_DIR/build} \\
1050+
{\tt cmake .. \\
1051+
\hspace{1cm} -DCMAKE\_POSITION\_INDEPENDENT\_CODE=ON $\backslash$\\
1052+
\hspace{1cm} -DORE\_BUILD\_DOC=OFF $\backslash$ \\
1053+
\hspace{1cm} -DORE\_BUILD\_EXAMPLES=OFF $\backslash$ \\
1054+
\hspace{1cm} -DORE\_BUILD\_TESTS=OFF $\backslash$\\
1055+
\hspace{1cm} -DORE\_BUILD\_APP=OFF $\backslash$\\
1056+
\hspace{1cm} -DBoost\_NO\_WARN\_NEW\_VERSIONS=1 $\backslash$\\
1057+
\hspace{1cm} -DBoost\_NO\_SYSTEM\_PATHS=1 $\backslash$\\
1058+
\hspace{1cm} -DBOOST\_ROOT=\$DEMO\_BOOST\_DIR }
1059+
1060+
\medskip
1061+
This will generate \$DEMO\_ORE\_DIR/build/Makefile
1062+
1063+
\medskip
1064+
Execute the following to kick off the build:
1065+
1066+
\medskip
1067+
{\tt cd \$DEMO\_ORE\_DIR/build} \\
1068+
{\tt cmake -{}-build} .
1069+
1070+
\medskip
1071+
This will generate \$DEMO\_ORE\_DIR/build/OREAnalytics/orea/libOREAnalytics.so
1072+
1073+
\subsubsection*{Build ORE-SWIG Wrapper and Wheel}
1074+
1075+
In contrast to the generic cmake-based SWIG build in section \ref{sec:oreswig}, we are now resorting to python's setup.py.
1076+
1077+
\medskip
1078+
{\tt cd \$DEMO\_ORE\_SWIG\_DIR/OREAnalytics-SWIG/Python} \\
1079+
{\tt export ORE=\$DEMO\_ORE\_DIR} \\
1080+
{\tt export BOOST=\$DEMO\_BOOST\_DIR} \\
1081+
{\tt python setup.py wrap} \\
1082+
{\tt python setup.py build} \\
1083+
{\tt python3 -m build -{}-wheel}
1084+
1085+
\medskip
1086+
will then generate the wheel file (filename.whl) in folder \$DEMO\_ORE\_SWIG\_DIR/OREAnalytics-SWIG/Python/dist.
1087+
1088+
\medskip
1089+
To use the wheel:
1090+
1091+
\medskip
1092+
{\tt cd \$DEMO\_ORE\_SWIG\_DIR/OREAnalytics-SWIG/Python/Examples} \\
1093+
{\tt python -m venv env1} \\
1094+
{\tt . ./env1/bin/activate} \\
1095+
{\tt pip install \$DEMO\_ORE\_SWIG\_DIR/OREAnalytics-SWIG/Python/dist/filename.whl} \\
1096+
{\tt python3 commodityforward.py} \\
1097+
{\tt deactivate} \\
1098+
{\tt rm -rf env1}
1099+
9211100
%========================================================
9221101
\section{Examples}\label{sec:examples}
9231102
%========================================================

OREAnalytics/orea/app/oreapp.cpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ std::vector<std::string> OREApp::getErrors() {
130130
return errors;
131131
}
132132

133-
int OREApp::run(const std::vector<std::string>& marketData,
134-
const std::vector<std::string>& fixingData) {
133+
void OREApp::run(const std::vector<std::string>& marketData,
134+
const std::vector<std::string>& fixingData) {
135135
try {
136136
LOG("ORE analytics starting");
137137

@@ -169,12 +169,10 @@ int OREApp::run(const std::vector<std::string>& marketData,
169169
ALOG(oss.str());
170170
CONSOLE(oss.str());
171171
QL_FAIL(oss.str());
172-
return 1;
172+
return;
173173
}
174174

175175
LOG("ORE analytics done");
176-
177-
return 0;
178176
}
179177

180178
vector<string> OREApp::getFileNames(const string& fileString, const string& path) {
@@ -231,18 +229,9 @@ void OREApp::analytics() {
231229
LOG("ORE analytics starting");
232230

233231
QL_REQUIRE(params_, "ORE input parameters not set");
234-
235-
// Read all inputs from params and files referenced in params
236-
CONSOLEW("Loading inputs");
237-
inputs_ = boost::make_shared<InputParameters>();
238-
buildInputParameters(inputs_, params_);
239-
auto outputs = boost::make_shared<OutputParameters>(params_);
240-
CONSOLE("OK");
241-
242-
// Set global evaluation date, though already set in the OREAppInputParameters c'tor
232+
243233
Settings::instance().evaluationDate() = inputs_->asof();
244234

245-
// FIXME
246235
GlobalPseudoCurrencyMarketParameters::instance().set(inputs_->pricingEngine()->globalParameters());
247236

248237
// Initialize the global conventions
@@ -265,7 +254,7 @@ void OREApp::analytics() {
265254
// Write reports to files in the results path
266255
Analytic::analytic_reports reports = analyticsManager_->reports();
267256
analyticsManager_->toFile(reports,
268-
inputs_->resultsPath().string(), outputs->fileNameMap(),
257+
inputs_->resultsPath().string(), outputs_->fileNameMap(),
269258
inputs_->csvSeparator(), inputs_->csvCommentCharacter(),
270259
inputs_->csvQuoteChar(), inputs_->reportNaString());
271260

@@ -274,7 +263,7 @@ void OREApp::analytics() {
274263
for (auto b : a.second) {
275264
LOG("write npv cube " << b.first);
276265
string reportName = b.first;
277-
std::string fileName = inputs_->resultsPath().string() + "/" + outputs->outputFileName(reportName, "dat");
266+
std::string fileName = inputs_->resultsPath().string() + "/" + outputs_->outputFileName(reportName, "dat");
278267
LOG("write npv cube " << reportName << " to file " << fileName);
279268
saveCube(fileName, *b.second);
280269
}
@@ -284,7 +273,7 @@ void OREApp::analytics() {
284273
for (auto a : analyticsManager_->mktCubes()) {
285274
for (auto b : a.second) {
286275
string reportName = b.first;
287-
std::string fileName = inputs_->resultsPath().string() + "/" + outputs->outputFileName(reportName, "dat");
276+
std::string fileName = inputs_->resultsPath().string() + "/" + outputs_->outputFileName(reportName, "dat");
288277
LOG("write market cube " << reportName << " to file " << fileName);
289278
saveAggregationScenarioData(fileName, *b.second);
290279
}
@@ -302,9 +291,17 @@ void OREApp::analytics() {
302291
}
303292

304293
OREApp::OREApp(boost::shared_ptr<Parameters> params, bool console)
305-
: params_(params), inputs_(nullptr), asof_(parseDate(params_->get("setup", "asofDate"))), cubeDepth_(0) {
294+
: params_(params), inputs_(nullptr), cubeDepth_(0) {
306295

296+
// Read all inputs from params and files referenced in params
297+
CONSOLEW("Loading inputs");
298+
inputs_ = boost::make_shared<InputParameters>();
299+
buildInputParameters(inputs_, params_);
300+
outputs_ = boost::make_shared<OutputParameters>(params_);
301+
CONSOLE("OK");
302+
307303
// Set global evaluation date
304+
asof_ = inputs_->asof();
308305
Settings::instance().evaluationDate() = asof_;
309306

310307
// initialise some pointers
@@ -335,6 +332,9 @@ OREApp::OREApp(const boost::shared_ptr<InputParameters>& inputs, const std::stri
335332
ConsoleLog::instance().switchOn();
336333
}
337334

335+
// Close any open loggers
336+
closeLog();
337+
338338
// Initialise file logger and buffered logger
339339
string logFilePath = (inputs_->resultsPath() / logFile).string();
340340
boost::filesystem::path p{inputs_->resultsPath()};
@@ -355,15 +355,15 @@ OREApp::~OREApp() {
355355
closeLog();
356356
}
357357

358-
int OREApp::run(bool useAnalytics) {
358+
void OREApp::run(bool useAnalytics) {
359359

360360
cpu_timer timer;
361361

362362
try {
363363

364364
if (useAnalytics) {
365365
analytics();
366-
return 0;
366+
return;
367367
}
368368

369369
CONSOLE("=====================================");
@@ -564,16 +564,14 @@ int OREApp::run(bool useAnalytics) {
564564
} catch (std::exception& e) {
565565
ALOG("Error: " << e.what());
566566
CONSOLE("Error: " << e.what());
567-
return 1;
567+
return;
568568
}
569569

570570
timer.stop();
571571
CONSOLE("run time: " << setprecision(2) << timer.format(default_places, "%w") << " sec");
572572
CONSOLE("ORE done.");
573573

574574
LOG("ORE done.");
575-
576-
return 0;
577575
}
578576

579577
void OREApp::buildInputParameters(boost::shared_ptr<InputParameters> inputs,
@@ -1428,6 +1426,8 @@ void OREApp::readSetup() {
14281426
}
14291427

14301428
void OREApp::setupLog() {
1429+
closeLog();
1430+
14311431
string outputPath = params_->get("setup", "outputPath");
14321432
string logFile = outputPath + "/" + params_->get("setup", "logFile");
14331433
Size logMask = 15; // Default level

0 commit comments

Comments
 (0)