mirror of
https://github.com/wassname/catalyst.git
synced 2026-06-28 12:08:34 +08:00
ENH: Annualize information ratio.
Use annualized values for information, so that it is calculated using the same units as sharpe, etc.
This commit is contained in:
@@ -238,6 +238,9 @@ class AnswerKey(object):
|
||||
'CUMULATIVE_SORTINO': DataIndex(
|
||||
'Sim Cumulative', 'V', 4, 254),
|
||||
|
||||
'CUMULATIVE_INFORMATION': DataIndex(
|
||||
'Sim Cumulative', 'Y', 4, 254),
|
||||
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
@@ -300,4 +303,6 @@ RISK_CUMULATIVE = pd.DataFrame({
|
||||
'downside_risk': pd.Series(dict(zip(
|
||||
DATES, ANSWER_KEY.CUMULATIVE_DOWNSIDE_RISK))),
|
||||
'sortino': pd.Series(dict(zip(
|
||||
DATES, ANSWER_KEY.CUMULATIVE_SORTINO)))})
|
||||
DATES, ANSWER_KEY.CUMULATIVE_SORTINO))),
|
||||
'information': pd.Series(dict(zip(
|
||||
DATES, ANSWER_KEY.CUMULATIVE_INFORMATION)))})
|
||||
|
||||
@@ -86,3 +86,11 @@ class TestRisk(unittest.TestCase):
|
||||
value,
|
||||
decimal=2,
|
||||
err_msg="Mismatch at %s" % (dt,))
|
||||
|
||||
def test_information_06(self):
|
||||
for dt, value in answer_key.RISK_CUMULATIVE.information.iterkv():
|
||||
np.testing.assert_almost_equal(
|
||||
self.cumulative_metrics_06.metrics.information[dt],
|
||||
value,
|
||||
decimal=2,
|
||||
err_msg="Mismatch at %s" % (dt,))
|
||||
|
||||
@@ -27,7 +27,6 @@ from pandas.tseries.tools import normalize_date
|
||||
from . risk import (
|
||||
alpha,
|
||||
check_entry,
|
||||
information_ratio,
|
||||
choose_treasury,
|
||||
)
|
||||
|
||||
@@ -86,6 +85,35 @@ def sortino_ratio(annualized_algorithm_return, treasury_return, downside_risk):
|
||||
return (annualized_algorithm_return - treasury_return) / downside_risk
|
||||
|
||||
|
||||
def information_ratio(algo_volatility, algorithm_return, benchmark_return):
|
||||
"""
|
||||
http://en.wikipedia.org/wiki/Information_ratio
|
||||
|
||||
Args:
|
||||
algorithm_returns (np.array-like):
|
||||
All returns during algorithm lifetime.
|
||||
benchmark_returns (np.array-like):
|
||||
All benchmark returns during algo lifetime.
|
||||
|
||||
Returns:
|
||||
float. Information ratio.
|
||||
"""
|
||||
if zp_math.tolerant_equals(algo_volatility, 0):
|
||||
return np.nan
|
||||
|
||||
return (
|
||||
(algorithm_return - benchmark_return)
|
||||
# The square of the annualization factor is in the volatility,
|
||||
# because the volatility is also annualized,
|
||||
# i.e. the sqrt(annual factor) is in the volatility's numerator.
|
||||
# So to have the the correct annualization factor for the
|
||||
# Sharpe value's numerator, which should be the sqrt(annual factor).
|
||||
# The square of the sqrt of the annual factor, i.e. the annual factor
|
||||
# itself, is needed in the numerator to factor out the division by
|
||||
# its square root.
|
||||
/ algo_volatility)
|
||||
|
||||
|
||||
class RiskMetricsCumulative(object):
|
||||
"""
|
||||
:Usage:
|
||||
@@ -159,6 +187,8 @@ class RiskMetricsCumulative(object):
|
||||
self.benchmark_returns = None
|
||||
self.mean_returns = None
|
||||
self.annualized_mean_returns = None
|
||||
self.mean_benchmark_returns = None
|
||||
self.annualized_benchmark_returns = None
|
||||
|
||||
self.compounded_log_returns = pd.Series(index=cont_index)
|
||||
self.algorithm_period_returns = pd.Series(index=cont_index)
|
||||
@@ -215,6 +245,13 @@ class RiskMetricsCumulative(object):
|
||||
self.benchmark_returns_cont[dt] = benchmark_returns
|
||||
self.benchmark_returns = self.benchmark_returns_cont.valid()
|
||||
|
||||
self.mean_benchmark_returns = pd.rolling_mean(
|
||||
self.benchmark_returns,
|
||||
window=len(self.benchmark_returns),
|
||||
min_periods=1)
|
||||
|
||||
self.annualized_benchmark_returns = self.mean_benchmark_returns * 252
|
||||
|
||||
if self.create_first_day_stats:
|
||||
if len(self.benchmark_returns) == 1:
|
||||
self.benchmark_returns = pd.Series(
|
||||
@@ -417,8 +454,10 @@ algorithm_returns ({algo_count}) in range {start} : {end} on {dt}"
|
||||
"""
|
||||
http://en.wikipedia.org/wiki/Information_ratio
|
||||
"""
|
||||
return information_ratio(self.algorithm_returns,
|
||||
self.benchmark_returns)
|
||||
return information_ratio(
|
||||
self.metrics.algorithm_volatility[self.latest_dt],
|
||||
self.annualized_mean_returns[self.latest_dt],
|
||||
self.annualized_benchmark_returns[self.latest_dt])
|
||||
|
||||
def calculate_alpha(self, dt):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user