Skip to content

Commit 775f6e8

Browse files
author
Sjogren
committed
Merge remote-tracking branch 'origin/master' into feature/martin_docs1
2 parents 9414e24 + 41002a2 commit 775f6e8

210 files changed

Lines changed: 10434 additions & 4512 deletions

File tree

Some content is hidden

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

Docker/Dockerfile-ORE-Dependencies

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@ RUN python3 -m venv /venv
4040
ENV PATH="/venv/bin:$PATH"
4141

4242
RUN \
43-
pip3 install cibuildwheel==3.2.1 && \
43+
pip3 install twine cibuildwheel==3.2.1 && \
4444
rm -rf ~/.cache/pip
4545

Docker/Dockerfile-Wheels-CIBW

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ FROM ${DOCKER_REPO}ore-build-dependencies:${ORE_BUILD_VERSION}
33

44
ARG WHEEL_ARCH
55
ARG WHEEL_IMAGE
6+
ARG WHEELS_VERSION
67

78
ENV PATH="/venv/bin:$PATH"
89

@@ -12,7 +13,9 @@ ENV CIBW_MANYLINUX_AARCH64_IMAGE=${WHEEL_IMAGE}
1213
ENV CIBW_BEFORE_BUILD="chmod +x ORE-SWIG/Wheels-gitlab/before_all_linux.sh && ORE-SWIG/Wheels-gitlab/before_all_linux.sh"
1314

1415
WORKDIR /builds/qs/oreplus/ore
15-
RUN cibuildwheel --output-dir wheelhouse ORE-SWIG
16+
RUN \
17+
python ../ore/Docker/update_version_number.py -f setup.py -v ${WHEELS_VERSION} && \
18+
cibuildwheel --output-dir wheelhouse ORE-SWIG
1619

1720
COPY wheelhouse /wheelhouse
1821

Docker/Dockerfile-Wheels-ORE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ FROM ${WHEEL_IMG}
44

55
ARG CMAKE_BUILD_TYPE=Release
66
ARG NUM_CORES=16
7+
ARG WHEELS_VERSION
78

89
COPY CMakeLists.txt /ore/CMakeLists.txt
910
COPY QuantLib /ore/QuantLib
@@ -12,6 +13,7 @@ COPY OREData /ore/OREData
1213
COPY OREAnalytics /ore/OREAnalytics
1314
COPY ThirdPartyLibs /ore/ThirdPartyLibs
1415
COPY cmake /ore/cmake
16+
COPY Docker/update_version_number.py /ore
1517

1618
RUN \
1719
dnf -y install clang && \
@@ -24,6 +26,7 @@ ENV CCACHE_MAXSIZE="10G"
2426

2527
WORKDIR /ore
2628
RUN \
29+
python3 update_version_number.py -f version.hpp -v ${WHEELS_VERSION} && \
2730
mkdir build && \
2831
cd build && \
2932
cmake .. -GNinja -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DCMAKE_CXX_FLAGS="-D BOOST_ENABLE_ASSERT_HANDLER $([ "$(uname -m)" = "x86_64" ] && echo "-mavx2")" -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DQL_BUILD_EXAMPLES=OFF -DQL_BUILD_TEST_SUITE=OFF -DQL_ENABLE_PARALLEL_UNIT_TEST_RUNNER=ON -DQL_ENABLE_SESSIONS=ON -DORE_BUILD_APP=OFF -DORE_BUILD_DOC=OFF -DORE_BUILD_EXAMPLES=OFF -DORE_BUILD_SWIG=OFF -DORE_BUILD_TESTS=OFF -DORE_ENABLE_OPENCL=OFF -DORE_ENABLE_PARALLEL_UNIT_TEST_RUNNER=ON -DORE_PYTHON_INTEGRATION=OFF

