Compare commits

...

5 Commits

Author SHA1 Message Date
Gourav Kumar 2f0f1e0e47 further testing 2 years ago
Gourav Kumar 44d5ea7b29 date parsing replaced with _parse_date function 2 years ago
Gourav Kumar cbace875c1 implemented _parse_date function to formalise date parsing 2 years ago
Gourav Kumar 053a93900a Rolling return was passing frequency object 2 years ago
Gourav Kumar 81856b2c1a changed IndexSlicer to _IndexSlicer 2 years ago
  1. 136
      fincal/core.py
  2. 29
      fincal/fincal.py
  3. 378
      testing.ipynb

136
fincal/core.py

@ -1,4 +1,5 @@
import datetime
from collections import UserList
from dataclasses import dataclass
from numbers import Number
from typing import Iterable, List, Literal, Mapping, Sequence, Tuple, Union
@ -6,8 +7,8 @@ from typing import Iterable, List, Literal, Mapping, Sequence, Tuple, Union
@dataclass
class FincalOptions:
date_format: str = '%Y-%m-%d'
closest: str = 'before' # after
date_format: str = "%Y-%m-%d"
closest: str = "before" # after
@dataclass(frozen=True)
@ -20,12 +21,12 @@ class Frequency:
class AllFrequencies:
D = Frequency('daily', 'days', 1, 1, 'D')
W = Frequency('weekly', 'days', 7, 7, 'W')
M = Frequency('monthly', 'months', 1, 30, 'M')
Q = Frequency('quarterly', 'months', 3, 91, 'Q')
H = Frequency('half-yearly', 'months', 6, 182, 'H')
Y = Frequency('annual', 'years', 1, 365, 'Y')
D = Frequency("daily", "days", 1, 1, "D")
W = Frequency("weekly", "days", 7, 7, "W")
M = Frequency("monthly", "months", 1, 30, "M")
Q = Frequency("quarterly", "months", 3, 91, "Q")
H = Frequency("half-yearly", "months", 6, 182, "H")
Y = Frequency("annual", "years", 1, 365, "Y")
def _preprocess_timeseries(
@ -33,9 +34,9 @@ def _preprocess_timeseries(
Sequence[Iterable[Union[str, datetime.datetime, float]]],
Sequence[Mapping[str, Union[float, datetime.datetime]]],
Sequence[Mapping[Union[str, datetime.datetime], float]],
Mapping[Union[str, datetime.datetime], float]
Mapping[Union[str, datetime.datetime], float],
],
date_format: str
date_format: str,
) -> List[Tuple[datetime.datetime, float]]:
"""Converts any type of list to the correct type"""
@ -75,12 +76,12 @@ def _preprocess_timeseries(
def _preprocess_match_options(as_on_match: str, prior_match: str, closest: str) -> datetime.timedelta:
"""Checks the arguments and returns appropriate timedelta objects"""
deltas = {'exact': 0, 'previous': -1, 'next': 1}
deltas = {"exact": 0, "previous": -1, "next": 1}
if closest not in deltas.keys():
raise ValueError(f"Invalid closest argument: {closest}")
as_on_match = closest if as_on_match == 'closest' else as_on_match
prior_match = closest if prior_match == 'closest' else prior_match
as_on_match = closest if as_on_match == "closest" else as_on_match
prior_match = closest if prior_match == "closest" else prior_match
if as_on_match in deltas.keys():
as_on_delta = datetime.timedelta(days=deltas[as_on_match])
@ -95,7 +96,25 @@ def _preprocess_match_options(as_on_match: str, prior_match: str, closest: str)
return as_on_delta, prior_delta
class IndexSlicer:
def _parse_date(date: str, date_format: str = None):
"""Parses date and handles errors"""
if isinstance(date, (datetime.datetime, datetime.date)):
return datetime.datetime.fromordinal(date.toordinal())
if date_format is None:
date_format = FincalOptions.date_format
try:
date = datetime.datetime.strptime(date, date_format)
except TypeError:
raise Exception("Date does not seem to be valid date-like string")
except ValueError:
raise Exception("Date could not be parsed. Have you set the correct date format in FincalOptions.date_format?")
return date
class _IndexSlicer:
def __init__(self, parent_obj):
self.parent = parent_obj
@ -112,7 +131,7 @@ class IndexSlicer:
return item
class Series:
class Series(UserList):
def __init__(self, data):
if not isinstance(data, Sequence):
raise TypeError("Series only supports creation using Sequence types")
@ -128,26 +147,26 @@ class Series:
data = [datetime.datetime.strptime(i, FincalOptions.date_format) for i in data]
self.dtype = datetime.datetime
except ValueError:
raise TypeError("Series does not support string data type")
elif isinstance(data[0], datetime.datetime):
raise TypeError(
"Series does not support string data type except dates.\n"
"Hint: Try setting the date format using FincalOptions.date_format"
)
elif isinstance(data[0], (datetime.datetime, datetime.date)):
self.dtype = datetime.datetime
self.data = data
self.data = [_parse_date(i) for i in data]
else:
raise TypeError(f"Cannot create series object from {type(data).__name__} of {type(data[0]).__name__}")
def __repr__(self):
return f"{self.__class__.__name__}({self.data})"
def __getitem__(self, n):
return self.data[n]
def __len__(self):
return len(self.data)
def __gt__(self, other):
if self.dtype == bool:
raise TypeError("> not supported for boolean series")
if isinstance(other, (str, datetime.datetime, datetime.date)):
other = _parse_date(other)
if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype):
gt = Series([i > other for i in self.data])
else:
@ -177,10 +196,7 @@ class TimeSeriesCore:
"""Defines the core building blocks of a TimeSeries object"""
def __init__(
self,
data: List[Iterable],
frequency: Literal['D', 'W', 'M', 'Q', 'H', 'Y'],
date_format: str = "%Y-%m-%d"
self, data: List[Iterable], frequency: Literal["D", "W", "M", "Q", "H", "Y"], date_format: str = "%Y-%m-%d"
):
"""Instantiate a TimeSeries object
@ -240,42 +256,42 @@ class TimeSeriesCore:
printable = {}
iter_f = iter(self.time_series)
first_n = [next(iter_f) for i in range(n//2)]
first_n = [next(iter_f) for i in range(n // 2)]
iter_b = reversed(self.time_series)
last_n = [next(iter_b) for i in range(n//2)]
last_n = [next(iter_b) for i in range(n // 2)]
last_n.sort()
printable['start'] = [str((i, self.time_series[i])) for i in first_n]
printable['end'] = [str((i, self.time_series[i])) for i in last_n]
printable["start"] = [str((i, self.time_series[i])) for i in first_n]
printable["end"] = [str((i, self.time_series[i])) for i in last_n]
return printable
def __repr__(self):
if len(self.time_series) > 6:
printable = self._get_printable_slice(6)
printable_str = "{}([{}\n\t ...\n\t {}], frequency={})".format(
self.__class__.__name__,
',\n\t '.join(printable['start']),
',\n\t '.join(printable['end']),
repr(self.frequency.symbol)
)
self.__class__.__name__,
",\n\t ".join(printable["start"]),
",\n\t ".join(printable["end"]),
repr(self.frequency.symbol),
)
else:
printable_str = "{}([{}], frequency={})".format(
self.__class__.__name__,
',\n\t'.join([str(i) for i in self.time_series.items()]),
repr(self.frequency.symbol)
)
self.__class__.__name__,
",\n\t".join([str(i) for i in self.time_series.items()]),
repr(self.frequency.symbol),
)
return printable_str
def __str__(self):
if len(self.time_series) > 6:
printable = self._get_printable_slice(6)
printable_str = "[{}\n ...\n {}]".format(
',\n '.join(printable['start']),
',\n '.join(printable['end']),
)
",\n ".join(printable["start"]),
",\n ".join(printable["end"]),
)
else:
printable_str = "[{}]".format(',\n '.join([str(i) for i in self.time_series.items()]))
printable_str = "[{}]".format(",\n ".join([str(i) for i in self.time_series.items()]))
return printable_str
def __getitem__(self, key):
@ -287,27 +303,25 @@ class TimeSeriesCore:
else:
dates_to_return = [self.dates[i] for i, j in enumerate(key) if j]
data_to_return = [(key, self.time_series[key]) for key in dates_to_return]
return TimeSeriesCore(data_to_return)
return TimeSeriesCore(data_to_return, frequency=self.frequency.symbol)
if isinstance(key, int):
raise KeyError(f"{key}. For index based slicing, use .iloc[{key}]")
elif isinstance(key, datetime.datetime):
elif isinstance(key, (datetime.datetime, datetime.date)):
key = _parse_date(key)
item = (key, self.time_series[key])
if isinstance(key, str):
if key == 'dates':
elif isinstance(key, str):
if key == "dates":
return self.dates
elif key == 'values':
return list(self.time_series.values())
try:
dt_key = datetime.datetime.strptime(key, FincalOptions.date_format)
item = (dt_key, self.time_series[dt_key])
except ValueError:
raise KeyError(f"{repr(key)}. If you passed a date as a string, "
"try setting the date format using Fincal.Options.date_format")
except KeyError:
raise KeyError(f"{repr(key)}. This date is not available.")
elif key == "values":
return self.values
dt_key = _parse_date(key)
item = (dt_key, self.time_series[dt_key])
elif isinstance(key, Sequence):
item = [(k, self.time_series[k]) for k in key]
keys = [_parse_date(i) for i in key]
item = [(k, self.time_series[k]) for k in keys]
else:
raise TypeError(f"Invalid type {repr(type(key).__name__)} for slicing.")
return item
@ -347,4 +361,4 @@ class TimeSeriesCore:
def iloc(self):
"""Returns an item or a set of items based on index"""
return IndexSlicer(self)
return _IndexSlicer(self)

29
fincal/fincal.py

@ -5,7 +5,7 @@ from typing import List, Union
from dateutil.relativedelta import relativedelta
from .core import AllFrequencies, TimeSeriesCore, _preprocess_match_options
from .core import AllFrequencies, TimeSeriesCore, _parse_date, _preprocess_match_options
def create_date_series(
@ -113,12 +113,13 @@ class TimeSeries(TimeSeriesCore):
def calculate_returns(
self,
as_on: datetime.datetime,
as_on: Union[str, datetime.datetime],
as_on_match: str = "closest",
prior_match: str = "closest",
closest: str = "previous",
compounding: bool = True,
years: int = 1,
date_format: str = None
) -> float:
"""Method to calculate returns for a certain time-period as on a particular date
@ -158,6 +159,7 @@ class TimeSeries(TimeSeriesCore):
>>> calculate_returns(datetime.date(2020, 1, 1), years=1)
"""
as_on = _parse_date(as_on, date_format)
as_on_delta, prior_delta = _preprocess_match_options(as_on_match, prior_match, closest)
while True:
@ -184,23 +186,30 @@ class TimeSeries(TimeSeriesCore):
def calculate_rolling_returns(
self,
from_date: datetime.date,
to_date: datetime.date,
frequency: str = "D",
from_date: Union[datetime.date, str],
to_date: Union[datetime.date, str],
frequency: str = None,
as_on_match: str = "closest",
prior_match: str = "closest",
closest: str = "previous",
compounding: bool = True,
years: int = 1,
date_format: str = None
) -> List[tuple]:
"""Calculates the rolling return"""
try:
frequency = getattr(AllFrequencies, frequency)
except AttributeError:
raise ValueError(f"Invalid argument for frequency {frequency}")
from_date = _parse_date(from_date, date_format)
to_date = _parse_date(to_date, date_format)
dates = create_date_series(from_date, to_date, frequency)
if frequency is None:
frequency = self.frequency
else:
try:
frequency = getattr(AllFrequencies, frequency)
except AttributeError:
raise ValueError(f"Invalid argument for frequency {frequency}")
dates = create_date_series(from_date, to_date, frequency.symbol)
if frequency == AllFrequencies.D:
dates = [i for i in dates if i in self.time_series]

378
testing.ipynb

@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 14,
"execution_count": 1,
"id": "3f7938c0-98e3-43b8-86e8-4f000cda7ce5",
"metadata": {},
"outputs": [],
@ -16,28 +16,20 @@
},
{
"cell_type": "code",
"execution_count": 16,
"id": "757eafc2-f804-4e7e-a3b8-2d09cd62e646",
"metadata": {},
"outputs": [],
"source": [
"dfd = pd.read_csv('test_files/nav_history_daily - copy.csv')"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "59b3d4a9-8ef4-4652-9e20-1bac69ab4ff9",
"execution_count": 2,
"id": "4b8ccd5f-dfff-4202-82c4-f66a30c122b6",
"metadata": {},
"outputs": [],
"source": [
"dfd = pd.read_csv('test_files/nav_history_daily - copy.csv')\n",
"\n",
"dfd = dfd[dfd['amfi_code'] == 118825].reset_index(drop=True)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "4bc95ae0-8c33-4eab-acf9-e765d22979b8",
"execution_count": 3,
"id": "c52b0c2c-dd01-48dd-9ffa-3147ec9571ef",
"metadata": {},
"outputs": [
{
@ -46,68 +38,370 @@
"text": [
"Warning: The input data contains duplicate dates which have been ignored.\n"
]
},
{
"data": {
"text/plain": [
"TimeSeries([(datetime.datetime(2013, 1, 2, 0, 0), 18.972),\n",
"\t (datetime.datetime(2013, 1, 3, 0, 0), 19.011),\n",
"\t (datetime.datetime(2013, 1, 4, 0, 0), 19.008)\n",
"\t ...\n",
"\t (datetime.datetime(2022, 2, 10, 0, 0), 86.5),\n",
"\t (datetime.datetime(2022, 2, 11, 0, 0), 85.226),\n",
"\t (datetime.datetime(2022, 2, 14, 0, 0), 82.533)], frequency='D')"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ts = TimeSeries([(i.date, i.nav) for i in dfd.itertuples()], frequency='D')"
"ts = TimeSeries([(i.date, i.nav) for i in dfd.itertuples()], frequency='D')\n",
"\n",
"ts"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "f2c3218c-3984-43d6-8638-41a74a9d0b58",
"execution_count": 4,
"id": "9e8ff6c6-3a36-435a-ba87-5b9844c18779",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"TimeSeries([(datetime.datetime(2013, 1, 2, 0, 0), 18.972),\n",
"\t (datetime.datetime(2013, 1, 3, 0, 0), 19.011),\n",
"\t (datetime.datetime(2013, 1, 4, 0, 0), 19.008)\n",
"\t ...\n",
"\t (datetime.datetime(2022, 2, 10, 0, 0), 86.5),\n",
"\t (datetime.datetime(2022, 2, 11, 0, 0), 85.226),\n",
"\t (datetime.datetime(2022, 2, 14, 0, 0), 82.53299999999999)], frequency='D')"
"[(datetime.datetime(2021, 1, 1, 0, 0), 66.652),\n",
" (datetime.datetime(2020, 1, 1, 0, 0), 57.804)]"
]
},
"execution_count": 20,
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ts"
"ts[['2021-01-01', '2020-01-01']]"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "dc469722-c816-4b57-8d91-7a3b865f86be",
"execution_count": 5,
"id": "4d927a61-0f90-4b47-89b7-0e0d3ab1b442",
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "getattr(): attribute name must be string",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
"File \u001b[1;32m<timed eval>:1\u001b[0m, in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n",
"File \u001b[1;32mD:\\Documents\\Projects\\fincal\\fincal\\fincal.py:203\u001b[0m, in \u001b[0;36mTimeSeries.calculate_rolling_returns\u001b[1;34m(self, from_date, to_date, frequency, as_on_match, prior_match, closest, compounding, years)\u001b[0m\n\u001b[0;32m 200\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mAttributeError\u001b[39;00m:\n\u001b[0;32m 201\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid argument for frequency \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfrequency\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m--> 203\u001b[0m dates \u001b[38;5;241m=\u001b[39m \u001b[43mcreate_date_series\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfrom_date\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mto_date\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfrequency\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 204\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m frequency \u001b[38;5;241m==\u001b[39m AllFrequencies\u001b[38;5;241m.\u001b[39mD:\n\u001b[0;32m 205\u001b[0m dates \u001b[38;5;241m=\u001b[39m [i \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m dates \u001b[38;5;28;01mif\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtime_series]\n",
"File \u001b[1;32mD:\\Documents\\Projects\\fincal\\fincal\\fincal.py:16\u001b[0m, in \u001b[0;36mcreate_date_series\u001b[1;34m(start_date, end_date, frequency, eomonth)\u001b[0m\n\u001b[0;32m 11\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcreate_date_series\u001b[39m(\n\u001b[0;32m 12\u001b[0m start_date: datetime\u001b[38;5;241m.\u001b[39mdatetime, end_date: datetime\u001b[38;5;241m.\u001b[39mdatetime, frequency: \u001b[38;5;28mstr\u001b[39m, eomonth: \u001b[38;5;28mbool\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 13\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m List[datetime\u001b[38;5;241m.\u001b[39mdatetime]:\n\u001b[0;32m 14\u001b[0m \u001b[38;5;124;03m\"\"\"Creates a date series using a frequency\"\"\"\u001b[39;00m\n\u001b[1;32m---> 16\u001b[0m frequency \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mgetattr\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mAllFrequencies\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfrequency\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m eomonth \u001b[38;5;129;01mand\u001b[39;00m frequency\u001b[38;5;241m.\u001b[39mdays \u001b[38;5;241m<\u001b[39m AllFrequencies\u001b[38;5;241m.\u001b[39mM\u001b[38;5;241m.\u001b[39mdays:\n\u001b[0;32m 18\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124meomonth cannot be set to True if frequency is higher than \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mAllFrequencies\u001b[38;5;241m.\u001b[39mM\u001b[38;5;241m.\u001b[39mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n",
"\u001b[1;31mTypeError\u001b[0m: getattr(): attribute name must be string"
"data": {
"text/plain": [
"Series([False, False, False, False, False, False, False, False, False, False])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s = ts.dates > '2020-01-01'\n",
"s[:10]"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "311d1c07-d827-4d69-855f-883e1198c162",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "bb625050-5d7b-45a9-9cde-ac6e599adea5",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 False\n",
"1 False\n",
"2 False\n",
"3 False\n",
"4 False\n",
" ... \n",
"2196 True\n",
"2197 True\n",
"2198 True\n",
"2199 True\n",
"2200 True\n",
"Length: 2201, dtype: bool"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.Series(s)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "dc469722-c816-4b57-8d91-7a3b865f86be",
"metadata": {
"scrolled": true,
"tags": []
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wall time: 14 ms\n"
]
},
{
"data": {
"text/plain": [
"[(datetime.datetime(2020, 1, 1, 0, 0), 0.13778442642311628),\n",
" (datetime.datetime(2020, 1, 2, 0, 0), 0.15907011891977874),\n",
" (datetime.datetime(2020, 1, 3, 0, 0), 0.16528842679940592),\n",
" (datetime.datetime(2020, 1, 6, 0, 0), 0.13725881835976517),\n",
" (datetime.datetime(2020, 1, 7, 0, 0), 0.1361567661029075),\n",
" (datetime.datetime(2020, 1, 8, 0, 0), 0.12943599493029145),\n",
" (datetime.datetime(2020, 1, 9, 0, 0), 0.14162066246056781),\n",
" (datetime.datetime(2020, 1, 10, 0, 0), 0.14866092589666624),\n",
" (datetime.datetime(2020, 1, 13, 0, 0), 0.15898777321998292),\n",
" (datetime.datetime(2020, 1, 14, 0, 0), 0.16791720569210877),\n",
" (datetime.datetime(2020, 1, 15, 0, 0), 0.15701288705571237),\n",
" (datetime.datetime(2020, 1, 16, 0, 0), 0.15895332557726816),\n",
" (datetime.datetime(2020, 1, 17, 0, 0), 0.1597678687747972),\n",
" (datetime.datetime(2020, 1, 20, 0, 0), 0.1517952575115793),\n",
" (datetime.datetime(2020, 1, 21, 0, 0), 0.14416159380188165),\n",
" (datetime.datetime(2020, 1, 22, 0, 0), 0.1388367359038718),\n",
" (datetime.datetime(2020, 1, 23, 0, 0), 0.15628915183454306),\n",
" (datetime.datetime(2020, 1, 24, 0, 0), 0.16305428514615228),\n",
" (datetime.datetime(2020, 1, 27, 0, 0), 0.1622537810406386),\n",
" (datetime.datetime(2020, 1, 28, 0, 0), 0.16702450881101893),\n",
" (datetime.datetime(2020, 1, 29, 0, 0), 0.1718259672423219),\n",
" (datetime.datetime(2020, 1, 30, 0, 0), 0.15395125479716287),\n",
" (datetime.datetime(2020, 1, 31, 0, 0), 0.13100540412138484),\n",
" (datetime.datetime(2020, 2, 3, 0, 0), 0.10046175704475502),\n",
" (datetime.datetime(2020, 2, 4, 0, 0), 0.12408874488808119),\n",
" (datetime.datetime(2020, 2, 5, 0, 0), 0.13495745562947903),\n",
" (datetime.datetime(2020, 2, 6, 0, 0), 0.1316705790297339),\n",
" (datetime.datetime(2020, 2, 7, 0, 0), 0.1293798434480471),\n",
" (datetime.datetime(2020, 2, 10, 0, 0), 0.13417161807378752),\n",
" (datetime.datetime(2020, 2, 11, 0, 0), 0.14703664006986616),\n",
" (datetime.datetime(2020, 2, 12, 0, 0), 0.15665338645418325),\n",
" (datetime.datetime(2020, 2, 13, 0, 0), 0.16157913712294203),\n",
" (datetime.datetime(2020, 2, 14, 0, 0), 0.15528598971722363),\n",
" (datetime.datetime(2020, 2, 17, 0, 0), 0.15469223007063593),\n",
" (datetime.datetime(2020, 2, 18, 0, 0), 0.1616112297833383),\n",
" (datetime.datetime(2020, 2, 19, 0, 0), 0.1795321518161237),\n",
" (datetime.datetime(2020, 2, 20, 0, 0), 0.16892628011136668),\n",
" (datetime.datetime(2020, 2, 24, 0, 0), 0.14102204408817642),\n",
" (datetime.datetime(2020, 2, 25, 0, 0), 0.1287774793593952),\n",
" (datetime.datetime(2020, 2, 26, 0, 0), 0.11844857467280234),\n",
" (datetime.datetime(2020, 2, 27, 0, 0), 0.11330677290836633),\n",
" (datetime.datetime(2020, 2, 28, 0, 0), 0.07688934948979576),\n",
" (datetime.datetime(2020, 3, 2, 0, 0), 0.06323384067997617),\n",
" (datetime.datetime(2020, 3, 3, 0, 0), 0.08272385847005337),\n",
" (datetime.datetime(2020, 3, 4, 0, 0), 0.07610199644198445),\n",
" (datetime.datetime(2020, 3, 5, 0, 0), 0.06134216421544747),\n",
" (datetime.datetime(2020, 3, 6, 0, 0), 0.0307951704490399),\n",
" (datetime.datetime(2020, 3, 9, 0, 0), -0.014902463666744414),\n",
" (datetime.datetime(2020, 3, 11, 0, 0), -0.02972061472425558),\n",
" (datetime.datetime(2020, 3, 12, 0, 0), -0.1201765519331679),\n",
" (datetime.datetime(2020, 3, 13, 0, 0), -0.08575267799689612),\n",
" (datetime.datetime(2020, 3, 16, 0, 0), -0.15648316950777152),\n",
" (datetime.datetime(2020, 3, 17, 0, 0), -0.17358618226925038),\n",
" (datetime.datetime(2020, 3, 18, 0, 0), -0.21612661547106204),\n",
" (datetime.datetime(2020, 3, 19, 0, 0), -0.2452152219243373),\n",
" (datetime.datetime(2020, 3, 20, 0, 0), -0.20796112876097927),\n",
" (datetime.datetime(2020, 3, 23, 0, 0), -0.30970261339741667),\n",
" (datetime.datetime(2020, 3, 24, 0, 0), -0.2908531090417543),\n",
" (datetime.datetime(2020, 3, 25, 0, 0), -0.24436994526204125),\n",
" (datetime.datetime(2020, 3, 26, 0, 0), -0.22233453129679548),\n",
" (datetime.datetime(2020, 3, 27, 0, 0), -0.21821047890707101),\n",
" (datetime.datetime(2020, 3, 30, 0, 0), -0.2572613339750828),\n",
" (datetime.datetime(2020, 3, 31, 0, 0), -0.23261195549549218),\n",
" (datetime.datetime(2020, 4, 1, 0, 0), -0.2608607426811047),\n",
" (datetime.datetime(2020, 4, 3, 0, 0), -0.27431740614334477),\n",
" (datetime.datetime(2020, 4, 7, 0, 0), -0.2134398339479976),\n",
" (datetime.datetime(2020, 4, 8, 0, 0), -0.20755173891175982),\n",
" (datetime.datetime(2020, 4, 9, 0, 0), -0.18395973278558087),\n",
" (datetime.datetime(2020, 4, 13, 0, 0), -0.19529673178409412),\n",
" (datetime.datetime(2020, 4, 15, 0, 0), -0.20106882889523636),\n",
" (datetime.datetime(2020, 4, 16, 0, 0), -0.1970295580918935),\n",
" (datetime.datetime(2020, 4, 17, 0, 0), -0.1732330992098331),\n",
" (datetime.datetime(2020, 4, 20, 0, 0), -0.16734041380324138),\n",
" (datetime.datetime(2020, 4, 21, 0, 0), -0.19352467752012048),\n",
" (datetime.datetime(2020, 4, 23, 0, 0), -0.15569230769230757),\n",
" (datetime.datetime(2020, 4, 24, 0, 0), -0.17741518697626335),\n",
" (datetime.datetime(2020, 4, 27, 0, 0), -0.1667833069357988),\n",
" (datetime.datetime(2020, 4, 28, 0, 0), -0.1604110648642676),\n",
" (datetime.datetime(2020, 4, 29, 0, 0), -0.14832958856679812),\n",
" (datetime.datetime(2020, 4, 30, 0, 0), -0.1300687474725194),\n",
" (datetime.datetime(2020, 5, 4, 0, 0), -0.17366232326032705),\n",
" (datetime.datetime(2020, 5, 5, 0, 0), -0.1822936881988726),\n",
" (datetime.datetime(2020, 5, 6, 0, 0), -0.1722083628104405),\n",
" (datetime.datetime(2020, 5, 7, 0, 0), -0.17076925965564504),\n",
" (datetime.datetime(2020, 5, 8, 0, 0), -0.15704080857208003),\n",
" (datetime.datetime(2020, 5, 11, 0, 0), -0.1536333632218556),\n",
" (datetime.datetime(2020, 5, 12, 0, 0), -0.15922315279394084),\n",
" (datetime.datetime(2020, 5, 13, 0, 0), -0.12893477713422308),\n",
" (datetime.datetime(2020, 5, 14, 0, 0), -0.1515904189772027),\n",
" (datetime.datetime(2020, 5, 15, 0, 0), -0.1482976040353089),\n",
" (datetime.datetime(2020, 5, 18, 0, 0), -0.19486496766831485),\n",
" (datetime.datetime(2020, 5, 19, 0, 0), -0.19478889311525294),\n",
" (datetime.datetime(2020, 5, 20, 0, 0), -0.20504325418737346),\n",
" (datetime.datetime(2020, 5, 21, 0, 0), -0.1923849185691976),\n",
" (datetime.datetime(2020, 5, 22, 0, 0), -0.20265491640901256),\n",
" (datetime.datetime(2020, 5, 26, 0, 0), -0.21261575969288427),\n",
" (datetime.datetime(2020, 5, 27, 0, 0), -0.1977462346949832),\n",
" (datetime.datetime(2020, 5, 28, 0, 0), -0.18100478037341028),\n",
" (datetime.datetime(2020, 5, 29, 0, 0), -0.16737799894662286),\n",
" (datetime.datetime(2020, 6, 1, 0, 0), -0.1486066432934544),\n",
" (datetime.datetime(2020, 6, 2, 0, 0), -0.1406549318682908),\n",
" (datetime.datetime(2020, 6, 3, 0, 0), -0.1455950320312639),\n",
" (datetime.datetime(2020, 6, 4, 0, 0), -0.14420304132112982),\n",
" (datetime.datetime(2020, 6, 5, 0, 0), -0.13168311511525865),\n",
" (datetime.datetime(2020, 6, 8, 0, 0), -0.11935565702688988),\n",
" (datetime.datetime(2020, 6, 9, 0, 0), -0.13055374356744232),\n",
" (datetime.datetime(2020, 6, 10, 0, 0), -0.12668580404051355),\n",
" (datetime.datetime(2020, 6, 11, 0, 0), -0.14811351293025943),\n",
" (datetime.datetime(2020, 6, 12, 0, 0), -0.13644004989063818),\n",
" (datetime.datetime(2020, 6, 15, 0, 0), -0.14417647273124712),\n",
" (datetime.datetime(2020, 6, 16, 0, 0), -0.13541476920835016),\n",
" (datetime.datetime(2020, 6, 17, 0, 0), -0.12496542567903979),\n",
" (datetime.datetime(2020, 6, 18, 0, 0), -0.10886799410029502),\n",
" (datetime.datetime(2020, 6, 19, 0, 0), -0.09316449153637418),\n",
" (datetime.datetime(2020, 6, 22, 0, 0), -0.09261870319166465),\n",
" (datetime.datetime(2020, 6, 23, 0, 0), -0.07956272545824083),\n",
" (datetime.datetime(2020, 6, 24, 0, 0), -0.09426049373672252),\n",
" (datetime.datetime(2020, 6, 25, 0, 0), -0.10081348053457295),\n",
" (datetime.datetime(2020, 6, 26, 0, 0), -0.09618408922470667),\n",
" (datetime.datetime(2020, 6, 29, 0, 0), -0.10191913883401882),\n",
" (datetime.datetime(2020, 6, 30, 0, 0), -0.10248092640582795),\n",
" (datetime.datetime(2020, 7, 1, 0, 0), -0.09865244649419913),\n",
" (datetime.datetime(2020, 7, 2, 0, 0), -0.09126384692849943),\n",
" (datetime.datetime(2020, 7, 3, 0, 0), -0.08705088880518042),\n",
" (datetime.datetime(2020, 7, 6, 0, 0), -0.06379048033036305),\n",
" (datetime.datetime(2020, 7, 7, 0, 0), -0.05848366297181784),\n",
" (datetime.datetime(2020, 7, 8, 0, 0), -0.045594224361347635),\n",
" (datetime.datetime(2020, 7, 9, 0, 0), -0.039114513981358234),\n",
" (datetime.datetime(2020, 7, 10, 0, 0), -0.03792507846888182),\n",
" (datetime.datetime(2020, 7, 13, 0, 0), -0.04068015895018928),\n",
" (datetime.datetime(2020, 7, 14, 0, 0), -0.05505960632104223),\n",
" (datetime.datetime(2020, 7, 15, 0, 0), -0.058529292332681115),\n",
" (datetime.datetime(2020, 7, 16, 0, 0), -0.05489779859827626),\n",
" (datetime.datetime(2020, 7, 17, 0, 0), -0.04157081827144271),\n",
" (datetime.datetime(2020, 7, 20, 0, 0), -0.008800284000672676),\n",
" (datetime.datetime(2020, 7, 21, 0, 0), 0.002092636535191872),\n",
" (datetime.datetime(2020, 7, 22, 0, 0), 0.0022844730731781393),\n",
" (datetime.datetime(2020, 7, 23, 0, 0), 0.014283837303151303),\n",
" (datetime.datetime(2020, 7, 24, 0, 0), 0.017490781885222795),\n",
" (datetime.datetime(2020, 7, 27, 0, 0), 0.0014461451779510526),\n",
" (datetime.datetime(2020, 7, 28, 0, 0), 0.010423513944971319),\n",
" (datetime.datetime(2020, 7, 29, 0, 0), 0.014873903404892141),\n",
" (datetime.datetime(2020, 7, 30, 0, 0), 0.021221125275567854),\n",
" (datetime.datetime(2020, 7, 31, 0, 0), 0.017523096892418044),\n",
" (datetime.datetime(2020, 8, 3, 0, 0), 0.017039424171667816),\n",
" (datetime.datetime(2020, 8, 4, 0, 0), 0.03604716234731087),\n",
" (datetime.datetime(2020, 8, 5, 0, 0), 0.05061139977341078),\n",
" (datetime.datetime(2020, 8, 6, 0, 0), 0.05082975513519794),\n",
" (datetime.datetime(2020, 8, 7, 0, 0), 0.05958251310737306),\n",
" (datetime.datetime(2020, 8, 10, 0, 0), 0.048723986751670445),\n",
" (datetime.datetime(2020, 8, 11, 0, 0), 0.05220837401642653),\n",
" (datetime.datetime(2020, 8, 12, 0, 0), 0.05186376428694506),\n",
" (datetime.datetime(2020, 8, 13, 0, 0), 0.07394496484839053),\n",
" (datetime.datetime(2020, 8, 14, 0, 0), 0.05147838833490859),\n",
" (datetime.datetime(2020, 8, 17, 0, 0), 0.05283004347993381),\n",
" (datetime.datetime(2020, 8, 18, 0, 0), 0.06824040940397857),\n",
" (datetime.datetime(2020, 8, 19, 0, 0), 0.07100728132024359),\n",
" (datetime.datetime(2020, 10, 8, 0, 0), 0.09372370534689822),\n",
" (datetime.datetime(2020, 10, 9, 0, 0), 0.08128249892061357),\n",
" (datetime.datetime(2020, 10, 12, 0, 0), 0.08653955068906938),\n",
" (datetime.datetime(2020, 10, 13, 0, 0), 0.08506701906739678),\n",
" (datetime.datetime(2020, 10, 14, 0, 0), 0.08405050922620161),\n",
" (datetime.datetime(2020, 10, 15, 0, 0), 0.05063125897469378),\n",
" (datetime.datetime(2020, 10, 16, 0, 0), 0.060133007954397355),\n",
" (datetime.datetime(2020, 10, 19, 0, 0), 0.04674158943297102),\n",
" (datetime.datetime(2020, 10, 20, 0, 0), 0.04907684448660876),\n",
" (datetime.datetime(2020, 10, 21, 0, 0), 0.052287820185360934),\n",
" (datetime.datetime(2020, 10, 22, 0, 0), 0.05187688373367427),\n",
" (datetime.datetime(2020, 10, 23, 0, 0), 0.05667055904247564),\n",
" (datetime.datetime(2020, 10, 26, 0, 0), 0.04027605345797136),\n",
" (datetime.datetime(2020, 10, 27, 0, 0), 0.04849193018330533),\n",
" (datetime.datetime(2020, 10, 28, 0, 0), 0.03806689549404818),\n",
" (datetime.datetime(2020, 10, 29, 0, 0), 0.014816143497757839),\n",
" (datetime.datetime(2020, 10, 30, 0, 0), 0.00481137623180139),\n",
" (datetime.datetime(2020, 11, 2, 0, 0), -0.00014131778837667142),\n",
" (datetime.datetime(2020, 11, 3, 0, 0), 0.010563504681151636),\n",
" (datetime.datetime(2020, 11, 4, 0, 0), 0.01794663654972828),\n",
" (datetime.datetime(2020, 11, 5, 0, 0), 0.0394424147838115),\n",
" (datetime.datetime(2020, 11, 6, 0, 0), 0.043924408336276866),\n",
" (datetime.datetime(2020, 11, 9, 0, 0), 0.06426903481460511),\n",
" (datetime.datetime(2020, 11, 10, 0, 0), 0.07422870082083222),\n",
" (datetime.datetime(2020, 11, 11, 0, 0), 0.08174632645483015),\n",
" (datetime.datetime(2020, 11, 12, 0, 0), 0.07851042385019369),\n",
" (datetime.datetime(2020, 11, 13, 0, 0), 0.0942456954233204),\n",
" (datetime.datetime(2020, 11, 17, 0, 0), 0.09901112922662514),\n",
" (datetime.datetime(2020, 11, 18, 0, 0), 0.10079208973472964),\n",
" (datetime.datetime(2020, 11, 19, 0, 0), 0.08264929654539355),\n",
" (datetime.datetime(2020, 11, 20, 0, 0), 0.07989130434782621),\n",
" (datetime.datetime(2020, 11, 23, 0, 0), 0.0914305886506046),\n",
" (datetime.datetime(2020, 11, 24, 0, 0), 0.10378607360338887),\n",
" (datetime.datetime(2020, 11, 25, 0, 0), 0.07314267788989381),\n",
" (datetime.datetime(2020, 11, 26, 0, 0), 0.08476710029374734),\n",
" (datetime.datetime(2020, 11, 27, 0, 0), 0.07934822345629589),\n",
" (datetime.datetime(2020, 12, 1, 0, 0), 0.09014280738418656),\n",
" (datetime.datetime(2020, 12, 2, 0, 0), 0.09430073533264638),\n",
" (datetime.datetime(2020, 12, 3, 0, 0), 0.10218081653420374),\n",
" (datetime.datetime(2020, 12, 4, 0, 0), 0.10882414661443751),\n",
" (datetime.datetime(2020, 12, 7, 0, 0), 0.13058534603084881),\n",
" (datetime.datetime(2020, 12, 8, 0, 0), 0.13247583879573832),\n",
" (datetime.datetime(2020, 12, 9, 0, 0), 0.14204505331544381),\n",
" (datetime.datetime(2020, 12, 10, 0, 0), 0.14810928106435184),\n",
" (datetime.datetime(2020, 12, 11, 0, 0), 0.14509213323883752),\n",
" (datetime.datetime(2020, 12, 14, 0, 0), 0.12969764486762192),\n",
" (datetime.datetime(2020, 12, 15, 0, 0), 0.1272258873087433),\n",
" (datetime.datetime(2020, 12, 16, 0, 0), 0.1384985949417905),\n",
" (datetime.datetime(2020, 12, 17, 0, 0), 0.1336538294659746),\n",
" (datetime.datetime(2020, 12, 18, 0, 0), 0.13410538706550335),\n",
" (datetime.datetime(2020, 12, 21, 0, 0), 0.09376186695204902),\n",
" (datetime.datetime(2020, 12, 22, 0, 0), 0.1060517140194015),\n",
" (datetime.datetime(2020, 12, 23, 0, 0), 0.12163516362002835),\n",
" (datetime.datetime(2020, 12, 24, 0, 0), 0.1345174146595043),\n",
" (datetime.datetime(2020, 12, 28, 0, 0), 0.13883233842862563),\n",
" (datetime.datetime(2020, 12, 29, 0, 0), 0.14235188571822932),\n",
" (datetime.datetime(2020, 12, 30, 0, 0), 0.1433421220424269),\n",
" (datetime.datetime(2020, 12, 31, 0, 0), 0.1496252444998356),\n",
" (datetime.datetime(2021, 1, 1, 0, 0), 0.15306899176527566)]"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%time\n",
"ts.calculate_rolling_returns(from_date='2020-01-01', to_date='2021-01-01')"
"from_date = datetime.date(2020, 1, 1)\n",
"to_date = datetime.date(2021, 1, 1)\n",
"# print(ts.calculate_returns(to_date, years=7))\n",
"ts.calculate_rolling_returns(from_date, to_date)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
@ -121,7 +415,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
"version": "3.9.2"
}
},
"nbformat": 4,

Loading…
Cancel
Save