rlquantdata 0.1.0__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.

Potentially problematic release.


This version of rlquantdata might be problematic. Click here for more details.

@@ -0,0 +1,319 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import re
4
+ from math import floor
5
+
6
+ from src.rlquantdata.DateUtilities.Date_enum import TimeUnits
7
+ from src.rlquantdata.DateUtilities.Asserts import require, ensureRaise
8
+
9
+ _unitPattern = re.compile('[BbDdMmWwYy]{1}')
10
+ _numberPattern = re.compile('[-+]*[0-9]+')
11
+
12
+ _unitsDict = {'d': TimeUnits.Days,
13
+ 'b': TimeUnits.BDays,
14
+ 'w': TimeUnits.Weeks,
15
+ 'm': TimeUnits.Months,
16
+ 'y': TimeUnits.Years}
17
+
18
+
19
+ class Period(object):
20
+
21
+ def __init__(self, reprStr=None, length=0, units=0):
22
+
23
+ n: int
24
+ unitsStr: str
25
+
26
+ if reprStr:
27
+ unitsPos = _unitPattern.search(reprStr)
28
+ numPos = _numberPattern.search(reprStr)
29
+ unitsStr = reprStr[unitsPos.start():unitsPos.end()].lower()
30
+ n = int(reprStr[numPos.start():numPos.end()])
31
+ self._length = n
32
+ self._units = _unitsDict[unitsStr]
33
+ else:
34
+ self._length = length
35
+ self._units = units
36
+
37
+ def length(self):
38
+ return self._length
39
+
40
+ def units(self):
41
+ return self._units
42
+
43
+ def normalize(self):
44
+ length = self.length()
45
+ units = self.units()
46
+ if length != 0:
47
+ if units == TimeUnits.BDays or units == TimeUnits.Weeks or units == TimeUnits.Years:
48
+ return Period(length=length, units=units)
49
+ elif units == TimeUnits.Months:
50
+ if length % 12 == 0:
51
+ length //= 12
52
+ units = TimeUnits.Years
53
+ return Period(length=length, units=units)
54
+ elif units == TimeUnits.Days:
55
+ if length % 7 == 0:
56
+ length //= 7
57
+ units = TimeUnits.Weeks
58
+ return Period(length=length, units=units)
59
+ else:
60
+ ensureRaise(TypeError, "wrong period units type {0}".format(units))
61
+
62
+ def __div__(self, n):
63
+
64
+ resunits = self.units()
65
+ reslength = self.length()
66
+
67
+ if reslength % n == 0:
68
+ reslength /= n
69
+ else:
70
+ if resunits == TimeUnits.Years:
71
+ reslength *= 12
72
+ resunits = TimeUnits.Months
73
+ elif resunits == TimeUnits.Weeks:
74
+ reslength *= 7
75
+ resunits = TimeUnits.Days
76
+
77
+ require(reslength % n == 0, ValueError, "{0} cannot be divided by {1:d}".format(self, n))
78
+
79
+ reslength //= n
80
+
81
+ return Period(length=reslength, units=resunits)
82
+
83
+ # only work for python 3
84
+ def __truediv__(self, n):
85
+
86
+ resunits = self.units()
87
+ reslength = self.length()
88
+
89
+ if reslength % n == 0:
90
+ reslength /= n
91
+ else:
92
+ if resunits == TimeUnits.Years:
93
+ reslength *= 12
94
+ resunits = TimeUnits.Months
95
+ elif resunits == TimeUnits.Weeks:
96
+ reslength *= 7
97
+ resunits = TimeUnits.Days
98
+
99
+ require(reslength % n == 0, ValueError, "{0} cannot be divided by {1:d}".format(self, n))
100
+ reslength //= n
101
+
102
+ return Period(length=reslength, units=resunits)
103
+
104
+ def __add__(self, p2):
105
+
106
+ reslength = self.length()
107
+ resunits = self.units()
108
+ p2length = p2.length()
109
+ p2units = p2.units()
110
+
111
+ if reslength == 0:
112
+ return Period(length=p2length, units=p2units)
113
+ elif resunits == p2units:
114
+ reslength += p2length
115
+ return Period(length=reslength, units=resunits)
116
+ else:
117
+ if resunits == TimeUnits.Years:
118
+ if p2units == TimeUnits.Months:
119
+ resunits = TimeUnits.Months
120
+ reslength = reslength * 12 + p2length
121
+ elif p2units == TimeUnits.Weeks or p2units == TimeUnits.Days or p2units == TimeUnits.BDays:
122
+ require(p2length == 0, ValueError, "impossible addition between {0} and {1}".format(self, p2))
123
+ else:
124
+ raise ValueError("unknown time unit ({0:d})".format(p2units))
125
+ return Period(length=reslength, units=resunits)
126
+ elif resunits == TimeUnits.Months:
127
+ if p2units == TimeUnits.Years:
128
+ reslength += 12 * p2length
129
+ elif p2units == TimeUnits.Weeks or p2units == TimeUnits.Days or p2units == TimeUnits.BDays:
130
+ require(p2length == 0, ValueError, "impossible addition between {0} and {1}".format(self, p2))
131
+ else:
132
+ raise ValueError("unknown time unit ({0:d})".format(p2units))
133
+ return Period(length=reslength, units=resunits)
134
+ elif resunits == TimeUnits.Weeks:
135
+ if p2units == TimeUnits.Days:
136
+ resunits = TimeUnits.Days
137
+ reslength = reslength * 7 + p2length
138
+ elif p2units == TimeUnits.Years or p2units == TimeUnits.Months or p2units == TimeUnits.BDays:
139
+ require(p2length == 0, ValueError, "impossible addition between {0} and {1}".format(self, p2))
140
+ else:
141
+ raise ValueError("unknown time unit ({0:d})".format(p2units))
142
+ return Period(length=reslength, units=resunits)
143
+ elif resunits == TimeUnits.Days:
144
+ if p2units == TimeUnits.Weeks:
145
+ reslength += 7 * p2length
146
+ elif p2units == TimeUnits.Years or p2units == TimeUnits.Months or p2units == TimeUnits.BDays:
147
+ require(p2length == 0, ValueError, "impossible addition between {0} and {1}".format(self, p2))
148
+ else:
149
+ raise ValueError("unknown time unit ({0:d})".format(p2units))
150
+ return Period(length=reslength, units=resunits)
151
+ elif resunits == TimeUnits.BDays:
152
+ if p2units == TimeUnits.Years or p2units == TimeUnits.Months or p2units == TimeUnits.Weeks or p2units == TimeUnits.Days:
153
+ require(p2length == 0, ValueError, "impossible addition between {0} and {1}".format(self, p2))
154
+ else:
155
+ raise ValueError("unknown time unit ({0:d})".format(p2units))
156
+ return Period(length=reslength, units=resunits)
157
+
158
+ def __neg__(self):
159
+ return Period(length=-self.length(), units=self.units())
160
+
161
+ def __sub__(self, p2):
162
+ return self + (-p2)
163
+
164
+ def __str__(self):
165
+ out = ""
166
+ n = self.length()
167
+ m = 0
168
+ units = self.units()
169
+
170
+ if units == TimeUnits.Days:
171
+ if n >= 7:
172
+ m = int(floor(n / 7, ))
173
+ out = '{0}W'.format(m)
174
+ n %= 7
175
+ if n != 0 or m == 0:
176
+ return '{0}{1}D'.format(out, n)
177
+ else:
178
+ return out
179
+ elif units == TimeUnits.Weeks:
180
+ return '{0}W'.format(n)
181
+ elif units == TimeUnits.Months:
182
+ if n >= 12:
183
+ m = int(floor(n / 12.))
184
+ out = '{0}Y'.format(m)
185
+ n %= 12
186
+ if n != 0 or m == 0:
187
+ return '{0}{1}M'.format(out, n)
188
+ else:
189
+ return out
190
+ elif units == TimeUnits.Years:
191
+ return '{0}Y'.format(n)
192
+ elif units == TimeUnits.BDays:
193
+ return '{0}B'.format(n)
194
+
195
+ def __deepcopy__(self, memo):
196
+ return Period(length=self.length(), units=self.units())
197
+
198
+ def __reduce__(self):
199
+ d = {}
200
+
201
+ return Period, (None, self.length(), self.units()), d
202
+
203
+ def __setstate__(self, state):
204
+ pass
205
+
206
+ def __lt__(self, right):
207
+ return _lt_cmp(self, right)
208
+
209
+ def __eq__(self, right):
210
+ return not (_lt_cmp(self, right) or _lt_cmp(right, self))
211
+
212
+ def __ne__(self, right):
213
+ return _lt_cmp(self, right) or _lt_cmp(right, self)
214
+
215
+ def __gt__(self, right):
216
+ return _lt_cmp(right, self)
217
+
218
+
219
+ def check_period(p):
220
+ if isinstance(p, Period):
221
+ return p
222
+ else:
223
+ return Period(p)
224
+
225
+
226
+ # implementation detail
227
+
228
+ def _lt_cmp(p1, p2):
229
+ p1lim: tuple
230
+ p2lim: tuple
231
+ p1length = p1.length()
232
+ p1units = p1.units()
233
+ p2length = p2.length()
234
+ p2units = p2.units()
235
+
236
+ if p1length == 0:
237
+ return p2length > 0
238
+
239
+ if p2length == 0:
240
+ return p1length < 0
241
+
242
+ # exact comparisons
243
+ if p1units == p2units:
244
+ return p1length < p2length
245
+ elif p1units == TimeUnits.Months and p2units == TimeUnits.Years:
246
+ return p1length < (p2length * 12)
247
+ elif p1units == TimeUnits.Years and p2units == TimeUnits.Months:
248
+ return (p1length * 12) < p2length
249
+ elif p1units == TimeUnits.Days and p2units == TimeUnits.Weeks:
250
+ return p1length < (p2length * 7)
251
+ elif p1units == TimeUnits.Weeks and p2units == TimeUnits.Days:
252
+ return (p1length * 7) < p2length
253
+
254
+ # inexact comparisons (handled by converting to days and using limits)
255
+
256
+ p1lim = _daysMinMax(p1)
257
+ p2lim = _daysMinMax(p2)
258
+
259
+ if p1lim[1] < p2lim[0]:
260
+ return True
261
+ elif p1lim[0] >= p2lim[1]:
262
+ return False
263
+ else:
264
+ ensureRaise(ValueError, "undecidable comparison between {0} and {1}".format(p1, p2))
265
+
266
+
267
+ def _daysMinMax(p):
268
+ units = p.units()
269
+ length = p.length()
270
+
271
+ if units == TimeUnits.Days:
272
+ return length, length
273
+ elif units == TimeUnits.Weeks:
274
+ return 7 * length, 7 * length
275
+ elif units == TimeUnits.Months:
276
+ return 28 * length, 31 * length
277
+ elif units == TimeUnits.Years:
278
+ return 365 * length, 366 * length
279
+ elif units == TimeUnits.BDays:
280
+ ensureRaise(ValueError, "Business days unit has not min max days")
281
+
282
+
283
+ def _lt_cmp(p1, p2):
284
+ p1lim: tuple
285
+ p2lim: tuple
286
+ p1length = p1.length()
287
+ p1units = p1.units()
288
+ p2length = p2.length()
289
+ p2units = p2.units()
290
+
291
+ if p1length == 0:
292
+ return p2length > 0
293
+
294
+ if p2length == 0:
295
+ return p1length < 0
296
+
297
+ # exact comparisons
298
+ if p1units == p2units:
299
+ return p1length < p2length
300
+ elif p1units == TimeUnits.Months and p2units == TimeUnits.Years:
301
+ return p1length < (p2length * 12)
302
+ elif p1units == TimeUnits.Years and p2units == TimeUnits.Months:
303
+ return (p1length * 12) < p2length
304
+ elif p1units == TimeUnits.Days and p2units == TimeUnits.Weeks:
305
+ return p1length < (p2length * 7)
306
+ elif p1units == TimeUnits.Weeks and p2units == TimeUnits.Days:
307
+ return (p1length * 7) < p2length
308
+
309
+ # inexact comparisons (handled by converting to days and using limits)
310
+
311
+ p1lim = _daysMinMax(p1)
312
+ p2lim = _daysMinMax(p2)
313
+
314
+ if p1lim[1] < p2lim[0]:
315
+ return True
316
+ elif p1lim[0] >= p2lim[1]:
317
+ return False
318
+ else:
319
+ ensureRaise(ValueError, "undecidable comparison between {0} and {1}".format(p1, p2))
@@ -0,0 +1,309 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from src.rlquantdata.DateUtilities.Date_enum import BizDayConventions, DateGeneration, TimeUnits
4
+ from src.rlquantdata.DateUtilities.Date import Date
5
+ from src.rlquantdata.DateUtilities.Period import Period
6
+ from src.rlquantdata.DateUtilities.Calendar import Calendar
7
+ from src.rlquantdata.DateUtilities.Settings import Settings
8
+ from src.rlquantdata.DateUtilities.Asserts import require
9
+
10
+
11
+ class Schedule(object):
12
+
13
+ def __init__(self,
14
+ effectiveDate,
15
+ terminationDate,
16
+ tenor,
17
+ calendar,
18
+ convention=BizDayConventions.Following,
19
+ terminationConvention=BizDayConventions.Following,
20
+ dateGenerationRule=DateGeneration.Forward,
21
+ endOfMonth=False,
22
+ firstDate=None,
23
+ nextToLastDate=None):
24
+
25
+ i: int
26
+ dateLen: int
27
+ nullCalendar: Calendar
28
+ evalDate: Date
29
+ y: int
30
+ periods: int
31
+ seed: Date
32
+ temp: Date
33
+ exitDate: Date
34
+
35
+ # Initialize private data
36
+ self._effectiveDate = effectiveDate
37
+ self._terminationDate = terminationDate
38
+ self._tenor = tenor
39
+ self._cal = calendar
40
+ self._convention = convention
41
+ self._terminationConvention = terminationConvention
42
+ self._rule = dateGenerationRule
43
+ self._dates = []
44
+ self._isRegular = []
45
+
46
+ if tenor < Period("1M"):
47
+ self._endOfMonth = False
48
+ else:
49
+ self._endOfMonth = endOfMonth
50
+
51
+ if not firstDate or firstDate == effectiveDate:
52
+ self._firstDate = None
53
+ else:
54
+ self._firstDate = firstDate
55
+
56
+ if not nextToLastDate or nextToLastDate == terminationDate:
57
+ self._nextToLastDate = None
58
+ else:
59
+ self._nextToLastDate = nextToLastDate
60
+
61
+ # in many cases (e.g. non-expired bonds) the effective date is not
62
+ # really necessary. In these cases a decent placeholder is enough
63
+ if not effectiveDate and not firstDate and dateGenerationRule == DateGeneration.Backward:
64
+ evalDate = Settings.evaluationDate
65
+ require(evalDate < terminationDate, ValueError, "null effective date")
66
+ if nextToLastDate:
67
+ y = int((nextToLastDate - evalDate) / 366) + 1
68
+ effectiveDate = nextToLastDate - Period(length=y, units=TimeUnits.Years)
69
+ else:
70
+ y = int((terminationDate - evalDate) / 366) + 1
71
+ effectiveDate = terminationDate - Period(length=y, units=TimeUnits.Years)
72
+ else:
73
+ require(effectiveDate, ValueError, "null effective date")
74
+
75
+ require(effectiveDate < terminationDate, ValueError, "effective date ({0}) "
76
+ "later than or equal to termination date ({1}"
77
+ .format(effectiveDate, terminationDate))
78
+
79
+ if tenor.length() == 0:
80
+ self._rule = DateGeneration.Zero
81
+ else:
82
+ require(tenor.length() > 0, ValueError, "non positive tenor ({0:d}) not allowed".format(tenor.length()))
83
+
84
+ if self._firstDate:
85
+ if self._rule == DateGeneration.Backward or self._rule == DateGeneration.Forward:
86
+ require(effectiveDate < self._firstDate < terminationDate, ValueError,
87
+ "first date ({0}) out of effective-termination date range [{1}, {2})"
88
+ .format(self._firstDate, effectiveDate, terminationDate))
89
+ # we should ensure that the above condition is still
90
+ # verified after adjustment
91
+ elif self._rule == DateGeneration.Zero:
92
+ raise ValueError("first date incompatible with {0:d} date generation rule".format(self._rule))
93
+ else:
94
+ raise ValueError("unknown rule ({0:d})".format(self._rule))
95
+
96
+ if self._nextToLastDate:
97
+ if self._rule == DateGeneration.Backward or self._rule == DateGeneration.Forward:
98
+ require(effectiveDate < self._nextToLastDate < terminationDate, ValueError,
99
+ "next to last date ({0}) out of effective-termination date range [{1}, {2})"
100
+ .format(self._nextToLastDate, effectiveDate, terminationDate))
101
+ # we should ensure that the above condition is still
102
+ # verified after adjustment
103
+ elif self._rule == DateGeneration.Zero:
104
+ raise ValueError("next to last date incompatible with {0:d} date generation rule".format(self._rule))
105
+ else:
106
+ raise ValueError("unknown rule ({0:d})".format(self._rule))
107
+
108
+ # calendar needed for endOfMonth adjustment
109
+ nullCalendar = Calendar("Null")
110
+ periods = 1
111
+
112
+ if self._rule == DateGeneration.Zero:
113
+ self._tenor = Period(length=0, units=TimeUnits.Years)
114
+ self._dates.extend([effectiveDate, terminationDate])
115
+ self._isRegular.append(True)
116
+ elif self._rule == DateGeneration.Backward:
117
+ self._dates.append(terminationDate)
118
+ seed = terminationDate
119
+ if self._nextToLastDate:
120
+ self._dates.insert(0, self._nextToLastDate)
121
+ temp = nullCalendar.advanceDate(seed,
122
+ Period(length=-periods * self._tenor.length(),
123
+ units=self._tenor.units()),
124
+ convention, self._endOfMonth)
125
+ if temp != self._nextToLastDate:
126
+ self._isRegular.insert(0, False)
127
+ else:
128
+ self._isRegular.insert(0, True)
129
+ seed = self._nextToLastDate
130
+
131
+ exitDate = effectiveDate
132
+ if self._firstDate:
133
+ exitDate = self._firstDate
134
+
135
+ while True:
136
+ temp = nullCalendar.advanceDate(seed,
137
+ Period(length=-periods * self._tenor.length(),
138
+ units=self._tenor.units()),
139
+ convention, self._endOfMonth)
140
+ if temp < exitDate:
141
+ if self._firstDate and self._cal.adjustDate(self._dates[0], convention) != self._cal.adjustDate(
142
+ self._firstDate, convention):
143
+ self._dates.insert(0, self._firstDate)
144
+ self._isRegular.insert(0, False)
145
+ break
146
+ else:
147
+ # skip dates that would result in duplicates
148
+ # after adjustment
149
+ if self._cal.adjustDate(self._dates[0], convention) != self._cal.adjustDate(temp, convention):
150
+ self._dates.insert(0, temp)
151
+ self._isRegular.insert(0, True)
152
+ periods += 1
153
+
154
+ if self._cal.adjustDate(self._dates[0], convention) != self._cal.adjustDate(effectiveDate, convention):
155
+ self._dates.insert(0, effectiveDate)
156
+ self._isRegular.insert(0, False)
157
+
158
+ elif self._rule == DateGeneration.Forward:
159
+ self._dates.append(effectiveDate)
160
+
161
+ seed = self._dates[-1]
162
+
163
+ if self._firstDate:
164
+ self._dates.append(self._firstDate)
165
+ temp = nullCalendar.advanceDate(seed,
166
+ Period(length=periods * self._tenor.length(),
167
+ units=self._tenor.units()),
168
+ convention, self._endOfMonth)
169
+ if temp != self._firstDate:
170
+ self._isRegular.append(False)
171
+ else:
172
+ self._isRegular.append(True)
173
+ seed = self._firstDate
174
+
175
+ exitDate = terminationDate
176
+ if self._nextToLastDate:
177
+ exitDate = self._nextToLastDate
178
+
179
+ while True:
180
+ temp = nullCalendar.advanceDate(seed,
181
+ Period(length=periods * self._tenor.length(),
182
+ units=self._tenor.units()),
183
+ convention, self._endOfMonth)
184
+ if temp > exitDate:
185
+ if self._nextToLastDate and self._cal.adjustDate(self._dates[-1],
186
+ convention) != self._cal.adjustDate(
187
+ self._nextToLastDate, convention):
188
+ self._dates.append(self._nextToLastDate)
189
+ self._isRegular.append(False)
190
+ break
191
+ else:
192
+ # skip dates that would result in duplicates
193
+ # after adjustment
194
+ if self._cal.adjustDate(self._dates[-1], convention) != self._cal.adjustDate(temp, convention):
195
+ self._dates.append(temp)
196
+ self._isRegular.append(True)
197
+ periods += 1
198
+
199
+ if self._cal.adjustDate(self._dates[-1], terminationConvention) != self._cal.adjustDate(terminationDate,
200
+ terminationConvention):
201
+ self._dates.append(terminationDate)
202
+ self._isRegular.append(False)
203
+ else:
204
+ raise ValueError("unknown rule ({0:d})".format(self._rule))
205
+
206
+ # adjustments
207
+ if self._endOfMonth and self._cal.isEndOfMonth(seed):
208
+ # adjust to end of month
209
+ if convention == BizDayConventions.Unadjusted:
210
+ for i in range(len(self._dates) - 1):
211
+ self._dates[i] = Date.endOfMonth(self._dates[i])
212
+ else:
213
+ for i in range(len(self._dates) - 1):
214
+ self._dates[i] = self._cal.endOfMonth(self._dates[i])
215
+
216
+ if terminationConvention != BizDayConventions.Unadjusted:
217
+ self._dates[0] = self._cal.endOfMonth(self._dates[0])
218
+ self._dates[-1] = self._cal.endOfMonth(self._dates[-1])
219
+ else:
220
+ if self._rule == DateGeneration.Backward:
221
+ self._dates[-1] = Date.endOfMonth(self._dates[-1])
222
+ else:
223
+ self._dates[0] = Date.endOfMonth(self._dates[0])
224
+ else:
225
+ for i in range(len(self._dates) - 1):
226
+ self._dates[i] = self._cal.adjustDate(self._dates[i], convention)
227
+
228
+ if terminationConvention != BizDayConventions.Unadjusted:
229
+ self._dates[-1] = self._cal.adjustDate(self._dates[-1], terminationConvention)
230
+
231
+ # Final safety checks to remove extra next-to-last date, if
232
+ # necessary. It can happen to be equal or later than the end
233
+ # date due to EOM adjustments (see the Schedule test suite
234
+ # for an example).
235
+
236
+ dateLen = len(self._dates)
237
+
238
+ if dateLen >= 2 and self._dates[dateLen - 2] >= self._dates[-1]:
239
+ self._isRegular[dateLen - 2] = (self._dates[dateLen - 2] == self._dates[-1])
240
+ self._dates[dateLen - 2] = self._dates[-1]
241
+ self._dates.pop()
242
+ self._isRegular.pop()
243
+
244
+ if len(self._dates) >= 2 and self._dates[1] <= self._dates[0]:
245
+ self._isRegular[1] = (self._dates[1] == self._dates[0])
246
+ self._dates[1] = self._dates[0]
247
+ self._dates = self._dates[1:]
248
+ self._isRegular = self._isRegular[1:]
249
+
250
+ require(len(self._dates) >= 1, ValueError, "degenerate single date ({0}) schedule\n"
251
+ "seed date: {1}\n"
252
+ "exit date: {2}\n"
253
+ "effective date: {3}\n"
254
+ "first date: {4}\n"
255
+ "next to last date: {5}\n"
256
+ "termination date: {6}\n"
257
+ "generation rule: {7}\n"
258
+ "end of month: {8}\n"
259
+ .format(self._dates[0],
260
+ seed, exitDate,
261
+ effectiveDate,
262
+ firstDate,
263
+ nextToLastDate,
264
+ terminationDate,
265
+ self._rule, self._endOfMonth))
266
+
267
+ def size(self):
268
+ return len(self._dates)
269
+
270
+ def calendar(self):
271
+ return self._cal
272
+
273
+ def tenor(self):
274
+ return self._tenor
275
+
276
+ def endOfMonth(self):
277
+ return self._endOfMonth
278
+
279
+ def isRegular(self, i):
280
+ return self._isRegular[i - 1]
281
+
282
+ def __getitem__(self, item):
283
+ return self._dates[item]
284
+
285
+ def __deepcopy__(self, memo):
286
+ return Schedule(self._effectiveDate,
287
+ self._terminationDate,
288
+ self._tenor,
289
+ self._cal,
290
+ self._convention,
291
+ self._terminationConvention,
292
+ self._rule,
293
+ self._endOfMonth,
294
+ self._firstDate,
295
+ self._nextToLastDate)
296
+
297
+ def __reduce__(self):
298
+ d = {}
299
+
300
+ return Schedule, (self._effectiveDate,
301
+ self._terminationDate,
302
+ self._tenor,
303
+ self._cal,
304
+ self._convention,
305
+ self._terminationConvention,
306
+ self._rule,
307
+ self._endOfMonth,
308
+ self._firstDate,
309
+ self._nextToLastDate), d
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from src.rlquantdata.DateUtilities import Date
4
+ from src.rlquantdata.DateUtilities import require
5
+
6
+
7
+ class SettingsFactory(object):
8
+ def __init__(self):
9
+ self._evaluationDate = None
10
+ self._includeToday = None
11
+
12
+ @property
13
+ def evaluationDate(self):
14
+ if not self._evaluationDate:
15
+ return Date.todaysDate()
16
+ return self._evaluationDate
17
+
18
+ @evaluationDate.setter
19
+ def evaluationDate(self, value):
20
+ require(isinstance(value, Date), ValueError, "{0} is not a valid PyFin date object".format(value))
21
+ self._evaluationDate = value
22
+
23
+ @property
24
+ def includeTodaysCashFlows(self):
25
+ return self._includeToday
26
+
27
+ @includeTodaysCashFlows.setter
28
+ def includeTodaysCashFlows(self, value):
29
+ self._evaluationDate = value
30
+
31
+ def resetEvaluationDate(self):
32
+ self._evaluationDate = None
33
+
34
+ def anchorEvaluationDate(self):
35
+ if self._evaluationDate is None:
36
+ self._evaluationDate = Date.todaysDate()
37
+
38
+
39
+ Settings = SettingsFactory()
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ u"""
3
+ Created on 2015-7-9
4
+
5
+ @author: cheng.li
6
+ """
7
+
8
+ from src.rlquantdata.DateUtilities.Asserts import require
9
+ from src.rlquantdata.DateUtilities.Date import Date
10
+ from src.rlquantdata.DateUtilities.Date import check_date
11
+ from src.rlquantdata.DateUtilities.Period import Period
12
+ from src.rlquantdata.DateUtilities.Period import check_period
13
+ from src.rlquantdata.DateUtilities.Schedule import Schedule
14
+ from src import rlquantdata
15
+ import src.rlquantdata.DateUtilities.Date_enum
16
+
17
+ __all__ = ['require',
18
+ 'Date',
19
+ 'Period',
20
+ 'Schedule',
21
+ 'check_date',
22
+ 'check_period',
23
+ 'DateUtilities',
24
+ 'Date_enum']
File without changes