Docker/update_version_number.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
2+
# Invoke this file from the ore directory to
3+
# overwrite the version number in one of the files below:
4+
#
5+
# ORE-SWIG/setup.py
6+
# QuantExt/qle/version.hpp
7+
#
8+
# e.g:
9+
# cd /path/to/ore
10+
# python /path/to/update_version_number.py -v 1.23.45 -f setup.py
11+
# python /path/to/update_version_number.py -v 1.23.45 -f version.hpp
12+
13+
import optparse
14+
import shutil
15+
import re
16+
import os.path
17+
18+
SETUP_PY = "ORE-SWIG/setup.py"
19+
VERSION_HPP = "QuantExt/qle/version.hpp"
20+
21+
# Convert a version string into a string
22+
# containing a corresponding numerical value:
23+
# 1.8.14.0 -> 1081400
24+
# 1.234.5 -> 12340500
25+
# 1.234.5.dev1 -> 12340501
26+
def version_string_to_number(v):
27+
ret = ""
28+
# match x.x.x or x.x.x.x
29+
# where x = one or more alphanumeric characters
30+
p = r"(\w*)\.(\w*)\.(\w*)(?:\.(\w*))?"
31+
m = re.match(p, v)
32+
if not m:
33+
raise Exception("version string '{v}' has invalid format, expected x.x.x or x.x.x.x where x in [a-zA-Z0-9_]")
34+
for x in m.groups():
35+
x = re.sub("[^0-9]", "", x or "")
36+
if x:
37+
ret += x.zfill(2)
38+
else:
39+
ret += '00'
40+
return ret.lstrip('0')
41+
42+
# Parse the command line arguments
43+
parser = optparse.OptionParser()
44+
parser.add_option('-f', '--file')
45+
parser.add_option('-v', '--version')
46+
opts, args = parser.parse_args()
47+
file = opts.file
48+
version = opts.version
49+
50+
if file is None:
51+
raise Exception("missing input parameter --file")
52+
53+
if version is None:
54+
raise Exception("missing input parameter --version")
55+
56+
def find_and_replace(file, repl):
57+
58+
if not os.path.isfile(file):
59+
raise Exception(f"invalid path: {file}")
60+
61+
shutil.copy(file, file + ".bak")
62+
63+
with open(file) as f:
64+
s = f.read()
65+
66+
for (p, r) in repl:
67+
s = re.sub(p, r, s)
68+
69+
with open(file, 'w') as f:
70+
f.write(s)
71+
72+
if file == "setup.py":
73+
find_and_replace(SETUP_PY, [(r'(version\s*=\s*").*(")', fr'\g<1>{version}\g<2>')])
74+
elif file == "version.hpp":
75+
version_num = version_string_to_number(version)
76+
find_and_replace(VERSION_HPP, [
77+
(r'(#define OPEN_SOURCE_RISK_VERSION ").*(")', fr'\g<1>{version}\g<2>'),
78+
(r'(#define OPEN_SOURCE_RISK_VERSION_NUM ).*', fr'\g<1>{version_num}')])
79+
else:
80+
raise Exception(f"unrecognized file: {file}")
81+

Docs/ScriptedTrade/docs/language.tex

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
\verb+max+ & \\
4242
\verb+min+ & \\
4343
\verb+pow+ & \\
44+
\verb+frac+ & \\
45+
\verb+round+ & \\
4446
\verb+black+ & \\
4547
\verb+dcf+ & \\
4648
\verb+days+ & \\ \hline
@@ -398,21 +400,21 @@
398400
\item {\tt REQUIRE Strike >= 0;}
399401
\end{itemize}
400402

401-
% ====================================================
402-
\stsubsection{Functions {\tt min}, {\tt max}, {\tt pow}}
403-
% ====================================================
403+
% =========================================================================
404+
\stsubsection{Functions {\tt min}, {\tt max}, {\tt pow}}, {\tt round(x,y)}
405+
% =========================================================================
404406

405-
Binary functions {\tt min(x,y)}, {\tt max(x,y)}, {\tt pow(x,y)}, applicable to numbers only.
407+
Binary functions {\tt min(x,y)}, {\tt max(x,y)}, {\tt pow(x,y)}, {\tt round(x,y)}, applicable to numbers only.
406408

407-
% ====================================================
408-
\stsubsection{Functions {\tt -}, abs, exp, ln, sqrt}
409-
% ====================================================
409+
% ========================================================
410+
\stsubsection{Functions {\tt -}, abs, exp, ln, sqrt, frac}
411+
% ========================================================
410412

411-
Unary functions {\tt -x}, {\tt abs(x)}, {\tt exp(x)}, {\tt ln(x)}, {\tt sqrt(x)}, applicable to numbers only.
413+
Unary functions {\tt -x}, {\tt abs(x)}, {\tt exp(x)}, {\tt ln(x)}, {\tt sqrt(x)}, {\tt frac(x)} which take the fractional part of a float, applicable to numbers only.
412414

413-
% ====================================================
415+
% =======================================================
414416
\stsubsection{Functions {\tt normalPdf}, {\tt normalCdf}}
415-
% ====================================================
417+
% =======================================================
416418

417419
Returns the standard normal pdf $\phi(x)$ resp. cdf $\Phi(x)$, applicable to numbers only.
418420

