Added skip weekend parameters to expand and bfill/ffill

This commit is contained in:
Gourav Kumar 2022-04-04 00:48:48 +05:30
parent fa2ab84c92
commit 03ccbe0cb1
2 changed files with 22 additions and 8 deletions

View File

@ -32,3 +32,7 @@ Fincal aims to simplify things by allowing you to:
- [ ] Jensen's Alpha - [ ] Jensen's Alpha
- [ ] Beta - [ ] Beta
- [x] Max drawdown - [x] Max drawdown
### Pending implementation
- [ ] Use limit parameter in ffill and bfill
- [ ] Implementation of ffill and bfill may be incorrect inside expand, check and correct

View File

@ -130,7 +130,7 @@ class TimeSeries(TimeSeriesCore):
res_string: str = "First date: {}\nLast date: {}\nNumber of rows: {}" res_string: str = "First date: {}\nLast date: {}\nNumber of rows: {}"
return res_string.format(self.start_date, self.end_date, total_dates) return res_string.format(self.start_date, self.end_date, total_dates)
def ffill(self, inplace: bool = False, limit: int = None) -> Union[TimeSeries, None]: def ffill(self, inplace: bool = False, limit: int = None, skip_weekends: bool = False) -> Union[TimeSeries, None]:
"""Forward fill missing dates in the time series """Forward fill missing dates in the time series
Parameters Parameters
@ -141,18 +141,23 @@ class TimeSeries(TimeSeriesCore):
limit : int, optional limit : int, optional
Maximum number of periods to forward fill Maximum number of periods to forward fill
skip_weekends: bool, optional, default false
Skip weekends while forward filling daily data
Returns Returns
------- -------
Returns a TimeSeries object if inplace is False, otherwise None Returns a TimeSeries object if inplace is False, otherwise None
""" """
eomonth: bool = True if self.frequency.days >= AllFrequencies.M.days else False eomonth: bool = True if self.frequency.days >= AllFrequencies.M.days else False
dates_to_fill = create_date_series(self.start_date, self.end_date, self.frequency.symbol, eomonth) dates_to_fill = create_date_series(
self.start_date, self.end_date, self.frequency.symbol, eomonth, skip_weekends=skip_weekends
)
new_ts = dict() new_ts = dict()
for cur_date in dates_to_fill: for cur_date in dates_to_fill:
try: try:
cur_val = self.data[cur_date] cur_val = self.get(cur_date, closest="previous")
except KeyError: except KeyError:
pass pass
new_ts.update({cur_date: cur_val}) new_ts.update({cur_date: cur_val})
@ -163,7 +168,7 @@ class TimeSeries(TimeSeriesCore):
return self.__class__(new_ts, frequency=self.frequency.symbol) return self.__class__(new_ts, frequency=self.frequency.symbol)
def bfill(self, inplace: bool = False, limit: int = None) -> Union[TimeSeries, None]: def bfill(self, inplace: bool = False, limit: int = None, skip_weekends: bool = False) -> Union[TimeSeries, None]:
"""Backward fill missing dates in the time series """Backward fill missing dates in the time series
Parameters Parameters
@ -174,13 +179,18 @@ class TimeSeries(TimeSeriesCore):
limit : int, optional limit : int, optional
Maximum number of periods to back fill Maximum number of periods to back fill
skip_weekends: bool, optional, default false
Skip weekends while forward filling daily data
Returns Returns
------- -------
Returns a TimeSeries object if inplace is False, otherwise None Returns a TimeSeries object if inplace is False, otherwise None
""" """
eomonth: bool = True if self.frequency.days >= AllFrequencies.M.days else False eomonth: bool = True if self.frequency.days >= AllFrequencies.M.days else False
dates_to_fill = create_date_series(self.start_date, self.end_date, self.frequency.symbol, eomonth) dates_to_fill = create_date_series(
self.start_date, self.end_date, self.frequency.symbol, eomonth, skip_weekends=skip_weekends
)
dates_to_fill.append(self.end_date) dates_to_fill.append(self.end_date)
bfill_ts = dict() bfill_ts = dict()
@ -574,9 +584,9 @@ class TimeSeries(TimeSeriesCore):
output_ts: TimeSeries = TimeSeries(new_ts, frequency=to_frequency.symbol) output_ts: TimeSeries = TimeSeries(new_ts, frequency=to_frequency.symbol)
if method == "ffill": if method == "ffill":
output_ts.ffill(inplace=True) output_ts.ffill(inplace=True, skip_weekends=skip_weekends)
elif method == "bfill": elif method == "bfill":
output_ts.bfill(inplace=True) output_ts.bfill(inplace=True, skip_weekends=skip_weekends)
else: else:
raise NotImplementedError(f"Method {method} not implemented") raise NotImplementedError(f"Method {method} not implemented")