Compare commits

...

7 Commits

  1. 15
      .ipynb_checkpoints/README-checkpoint.md
  2. 129
      .ipynb_checkpoints/testing-checkpoint.ipynb
  3. 15
      .vscode/launch.json
  4. 128
      fincal/core.py
  5. 22
      fincal/fincal.py
  6. 326
      testing.ipynb

15
.ipynb_checkpoints/README-checkpoint.md

@ -0,0 +1,15 @@
# Fincal
This module simplified handling of time-series data
## The problem
Time series data often have missing data points. These missing points mess things up when you are trying to do a comparison between two sections of a time series.
To make things worse, most libraries don't allow comparison based on dates. Month to Month and year to year comparisons become difficult as they cannot be translated into number of days. However, these are commonly used metrics while looking at financial data.
## The Solution
Fincal aims to simplify things by allowing you to:
* Compare time-series data based on dates
* Easy way to work around missing dates by taking the closest data points
* Completing series with missing data points using forward fill and backward fill
## Examples

129
.ipynb_checkpoints/testing-checkpoint.ipynb

@ -0,0 +1,129 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 14,
"id": "3f7938c0-98e3-43b8-86e8-4f000cda7ce5",
"metadata": {},
"outputs": [],
"source": [
"import datetime\n",
"import pandas as pd\n",
"\n",
"from fincal.fincal import TimeSeries\n",
"from fincal.core import Series"
]
},
{
"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",
"metadata": {},
"outputs": [],
"source": [
"dfd = dfd[dfd['amfi_code'] == 118825].reset_index(drop=True)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "4bc95ae0-8c33-4eab-acf9-e765d22979b8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Warning: The input data contains duplicate dates which have been ignored.\n"
]
}
],
"source": [
"ts = TimeSeries([(i.date, i.nav) for i in dfd.itertuples()], frequency='D')"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "f2c3218c-3984-43d6-8638-41a74a9d0b58",
"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')"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ts"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "dc469722-c816-4b57-8d91-7a3b865f86be",
"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"
]
}
],
"source": [
"%%time\n",
"ts.calculate_rolling_returns(from_date='2020-01-01', to_date='2021-01-01')"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

15
.vscode/launch.json

@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}

128
fincal/core.py

