quantlib-xloil 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quantlib_xloil-0.0.1/.github/workflows/ci.yml +30 -0
- quantlib_xloil-0.0.1/.gitignore +221 -0
- quantlib_xloil-0.0.1/LICENSE +21 -0
- quantlib_xloil-0.0.1/PKG-INFO +82 -0
- quantlib_xloil-0.0.1/README.md +66 -0
- quantlib_xloil-0.0.1/conftest.py +4 -0
- quantlib_xloil-0.0.1/pyproject.toml +33 -0
- quantlib_xloil-0.0.1/requirements.txt +12 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/README.md +145 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/__about__.py +1 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/__init__.py +14 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/calendars.py +351 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/cashflows.py +2337 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/config.py +2 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/currencies.py +247 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/date.py +326 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/daycounters.py +107 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/indexes.py +1043 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/interpolatedyieldcurves.py +157 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/quantlib_.py +21 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/rounding.py +50 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/scheduler.py +405 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/settings.py +93 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/termstructures.py +367 -0
- quantlib_xloil-0.0.1/src/quantlib_xloil/utilities.py +22 -0
- quantlib_xloil-0.0.1/tests/README.md +39 -0
- quantlib_xloil-0.0.1/tests/unittests/test_calendars.py +405 -0
- quantlib_xloil-0.0.1/tests/unittests/test_cashflows.py +556 -0
- quantlib_xloil-0.0.1/tests/unittests/test_currencies.py +68 -0
- quantlib_xloil-0.0.1/tests/unittests/test_date.py +190 -0
- quantlib_xloil-0.0.1/tests/unittests/test_daycounters.py +289 -0
- quantlib_xloil-0.0.1/tests/unittests/test_indexes.py +191 -0
- quantlib_xloil-0.0.1/tests/unittests/test_interpolatedyieldcurves.py +181 -0
- quantlib_xloil-0.0.1/tests/unittests/test_quantlib.py +12 -0
- quantlib_xloil-0.0.1/tests/unittests/test_rounding.py +43 -0
- quantlib_xloil-0.0.1/tests/unittests/test_scheduler.py +162 -0
- quantlib_xloil-0.0.1/tests/unittests/test_settings.py +82 -0
- quantlib_xloil-0.0.1/tests/unittests/test_termstructures.py +120 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_calendars.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_cashflows.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_currencies.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_date.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_daycounters.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_indexes.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_interpolatedyieldcurves.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_quantlib.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_rounding.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_scheduler.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_settings.xlsx +0 -0
- quantlib_xloil-0.0.1/tests/workbooks/test_termstructures.xlsx +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
runs-on: windows-latest
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout code
|
|
16
|
+
uses: actions/checkout@v6
|
|
17
|
+
|
|
18
|
+
- name: Set up Python
|
|
19
|
+
uses: actions/setup-python@v6
|
|
20
|
+
with:
|
|
21
|
+
python-version: '3.14'
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: |
|
|
25
|
+
python -m pip install --upgrade pip
|
|
26
|
+
pip install -r requirements.txt
|
|
27
|
+
|
|
28
|
+
- name: Run tests
|
|
29
|
+
run: |
|
|
30
|
+
pytest tests/unittests -v
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
# Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
# poetry.lock
|
|
109
|
+
# poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
# pdm.lock
|
|
116
|
+
# pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
# pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# Redis
|
|
135
|
+
*.rdb
|
|
136
|
+
*.aof
|
|
137
|
+
*.pid
|
|
138
|
+
|
|
139
|
+
# RabbitMQ
|
|
140
|
+
mnesia/
|
|
141
|
+
rabbitmq/
|
|
142
|
+
rabbitmq-data/
|
|
143
|
+
|
|
144
|
+
# ActiveMQ
|
|
145
|
+
activemq-data/
|
|
146
|
+
|
|
147
|
+
# SageMath parsed files
|
|
148
|
+
*.sage.py
|
|
149
|
+
|
|
150
|
+
# Environments
|
|
151
|
+
.env
|
|
152
|
+
.envrc
|
|
153
|
+
.venv
|
|
154
|
+
env/
|
|
155
|
+
venv/
|
|
156
|
+
ENV/
|
|
157
|
+
env.bak/
|
|
158
|
+
venv.bak/
|
|
159
|
+
|
|
160
|
+
# Spyder project settings
|
|
161
|
+
.spyderproject
|
|
162
|
+
.spyproject
|
|
163
|
+
|
|
164
|
+
# Rope project settings
|
|
165
|
+
.ropeproject
|
|
166
|
+
|
|
167
|
+
# mkdocs documentation
|
|
168
|
+
/site
|
|
169
|
+
|
|
170
|
+
# mypy
|
|
171
|
+
.mypy_cache/
|
|
172
|
+
.dmypy.json
|
|
173
|
+
dmypy.json
|
|
174
|
+
|
|
175
|
+
# Pyre type checker
|
|
176
|
+
.pyre/
|
|
177
|
+
|
|
178
|
+
# pytype static type analyzer
|
|
179
|
+
.pytype/
|
|
180
|
+
|
|
181
|
+
# Cython debug symbols
|
|
182
|
+
cython_debug/
|
|
183
|
+
|
|
184
|
+
# PyCharm
|
|
185
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
186
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
188
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
189
|
+
# .idea/
|
|
190
|
+
|
|
191
|
+
# Abstra
|
|
192
|
+
# Abstra is an AI-powered process automation framework.
|
|
193
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
194
|
+
# Learn more at https://abstra.io/docs
|
|
195
|
+
.abstra/
|
|
196
|
+
|
|
197
|
+
# Visual Studio Code
|
|
198
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
199
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
200
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
201
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
202
|
+
# .vscode/
|
|
203
|
+
# Temporary file for partial code execution
|
|
204
|
+
tempCodeRunnerFile.py
|
|
205
|
+
|
|
206
|
+
# Ruff stuff:
|
|
207
|
+
.ruff_cache/
|
|
208
|
+
|
|
209
|
+
# PyPI configuration file
|
|
210
|
+
.pypirc
|
|
211
|
+
|
|
212
|
+
# Marimo
|
|
213
|
+
marimo/_static/
|
|
214
|
+
marimo/_lsp/
|
|
215
|
+
__marimo__/
|
|
216
|
+
|
|
217
|
+
# Streamlit
|
|
218
|
+
.streamlit/secrets.toml
|
|
219
|
+
|
|
220
|
+
# VS Code settings
|
|
221
|
+
.vscode/
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sebastian Schlenkrich
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: quantlib_xloil
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Interface package to make QuantLib pricing library functions available in Excel.
|
|
5
|
+
Project-URL: Homepage, https://github.com/frame-consulting/QuantLibXlOil
|
|
6
|
+
Project-URL: Issues, https://github.com/frame-consulting/QuantLibXlOil/issues
|
|
7
|
+
Author-email: Sebastian Schlenkrich <sebastian.schlenkrich@frame-consult.de>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Requires-Dist: quantlib
|
|
14
|
+
Requires-Dist: xloil
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# QuantLibXlOil
|
|
18
|
+
|
|
19
|
+
QuantLibXlOil is an interface package to make functions of the open-source [QuantLib](https://github.com/lballabio/QuantLib) pricing library available in Excel.
|
|
20
|
+
|
|
21
|
+
The interface builds on the Python bindings for QuantLib via [QuantLib-SWIG](https://github.com/lballabio/QuantLib-SWIG).
|
|
22
|
+
|
|
23
|
+
We use [xlOil](https://github.com/cunnane/xloil) to make the QuantLib Python objects and functions available in Excel.
|
|
24
|
+
|
|
25
|
+
The QuantLibXlOil package largely contains wrapper functions in Python which delegate calls to QuantLib constructors and method/function call. The wrapper functions are made available to Excel via xlOil's function decorator. In addition, the package provides converter functions between Excel data types and QuantLib types.
|
|
26
|
+
|
|
27
|
+
## Why Another QuantLib Interface?
|
|
28
|
+
|
|
29
|
+
Excel is widely adapted in the industry as calculation tool and GUI for a large variety of use cases.
|
|
30
|
+
|
|
31
|
+
QuantLib has the classical [QuantLibXL](https://www.quantlib.org/quantlibxl/) interface for Excel. However, QuantLibXL was last updated for QuantLib v1.22 (April 2021). The QuantLibXL object and interface specification is quite complex and closely linked to QuantLib internals. This makes maintenance quite challenging.
|
|
32
|
+
|
|
33
|
+
The QuantLib Python interface is probably the best QuantLib interface in terms of coverage and maintenance. With the QuantLibXlOil package, we aim at leveraging the matured QuantLib Python interface.
|
|
34
|
+
|
|
35
|
+
As an additional objective, we want to disentangle QuantLib developments from Excel interface development. This is particularly relevant for QuantLib C++ internals. For example, switching from `boost::something` to `std::something` should not affect the Excel interface. This motivates building on top of an existing high-level language interface.
|
|
36
|
+
|
|
37
|
+
Linking between Python and Excel is a well understood task. There are [several tools](https://xloil.readthedocs.io/en/stable/Introduction.html#why-xloil-was-created) that implement that bridge. We opt for xlOil because it is open-source and works well for the use cases tested.
|
|
38
|
+
|
|
39
|
+
## Getting Started
|
|
40
|
+
|
|
41
|
+
The manual way...
|
|
42
|
+
|
|
43
|
+
### Setup Python Environment
|
|
44
|
+
|
|
45
|
+
Set up a Python environment via `conda` or `pip` and with the following packages:
|
|
46
|
+
|
|
47
|
+
- `quanlib-python`,
|
|
48
|
+
- `numpy`,
|
|
49
|
+
- `pandas` (Version 2).
|
|
50
|
+
|
|
51
|
+
### Install xlOil
|
|
52
|
+
|
|
53
|
+
xlOil is available via pip and `pip install xloil`.
|
|
54
|
+
|
|
55
|
+
Install the xlOil Excel add-in by running `xloil install` from the command line of the Python environment.
|
|
56
|
+
|
|
57
|
+
Open Excel and create a new Workbook. The *xlOil Py* add-in should appear as a new ribbon.
|
|
58
|
+
|
|
59
|
+
Navigate to the *xlOil Py* ribbon and select the Python environment with `xloil` package installed in the *Environment* drop-down menu.
|
|
60
|
+
|
|
61
|
+
Run `=xloVersion()` in a Workbook cell. This should output version and build date details in the Excel cells.
|
|
62
|
+
|
|
63
|
+
Details on getting started with xlOil are documented [here](https://xloil.readthedocs.io/en/stable/xlOil_Python/GettingStarted.html#getting-started).
|
|
64
|
+
|
|
65
|
+
### Install QuantLibXlOil
|
|
66
|
+
|
|
67
|
+
Clone the QuantLibXlOil repository.
|
|
68
|
+
|
|
69
|
+
Add the complete path to `C:\...\QuantLibXlOil\src\` in the *Search Path* tet field.
|
|
70
|
+
|
|
71
|
+
Add `quantlib_xloil` to the *Load Modules* text field. Use comma separator and *no* blanks. The resulting input of the *Load Modules* text field should then be:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
xloil.xloil_ribbon,quantlib_xloil
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Restart Excel and open a blank Workbook.
|
|
78
|
+
|
|
79
|
+
Now, the QuantLibXlOil functions should be available in Excel.
|
|
80
|
+
|
|
81
|
+
Test the QuantLibXlOil functions by typing `=qlVersion()` in an empty cell. This should give the QuantLib version number.
|
|
82
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# QuantLibXlOil
|
|
2
|
+
|
|
3
|
+
QuantLibXlOil is an interface package to make functions of the open-source [QuantLib](https://github.com/lballabio/QuantLib) pricing library available in Excel.
|
|
4
|
+
|
|
5
|
+
The interface builds on the Python bindings for QuantLib via [QuantLib-SWIG](https://github.com/lballabio/QuantLib-SWIG).
|
|
6
|
+
|
|
7
|
+
We use [xlOil](https://github.com/cunnane/xloil) to make the QuantLib Python objects and functions available in Excel.
|
|
8
|
+
|
|
9
|
+
The QuantLibXlOil package largely contains wrapper functions in Python which delegate calls to QuantLib constructors and method/function call. The wrapper functions are made available to Excel via xlOil's function decorator. In addition, the package provides converter functions between Excel data types and QuantLib types.
|
|
10
|
+
|
|
11
|
+
## Why Another QuantLib Interface?
|
|
12
|
+
|
|
13
|
+
Excel is widely adapted in the industry as calculation tool and GUI for a large variety of use cases.
|
|
14
|
+
|
|
15
|
+
QuantLib has the classical [QuantLibXL](https://www.quantlib.org/quantlibxl/) interface for Excel. However, QuantLibXL was last updated for QuantLib v1.22 (April 2021). The QuantLibXL object and interface specification is quite complex and closely linked to QuantLib internals. This makes maintenance quite challenging.
|
|
16
|
+
|
|
17
|
+
The QuantLib Python interface is probably the best QuantLib interface in terms of coverage and maintenance. With the QuantLibXlOil package, we aim at leveraging the matured QuantLib Python interface.
|
|
18
|
+
|
|
19
|
+
As an additional objective, we want to disentangle QuantLib developments from Excel interface development. This is particularly relevant for QuantLib C++ internals. For example, switching from `boost::something` to `std::something` should not affect the Excel interface. This motivates building on top of an existing high-level language interface.
|
|
20
|
+
|
|
21
|
+
Linking between Python and Excel is a well understood task. There are [several tools](https://xloil.readthedocs.io/en/stable/Introduction.html#why-xloil-was-created) that implement that bridge. We opt for xlOil because it is open-source and works well for the use cases tested.
|
|
22
|
+
|
|
23
|
+
## Getting Started
|
|
24
|
+
|
|
25
|
+
The manual way...
|
|
26
|
+
|
|
27
|
+
### Setup Python Environment
|
|
28
|
+
|
|
29
|
+
Set up a Python environment via `conda` or `pip` and with the following packages:
|
|
30
|
+
|
|
31
|
+
- `quanlib-python`,
|
|
32
|
+
- `numpy`,
|
|
33
|
+
- `pandas` (Version 2).
|
|
34
|
+
|
|
35
|
+
### Install xlOil
|
|
36
|
+
|
|
37
|
+
xlOil is available via pip and `pip install xloil`.
|
|
38
|
+
|
|
39
|
+
Install the xlOil Excel add-in by running `xloil install` from the command line of the Python environment.
|
|
40
|
+
|
|
41
|
+
Open Excel and create a new Workbook. The *xlOil Py* add-in should appear as a new ribbon.
|
|
42
|
+
|
|
43
|
+
Navigate to the *xlOil Py* ribbon and select the Python environment with `xloil` package installed in the *Environment* drop-down menu.
|
|
44
|
+
|
|
45
|
+
Run `=xloVersion()` in a Workbook cell. This should output version and build date details in the Excel cells.
|
|
46
|
+
|
|
47
|
+
Details on getting started with xlOil are documented [here](https://xloil.readthedocs.io/en/stable/xlOil_Python/GettingStarted.html#getting-started).
|
|
48
|
+
|
|
49
|
+
### Install QuantLibXlOil
|
|
50
|
+
|
|
51
|
+
Clone the QuantLibXlOil repository.
|
|
52
|
+
|
|
53
|
+
Add the complete path to `C:\...\QuantLibXlOil\src\` in the *Search Path* tet field.
|
|
54
|
+
|
|
55
|
+
Add `quantlib_xloil` to the *Load Modules* text field. Use comma separator and *no* blanks. The resulting input of the *Load Modules* text field should then be:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
xloil.xloil_ribbon,quantlib_xloil
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Restart Excel and open a blank Workbook.
|
|
62
|
+
|
|
63
|
+
Now, the QuantLibXlOil functions should be available in Excel.
|
|
64
|
+
|
|
65
|
+
Test the QuantLibXlOil functions by typing `=qlVersion()` in an empty cell. This should give the QuantLib version number.
|
|
66
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "quantlib_xloil"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
authors = [
|
|
5
|
+
{ name="Sebastian Schlenkrich", email="sebastian.schlenkrich@frame-consult.de" },
|
|
6
|
+
]
|
|
7
|
+
description = "Interface package to make QuantLib pricing library functions available in Excel."
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
requires-python = ">=3.9"
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"Operating System :: Microsoft :: Windows",
|
|
13
|
+
]
|
|
14
|
+
license = "MIT"
|
|
15
|
+
license-files = ["LICEN[CS]E*"]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"QuantLib",
|
|
18
|
+
"xloil",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Homepage = "https://github.com/frame-consulting/QuantLibXlOil"
|
|
23
|
+
Issues = "https://github.com/frame-consulting/QuantLibXlOil/issues"
|
|
24
|
+
|
|
25
|
+
[build-system]
|
|
26
|
+
requires = ["hatchling >= 1.26"]
|
|
27
|
+
build-backend = "hatchling.build"
|
|
28
|
+
|
|
29
|
+
[tool.hatch.version]
|
|
30
|
+
path = "src/quantlib_xloil/__about__.py"
|
|
31
|
+
|
|
32
|
+
[tool.hatch.build.targets.wheel]
|
|
33
|
+
packages = ["src/quantlib_xloil"]
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# QuantLib-Python Wrappers for Excel
|
|
2
|
+
|
|
3
|
+
This folder contains wrapper functions for QuantLib object creation and method calls.
|
|
4
|
+
|
|
5
|
+
We follow the file structure of the [QuantLib-SWIG](https://github.com/lballabio/QuantLib-SWIG/tree/master/SWIG) interface specification to ensure transparency what the functions do.
|
|
6
|
+
|
|
7
|
+
## Implementation Guidelines
|
|
8
|
+
|
|
9
|
+
We apply the following guidelines for function implementation to ensure consistency across the Excel interface.
|
|
10
|
+
|
|
11
|
+
The guidelines aim at mimicking the classical [QuantLibXL](https://github.com/eehlers/QuantLibAddin-Old/tree/master/QuantLibAddin/gensrc/metadata/functions) interface. If necessary or if it is deemed an improvement, we deviate from the QuantLibXL interface.
|
|
12
|
+
|
|
13
|
+
### Function Names
|
|
14
|
+
|
|
15
|
+
We use lower camel case function names with `ql` as prefix.
|
|
16
|
+
|
|
17
|
+
Constructor function are identified by the class name, e.g., `Schedule`. We do not use `CreateSomeObject`, `MakeSomeObject` unless the SWIG interface specifies that function.
|
|
18
|
+
|
|
19
|
+
Class member functions are identified by the class name concatenated with member function name. Class name corresponds to the class where the function is declared.
|
|
20
|
+
|
|
21
|
+
### Function Argument Names and Types
|
|
22
|
+
|
|
23
|
+
Function argument names follow the names of the SWIG interface names.
|
|
24
|
+
|
|
25
|
+
Argument types are specified as type annotations. Build-in types (`str`, `int`, `float`, `bool`) are used directly.
|
|
26
|
+
|
|
27
|
+
Dates from Excel are supplied as serial numbers. We use the `qDate` argument [converter function](https://xloil.readthedocs.io/en/stable/xlOil_Python/TypeConversion.html#custom-type-conversion) for type annotation.
|
|
28
|
+
|
|
29
|
+
QuantLib object types are used directly as type annotations. User-created QuantLib object are stored in the xlOil cache and are supplied by xlOil as objects to the function.
|
|
30
|
+
|
|
31
|
+
For enumerations and enumerated classes (e.g. calendars, day count conventions) we also use converter functions.
|
|
32
|
+
|
|
33
|
+
Lists of inputs are specified as `xlo.Array(dims=1)`. This is applied for any underlying object types. Note that type checking and error handling is advised in the interface function.
|
|
34
|
+
|
|
35
|
+
### Return Types
|
|
36
|
+
|
|
37
|
+
Function results are returned as is.
|
|
38
|
+
|
|
39
|
+
If the result type has a custom argument converter then a corresponding custom return [type conversion] (https://xloil.readthedocs.io/en/stable/xlOil_Python/TypeConversion.html#custom-return-conversion) should be implemented as well.
|
|
40
|
+
|
|
41
|
+
Return type converters are use the function name prefix `x`, e.g., `xDate(...)` for conversion from `ql.Date` to excel serial number.
|
|
42
|
+
|
|
43
|
+
### Function Annotations
|
|
44
|
+
|
|
45
|
+
xlOil function annotations are specified as follows:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
@xlo.func(
|
|
49
|
+
help='One-line docstring.',
|
|
50
|
+
args={
|
|
51
|
+
'Arg1': 'Help on Arg1 parameter.',
|
|
52
|
+
'Arg1': 'Help on Arg1 parameter.',
|
|
53
|
+
},
|
|
54
|
+
group=EXCEL_GROUP_NAME,
|
|
55
|
+
)
|
|
56
|
+
def qlFunctionName(arg1 : Type1, arg2 : Type2, Trigger = None):
|
|
57
|
+
...
|
|
58
|
+
return someThing
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The arguments `help` and `args` are shown in Excel in the *Insert Function* (*fx*) dialog.
|
|
62
|
+
|
|
63
|
+
Use Excel help strings for function and arguments equal/similar as in the classical [QuantLibXL](https://github.com/eehlers/QuantLibAddin-Old/tree/master/QuantLibAddin/gensrc/metadata/functions) interface.
|
|
64
|
+
|
|
65
|
+
Help string is a capitalised sentence finished with punctuation.
|
|
66
|
+
|
|
67
|
+
Excel argument names `Arg1` and `Arg2` equal function argument names but with starting capital letter.
|
|
68
|
+
|
|
69
|
+
No Python docstring or Python docstring equals the Excel help string.
|
|
70
|
+
|
|
71
|
+
### Additional Trigger Function Argument
|
|
72
|
+
|
|
73
|
+
Functions should include an additional `Trigger` argument as specified in the section above. We use a capitalized variable (only) here, because optional parameters are not picked up in the Excel help strings.
|
|
74
|
+
|
|
75
|
+
QuantLib functions (may) depend on session data and QuantLib's internal state. As a consequence, updates may not be propagated through Excel's dependency tree.
|
|
76
|
+
|
|
77
|
+
For example, the `Index.fixing(...)` method depends on the session-specific `evaluationDate`. However, Excel cannot recognise a change in `evaluationDate` and re-calculate an `Index.fixing(...)`.
|
|
78
|
+
|
|
79
|
+
Another example is the method `Instrument.NPV()`. This method requires a preceding call of `Instrument.setPricingEngine(engine)`. However, Excel on its own cannot determine that the pricing engine needs to be linked to the instrument before an NPV can be calculated.
|
|
80
|
+
|
|
81
|
+
To mitigate above limitation, the `Trigger` argument allows specifying additional input cells. That way, the QuantLib dependencies can be reflected in Excel's dependency graph by the user.
|
|
82
|
+
|
|
83
|
+
### Enumerations and Enumerated Classes
|
|
84
|
+
|
|
85
|
+
QuantLib uses various enumerations, e.g., for business day conventions (`Preceding`, `ModifiedFollowing`, `Following`) and volatility types (`Normal`, `ShiftedLognormal`).
|
|
86
|
+
|
|
87
|
+
Similarly, class objects may specify behaviour of functions. Typical examples are `DayCounter` and `Calendar`.
|
|
88
|
+
|
|
89
|
+
Enumerations and enumerated classes are represented by string identifiers in Excel.
|
|
90
|
+
|
|
91
|
+
The string identifiers are mapped to QuantLib objects via (constant) dictionaries as follows.
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
QL_TYPE_NAME = {
|
|
95
|
+
'STRINGIDENTIER' : ql.Type1,
|
|
96
|
+
'STRINGIDENTIER' : ql.Type2,
|
|
97
|
+
...
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Here, `TYPE_NAME` represents the QuantLib type, e.g. `BUSINESS_DAY_CONVENTION`, `CALENDAR`. Camel case names are replaced by upper case names with underscores.
|
|
102
|
+
|
|
103
|
+
Dictionary keys are upper case.
|
|
104
|
+
|
|
105
|
+
Dictionary entries are ordered alphabetically by key.
|
|
106
|
+
|
|
107
|
+
Several identifiers may point to the same QuantLib object, e.g. `MODIFIEDFOLLOWING` and `MF` may point to `ql.ModifiedFollowing` business day convention.
|
|
108
|
+
|
|
109
|
+
Text identifiers follow the [QuantLibXL enumerations specification](https://github.com/eehlers/QuantLibAddin-Old/tree/master/QuantLibAddin/gensrc/metadata/enumerations).
|
|
110
|
+
|
|
111
|
+
### Argument Converter Functions
|
|
112
|
+
|
|
113
|
+
[Argument converters](https://xloil.readthedocs.io/en/stable/xlOil_Python/TypeConversion.html#custom-type-conversion) are specified by `@xlo.converter()` decorator.
|
|
114
|
+
|
|
115
|
+
Argument converter functions typically take an input string (from Excel) and convert it into a QuantLib class object or QuantLib enumeration (int) object.
|
|
116
|
+
|
|
117
|
+
Argument converters also need to handle default values for QuantLib wrapper functions. Default values typically are QuantLib class object or QuantLib enumeration
|
|
118
|
+
|
|
119
|
+
We use the following pattern and naming conventions for argument converters.
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
def _qSomeQuantLibType(s : string) -> ql.SomeQuantLibType
|
|
123
|
+
if isinstance(s, ql.SomeQuantLibType):
|
|
124
|
+
return s
|
|
125
|
+
[do actual conversion]
|
|
126
|
+
return quantlib_object
|
|
127
|
+
|
|
128
|
+
@xlo.converter()
|
|
129
|
+
def qSomeQuantLibType(s : string) -> ql.SomeQuantLibType
|
|
130
|
+
return _qSomeQuantLibType(s)
|
|
131
|
+
|
|
132
|
+
def qlSomeQuantLibFunction(arg : qSomeQuantLibType = ql.SomeDefault())
|
|
133
|
+
...
|
|
134
|
+
return
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The similarities in prefixes `_q`, `q` and `ql.` and the common use of `SomeQuantLibType` naming aims at improving AI coding support.
|
|
138
|
+
|
|
139
|
+
Note that the decorated functions `qSomeQuantLibType` are not accessible in Python. As a consequence, conversion implementation is delegated to separate functions `_qSomeQuantLibType`. The separate functions allow for testing conversions and manually calling conversions (if necessary).
|
|
140
|
+
|
|
141
|
+
## Testing
|
|
142
|
+
|
|
143
|
+
Each function should be covered by a test [here](../../tests/).
|
|
144
|
+
|
|
145
|
+
Details on test case specification are documented [here](../../tests/README.md).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.1"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from __about__ import __version__
|
|
2
|
+
|
|
3
|
+
from quantlib_xloil.calendars import *
|
|
4
|
+
from quantlib_xloil.cashflows import *
|
|
5
|
+
from quantlib_xloil.currencies import *
|
|
6
|
+
from quantlib_xloil.date import *
|
|
7
|
+
from quantlib_xloil.daycounters import *
|
|
8
|
+
from quantlib_xloil.interpolatedyieldcurves import *
|
|
9
|
+
from quantlib_xloil.indexes import *
|
|
10
|
+
from quantlib_xloil.quantlib_ import *
|
|
11
|
+
from quantlib_xloil.rounding import *
|
|
12
|
+
from quantlib_xloil.scheduler import *
|
|
13
|
+
from quantlib_xloil.settings import *
|
|
14
|
+
from quantlib_xloil.termstructures import *
|