Compare commits
2 Commits
65f2e8434c
...
978566e0a8
Author | SHA1 | Date | |
---|---|---|---|
978566e0a8 | |||
c99ffe02d0 |
@ -19,7 +19,7 @@ Fincal aims to simplify things by allowing you to:
|
||||
## To-do
|
||||
|
||||
### Core features
|
||||
- [ ] Add __setitem__
|
||||
- [x] Add __setitem__
|
||||
- [ ] Create emtpy TimeSeries object
|
||||
- [x] Read from CSV
|
||||
- [ ] Write to CSV
|
||||
|
@ -6,7 +6,7 @@ import warnings
|
||||
from collections import UserList
|
||||
from dataclasses import dataclass
|
||||
from numbers import Number
|
||||
from typing import Callable, Iterable, List, Literal, Mapping, Sequence, Type
|
||||
from typing import Any, Callable, Iterable, List, Literal, Mapping, Sequence, Type
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
@ -393,7 +393,7 @@ class TimeSeriesCore:
|
||||
def _get_item_from_date(self, date: str | datetime.datetime):
|
||||
"""Helper function to retrieve item using a date"""
|
||||
|
||||
return date, self.data[date]
|
||||
return self.get(date, raise_error=True)
|
||||
|
||||
def _get_item_from_key(self, key: str | datetime.datetime):
|
||||
"""Helper function to implement special keys"""
|
||||
@ -447,9 +447,9 @@ class TimeSeriesCore:
|
||||
raise TypeError("Only numerical values can be stored in TimeSeries")
|
||||
|
||||
if key in self.data:
|
||||
self.data[key] = value
|
||||
self.data[key] = float(value)
|
||||
else:
|
||||
self.data.update({key: value})
|
||||
self.data.update({key: float(value)})
|
||||
self.data = dict(sorted(self.data.items()))
|
||||
|
||||
@date_parser(1)
|
||||
@ -765,32 +765,71 @@ class TimeSeriesCore:
|
||||
raise NotImplementedError("This operation is not supported.")
|
||||
|
||||
@date_parser(1)
|
||||
def get(self, date: str | datetime.datetime, default=None, closest=None):
|
||||
def get(
|
||||
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:
|
||||
closest = FincalOptions.get_closest
|
||||
|
||||
if closest == "exact":
|
||||
try:
|
||||
item = self._get_item_from_date(date)
|
||||
return item
|
||||
except KeyError:
|
||||
return default
|
||||
time_delta_dict = {"exact": 0, "previous": -1, "next": 1}
|
||||
|
||||
if closest == "previous":
|
||||
delta = datetime.timedelta(-1)
|
||||
elif closest == "next":
|
||||
delta = datetime.timedelta(1)
|
||||
else:
|
||||
if closest not in time_delta_dict:
|
||||
raise ValueError(f"Invalid argument from closest {closest!r}")
|
||||
delta = relativedelta(days=time_delta_dict[closest])
|
||||
|
||||
while True:
|
||||
for _ in range(limit):
|
||||
try:
|
||||
item = self._get_item_from_date(date)
|
||||
return item
|
||||
return date, self.data[date]
|
||||
except KeyError:
|
||||
if not delta:
|
||||
break
|
||||
date += delta
|
||||
|
||||
if raise_error:
|
||||
raise KeyError(date)
|
||||
return default
|
||||
|
||||
@property
|
||||
def iloc(self) -> Mapping:
|
||||
"""Returns an item or a set of items based on index
|
||||
|
@ -8,7 +8,7 @@ from .exceptions import DateNotFoundError, DateOutOfRangeError
|
||||
@dataclass
|
||||
class FincalOptions:
|
||||
date_format: str = "%Y-%m-%d"
|
||||
closest: str = "before" # after
|
||||
closest: str = "previous" # next
|
||||
traded_days: int = 365
|
||||
get_closest: str = "exact"
|
||||
|
||||
|
@ -386,7 +386,7 @@ class TestTimeSeriesArithmatic:
|
||||
|
||||
def test_truediv(self):
|
||||
ts = TimeSeriesCore(self.data, "M")
|
||||
ser = Series([21, 21, 23, 24], "number")
|
||||
ser = Series([22, 23, 24, 25], "number")
|
||||
|
||||
num_div_ts = ts / 10
|
||||
assert num_div_ts["2021-01-01"][1] == 22
|
||||
|
Loading…
Reference in New Issue
Block a user