mirror of
https://github.com/wassname/catalyst.git
synced 2026-08-13 12:00:16 +08:00
Add the information ratio to risk metrics.
Calculates relative to the benchmark returns.
This commit is contained in:
@@ -367,6 +367,46 @@ class Risk(unittest.TestCase):
|
||||
for x in self.metrics_06.year_periods],
|
||||
[-0.524])
|
||||
|
||||
def test_algorithm_information_06(self):
|
||||
self.assertEqual([round(x.information, 3)
|
||||
for x in self.metrics_06.month_periods],
|
||||
[0.131,
|
||||
-0.11,
|
||||
-0.067,
|
||||
0.144,
|
||||
0.298,
|
||||
-0.391,
|
||||
0.106,
|
||||
-0.034,
|
||||
-0.058,
|
||||
0.068,
|
||||
0.09,
|
||||
-0.125])
|
||||
self.assertEqual([round(x.information, 3)
|
||||
for x in self.metrics_06.three_month_periods],
|
||||
[-0.013,
|
||||
-0.006,
|
||||
0.113,
|
||||
-0.012,
|
||||
-0.02,
|
||||
-0.11,
|
||||
0.01,
|
||||
-0.005,
|
||||
0.03,
|
||||
0.009])
|
||||
self.assertEqual([round(x.information, 3)
|
||||
for x in self.metrics_06.six_month_periods],
|
||||
[-0.013,
|
||||
-0.013,
|
||||
-0.003,
|
||||
-0.002,
|
||||
-0.013,
|
||||
-0.042,
|
||||
0.009])
|
||||
self.assertEqual([round(x.information, 3)
|
||||
for x in self.metrics_06.year_periods],
|
||||
[-0.002])
|
||||
|
||||
def dtest_algorithm_beta_06(self):
|
||||
self.assertEqual([round(x.beta, 3)
|
||||
for x in self.metrics_06.month_periods],
|
||||
|
||||
@@ -37,6 +37,9 @@ Risk Report
|
||||
| sharpe | The sharpe ratio based on the _algorithm_ (rather |
|
||||
| | than the static portfolio) returns. |
|
||||
+-----------------+----------------------------------------------------+
|
||||
| information | The information ratio based on the _algorithm_ |
|
||||
| | (rather than the static portfolio) returns. |
|
||||
+-----------------+----------------------------------------------------+
|
||||
| beta | The _algorithm_ beta to the benchmark. |
|
||||
+-----------------+----------------------------------------------------+
|
||||
| alpha | The _algorithm_ alpha to the benchmark. |
|
||||
@@ -55,6 +58,7 @@ Risk Report
|
||||
import logbook
|
||||
import datetime
|
||||
import math
|
||||
import itertools
|
||||
from collections import OrderedDict
|
||||
import bisect
|
||||
import numpy as np
|
||||
@@ -145,6 +149,7 @@ class RiskMetricsBase(object):
|
||||
self.treasury_period_return = self.choose_treasury()
|
||||
self.sharpe = self.calculate_sharpe()
|
||||
self.sortino = self.calculate_sortino()
|
||||
self.information = self.calculate_information()
|
||||
self.beta, self.algorithm_covariance, self.benchmark_variance, \
|
||||
self.condition_number, self.eigen_values = self.calculate_beta()
|
||||
self.alpha = self.calculate_alpha()
|
||||
@@ -167,6 +172,7 @@ class RiskMetricsBase(object):
|
||||
'benchmark_period_return': self.benchmark_period_returns,
|
||||
'sharpe': self.sharpe,
|
||||
'sortino': self.sortino,
|
||||
'information': self.information,
|
||||
'beta': self.beta,
|
||||
'alpha': self.alpha,
|
||||
'excess_return': self.excess_return,
|
||||
@@ -196,6 +202,7 @@ class RiskMetricsBase(object):
|
||||
"algorithm_volatility",
|
||||
"sharpe",
|
||||
"sortino",
|
||||
"information",
|
||||
"algorithm_covariance",
|
||||
"benchmark_variance",
|
||||
"beta",
|
||||
@@ -265,6 +272,23 @@ class RiskMetricsBase(object):
|
||||
|
||||
return ((self.algorithm_period_returns - mar) / dr)
|
||||
|
||||
def calculate_information(self):
|
||||
"""
|
||||
http://en.wikipedia.org/wiki/Information_ratio
|
||||
"""
|
||||
|
||||
relative_returns = [
|
||||
r - b
|
||||
for r, b
|
||||
in itertools.izip(self.algorithm_returns, self.benchmark_returns)]
|
||||
|
||||
relative_deviation = np.std(relative_returns, ddof=1)
|
||||
|
||||
if relative_deviation < 0.000001 or np.isnan(relative_deviation):
|
||||
return 0.0
|
||||
|
||||
return np.mean(relative_returns) / relative_deviation
|
||||
|
||||
def calculate_beta(self):
|
||||
"""
|
||||
|
||||
@@ -450,6 +474,7 @@ class RiskMetricsIterative(RiskMetricsBase):
|
||||
self.benchmark_period_returns = []
|
||||
self.sharpe = []
|
||||
self.sortino = []
|
||||
self.information = []
|
||||
self.beta = []
|
||||
self.alpha = []
|
||||
self.max_drawdown = 0
|
||||
@@ -501,6 +526,7 @@ algorithm_returns ({algo_count}) in range {start} : {end}"
|
||||
self.alpha.append(self.calculate_alpha())
|
||||
self.sharpe.append(self.calculate_sharpe())
|
||||
self.sortino.append(self.calculate_sortino())
|
||||
self.information.append(self.calculate_information())
|
||||
self.max_drawdown = self.calculate_max_drawdown()
|
||||
|
||||
def to_dict(self):
|
||||
@@ -518,6 +544,7 @@ algorithm_returns ({algo_count}) in range {start} : {end}"
|
||||
'benchmark_period_return': self.benchmark_period_returns[-1],
|
||||
'sharpe': self.sharpe[-1],
|
||||
'sortino': self.sortino[-1],
|
||||
'information': self.information[-1],
|
||||
'beta': self.beta[-1],
|
||||
'alpha': self.alpha[-1],
|
||||
'excess_return': self.excess_returns[-1],
|
||||
@@ -548,6 +575,7 @@ algorithm_returns ({algo_count}) in range {start} : {end}"
|
||||
"algorithm_volatility",
|
||||
"sharpe",
|
||||
"sortino",
|
||||
"information",
|
||||
"algorithm_covariance",
|
||||
"benchmark_variance",
|
||||
"beta",
|
||||
@@ -648,6 +676,23 @@ algorithm_returns ({algo_count}) in range {start} : {end}"
|
||||
return ((self.algorithm_period_returns[-1] - mar) /
|
||||
dr)
|
||||
|
||||
def calculate_information(self):
|
||||
"""
|
||||
http://en.wikipedia.org/wiki/Information_ratio
|
||||
"""
|
||||
|
||||
relative_returns = [
|
||||
r - b
|
||||
for r, b
|
||||
in itertools.izip(self.algorithm_returns, self.benchmark_returns)]
|
||||
|
||||
relative_deviation = np.std(relative_returns, ddof=1)
|
||||
|
||||
if relative_deviation < 0.000001 or np.isnan(relative_deviation):
|
||||
return 0.0
|
||||
|
||||
return np.mean(relative_returns) / relative_deviation
|
||||
|
||||
def calculate_alpha(self):
|
||||
"""
|
||||
http://en.wikipedia.org/wiki/Alpha_(investment)
|
||||
|
||||
Reference in New Issue
Block a user