@ -1,8 +1,8 @@
import datetime import datetime
from collections import UserList from collections import UserDict, UserList
from dataclasses import dataclass from dataclasses import dataclass
from numbers import Number from numbers import Number
from typing import Iterable, List, Literal, Mapping, Sequence, Tuple, Union from typing import Iterable, List, Literal, Mapping, Sequence, Tuple, Type, Union
@dataclass @dataclass
@ -108,23 +108,24 @@ def _parse_date(date: str, date_format: str = None):
try: try:
date = datetime.datetime.strptime(date, date_format) date = datetime.datetime.strptime(date, date_format)
except TypeError: except TypeError:
raise Exception("Date does not seem to be valid date-like string") raise ValueError("Date does not seem to be valid date-like string")
except ValueError: except ValueError:
raise Exception("Date could not be parsed. Have you set the correct date format in FincalOptions.date_format?") raise ValueError("Date could not be parsed. Have you set the correct date format in FincalOptions.date_format?")
return date return date
class _IndexSlicer: class _IndexSlicer:
"""Class to create a slice using iloc in TimeSeriesCore"""
def __init__(self, parent_obj): def __init__(self, parent_obj):
self.parent = parent_obj self.parent = parent_obj
def __getitem__(self, n): def __getitem__(self, n):
all_keys = list(self.parent.time_series)
if isinstance(n, int): if isinstance(n, int):
keys = [all_keys[n]] keys = [self.parent.dates[n]]
else: else:
keys = all_keys[n] keys = self.parent.dates[n]
item = [(key, self.parent.time_series[key]) for key in keys] item = [(key, self.parent.data[key]) for key in keys]
if len(item) == 1: if len(item) == 1:
return item[0] return item[0]
@ -132,34 +133,36 @@ class _IndexSlicer:
class Series(UserList): class Series(UserList):
def __init__(self, data): """Container for a series of objects, all objects must be of the same type"""
def __init__(
self,
data,
data_type: Union[Type[bool], Type[float], Type[str], Type[datetime.datetime]],
date_format: str = None,
):
self.dtype = data_type
if not isinstance(data, Sequence): if not isinstance(data, Sequence):
raise TypeError("Series only supports creation using Sequence types") raise TypeError("Series object can only be created using Sequence types")
if isinstance(data[0], bool): for i in data:
self.data = data if not isinstance(i, data_type):
self.dtype = bool raise Exception("All arguments must be of the same type")
elif isinstance(data[0], Number):
self.dtype = float if data_type == str:
self.data = [float(i) for i in data] data = [_parse_date(i, date_format) for i in data]
elif isinstance(data[0], str):
try: self.data = data
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 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 = [_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): def __repr__(self):
return f"{self.__class__.__name__}({self.data})" return f"{self.__class__.__name__}({self.data})"
def __getitem__(self, i):
if isinstance(i, slice):
return self.__class__(self.data[i], self.dtype)
else:
return self.data[i]
def __gt__(self, other): def __gt__(self, other):
if self.dtype == bool: if self.dtype == bool:
raise TypeError("> not supported for boolean series") raise TypeError("> not supported for boolean series")
@ -168,7 +171,7 @@ class Series(UserList):
other = _parse_date(other) other = _parse_date(other)
if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype): if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype):
gt = Series([i > other for i in self.data]) gt = Series([i > other for i in self.data], bool)
else: else:
raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}") raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}")
@ -179,20 +182,20 @@ class Series(UserList):
raise TypeError("< not supported for boolean series") raise TypeError("< not supported for boolean series")
if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype): if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype):
lt = Series([i < other for i in self.data]) lt = Series([i < other for i in self.data], bool)
else: else:
raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}") raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}")
return lt return lt
def __eq__(self, other): def __eq__(self, other):
if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype): if self.dtype == float and isinstance(other, Number) or isinstance(other, self.dtype):
eq = Series([i == other for i in self.data]) eq = Series([i == other for i in self.data], bool)
else: else:
raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}") raise Exception(f"Cannot compare type {self.dtype.__name__} to {type(other).__name__}")
return eq return eq
class TimeSeriesCore: class TimeSeriesCore(UserDict):
"""Defines the core building blocks of a TimeSeries object""" """Defines the core building blocks of a TimeSeries object"""
def __init__( def __init__(
@ -219,8 +222,8 @@ class TimeSeriesCore:
data = _preprocess_timeseries(data, date_format=date_format) data = _preprocess_timeseries(data, date_format=date_format)
self.time_series = dict(data) self.data = dict(data)
if len(self.time_series) != len(data): if len(self.data) != len(data):
print("Warning: The input data contains duplicate dates which have been ignored.") print("Warning: The input data contains duplicate dates which have been ignored.")
self.frequency = getattr(AllFrequencies, frequency) self.frequency = getattr(AllFrequencies, frequency)
self.iter_num = -1 self.iter_num = -1
@ -231,17 +234,17 @@ class TimeSeriesCore:
@property @property
def dates(self): def dates(self):
if self._dates is None or len(self._dates) != len(self.time_series): if self._dates is None or len(self._dates) != len(self.data):
self._dates = list(self.time_series.keys()) self._dates = list(self.data.keys())
return Series(self._dates) return Series(self._dates, datetime.datetime)
@property @property
def values(self): def values(self):
if self._values is None or len(self._values) != len(self.time_series): if self._values is None or len(self._values) != len(self.data):
self._values = list(self.time_series.values()) self._values = list(self.data.values())
return Series(self._values) return Series(self._values, float)
@property @property
def start_date(self): def start_date(self):
@ -255,19 +258,19 @@ class TimeSeriesCore:
"""Returns a slice of the dataframe from beginning and end""" """Returns a slice of the dataframe from beginning and end"""
printable = {} printable = {}
iter_f = iter(self.time_series) iter_f = iter(self.data)
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) iter_b = reversed(self.data)
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() last_n.sort()
printable["start"] = [str((i, self.time_series[i])) for i in first_n] printable["start"] = [str((i, self.data[i])) for i in first_n]
printable["end"] = [str((i, self.time_series[i])) for i in last_n] printable["end"] = [str((i, self.data[i])) for i in last_n]
return printable return printable
def __repr__(self): def __repr__(self):
if len(self.time_series) > 6: if len(self.data) > 6:
printable = self._get_printable_slice(6) printable = self._get_printable_slice(6)
printable_str = "{}([{}\n\t ...\n\t {}], frequency={})".format( printable_str = "{}([{}\n\t ...\n\t {}], frequency={})".format(
self.__class__.__name__, self.__class__.__name__,
@ -278,20 +281,20 @@ class TimeSeriesCore:
else: else:
printable_str = "{}([{}], frequency={})".format( printable_str = "{}([{}], frequency={})".format(
self.__class__.__name__, self.__class__.__name__,
",\n\t".join([str(i) for i in self.time_series.items()]), ",\n\t".join([str(i) for i in self.data.items()]),
repr(self.frequency.symbol), repr(self.frequency.symbol),
) )
return printable_str return printable_str
def __str__(self): def __str__(self):
if len(self.time_series) > 6: if len(self.data) > 6:
printable = self._get_printable_slice(6) printable = self._get_printable_slice(6)
printable_str = "[{}\n ...\n {}]".format( printable_str = "[{}\n ...\n {}]".format(
",\n ".join(printable["start"]), ",\n ".join(printable["start"]),
",\n ".join(printable["end"]), ",\n ".join(printable["end"]),
) )
else: 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.data.items()]))
return printable_str return printable_str
def __getitem__(self, key): def __getitem__(self, key):
@ -302,14 +305,14 @@ class TimeSeriesCore:
raise Exception(f"Length of Series: {len(key)} did not match length of object: {len(self.dates)}") raise Exception(f"Length of Series: {len(key)} did not match length of object: {len(self.dates)}")
else: else:
dates_to_return = [self.dates[i] for i, j in enumerate(key) if j] 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] data_to_return = [(key, self.data[key]) for key in dates_to_return]
return TimeSeriesCore(data_to_return, frequency=self.frequency.symbol) return self.__class__(data_to_return, frequency=self.frequency.symbol)
if isinstance(key, int): if isinstance(key, int):
raise KeyError(f"{key}. For index based slicing, use .iloc[{key}]") raise KeyError(f"{key}. For index based slicing, use .iloc[{key}]")
elif isinstance(key, (datetime.datetime, datetime.date)): elif isinstance(key, (datetime.datetime, datetime.date)):
key = _parse_date(key) key = _parse_date(key)
item = (key, self.time_series[key]) item = (key, self.data[key])
elif isinstance(key, str): elif isinstance(key, str):
if key == "dates": if key == "dates":
return self.dates return self.dates
@ -317,18 +320,15 @@ class TimeSeriesCore:
return self.values return self.values
dt_key = _parse_date(key) dt_key = _parse_date(key)
item = (dt_key, self.time_series[dt_key]) item = (dt_key, self.data[dt_key])
elif isinstance(key, Sequence): elif isinstance(key, Sequence):
keys = [_parse_date(i) for i in key] keys = [_parse_date(i) for i in key]
item = [(k, self.time_series[k]) for k in keys] item = [(k, self.data[k]) for k in keys]
else: else:
raise TypeError(f"Invalid type {repr(type(key).__name__)} for slicing.") raise TypeError(f"Invalid type {repr(type(key).__name__)} for slicing.")
return item return item
def __len__(self):
return len(self.time_series)
def __iter__(self): def __iter__(self):
self.n = 0 self.n = 0
return self return self
@ -339,22 +339,22 @@ class TimeSeriesCore:
else: else:
key = self.dates[self.n] key = self.dates[self.n]
self.n += 1 self.n += 1
return key, self.time_series[key] return key, self.data[key]
def head(self, n: int = 6): def head(self, n: int = 6):
"""Returns the first n items of the TimeSeries object""" """Returns the first n items of the TimeSeries object"""
keys = list(self.time_series.keys()) keys = list(self.data.keys())
keys = keys[:n] keys = keys[:n]
result = [(key, self.time_series[key]) for key in keys] result = [(key, self.data[key]) for key in keys]
return result return result
def tail(self, n: int = 6): def tail(self, n: int = 6):
"""Returns the last n items of the TimeSeries object""" """Returns the last n items of the TimeSeries object"""
keys = list(self.time_series.keys()) keys = list(self.data.keys())
keys = keys[-n:] keys = keys[-n:]
result = [(key, self.time_series[key]) for key in keys] result = [(key, self.data[key]) for key in keys]
return result return result
@property @property

