PERF: Remove the drop of 'null return' from cumulative returns.

The check of existence of the null return key, and the drop of said
return on every single bar was adding unneeded CPU time when an
algorithm was run with minute emissions.

Instead, add the 0.0 return with an index of the trading day before
the start date.

The removal of the `null return` was mainly in place so that the
period calculation was not crashing on a non-date index value;
with the index as a date, the period return can also approximate
volatility (even though the that volatility has high noise-to-signal
strength because it uses only two values as an input.)
This commit is contained in:
Eddie Hebert
2014-04-16 15:48:13 -04:00
parent ea7d988721
commit 1406f8e9ba
+13 -27
View File
@@ -110,6 +110,12 @@ class RiskMetricsCumulative(object):
self.start_date,
self.end_date)
# Hold on to the trading day before the start,
# used for index of the zero return value when forcing returns
# on the first day.
self.day_before_start = self.start_date - \
trading.environment.trading_days.freq
last_day = normalize_date(sim_params.period_end)
if last_day not in self.trading_days:
last_day = pd.tseries.index.DatetimeIndex(
@@ -199,7 +205,8 @@ class RiskMetricsCumulative(object):
if self.create_first_day_stats:
if len(self.algorithm_returns) == 1:
self.algorithm_returns = pd.Series(
{'null return': 0.0}).append(self.algorithm_returns)
{self.day_before_start: 0.0}).append(
self.algorithm_returns)
self.algorithm_cumulative_returns[dt] = \
self.calculate_cumulative_returns(self.algorithm_returns)
@@ -220,9 +227,10 @@ class RiskMetricsCumulative(object):
if self.create_first_day_stats:
if len(self.mean_returns) == 1:
self.mean_returns = pd.Series(
{'null return': 0.0}).append(self.mean_returns)
{self.day_before_start: 0.0}).append(self.mean_returns)
self.annualized_mean_returns = pd.Series(
{'null return': 0.0}).append(self.annualized_mean_returns)
{self.day_before_start: 0.0}).append(
self.annualized_mean_returns)
self.benchmark_returns_cont[dt] = benchmark_returns
self.benchmark_returns = self.benchmark_returns_cont[:dt]
@@ -230,7 +238,8 @@ class RiskMetricsCumulative(object):
if self.create_first_day_stats:
if len(self.benchmark_returns) == 1:
self.benchmark_returns = pd.Series(
{'null return': 0.0}).append(self.benchmark_returns)
{self.day_before_start: 0.0}).append(
self.benchmark_returns)
self.benchmark_cumulative_returns[dt] = \
self.calculate_cumulative_returns(self.benchmark_returns)
@@ -295,29 +304,6 @@ algorithm_returns ({algo_count}) in range {start} : {end} on {dt}"
self.max_drawdown = self.calculate_max_drawdown()
self.max_drawdowns[dt] = self.max_drawdown
if self.create_first_day_stats:
# Remove placeholder 0 return
if 'null return' in self.algorithm_returns:
self.algorithm_returns = self.algorithm_returns.drop(
'null return')
self.algorithm_returns.index = pd.to_datetime(
self.algorithm_returns.index)
if 'null return' in self.benchmark_returns:
self.benchmark_returns = self.benchmark_returns.drop(
'null return')
self.benchmark_returns.index = pd.to_datetime(
self.benchmark_returns.index)
if 'null return' in self.mean_returns:
self.mean_returns = self.mean_returns.drop(
'null return')
self.mean_returns.index = pd.to_datetime(
self.mean_returns.index)
if 'null return' in self.annualized_mean_returns:
self.annualized_mean_returns = \
self.annualized_mean_returns.drop('null return')
self.annualized_mean_returns.index = pd.to_datetime(
self.mean_returns.index)
def to_dict(self):
"""
Creates a dictionary representing the state of the risk report.