mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-02 08:10:53 +08:00
Merge pull request #859 from quantopian/future_beta
Better handle missing benchmarks when calculating beta
This commit is contained in:
@@ -44,6 +44,9 @@ Bug Fixes
|
||||
the ``len`` of a :class:`~zipline.protocol.SIDData` object. This would cause
|
||||
us to think that the object was not empty even when it was (:issue:`826`).
|
||||
|
||||
* Fixes an error raised in calculating beta when benchmark data were sparse.
|
||||
Instead `numpy.nan` is returned (:issue:`859`).
|
||||
|
||||
Performance
|
||||
~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ import datetime
|
||||
import calendar
|
||||
import numpy as np
|
||||
import pytz
|
||||
|
||||
from itertools import chain
|
||||
from six import itervalues
|
||||
|
||||
import zipline.finance.risk as risk
|
||||
from zipline.utils import factory
|
||||
|
||||
@@ -622,3 +626,17 @@ class TestRisk(unittest.TestCase):
|
||||
)
|
||||
self.assert_month(start_date.month, col[-1].end_date.month)
|
||||
self.assert_last_day(col[-1].end_date)
|
||||
|
||||
def test_sparse_benchmark(self):
|
||||
benchmark_returns = self.benchmark_returns_06.copy()
|
||||
# Set every other day to nan.
|
||||
benchmark_returns.iloc[::2] = np.nan
|
||||
|
||||
report = risk.RiskReport(
|
||||
self.algo_returns_06,
|
||||
self.sim_params,
|
||||
benchmark_returns=benchmark_returns,
|
||||
env=self.env,
|
||||
)
|
||||
for risk_period in chain.from_iterable(itervalues(report.to_dict())):
|
||||
self.assertIsNone(risk_period['beta'])
|
||||
|
||||
@@ -252,13 +252,19 @@ class RiskMetricsPeriod(object):
|
||||
http://en.wikipedia.org/wiki/Beta_(finance)
|
||||
"""
|
||||
# it doesn't make much sense to calculate beta for less than two days,
|
||||
# so return none.
|
||||
# so return nan.
|
||||
if len(self.algorithm_returns) < 2:
|
||||
return 0.0, 0.0, 0.0, 0.0, []
|
||||
return np.nan, np.nan, np.nan, np.nan, []
|
||||
|
||||
returns_matrix = np.vstack([self.algorithm_returns,
|
||||
self.benchmark_returns])
|
||||
C = np.cov(returns_matrix, ddof=1)
|
||||
|
||||
# If there are missing benchmark values, then we can't calculate the
|
||||
# beta.
|
||||
if not np.isfinite(C).all():
|
||||
return np.nan, np.nan, np.nan, np.nan, []
|
||||
|
||||
eigen_values = la.eigvals(C)
|
||||
condition_number = max(eigen_values) / min(eigen_values)
|
||||
algorithm_covariance = C[0][1]
|
||||
|
||||
Reference in New Issue
Block a user