Source code for qf_lib.common.utils.miscellaneous.periods_list

#     Copyright 2016-present CERN – European Organization for Nuclear Research
#
#     Licensed under the Apache License, Version 2.0 (the "License");
#     you may not use this file except in compliance with the License.
#     You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#     Unless required by applicable law or agreed to in writing, software
#     distributed under the License is distributed on an "AS IS" BASIS,
#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#     See the License for the specific language governing permissions and
#     limitations under the License.

from datetime import datetime
from typing import Sequence, Tuple

from qf_lib.common.utils.miscellaneous.consecutive_duplicates import drop_consecutive_duplicates, Method
from qf_lib.containers.series.qf_series import QFSeries


[docs]def periods_list_from_bool_series(series: QFSeries) -> Sequence[Tuple[datetime, datetime]]: """ Uses a timeseries containing boolean values to create periods of True values. Parameters ---------- series: QFSeries the series of boolean values For example: - 2017-01-01 True - 2017-01-02 False - 2017-01-03 True - 2017-01-05 False - 2017-01-06 True - 2017-01-07 True - 2017-01-08 False - 2017-01-09 True - 2017-01-10 True frequency: Frequency.DAILY Periods: - 2017-01-01 - 2017-01-02 - 2017-01-03 - 2017-01-05 - 2017-01-06 - 2017-01-08 - 2017-01-09 - 2017-01-11 (end date calculated based on a frequency of the series) Returns ------- Tuple[datetime, datetime] list of tuples. Each tuple corresponds to one period and consists of two dates: start date and end date of a period. """ result = [] first_occurrences_only = drop_consecutive_duplicates(series, Method.KEEP_FIRST) start_date = None for date, should_be_shadowed in first_occurrences_only.items(): date = date.to_pydatetime() # convert from pandas.Timestamp if should_be_shadowed: start_date = date elif start_date is not None: result.append((start_date, date)) start_date = None last_period_of_series_should_be_shadowed = start_date is not None if last_period_of_series_should_be_shadowed: end_date = _infer_end_date(series) result.append((start_date, end_date)) return result
def _infer_end_date(series: QFSeries) -> datetime: time_delta = series.get_frequency().time_delta() last_series_date = series.index[-1].to_pydatetime() end_date = last_series_date + time_delta return end_date