22
fincal/fincal.py

@ -40,7 +40,7 @@ class TimeSeries(TimeSeriesCore):
def info(self): def info(self):
"""Summary info about the TimeSeries object""" """Summary info about the TimeSeries object"""
total_dates = len(self.time_series.keys()) total_dates = len(self.data.keys())
res_string = "First date: {}\nLast date: {}\nNumber of rows: {}" res_string = "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)
@ -66,16 +66,16 @@ class TimeSeries(TimeSeriesCore):
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.time_series[cur_date] cur_val = self.data[cur_date]
except KeyError: except KeyError:
pass pass
new_ts.update({cur_date: cur_val}) new_ts.update({cur_date: cur_val})
if inplace: if inplace:
self.time_series = new_ts self.data = new_ts
return None return None
return TimeSeries(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) -> Union[TimeSeries, None]:
"""Backward fill missing dates in the time series """Backward fill missing dates in the time series
@ -100,16 +100,16 @@ class TimeSeries(TimeSeriesCore):
bfill_ts = dict() bfill_ts = dict()
for cur_date in reversed(dates_to_fill): for cur_date in reversed(dates_to_fill):
try: try:
cur_val = self.time_series[cur_date] cur_val = self.data[cur_date]
except KeyError: except KeyError:
pass pass
bfill_ts.update({cur_date: cur_val}) bfill_ts.update({cur_date: cur_val})
new_ts = {k: bfill_ts[k] for k in reversed(bfill_ts)} new_ts = {k: bfill_ts[k] for k in reversed(bfill_ts)}
if inplace: if inplace:
self.time_series = new_ts self.data = new_ts
return None return None
return TimeSeries(new_ts, frequency=self.frequency.symbol) return self.__class__(new_ts, frequency=self.frequency.symbol)
def calculate_returns( def calculate_returns(
self, self,
@ -163,7 +163,7 @@ class TimeSeries(TimeSeriesCore):
as_on_delta, prior_delta = _preprocess_match_options(as_on_match, prior_match, closest) as_on_delta, prior_delta = _preprocess_match_options(as_on_match, prior_match, closest)
while True: while True:
current = self.time_series.get(as_on, None) current = self.data.get(as_on, None)
if current is not None: if current is not None:
break break
elif not as_on_delta: elif not as_on_delta:
@ -172,7 +172,7 @@ class TimeSeries(TimeSeriesCore):
prev_date = as_on - relativedelta(years=years) prev_date = as_on - relativedelta(years=years)
while True: while True:
previous = self.time_series.get(prev_date, None) previous = self.data.get(prev_date, None)
if previous is not None: if previous is not None:
break break
elif not prior_delta: elif not prior_delta:
@ -211,7 +211,7 @@ class TimeSeries(TimeSeriesCore):
dates = create_date_series(from_date, to_date, frequency.symbol) dates = create_date_series(from_date, to_date, frequency.symbol)
if frequency == AllFrequencies.D: if frequency == AllFrequencies.D:
dates = [i for i in dates if i in self.time_series] dates = [i for i in dates if i in self.data]
rolling_returns = [] rolling_returns = []
for i in dates: for i in dates:
@ -225,7 +225,7 @@ class TimeSeries(TimeSeriesCore):
) )
rolling_returns.append((i, returns)) rolling_returns.append((i, returns))
rolling_returns.sort() rolling_returns.sort()
return rolling_returns return self.__class__(rolling_returns, self.frequency.symbol)
if __name__ == "__main__": if __name__ == "__main__":