Docs/UserGuide/curve_configurations/yieldcurves.tex

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,19 @@ \subsubsection{Yield Curves}
5656
\item Extrapolation [Optional]: Set to \emph{True} or \emph{False} to enable or disable extrapolation respectively. If
5757
the element is omitted or left blank, then it defaults to \emph{True}.
5858

59-
\item ExcludeT0FromInterpolation [Optional]: Set to \emph{True} to exclude the synthetic time-zero (t0) point from
60-
yield curve interpolation. When enabled, the curve interpolates only on actual market pillar dates, while still
61-
ensuring proper behavior at the reference date (e.g., $DF(t_0) = 1.0$ for discount curves). This is useful when the
62-
first market pillar date does not coincide with the as-of date and you want to avoid including a synthetic point in
63-
the interpolation.
59+
\item ExtrapolationMethod [Optional]: Only applies to bootstrapped curves and interpolated zero / discount curves.
60+
Controls how the curve is extrapolated:
61+
\begin{itemize}
62+
\item \emph{ContinuousForward}: The instantaneous forward rate at the last curve pillar date $T$ is kept constant
63+
\item \emph{DiscreteForward}: The discrete forward rate between $T-1$ and $T$ is kept constant, where $T$ is the last
64+
curve pillar date and $T-1$ lies one calendar day before $T$.
65+
\end{itemize}
66+
67+
\item ExcludeT0FromInterpolation [Optional]: Only applies to bootstrapped curves and interpolated zero / discount curves.
68+
Set to \emph{True} to exclude the synthetic time-zero (t0) point from yield curve interpolation. When enabled, the curve
69+
interpolates only on actual market pillar dates, while still ensuring proper behavior at the reference date
70+
(e.g., $DF(t_0) = 1.0$ for discount curves). This is useful when the first market pillar date does not coincide with the
71+
as-of date and you want to avoid including a synthetic point in the interpolation.
6472

