From 31abaa4052e435571e5c4bebfda13893eb1f3916 Mon Sep 17 00:00:00 2001 From: Gourav Kumar Date: Sun, 26 Jun 2022 20:40:03 +0530 Subject: [PATCH] changed interval days calculation to math.ceil This is to avoid distorting round figure years --- pyfacts/statistics.py | 10 +++++----- tests/test_stats.py | 46 +++++++++++-------------------------------- 2 files changed, 17 insertions(+), 39 deletions(-) diff --git a/pyfacts/statistics.py b/pyfacts/statistics.py index 7de44b7..58694a7 100644 --- a/pyfacts/statistics.py +++ b/pyfacts/statistics.py @@ -90,7 +90,7 @@ def sharpe_ratio( If risk free data or risk free rate is not provided. """ - interval_days = int(_interval_to_years(return_period_unit, return_period_value) * 365 + 1) + interval_days = math.ceil(_interval_to_years(return_period_unit, return_period_value) * 365) if from_date is None: from_date = time_series_data.start_date + datetime.timedelta(days=interval_days) @@ -187,7 +187,7 @@ def beta( The value of beta as a float. """ interval_years = _interval_to_years(return_period_unit, return_period_value) - interval_days = int(interval_years * 365 + 1) + interval_days = math.ceil(interval_years * 365) annual_compounded_returns = True if interval_years > 1 else False @@ -300,7 +300,7 @@ def jensens_alpha( """ interval_years = _interval_to_years(return_period_unit, return_period_value) - interval_days = int(interval_years * 365 + 1) + interval_days = math.ceil(interval_years * 365) if from_date is None: from_date = asset_data.start_date + datetime.timedelta(days=interval_days) @@ -423,7 +423,7 @@ def correlation( * If both time series do not have data between the from date and to date """ interval_years = _interval_to_years(return_period_unit, return_period_value) - interval_days = int(interval_years * 365 + 1) + interval_days = math.ceil(interval_years * 365) annual_compounded_returns = True if interval_years > 1 else False @@ -538,7 +538,7 @@ def sortino_ratio( If risk free data or risk free rate is not provided. """ - interval_days = int(_interval_to_years(return_period_unit, return_period_value) * 365 + 1) + interval_days = math.ceil(_interval_to_years(return_period_unit, return_period_value) * 365) if from_date is None: from_date = time_series_data.start_date + datetime.timedelta(days=interval_days) diff --git a/tests/test_stats.py b/tests/test_stats.py index 4e306be..70a9b47 100644 --- a/tests/test_stats.py +++ b/tests/test_stats.py @@ -86,47 +86,25 @@ class TestSharpe: class TestSortino: def test_sortino_daily_freq(self, create_test_data): - data = create_test_data(num=1305, frequency=pft.AllFrequencies.D, skip_weekends=True) + data = create_test_data(num=3600, frequency=pft.AllFrequencies.D, mu=0.12, sigma=0.12) ts = pft.TimeSeries(data, "D") sortino_ratio = pft.sortino_ratio( ts, - risk_free_rate=0.06, + risk_free_rate=0.06 / 12, from_date="2017-02-02", - to_date="2021-12-31", return_period_unit="months", return_period_value=1, ) - assert round(sortino_ratio, 4) == 2.5377 + assert round(sortino_ratio, 4) == 1.625 - # sharpe_ratio = pft.sharpe_ratio( - # ts, - # risk_free_rate=0.06, - # from_date="2017-01-09", - # to_date="2021-12-31", - # return_period_unit="days", - # return_period_value=7, - # ) - # assert round(sharpe_ratio, 4) == 1.0701 - - # sharpe_ratio = pft.sharpe_ratio( - # ts, - # risk_free_rate=0.06, - # from_date="2018-01-02", - # to_date="2021-12-31", - # return_period_unit="years", - # return_period_value=1, - # ) - # assert round(sharpe_ratio, 4) == 1.4374 - - # sharpe_ratio = pft.sharpe_ratio( - # ts, - # risk_free_rate=0.06, - # from_date="2017-07-03", - # to_date="2021-12-31", - # return_period_unit="months", - # return_period_value=6, - # ) - # assert round(sharpe_ratio, 4) == 0.8401 + sortino_ratio = pft.sortino_ratio( + ts, + risk_free_rate=0.06, + from_date="2018-01-02", + return_period_unit="years", + return_period_value=1, + ) + assert round(sortino_ratio, 4) == 1.2564 # def test_sharpe_weekly_freq(self, create_test_data): # data = create_test_data(num=261, frequency=pft.AllFrequencies.W, mu=0.6, sigma=0.7) @@ -185,7 +163,7 @@ class TestBeta: sts = pft.TimeSeries(stock_data, "D") mts = pft.TimeSeries(market_data, "D") beta = pft.beta(sts, mts, frequency="M") - assert round(beta, 4) == 1.6137 + assert round(beta, 4) == 1.6131 def test_beta_monthly_freq_monthly_returns(self, create_test_data): market_data = create_test_data(num=3600, frequency=pft.AllFrequencies.D)