Compare commits

..

No commits in common. "978566e0a885380cc6fdbe95aff897442b5311f2" and "65f2e8434ccdbe16b538006b8407890845e99f25" have entirely different histories.

4 changed files with 25 additions and 64 deletions

View File

@ -19,7 +19,7 @@ Fincal aims to simplify things by allowing you to:
## To-do ## To-do
### Core features ### Core features
- [x] Add __setitem__ - [ ] Add __setitem__
- [ ] Create emtpy TimeSeries object - [ ] Create emtpy TimeSeries object
- [x] Read from CSV - [x] Read from CSV
- [ ] Write to CSV - [ ] Write to CSV

View File

@ -6,7 +6,7 @@ import warnings
from collections import UserList from collections import UserList
from dataclasses import dataclass from dataclasses import dataclass
from numbers import Number from numbers import Number
from typing import Any, Callable, Iterable, List, Literal, Mapping, Sequence, Type from typing import Callable, Iterable, List, Literal, Mapping, Sequence, Type
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
@ -393,7 +393,7 @@ class TimeSeriesCore:
def _get_item_from_date(self, date: str | datetime.datetime): def _get_item_from_date(self, date: str | datetime.datetime):
"""Helper function to retrieve item using a date""" """Helper function to retrieve item using a date"""
return self.get(date, raise_error=True) return date, self.data[date]
def _get_item_from_key(self, key: str | datetime.datetime): def _get_item_from_key(self, key: str | datetime.datetime):
"""Helper function to implement special keys""" """Helper function to implement special keys"""
@ -447,9 +447,9 @@ class TimeSeriesCore:
raise TypeError("Only numerical values can be stored in TimeSeries") raise TypeError("Only numerical values can be stored in TimeSeries")
if key in self.data: if key in self.data:
self.data[key] = float(value) self.data[key] = value
else: else:
self.data.update({key: float(value)}) self.data.update({key: value})
self.data = dict(sorted(self.data.items())) self.data = dict(sorted(self.data.items()))
@date_parser(1) @date_parser(1)
@ -765,70 +765,31 @@ class TimeSeriesCore:
raise NotImplementedError("This operation is not supported.") raise NotImplementedError("This operation is not supported.")
@date_parser(1) @date_parser(1)
def get( def get(self, date: str | datetime.datetime, default=None, closest=None):
self,
date: str | datetime.datetime,
default: Any = None,
closest: Literal["previous", "next"] = None,
limit: int = 1000,
raise_error: bool = False,
) -> tuple | Any:
"""Get a value for a particular key. Return a default value on KeyError
Parameters
----------
date:
Date for which the value needs to be fetched.
default: Optional, Default None
Default value to be returned in case the date is not found. Default None.
closest:
Look for previous or next value when date is not found.
If not specified, the value set in FincalOptions is used
limit:
Maximum number of days to look for the closest available date.
If exceeded without finding a date, default value will be returned.
raise_error : bool, optional
Whether to raise an error and ignore the default value.
Meant for use with __getitem__.
Returns
-------
tuple | Any
_description_
Raises
------
ValueError
If the argument for closest is not valid.
KeyError
if raise_error is true and date is not found
"""
if closest is None: if closest is None:
closest = FincalOptions.get_closest closest = FincalOptions.get_closest
time_delta_dict = {"exact": 0, "previous": -1, "next": 1} if closest == "exact":
if closest not in time_delta_dict:
raise ValueError(f"Invalid argument from closest {closest!r}")
delta = relativedelta(days=time_delta_dict[closest])
for _ in range(limit):
try: try:
return date, self.data[date] item = self._get_item_from_date(date)
return item
except KeyError: except KeyError:
if not delta: return default
break
date += delta
if raise_error: if closest == "previous":
raise KeyError(date) delta = datetime.timedelta(-1)
return default elif closest == "next":
delta = datetime.timedelta(1)
else:
raise ValueError(f"Invalid argument from closest {closest!r}")
while True:
try:
item = self._get_item_from_date(date)
return item
except KeyError:
date += delta
@property @property
def iloc(self) -> Mapping: def iloc(self) -> Mapping:

View File

@ -8,7 +8,7 @@ from .exceptions import DateNotFoundError, DateOutOfRangeError
@dataclass @dataclass
class FincalOptions: class FincalOptions:
date_format: str = "%Y-%m-%d" date_format: str = "%Y-%m-%d"
closest: str = "previous" # next closest: str = "before" # after
traded_days: int = 365 traded_days: int = 365
get_closest: str = "exact" get_closest: str = "exact"

View File

@ -386,7 +386,7 @@ class TestTimeSeriesArithmatic:
def test_truediv(self): def test_truediv(self):
ts = TimeSeriesCore(self.data, "M") ts = TimeSeriesCore(self.data, "M")
ser = Series([22, 23, 24, 25], "number") ser = Series([21, 21, 23, 24], "number")
num_div_ts = ts / 10 num_div_ts = ts / 10
assert num_div_ts["2021-01-01"][1] == 22 assert num_div_ts["2021-01-01"][1] == 22