Sharpe ratio is working
This commit is contained in:
parent
2a8f5b4041
commit
0d0b2121a3
@ -449,7 +449,7 @@ class TimeSeries(TimeSeriesCore):
|
|||||||
prior_match: str = "closest",
|
prior_match: str = "closest",
|
||||||
closest: Literal["previous", "next", "exact"] = "previous",
|
closest: Literal["previous", "next", "exact"] = "previous",
|
||||||
if_not_found: Literal["fail", "nan"] = "fail",
|
if_not_found: Literal["fail", "nan"] = "fail",
|
||||||
annual_compounded_returns: bool = False,
|
annual_compounded_returns: bool = None,
|
||||||
date_format: str = None,
|
date_format: str = None,
|
||||||
) -> float:
|
) -> float:
|
||||||
"""Calculates the volatility of the time series.add()
|
"""Calculates the volatility of the time series.add()
|
||||||
@ -503,6 +503,12 @@ class TimeSeries(TimeSeriesCore):
|
|||||||
from_date = self.start_date + relativedelta(**{return_period_unit: return_period_value})
|
from_date = self.start_date + relativedelta(**{return_period_unit: return_period_value})
|
||||||
if to_date is None:
|
if to_date is None:
|
||||||
to_date = self.end_date
|
to_date = self.end_date
|
||||||
|
years = _interval_to_years(return_period_unit, return_period_value)
|
||||||
|
if annual_compounded_returns is None:
|
||||||
|
if years > 1:
|
||||||
|
annual_compounded_returns = True
|
||||||
|
else:
|
||||||
|
annual_compounded_returns = False
|
||||||
|
|
||||||
rolling_returns = self.calculate_rolling_returns(
|
rolling_returns = self.calculate_rolling_returns(
|
||||||
from_date=from_date,
|
from_date=from_date,
|
||||||
@ -524,7 +530,7 @@ class TimeSeries(TimeSeriesCore):
|
|||||||
if return_period_unit == "months":
|
if return_period_unit == "months":
|
||||||
sd *= math.sqrt(12)
|
sd *= math.sqrt(12)
|
||||||
elif return_period_unit == "days":
|
elif return_period_unit == "days":
|
||||||
sd *= math.sqrt(traded_days)
|
sd *= math.sqrt(traded_days / return_period_value)
|
||||||
|
|
||||||
return sd
|
return sd
|
||||||
|
|
||||||
@ -544,19 +550,32 @@ class TimeSeries(TimeSeriesCore):
|
|||||||
---------
|
---------
|
||||||
TimeSeries.calculate_rolling_returns()
|
TimeSeries.calculate_rolling_returns()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
kwargs["return_period_unit"] = kwargs.get("return_period_unit", self.frequency.freq_type)
|
kwargs["return_period_unit"] = kwargs.get("return_period_unit", self.frequency.freq_type)
|
||||||
kwargs["return_period_value"] = kwargs.get("return_period_value", 1)
|
kwargs["return_period_value"] = kwargs.get("return_period_value", 1)
|
||||||
kwargs["to_date"] = kwargs.get("to_date", self.end_date)
|
|
||||||
|
|
||||||
if kwargs.get("from_date", None) is None:
|
years = _interval_to_years(kwargs["return_period_unit"], kwargs["return_period_value"])
|
||||||
start_date = self.start_date + relativedelta(
|
if kwargs.get("annual_compounded_returns", True):
|
||||||
|
if years >= 1:
|
||||||
|
kwargs["annual_compounded_returns"] = True
|
||||||
|
annualise_returns = False
|
||||||
|
else:
|
||||||
|
kwargs["annual_compounded_returns"] = False
|
||||||
|
annualise_returns = True
|
||||||
|
elif not kwargs["annual_compounded_returns"]:
|
||||||
|
annualise_returns = False
|
||||||
|
|
||||||
|
if kwargs.get("from_date") is None:
|
||||||
|
kwargs["from_date"] = self.start_date + relativedelta(
|
||||||
**{kwargs["return_period_unit"]: kwargs["return_period_value"]}
|
**{kwargs["return_period_unit"]: kwargs["return_period_value"]}
|
||||||
)
|
)
|
||||||
kwargs["from_date"] = start_date
|
kwargs["to_date"] = kwargs.get("to_date", self.end_date)
|
||||||
|
|
||||||
rr = self.calculate_rolling_returns(**kwargs)
|
rr = self.calculate_rolling_returns(**kwargs)
|
||||||
return statistics.mean(rr.values)
|
mean_rr = statistics.mean(rr.values)
|
||||||
|
if annualise_returns:
|
||||||
|
mean_rr = (1 + mean_rr) ** (1 / years) - 1
|
||||||
|
|
||||||
|
return mean_rr
|
||||||
|
|
||||||
def max_drawdown(self) -> MaxDrawdown:
|
def max_drawdown(self) -> MaxDrawdown:
|
||||||
"""Calculates the maximum fall the stock has taken between any two points.
|
"""Calculates the maximum fall the stock has taken between any two points.
|
||||||
|
@ -21,10 +21,10 @@ def sharpe_ratio(
|
|||||||
closest: Literal["previous", "next"] = "previous",
|
closest: Literal["previous", "next"] = "previous",
|
||||||
date_format: str = None,
|
date_format: str = None,
|
||||||
):
|
):
|
||||||
pass
|
|
||||||
|
|
||||||
if risk_free_data is None and risk_free_rate is None:
|
if risk_free_data is None and risk_free_rate is None:
|
||||||
raise ValueError("At least one of risk_free_data or risk_free rate is required")
|
raise ValueError("At least one of risk_free_data or risk_free rate is required")
|
||||||
|
elif risk_free_data is not None:
|
||||||
|
risk_free_rate = risk_free_data.mean()
|
||||||
|
|
||||||
common_params = {
|
common_params = {
|
||||||
"from_date": from_date,
|
"from_date": from_date,
|
||||||
@ -37,18 +37,13 @@ def sharpe_ratio(
|
|||||||
"closest": closest,
|
"closest": closest,
|
||||||
"date_format": date_format,
|
"date_format": date_format,
|
||||||
}
|
}
|
||||||
returns_ts = time_series_data.calculate_rolling_returns(**common_params, annual_compounded_returns=True)
|
average_rr = time_series_data.average_rolling_return(**common_params, annual_compounded_returns=True)
|
||||||
|
|
||||||
if risk_free_data is not None:
|
excess_returns = average_rr - risk_free_rate
|
||||||
risk_free_data = returns_ts.sync(risk_free_data)
|
|
||||||
else:
|
|
||||||
risk_free_data = risk_free_rate
|
|
||||||
|
|
||||||
excess_returns = returns_ts - risk_free_data
|
|
||||||
sd = time_series_data.volatility(
|
sd = time_series_data.volatility(
|
||||||
**common_params,
|
**common_params,
|
||||||
annualize_volatility=True,
|
annualize_volatility=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
sharpe_ratio = excess_returns.mean() / sd
|
sharpe_ratio_value = excess_returns / sd
|
||||||
return sharpe_ratio
|
return sharpe_ratio_value
|
||||||
|
@ -206,6 +206,8 @@ class TestTimeSeriesCreation:
|
|||||||
|
|
||||||
|
|
||||||
class TestTimeSeriesBasics:
|
class TestTimeSeriesBasics:
|
||||||
|
FincalOptions.get_closest = "exact"
|
||||||
|
|
||||||
def test_fill(self):
|
def test_fill(self):
|
||||||
ts_data = create_test_data(frequency=AllFrequencies.D, num=50, skip_weekends=True)
|
ts_data = create_test_data(frequency=AllFrequencies.D, num=50, skip_weekends=True)
|
||||||
ts = TimeSeries(ts_data, frequency="D")
|
ts = TimeSeries(ts_data, frequency="D")
|
||||||
|
Loading…
Reference in New Issue
Block a user