|
|
@ -1,15 +1,44 @@ |
|
|
|
import datetime |
|
|
|
from typing import Literal |
|
|
|
|
|
|
|
from fincal.core import date_parser |
|
|
|
|
|
|
|
from .fincal import TimeSeries |
|
|
|
|
|
|
|
|
|
|
|
@date_parser(3, 4) |
|
|
|
def sharpe_ratio( |
|
|
|
time_series_data: TimeSeries, risk_free_data: TimeSeries = None, risk_free_rate: float = None, **kwargs |
|
|
|
time_series_data: TimeSeries, |
|
|
|
risk_free_data: TimeSeries = None, |
|
|
|
risk_free_rate: float = None, |
|
|
|
from_date: str | datetime.datetime = None, |
|
|
|
to_date: str | datetime.datetime = None, |
|
|
|
frequency: Literal["D", "W", "M", "Q", "H", "Y"] = None, |
|
|
|
return_period_unit: Literal["years", "months", "days"] = "years", |
|
|
|
return_period_value: int = 1, |
|
|
|
as_on_match: str = "closest", |
|
|
|
prior_match: str = "closest", |
|
|
|
closest: Literal["previous", "next"] = "previous", |
|
|
|
date_format: str = None, |
|
|
|
): |
|
|
|
pass |
|
|
|
|
|
|
|
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") |
|
|
|
|
|
|
|
returns_ts = time_series_data.calculate_rolling_returns(**kwargs) |
|
|
|
common_params = { |
|
|
|
"from_date": from_date, |
|
|
|
"to_date": to_date, |
|
|
|
"frequency": frequency, |
|
|
|
"annual_compounded_returns": True, |
|
|
|
"return_period_unit": return_period_unit, |
|
|
|
"return_period_value": return_period_value, |
|
|
|
"as_on_match": as_on_match, |
|
|
|
"prior_match": prior_match, |
|
|
|
"closest": closest, |
|
|
|
"date_format": date_format, |
|
|
|
} |
|
|
|
returns_ts = time_series_data.calculate_rolling_returns(**common_params) |
|
|
|
|
|
|
|
if risk_free_data is not None: |
|
|
|
risk_free_data = returns_ts.sync(risk_free_data) |
|
|
@ -17,6 +46,10 @@ def sharpe_ratio( |
|
|
|
risk_free_data = risk_free_rate |
|
|
|
|
|
|
|
excess_returns = returns_ts - risk_free_data |
|
|
|
sd = time_series_data.volatility(**kwargs) |
|
|
|
sd = time_series_data.volatility( |
|
|
|
**common_params, |
|
|
|
annualize_volatility=True, |
|
|
|
) |
|
|
|
|
|
|
|
sharpe_ratio = excess_returns.mean() / sd |
|
|
|
return sharpe_ratio |
|
|
|