6573
This feature is supported for all three interpolation variables:
6674
\begin{itemize}
@@ -194,7 +202,10 @@ \subsubsection*{Simple Segment}
194202
floating rates on the instruments underlying the quotes listed in the \lstinline!Quote! nodes during the bootstrap
195203
procedure. This is an optional node. If it is left blank or omitted, then the projection curve is assumed to equal the
196204
curve being bootstrapped i.e.\ the current CurveId. The \lstinline!PillarChoice! node determines the bootstrap pillars
197-
that are used (MaturityDate, LastRelevantDate, if not given 'LastRelevantDate' is the default value).
205+
that are used (MaturityDate, LastRelevantDate, NoPillar, StartDate, StartDateAndMaturityDate,
206+
StartDateAndLastRelevantDate; if not given 'LastRelevantDate' is the default
207+
value). The \lstinline!DuplicatePillarPolcicy! node determined how curve instruments within the same segment with
208+
identical pillar dates are handled (Keep Last, KeepFirst, KeepAll, ThrowError; if not given 'KeepLast' is used).
198209
199210
The \lstinline!Priority! node determines the priority of the segment, this has to be a non-negative integer. A lower
200211
number means a higher priority (more ``important'') segment. If two adjacent segments overlap w.r.t. the pillar dates of
@@ -223,6 +234,7 @@ \subsubsection*{Simple Segment}
223234
</Quotes>
224235
<Conventions> </Conventions>
225236
<PillarChoice> </PillarChoice>
237+
<DuplicatePillarPolicy> </DuplicatePillarPolicy>
226238
<Priority> </Priority>
227239
<MinDistance> </MinDistance>
228240
<ProjectionCurve> </ProjectionCurve>
@@ -261,11 +273,10 @@ \subsubsection*{Average OIS Segment}
261273
quote for an Average OIS instrument (a typical example in a USD Overnight Index Swap) consists of two quotes, a vanilla
262274
IRS quote and an OIS-LIBOR basis swap spread quote. The IDs of these two quotes are stored in the
263275
\lstinline!CompositeQuote! node. The \lstinline!RateQuote! node holds the ID of the vanilla IRS quote and the
264-
\lstinline!SpreadQuote! node holds the ID of the OIS-LIBOR basis swap spread quote. The \lstinline!PillarChoice! node
265-
determines the bootstrap pillars that are used (MaturityDate, LastRelevantDate, if not given `LastRelevantDate' is the
266-
default value).
276+
\lstinline!SpreadQuote! node holds the ID of the OIS-LIBOR basis swap spread quote.
267277
268-
For the \lstinline!Priority! and \lstinline!MinDistance! nodes see the explanation under ``Simple Segment''.
278+
For the \lstinline!PillarChoice!, \lstinline!DuplicatePillarPolicy!, \lstinline!Priority! and \lstinline!MinDistance!
279+
nodes see the explanation under ``Simple Segment''.
269280
270281
\begin{listing}[H]
271282
%\hrule\medskip
@@ -279,6 +290,7 @@ \subsubsection*{Average OIS Segment}
279290
</Quotes>
280291
<Conventions> </Conventions>
281292
<PillarChoice> </PillarChoice>
293+
<DuplicatePillarPolicy> </DuplicatePillarPolicy>
282294
<Priority> </Priority>
283295
<MinDistance> </MinDistance>
284296
<ProjectionCurve> </ProjectionCurve>
@@ -313,13 +325,13 @@ \subsubsection*{Tenor Basis Segment}
313325
node has the value \emph{Tenor Basis Two Swaps}. Again, the structure is similar to the simple segment in Listing
314326
\ref{lst:simple_segment} except that there are two projection curve nodes. There is a \lstinline!ProjectionCurveReceive!
315327
node for the index with the shorter tenor. This node holds the CurveId of a curve for projecting the floating rates on
316-
the receiving side. Similarly, there is a \lstinline!ProjectionCurvePay! node for the index of the pay side. The deprecated
317-
values are short for receive, and long for pay. These are optional nodes. If they are left blank or omitted, then the projection
318-
curve is assumed to equal the curve being bootstrapped i.e.\ the current CurveId. However, at least one of the nodes
319-
needs to be populated to allow the bootstrap to proceed. The \lstinline!PillarChoice! node determines the bootstrap pillars
320-
that are used (MaturityDate, LastRelevantDate, if not given `LastRelevantDate' is the default value).
328+
the receiving side. Similarly, there is a \lstinline!ProjectionCurvePay! node for the index of the pay side. The
329+
deprecated values are short for receive, and long for pay. These are optional nodes. If they are left blank or omitted,
330+
then the projection curve is assumed to equal the curve being bootstrapped i.e.\ the current CurveId. However, at least
331+
one of the nodes needs to be populated to allow the bootstrap to proceed.
321332
322-
For the \lstinline!Priority! and \lstinline!MinDistance! nodes see the explanation under ``Simple Segment''.
333+
For the \lstinline!PillarChoice!, \lstinline!DuplicatePillarPolicy!, \lstinline!Priority! and \lstinline!MinDistance!
334+
nodes see the explanation under ``Simple Segment''.
323335
324336
\begin{listing}[H]
325337
%\hrule\medskip
@@ -333,6 +345,7 @@ \subsubsection*{Tenor Basis Segment}
333345
</Quotes>
334346
<Conventions> </Conventions>
335347
<PillarChoice> </PillarChoice>
348+
<DuplicatePillarPolicy> </DuplicatePillarPolicy>
336349
<Priority> </Priority>
337350
<MinDistance> </MinDistance>
338351
<ProjectionCurvePay> </ProjectionCurvePay>
@@ -350,8 +363,7 @@ \subsubsection*{Cross Currency Segment}
350363
for FX forward instruments. The \lstinline!DiscountCurve! node holds the CurveId of a curve used to discount cash flows
351364
in the other currency i.e.\ the currency in the currency pair that is not equal to the currency in Listing
352365
\ref{lst:top_level_yc}. The \lstinline!SpotRate! node holds the ID of a spot FX quote for the currency pair that is
353-
looked up in the {\tt market.txt} file. The \lstinline!PillarChoice! node determines the bootstrap pillars that are used
354-
(MaturityDate, LastRelevantDate, if not given `LastRelevantDate' is the default value).
366+
looked up in the {\tt market.txt} file.
355367
356368
\begin{listing}[H]
357369
%\hrule\medskip
@@ -365,6 +377,7 @@ \subsubsection*{Cross Currency Segment}
365377
</Quotes>
366378
<Conventions> </Conventions>
367379
<PillarChoice> </PillarChoice>
380+
<DuplicatePillarPolicy> </DuplicatePillarPolicy>
368381
<Priority> </Priority>
369382
<MinDistance> </MinDistance>
370383
<DiscountCurve> </DiscountCurve>
@@ -388,7 +401,8 @@ \subsubsection*{Cross Currency Segment}
388401
the other currency. If it is left blank or omitted, then it is assumed to equal the CurveId provided in the
389402
\lstinline!DiscountCurve! node in this segment.
390403
391-
For the \lstinline!Priority! and \lstinline!MinDistance! nodes see the explanation under ``Simple Segment''.
404+
For the \lstinline!PillarChoice!, \lstinline!DuplicatePillarPolicy!, \lstinline!Priority! and \lstinline!MinDistance!
405+
nodes see the explanation under ``Simple Segment''.
392406
393407
\begin{listing}[H]
394408
%\hrule\medskip
@@ -402,6 +416,7 @@ \subsubsection*{Cross Currency Segment}
402416
</Quotes>
403417
<Conventions> </Conventions>
404418
<PillarChoice> </PillarChoice>
419+
<DuplicatePillarPolicy> </DuplicatePillarPolicy>
405420
<Priority> </Priority>
406421
<MinDistance> </MinDistance>
407422
<DiscountCurve> </DiscountCurve>

Docs/UserGuide/examples/examples.tex

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,8 +615,9 @@ \subsubsection{Historical Simulation VaR}
615615
The analytic is specified as usual in {\tt ore.xml} with the following parameters:
616616
\begin{itemize}
617617
\item outputFile: csv file name of the resulting VaR report
618-
%\item breakdown: boolean, if true the VaR report will contain a breakdown by risk class and risk type, otherwise the report shows the portfolio-lvel VaR only.
619-
\item tradePnl: boolean, if true the VaR report will contain a breakdown by tradeID, risk class and risk type, otherwise the report shows the portfolio-lvel VaR only.
618+
%\item breakdown: boolean, if true the VaR report will contain a breakdown by risk class and risk type, otherwise the report shows the portfolio-level VaR only.
619+
\item tradePnl: boolean, if true the VaR report will contain a breakdown by tradeID, risk class and risk type, otherwise the report shows the portfolio-level VaR only.
620+
\item riskFactorBreakdown: boolean, if true the VaR report will contain a breakdown by risk factor.
620621
\item quantiles: comma separated list of quantiles to be reported
621622
\item portfolioFilter (optional): Only trades with {\tt portfolioId} equal to the provided filter name are processed, see {\tt portfolio.xml}; the entire portfolio is processed, if omitted
622623
\item historicalPeriod: comma-separated date list, an even number of ordered dates is required (d1, d2, d3, d4, ...), where each pair (d1-d2, d3-d4, ...) defines the start and end of historical observation periods used

Docs/UserGuide/parameterisation/curveconfig.tex

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,11 +1263,21 @@ \subsubsection{Bootstrap Configuration}
12631263
\item \lstinline!DontThrowSteps! [Optional]:
12641264
This node is used only if \lstinline!DontThrow! is \lstinline!true!. The meaning of this node is given in the description of the \lstinline!DontThrow! node. This node should hold a positive integer. If omitted, the default value is 10.
12651265
1266-
\item \lstinline!Global! [Optional]: This nodes specifies whether the curve should use a global bootstrap over all
1267-
instruments of the curve (true) or iterative bootstrap (false, default value). If global bootstrap is used, only the
1268-
Accuracy field of the BootstrapConfig is relevant and specifies the accuracy of the global optimizer. If a cycle is
1269-
present in the dependency graph of the curves, all members of the cycle must use global bootstrap, in this case a
1270-
global optimization is run over all instrument of all members of the cycle simultaneously.
1266+
\item \lstinline!Global! [Optional]: Defaults to false. This nodes specifies whether the curve should use a global
1267+
bootstrap over all instruments of the curve (true) or iterative bootstrap (false, default value). If global bootstrap
1268+
is used, only the fields Accuracy and SmoothnessLambda of the BootstrapConfig are relevant. Accurcy specifies the
1269+
accuracy of the global optimizer in this case. Global bootstrap is required to build curves that form a cycle in the
1270+
dependency graph, in this case all members of the cycle must have Global set to true in their bootstrap configs. In
1271+
this case a global optimization is run over all instrument of all members of the cycle simultaneously. Global
1272+
bootstrap is also required if according to the PillarChoice configuration of each segment there are curve instrument
1273+
without or with more than one associated curve pillar date. Finally, global bootstrap can be preferable over iterative
1274+
bootstrap if the latter requires an outer convergence loop, i.e. if a pillar choice is not set to LastRelevatDate or
1275+
if the interpolation is non-local.
1276+
1277+
\item \lstinline!SmoothnessLambda! [Optional]: Defaults to zero. Only applies if GLobal is set to true. If positive,
1278+
penalty components are included in the global optimization used to build a curve. For each adjacent pair of discrete
1279+
forward rates $F_i$, $F_{i+1}$ between curve interpolation pillars, the term $\lambda\cdot(F_{i+1} - F_i)$ is added to
1280+
the target function vector of which the MSE is optimized.
12711281
12721282
\end{itemize}
12731283

0 commit comments

Comments
 (0)