326
testing.ipynb

@ -22,7 +22,6 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"dfd = pd.read_csv('test_files/nav_history_daily - copy.csv')\n", "dfd = pd.read_csv('test_files/nav_history_daily - copy.csv')\n",
"\n",
"dfd = dfd[dfd['amfi_code'] == 118825].reset_index(drop=True)" "dfd = dfd[dfd['amfi_code'] == 118825].reset_index(drop=True)"
] ]
}, },
@ -48,7 +47,7 @@
"\t ...\n", "\t ...\n",
"\t (datetime.datetime(2022, 2, 10, 0, 0), 86.5),\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, 11, 0, 0), 85.226),\n",
"\t (datetime.datetime(2022, 2, 14, 0, 0), 82.533)], frequency='D')" "\t (datetime.datetime(2022, 2, 14, 0, 0), 82.53299999999999)], frequency='D')"
] ]
}, },
"execution_count": 3, "execution_count": 3,
@ -58,7 +57,6 @@
], ],
"source": [ "source": [
"ts = TimeSeries([(i.date, i.nav) for i in dfd.itertuples()], frequency='D')\n", "ts = TimeSeries([(i.date, i.nav) for i in dfd.itertuples()], frequency='D')\n",
"\n",
"ts" "ts"
] ]
}, },
@ -71,8 +69,8 @@
{ {
"data": { "data": {
"text/plain": [ "text/plain": [
"[(datetime.datetime(2021, 1, 1, 0, 0), 66.652),\n", "[(datetime.datetime(2022, 1, 31, 0, 0), 85.18),\n",
" (datetime.datetime(2020, 1, 1, 0, 0), 57.804)]" " (datetime.datetime(2021, 5, 31, 0, 0), 74.85)]"
] ]
}, },
"execution_count": 4, "execution_count": 4,
@ -81,79 +79,99 @@
} }
], ],
"source": [ "source": [
"ts[['2021-01-01', '2020-01-01']]" "ts[['2022-01-31', '2021-05-31']]"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 5, "execution_count": 16,
"id": "4d927a61-0f90-4b47-89b7-0e0d3ab1b442", "id": "086d4377-d1b1-4e51-84c0-39dee28ef75e",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"text/plain": [ "text/plain": [
"Series([False, False, False, False, False, False, False, False, False, False])" "TimeSeries([(datetime.datetime(2021, 2, 15, 0, 0), 73.483),\n",
"\t (datetime.datetime(2021, 2, 16, 0, 0), 73.237),\n",
"\t (datetime.datetime(2021, 2, 17, 0, 0), 72.98)\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')"
] ]
}, },
"execution_count": 5, "execution_count": 16,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
], ],
"source": [ "source": [
"s = ts.dates > '2020-01-01'\n", "ts[ts.dates>'2021-02-14']"
"s[:10]"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 8, "execution_count": 5,
"id": "311d1c07-d827-4d69-855f-883e1198c162", "id": "6f1226a3-2327-435b-88e7-fd0fdcc8cc1c",
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [
{
"data": {
"text/plain": [
"TimeSeries([(datetime.datetime(2020, 1, 2, 0, 0), 58.285),\n",
"\t (datetime.datetime(2020, 1, 3, 0, 0), 58.056999999999995),\n",
"\t (datetime.datetime(2020, 1, 6, 0, 0), 56.938)\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')"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [ "source": [
"import pandas as pd" "s = ts.dates > '2020-01-01'\n",
"ts[s]"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 10, "execution_count": 9,
"id": "bb625050-5d7b-45a9-9cde-ac6e599adea5", "id": "e815edc9-3746-4192-814e-bd27b2771a0c",
"metadata": {}, "metadata": {},
"outputs": [ "outputs": [
{ {
"data": { "data": {
"text/plain": [ "text/plain": [
"0 False\n", "[(datetime.datetime(2013, 1, 2, 0, 0), 18.972),\n",
"1 False\n", " (datetime.datetime(2013, 1, 3, 0, 0), 19.011),\n",
"2 False\n", " (datetime.datetime(2013, 1, 4, 0, 0), 19.008),\n",
"3 False\n", " (datetime.datetime(2013, 1, 7, 0, 0), 18.95),\n",
"4 False\n", " (datetime.datetime(2013, 1, 8, 0, 0), 18.954),\n",
" ... \n", " (datetime.datetime(2013, 1, 9, 0, 0), 18.94),\n",
"2196 True\n", " (datetime.datetime(2013, 1, 10, 0, 0), 18.957),\n",
"2197 True\n", " (datetime.datetime(2013, 1, 11, 0, 0), 18.948),\n",
"2198 True\n", " (datetime.datetime(2013, 1, 14, 0, 0), 19.177),\n",
"2199 True\n", " (datetime.datetime(2013, 1, 15, 0, 0), 19.272000000000002)]"
"2200 True\n",
"Length: 2201, dtype: bool"
] ]
}, },
"execution_count": 10, "execution_count": 9,
"metadata": {}, "metadata": {},
"output_type": "execute_result" "output_type": "execute_result"
} }
], ],
"source": [ "source": [
"pd.Series(s)" "ts.iloc[:10]"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": 9, "execution_count": 6,
"id": "dc469722-c816-4b57-8d91-7a3b865f86be", "id": "dc469722-c816-4b57-8d91-7a3b865f86be",
"metadata": { "metadata": {
"scrolled": true,
"tags": [] "tags": []
}, },
"outputs": [ "outputs": [
@ -161,233 +179,9 @@
"name": "stdout", "name": "stdout",
"output_type": "stream", "output_type": "stream",
"text": [ "text": [
"CPU times: total: 15.6 ms\n",
"Wall time: 14 ms\n" "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": [ "source": [
@ -395,13 +189,21 @@
"from_date = datetime.date(2020, 1, 1)\n", "from_date = datetime.date(2020, 1, 1)\n",
"to_date = datetime.date(2021, 1, 1)\n", "to_date = datetime.date(2021, 1, 1)\n",
"# print(ts.calculate_returns(to_date, years=7))\n", "# print(ts.calculate_returns(to_date, years=7))\n",
"ts.calculate_rolling_returns(from_date, to_date)" "rr = ts.calculate_rolling_returns(from_date, to_date)"
] ]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e5d357b4-4fe5-4a0a-8107-0ab6828d7c41",
"metadata": {},
"outputs": [],
"source": []
} }
], ],
"metadata": { "metadata": {
"kernelspec": { "kernelspec": {
"display_name": "Python 3", "display_name": "Python 3 (ipykernel)",
"language": "python", "language": "python",
"name": "python3" "name": "python3"
}, },
@ -415,7 +217,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.9.2" "version": "3.8.3"
} }
}, },
"nbformat": 4, "nbformat": 4,

Loading…
Cancel
Save