Browse Source

Documentation for max_drawdown

Added other type hints for variables
switch-to-decimal
Gourav Kumar 2 years ago
parent
commit
1a5518e62a
  1. 44
      fincal/fincal.py

44
fincal/fincal.py

@ -3,7 +3,7 @@ from __future__ import annotations
import datetime import datetime
import math import math
import statistics import statistics
from typing import Iterable, List, Literal, Mapping, Union from typing import Iterable, List, Literal, Mapping, TypedDict, Union
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
@ -16,6 +16,12 @@ from .utils import (
) )
class MaxDrawdown(TypedDict):
start_date: datetime.datetime
end_date: datetime.datetime
drawdown: float
@date_parser(0, 1) @date_parser(0, 1)
def create_date_series( def create_date_series(
start_date: Union[str, datetime.datetime], start_date: Union[str, datetime.datetime],
@ -115,11 +121,11 @@ class TimeSeries(TimeSeriesCore):
super().__init__(data, frequency, date_format) super().__init__(data, frequency, date_format)
def info(self): def info(self) -> str:
"""Summary info about the TimeSeries object""" """Summary info about the TimeSeries object"""
total_dates = len(self.data.keys()) total_dates: int = len(self.data.keys())
res_string = "First date: {}\nLast date: {}\nNumber of rows: {}" res_string: str = "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)
def ffill(self, inplace: bool = False, limit: int = None) -> Union[TimeSeries, None]: def ffill(self, inplace: bool = False, limit: int = None) -> Union[TimeSeries, None]:
@ -138,7 +144,7 @@ class TimeSeries(TimeSeriesCore):
Returns a TimeSeries object if inplace is False, otherwise None Returns a TimeSeries object if inplace is False, otherwise None
""" """
eomonth = True if self.frequency.days >= AllFrequencies.M.days else False eomonth: bool = True if self.frequency.days >= AllFrequencies.M.days else False
dates_to_fill = create_date_series(self.start_date, self.end_date, self.frequency.symbol, eomonth) dates_to_fill = create_date_series(self.start_date, self.end_date, self.frequency.symbol, eomonth)
new_ts = dict() new_ts = dict()
@ -171,7 +177,7 @@ class TimeSeries(TimeSeriesCore):
Returns a TimeSeries object if inplace is False, otherwise None Returns a TimeSeries object if inplace is False, otherwise None
""" """
eomonth = True if self.frequency.days >= AllFrequencies.M.days else False eomonth: bool = True if self.frequency.days >= AllFrequencies.M.days else False
dates_to_fill = create_date_series(self.start_date, self.end_date, self.frequency.symbol, eomonth) dates_to_fill = create_date_series(self.start_date, self.end_date, self.frequency.symbol, eomonth)
dates_to_fill.append(self.end_date) dates_to_fill.append(self.end_date)
@ -517,21 +523,31 @@ class TimeSeries(TimeSeriesCore):
rr = self.calculate_rolling_returns(**kwargs) rr = self.calculate_rolling_returns(**kwargs)
return statistics.mean(rr.values) return statistics.mean(rr.values)
def max_drawdown(self): def max_drawdown(self) -> MaxDrawdown:
max_val_dict = {} """Calculates the maximum fall the stock has taken between any two points.
Returns
-------
MaxDrawdown
Returns the start_date, end_date, and the drawdown value in decimal.
"""
drawdowns: dict = dict()
prev_val = 0 prev_val: float = 0
prev_date = list(self.data)[0] prev_date: datetime.datetime = list(self.data)[0]
for dt, val in self.data.items(): for dt, val in self.data.items():
if val > prev_val: if val > prev_val:
max_val_dict[dt] = (dt, val, 0) drawdowns[dt] = (dt, val, 0)
prev_date, prev_val = dt, val prev_date, prev_val = dt, val
else: else:
max_val_dict[dt] = (prev_date, prev_val, val / prev_val - 1) drawdowns[dt] = (prev_date, prev_val, val / prev_val - 1)
max_drawdown = min(max_val_dict.items(), key=lambda x: x[1][2]) max_drawdown = min(drawdowns.items(), key=lambda x: x[1][2])
max_drawdown = dict(start_date=max_drawdown[1][0], end_date=max_drawdown[0], drawdown=max_drawdown[1][2]) max_drawdown: MaxDrawdown = dict(
start_date=max_drawdown[1][0], end_date=max_drawdown[0], drawdown=max_drawdown[1][2]
)
return max_drawdown return max_drawdown

Loading…
Cancel
Save