quantlib-xloil 0.0.1__py3-none-any.whl
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/README.md +145 -0
- quantlib_xloil/__about__.py +1 -0
- quantlib_xloil/__init__.py +14 -0
- quantlib_xloil/calendars.py +351 -0
- quantlib_xloil/cashflows.py +2337 -0
- quantlib_xloil/config.py +2 -0
- quantlib_xloil/currencies.py +247 -0
- quantlib_xloil/date.py +326 -0
- quantlib_xloil/daycounters.py +107 -0
- quantlib_xloil/indexes.py +1043 -0
- quantlib_xloil/interpolatedyieldcurves.py +157 -0
- quantlib_xloil/quantlib_.py +21 -0
- quantlib_xloil/rounding.py +50 -0
- quantlib_xloil/scheduler.py +405 -0
- quantlib_xloil/settings.py +93 -0
- quantlib_xloil/termstructures.py +367 -0
- quantlib_xloil/utilities.py +22 -0
- quantlib_xloil-0.0.1.dist-info/METADATA +82 -0
- quantlib_xloil-0.0.1.dist-info/RECORD +21 -0
- quantlib_xloil-0.0.1.dist-info/WHEEL +4 -0
- quantlib_xloil-0.0.1.dist-info/licenses/LICENSE +21 -0
quantlib_xloil/README.md
ADDED
|
@@ -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 *
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import QuantLib as ql
|
|
2
|
+
import xloil as xlo
|
|
3
|
+
|
|
4
|
+
from .config import EXCEL_GROUP_NAME
|
|
5
|
+
from .date import qDate, qPeriod, qWeekday, qTimeUnit
|
|
6
|
+
from .utilities import first_key, UNKNOWN_KEY, UNKNOWN_VALUE, enum_value
|
|
7
|
+
|
|
8
|
+
# Todo BespokeCalendars, explicit JointCalendars, JointCalenders and USCalenders
|
|
9
|
+
|
|
10
|
+
QL_CALENDAR= {
|
|
11
|
+
"ARGENTINA": ql.Argentina,
|
|
12
|
+
"AUSTRALIA": ql.Australia,
|
|
13
|
+
"AUSTRIA": ql.Austria,
|
|
14
|
+
"BOTSWANA": ql.Botswana,
|
|
15
|
+
"BRAZIL": ql.Brazil,
|
|
16
|
+
"CANADA": ql.Canada,
|
|
17
|
+
"CHILE": ql.Chile,
|
|
18
|
+
"CHINA": ql.China,
|
|
19
|
+
"CZECHREPUBLIC": ql.CzechRepublic,
|
|
20
|
+
"DENMARK": ql.Denmark,
|
|
21
|
+
"FINLAND": ql.Finland,
|
|
22
|
+
"FRANCE": ql.France,
|
|
23
|
+
"GERMANY": ql.Germany,
|
|
24
|
+
"HONGKONG": ql.HongKong,
|
|
25
|
+
"HUNGARY": ql.Hungary,
|
|
26
|
+
"ICELAND": ql.Iceland,
|
|
27
|
+
"INDIA": ql.India,
|
|
28
|
+
"INDONESIA": ql.Indonesia,
|
|
29
|
+
"ISRAEL": ql.Israel,
|
|
30
|
+
"ITALY": ql.Italy,
|
|
31
|
+
"JAPAN": ql.Japan,
|
|
32
|
+
#"MALTA": ql.Malta,
|
|
33
|
+
"MEXICO": ql.Mexico,
|
|
34
|
+
#"MONTENEGRO": ql.Montenegro,
|
|
35
|
+
"NEWZEALAND": ql.NewZealand,
|
|
36
|
+
#"NORTHMACEDONIA": ql.NorthMacedonia,
|
|
37
|
+
"NORWAY": ql.Norway,
|
|
38
|
+
"POLAND": ql.Poland,
|
|
39
|
+
"ROMANIA": ql.Romania,
|
|
40
|
+
"RUSSIA": ql.Russia,
|
|
41
|
+
"SAUDIARABIA": ql.SaudiArabia,
|
|
42
|
+
#"SERBIA": ql.Serbia,
|
|
43
|
+
"SINGAPORE": ql.Singapore,
|
|
44
|
+
"SLOVAKIA": ql.Slovakia,
|
|
45
|
+
#"SLOVENIA": ql.Slovenia,
|
|
46
|
+
"SOUTHAFRICA": ql.SouthAfrica,
|
|
47
|
+
"SOUTHKOREA": ql.SouthKorea,
|
|
48
|
+
"SWEDEN": ql.Sweden,
|
|
49
|
+
"SWITZERLAND": ql.Switzerland,
|
|
50
|
+
"TAIWAN": ql.Taiwan,
|
|
51
|
+
"TARGET": ql.TARGET,
|
|
52
|
+
"THAILAND": ql.Thailand,
|
|
53
|
+
"TURKEY": ql.Turkey,
|
|
54
|
+
"UKRAINE": ql.Ukraine,
|
|
55
|
+
"UNITEDSTATES": ql.UnitedStates(ql.UnitedStates.NYSE),
|
|
56
|
+
"UNITEDKINGDOM": ql.UnitedKingdom,
|
|
57
|
+
#"UZBEKISTAN": ql.Uzbekistan,
|
|
58
|
+
"NULLCALENDAR": ql.NullCalendar,
|
|
59
|
+
"WEEKENDSONLY": ql.WeekendsOnly,
|
|
60
|
+
"JOINTCALENDAR": ql.JointCalendar,
|
|
61
|
+
UNKNOWN_KEY: UNKNOWN_VALUE,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
QL_BUSINESSDAYCONVENTION = {
|
|
65
|
+
"FOLLOWING": ql.Following,
|
|
66
|
+
"PRECEDING": ql.Preceding,
|
|
67
|
+
"MODIFIEDFOLLOWING": ql.ModifiedFollowing,
|
|
68
|
+
"MODIFIEDPRECEDING": ql.ModifiedPreceding,
|
|
69
|
+
"UNADJUSTED": ql.Unadjusted,
|
|
70
|
+
"HALFMONTHMODIFIEDFOLLOWING": ql.HalfMonthModifiedFollowing,
|
|
71
|
+
"NEAREST": ql.Nearest,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
QL_JOINTCALENDARRULE = {
|
|
75
|
+
"JOINHOLIDAYS": ql.JoinHolidays,
|
|
76
|
+
"JOINBUSINESSDAYS": ql.JoinBusinessDays,
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
def _qCalendar(name : str) -> ql.Calendar:
|
|
80
|
+
if isinstance(name, ql.Calendar): # capture default argument values
|
|
81
|
+
return name
|
|
82
|
+
if isinstance(name, str):
|
|
83
|
+
name = name.strip().upper()
|
|
84
|
+
if name in QL_CALENDAR:
|
|
85
|
+
return QL_CALENDAR[name]()
|
|
86
|
+
raise ValueError(f"Unknown calendar: {name}")
|
|
87
|
+
|
|
88
|
+
@xlo.converter()
|
|
89
|
+
def qCalendar(calendarname : str) -> ql.Calendar:
|
|
90
|
+
return _qCalendar(calendarname)
|
|
91
|
+
|
|
92
|
+
@xlo.returner(target=ql.Calendar, register=True)
|
|
93
|
+
def xCalendar(calendar : ql.Calendar):
|
|
94
|
+
return calendar.name()
|
|
95
|
+
|
|
96
|
+
def _qBusinessDayConvention(conventionname : str):
|
|
97
|
+
return enum_value(conventionname, QL_BUSINESSDAYCONVENTION)
|
|
98
|
+
|
|
99
|
+
@xlo.converter()
|
|
100
|
+
def qBusinessDayConvention(conventionname : str):
|
|
101
|
+
return _qBusinessDayConvention(conventionname)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _qJointCalendarRule(rule_name : str):
|
|
105
|
+
return enum_value(rule_name, QL_JOINTCALENDARRULE)
|
|
106
|
+
|
|
107
|
+
@xlo.converter()
|
|
108
|
+
def qJointCalendarRule(rule_name : str):
|
|
109
|
+
return _qJointCalendarRule(rule_name)
|
|
110
|
+
|
|
111
|
+
@xlo.func(
|
|
112
|
+
help='Return a QuantLib Calendar object given its name.',
|
|
113
|
+
args={
|
|
114
|
+
'CalendarName': 'The name of the calendar.',
|
|
115
|
+
},
|
|
116
|
+
group=EXCEL_GROUP_NAME,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
def qlCalendar(calendar_name: str, Trigger = None) -> ql.Calendar:
|
|
120
|
+
return _qCalendar(calendar_name)
|
|
121
|
+
|
|
122
|
+
@xlo.func(
|
|
123
|
+
help='Check if a day is a weekend day.',
|
|
124
|
+
args={
|
|
125
|
+
'Weekday': 'The day of the week (0=Sunday, 1=Monday, ..., 6=Saturday).',
|
|
126
|
+
},
|
|
127
|
+
group=EXCEL_GROUP_NAME,
|
|
128
|
+
)
|
|
129
|
+
def qlCalendarisWeekend(calendar: qCalendar, weekday: qWeekday, Trigger = None) -> bool:
|
|
130
|
+
return calendar.isWeekend(weekday)
|
|
131
|
+
#weekday in (ql.Saturday, ql.Sunday)
|
|
132
|
+
|
|
133
|
+
@xlo.func(
|
|
134
|
+
help='Return the first day of the month for a given date.',
|
|
135
|
+
args={
|
|
136
|
+
'Date': 'The date for which to find the start of the month.',
|
|
137
|
+
},
|
|
138
|
+
group=EXCEL_GROUP_NAME,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
def qlCalendarStartOfMonth(calendar : qCalendar, date : qDate, Trigger = None) -> ql.Date:
|
|
142
|
+
return calendar.startOfMonth(date)
|
|
143
|
+
#l.Date(ql.startOfMonth(date))
|
|
144
|
+
|
|
145
|
+
@xlo.func(
|
|
146
|
+
help='Return the last day of the month for a given date.',
|
|
147
|
+
args={
|
|
148
|
+
'Date': 'The date for which to find the end of the month.',
|
|
149
|
+
},
|
|
150
|
+
group=EXCEL_GROUP_NAME,
|
|
151
|
+
)
|
|
152
|
+
def qlCalendarEndOfMonth(calendar : qCalendar, date : qDate, Trigger = None) -> ql.Date:
|
|
153
|
+
return calendar.endOfMonth(date)
|
|
154
|
+
#ql.Date(ql.endOfMonth(date))
|
|
155
|
+
|
|
156
|
+
@xlo.func(
|
|
157
|
+
help='Check if a date is a business day.',
|
|
158
|
+
args={
|
|
159
|
+
'Date': 'The date to check.',
|
|
160
|
+
},
|
|
161
|
+
group=EXCEL_GROUP_NAME,
|
|
162
|
+
)
|
|
163
|
+
def qlCalendarIsBusinessDay(calendar : qCalendar, date : qDate, Trigger = None) -> bool:
|
|
164
|
+
return calendar.isBusinessDay(date)
|
|
165
|
+
|
|
166
|
+
@xlo.func(
|
|
167
|
+
help='Check if a date is a holiday.',
|
|
168
|
+
args={
|
|
169
|
+
'Date': 'The date to check.',
|
|
170
|
+
},
|
|
171
|
+
group=EXCEL_GROUP_NAME,
|
|
172
|
+
)
|
|
173
|
+
def qlCalendarIsHoliday(calendar : qCalendar, date : qDate, Trigger = None) -> bool:
|
|
174
|
+
return calendar.isHoliday(date)
|
|
175
|
+
|
|
176
|
+
@xlo.func(
|
|
177
|
+
help='Check if a date is the end of the month.',
|
|
178
|
+
args={
|
|
179
|
+
'Date': 'The date to check.',
|
|
180
|
+
},
|
|
181
|
+
group=EXCEL_GROUP_NAME,
|
|
182
|
+
)
|
|
183
|
+
def qlCalendarIsEndOfMonth(calendar : qCalendar, date : qDate, Trigger = None) -> bool:
|
|
184
|
+
return calendar.isEndOfMonth(date)
|
|
185
|
+
|
|
186
|
+
@xlo.func(
|
|
187
|
+
help='Check if a date is the start of the month.',
|
|
188
|
+
args={
|
|
189
|
+
'Date': 'The date to check.',
|
|
190
|
+
},
|
|
191
|
+
group=EXCEL_GROUP_NAME,
|
|
192
|
+
)
|
|
193
|
+
def qlCalendarIsStartOfMonth(calendar : qCalendar, date : qDate, Trigger = None) -> bool:
|
|
194
|
+
return calendar.isStartOfMonth(date)
|
|
195
|
+
|
|
196
|
+
@xlo.func(
|
|
197
|
+
help='Add a holiday to the calendar.',
|
|
198
|
+
args={
|
|
199
|
+
'Date': 'The date to add as a holiday.',
|
|
200
|
+
},
|
|
201
|
+
group=EXCEL_GROUP_NAME,
|
|
202
|
+
)
|
|
203
|
+
def qlCalendarAddHoliday(calendar : qCalendar, date : qDate, Trigger = None) -> None:
|
|
204
|
+
calendar.addHoliday(date)
|
|
205
|
+
|
|
206
|
+
@xlo.func(
|
|
207
|
+
help='Remove a holiday from the calendar.',
|
|
208
|
+
args={
|
|
209
|
+
'Date': 'The date to remove as a holiday.',
|
|
210
|
+
},
|
|
211
|
+
group=EXCEL_GROUP_NAME,
|
|
212
|
+
)
|
|
213
|
+
def qlCalendarRemoveHoliday(calendar :qCalendar, date : qDate, Trigger = None) -> None:
|
|
214
|
+
calendar.removeHoliday(date)
|
|
215
|
+
|
|
216
|
+
@xlo.func(
|
|
217
|
+
help='Reset the added and removed holidays for the calendar.',
|
|
218
|
+
args={},
|
|
219
|
+
group=EXCEL_GROUP_NAME,
|
|
220
|
+
)
|
|
221
|
+
def qlCalendarResetAddedAndRemovedHolidays(calendar : qCalendar, Trigger = None) -> None:
|
|
222
|
+
calendar.resetAddedAndRemovedHolidays()
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@xlo.func(
|
|
226
|
+
help='Adjust a date according to the calendar and business day convention.',
|
|
227
|
+
args={
|
|
228
|
+
'Date': 'The date to adjust.',
|
|
229
|
+
'Calendar': 'The calendar to use for adjustment.',
|
|
230
|
+
'Convention': 'The business day convention to apply.',
|
|
231
|
+
},
|
|
232
|
+
group=EXCEL_GROUP_NAME,
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
def qlCalendarAdjust(calendar : qCalendar, date : qDate, convention : qBusinessDayConvention = "Following", Trigger = None) -> ql.Date:
|
|
236
|
+
return calendar.adjust(date, convention)
|
|
237
|
+
|
|
238
|
+
@xlo.func(
|
|
239
|
+
help='Advance a date by a given number of time units according to the calendar and business day convention.',
|
|
240
|
+
args={
|
|
241
|
+
'Date': 'The date to advance.',
|
|
242
|
+
'Calendar': 'The calendar to use for advancement.',
|
|
243
|
+
'n': 'The number of time units to advance',
|
|
244
|
+
'unit': 'The time unit to advance (e.g. "DAYS", "MONTHS", "YEARS").',
|
|
245
|
+
'Convention': 'The business day convention to apply.',
|
|
246
|
+
'EndOfMonth': 'Whether to adjust to the end of the month.',
|
|
247
|
+
},
|
|
248
|
+
group=EXCEL_GROUP_NAME,
|
|
249
|
+
)
|
|
250
|
+
def qlCalendarAdvance(calendar : qCalendar, date : qDate, n : int, unit : qTimeUnit, convention : qBusinessDayConvention = "Following", end_of_month : bool = False, Trigger = None) -> ql.Date:
|
|
251
|
+
return calendar.advance(date, n, unit, convention, end_of_month)
|
|
252
|
+
|
|
253
|
+
@xlo.func(
|
|
254
|
+
help='Advance a date by a given period according to the calendar and business day convention.',
|
|
255
|
+
args={
|
|
256
|
+
'Date': 'The date to advance.',
|
|
257
|
+
'Calendar': 'The calendar to use for advancement.',
|
|
258
|
+
'Period': 'The period by which to advance.',
|
|
259
|
+
'Convention': 'The business day convention to apply.',
|
|
260
|
+
'EndOfMonth': 'Whether to adjust to the end of the month.',
|
|
261
|
+
},
|
|
262
|
+
group=EXCEL_GROUP_NAME,
|
|
263
|
+
)
|
|
264
|
+
def qlCalendarAdvance2(calendar : qCalendar, date : qDate, period : qPeriod, convention : qBusinessDayConvention = "Following", end_of_month : bool = False, Trigger = None) -> ql.Date:
|
|
265
|
+
return calendar.advance(date, period, convention, end_of_month)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
@xlo.func(
|
|
269
|
+
help='Return the number of business days between two QuantLib Dates according to the calendar.',
|
|
270
|
+
args={
|
|
271
|
+
'Calendar': 'The calendar to use.',
|
|
272
|
+
'FromDate': 'The starting date.',
|
|
273
|
+
'ToDate': 'The ending date.',
|
|
274
|
+
'IncludeFirst': 'Whether to include the first date.',
|
|
275
|
+
'IncludeLast': 'Whether to include the last date.',
|
|
276
|
+
},
|
|
277
|
+
group=EXCEL_GROUP_NAME,
|
|
278
|
+
)
|
|
279
|
+
def qlCalendarBusinessDaysBetween(calendar : qCalendar, from_date : qDate, to_date : qDate, includeFirst : bool = True, includeLast : bool = False, Trigger = None) -> int:
|
|
280
|
+
return calendar.businessDaysBetween(from_date, to_date, includeFirst, includeLast)
|
|
281
|
+
|
|
282
|
+
@xlo.func(
|
|
283
|
+
help='Return the list of holidays in the calendar.',
|
|
284
|
+
args={
|
|
285
|
+
'Calendar': 'The calendar for which to list holidays.',
|
|
286
|
+
},
|
|
287
|
+
group=EXCEL_GROUP_NAME,
|
|
288
|
+
)
|
|
289
|
+
def qlCalendarHolidayList(calendar : qCalendar, from_date : qDate, to_date : qDate,Trigger = None) -> list:
|
|
290
|
+
return list(calendar.holidayList(from_date, to_date))
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@xlo.func(
|
|
294
|
+
help='Return the list of business days in the calendar.',
|
|
295
|
+
args={
|
|
296
|
+
'Calendar': 'The calendar for which to list business days.',
|
|
297
|
+
},
|
|
298
|
+
group=EXCEL_GROUP_NAME,
|
|
299
|
+
)
|
|
300
|
+
def qlCalendarBusinessDayList(calendar : qCalendar, from_date : qDate, to_date : qDate, Trigger = None) -> list:
|
|
301
|
+
return list(calendar.businessDayList(from_date, to_date))
|
|
302
|
+
|
|
303
|
+
@xlo.func(
|
|
304
|
+
help='Return the name of the calendar.',
|
|
305
|
+
args={
|
|
306
|
+
'Calendar': 'The calendar for which to get the name.',
|
|
307
|
+
},
|
|
308
|
+
group=EXCEL_GROUP_NAME,
|
|
309
|
+
)
|
|
310
|
+
def qlCalendarName(calendar : qCalendar, Trigger = None) -> str:
|
|
311
|
+
return calendar.name()
|
|
312
|
+
|
|
313
|
+
@xlo.func(
|
|
314
|
+
help='Check if the calendar is empty.',
|
|
315
|
+
args={
|
|
316
|
+
'Calendar': 'The calendar to check.',
|
|
317
|
+
},
|
|
318
|
+
group=EXCEL_GROUP_NAME,
|
|
319
|
+
)
|
|
320
|
+
def qlCalendarEmpty(calendar : qCalendar, Trigger = None) -> bool:
|
|
321
|
+
return calendar.empty()
|
|
322
|
+
|
|
323
|
+
@xlo.func(
|
|
324
|
+
help='Return a calendar that represents the union of two calendars.',
|
|
325
|
+
args={
|
|
326
|
+
'Calendar1': 'The first calendar.',
|
|
327
|
+
'Calendar2': 'The second calendar.',
|
|
328
|
+
'Rule': 'The rule for combining the calendars.',
|
|
329
|
+
},
|
|
330
|
+
group=EXCEL_GROUP_NAME,
|
|
331
|
+
)
|
|
332
|
+
def qlCalendarJointCalendar(calendar1 : qCalendar, calendar2 : qCalendar, rule : qJointCalendarRule = "JOINHOLIDAYS") -> ql.Calendar:
|
|
333
|
+
return ql.JointCalendar(calendar1, calendar2, rule)
|
|
334
|
+
|
|
335
|
+
@xlo.func(
|
|
336
|
+
help='Return a calendar that represents the union of three calendars.',
|
|
337
|
+
args={
|
|
338
|
+
'Calendar1': 'The first calendar.',
|
|
339
|
+
'Calendar2': 'The second calendar.',
|
|
340
|
+
'Calendar3': 'The third calendar.',
|
|
341
|
+
'Rule': 'The rule for combining the calendars.',
|
|
342
|
+
},
|
|
343
|
+
group=EXCEL_GROUP_NAME,
|
|
344
|
+
)
|
|
345
|
+
def qlCalendarJointCalendar2(calendar1 : qCalendar, calendar2 : qCalendar, calendar3 : qCalendar, rule : qJointCalendarRule = "JOINHOLIDAYS", Trigger = None) -> ql.Calendar:
|
|
346
|
+
return ql.JointCalendar(calendar1, calendar2, calendar3, rule)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
|