diff --git a/fincal/core.py b/fincal/core.py index 8a52a3e..f22bb77 100644 --- a/fincal/core.py +++ b/fincal/core.py @@ -237,7 +237,7 @@ class TimeSeriesCore(UserDict): data = _preprocess_timeseries(data, date_format=date_format) - self.data = dict(data) + super().__init__(dict(data)) if len(self.data) != len(data): print("Warning: The input data contains duplicate dates which have been ignored.") self.frequency: Frequency = getattr(AllFrequencies, frequency) @@ -364,6 +364,9 @@ class TimeSeriesCore(UserDict): raise TypeError(f"Invalid type {repr(type(key).__name__)} for slicing.") + # def __setitem__(self, key, value): + # pass + def __iter__(self): self.n = 0 return self diff --git a/fincal/fincal.py b/fincal/fincal.py index a481b9d..4946cba 100644 --- a/fincal/fincal.py +++ b/fincal/fincal.py @@ -319,8 +319,7 @@ class TimeSeries(TimeSeriesCore): def calculate_rolling_returns( self, from_date: datetime.date | str, - to_date: datetime.date, - str, + to_date: datetime.date | str, frequency: Literal["D", "W", "M", "Q", "H", "Y"] = None, as_on_match: str = "closest", prior_match: str = "closest", @@ -607,6 +606,26 @@ class TimeSeries(TimeSeriesCore): return output_ts + def sync(self, other: TimeSeries, fill_method: Literal["ffill", "bfill"] = "ffill"): + """Synchronize two TimeSeries objects + + This will ensure that both time series have the same frequency and same set of dates. + The frequency will be set to the higher of the two objects. + Dates will be taken from the class on which the method is called. + """ + + if not isinstance(other, TimeSeries): + raise TypeError("Only objects of type TimeSeries can be passed for sync") + + if self.frequency.days > other.frequency.days: + other = other.expand(to_frequency=self.frequency.symbol, method=fill_method) + if self.frequency.days < other.frequency.days: + self = self.expand(to_frequency=other.frequency.symbol, method=fill_method) + + for dt, val in self.data.items(): + if dt not in other: + pass # Need to create setitem first before implementing this + def _preprocess_csv(file_path: str | pathlib.Path, delimiter: str = ",", encoding: str = "utf-8") -> List[list]: """Preprocess csv data""" diff --git a/fincal/utils.py b/fincal/utils.py index 71f6cd5..45de083 100644 --- a/fincal/utils.py +++ b/fincal/utils.py @@ -1,6 +1,6 @@ import datetime from dataclasses import dataclass -from typing import Iterable, List, Literal, Mapping, Sequence, Tuple +from typing import List, Literal, Mapping, Sequence, Tuple from .exceptions import DateNotFoundError, DateOutOfRangeError @@ -32,7 +32,7 @@ def _parse_date(date: str, date_format: str = None): def _preprocess_timeseries( - data: Sequence[Iterable[str | datetime.datetime, float]] + data: Sequence[Tuple[str | datetime.datetime, float]] | Sequence[Mapping[str | datetime.datetime, float]] | Mapping[str | datetime.datetime, float], date_format: str,