MAINT: Use pandas for values directly derived from returns in risk.

Remove more use of lists for storing internal risk values to use
pandas structures, for easier matching of time to value.

Accordingy, convert use of -1 for getting last value,
to use current dt.
This commit is contained in:
Eddie Hebert
2013-09-25 12:26:56 -04:00
parent cd3a63415c
commit 6a0c494ce0
2 changed files with 33 additions and 34 deletions
+1 -1
View File
@@ -357,7 +357,7 @@ class PerformanceTracker(object):
bench_minute_returns)
bench_since_open = \
self.intraday_risk_metrics.benchmark_period_returns[-1]
self.intraday_risk_metrics.benchmark_period_returns[dt]
benchmark_returns = pd.Series({todays_date: bench_since_open})
+32 -33
View File
@@ -93,10 +93,10 @@ class RiskMetricsCumulative(object):
self.algorithm_returns = None
self.benchmark_returns = None
self.compounded_log_returns = []
self.algorithm_period_returns = []
self.benchmark_period_returns = []
self.compounded_log_returns = pd.Series(index=cont_index)
self.algorithm_period_returns = pd.Series(index=cont_index)
self.benchmark_period_returns = pd.Series(index=cont_index)
self.excess_returns = pd.Series(index=cont_index)
self.latest_dt = cont_index[0]
@@ -107,7 +107,6 @@ class RiskMetricsCumulative(object):
self.information = []
self.max_drawdown = 0
self.current_max = -np.inf
self.excess_returns = []
self.daily_treasury = {}
def get_minute_index(self, sim_params):
@@ -136,10 +135,10 @@ class RiskMetricsCumulative(object):
self.update_compounded_log_returns()
self.algorithm_period_returns.append(
self.calculate_period_returns(self.algorithm_returns))
self.benchmark_period_returns.append(
self.calculate_period_returns(self.benchmark_returns))
self.algorithm_period_returns[dt] = \
self.calculate_period_returns(self.algorithm_returns)
self.benchmark_period_returns[dt] = \
self.calculate_period_returns(self.benchmark_returns)
if not self.algorithm_returns.index.equals(
self.benchmark_returns.index
@@ -176,8 +175,10 @@ algorithm_returns ({algo_count}) in range {start} : {end} on {dt}"
treasury_period_return
self.treasury_period_return = \
self.daily_treasury[treasury_end]
self.excess_returns.append(
self.algorithm_period_returns[-1] - self.treasury_period_return)
self.excess_returns[self.latest_dt] = (
self.algorithm_period_returns[self.latest_dt]
-
self.treasury_period_return)
self.metrics.beta[dt] = self.calculate_beta()
self.metrics.alpha[dt] = self.calculate_alpha(dt)
self.metrics.sharpe[dt] = self.calculate_sharpe()
@@ -191,23 +192,24 @@ algorithm_returns ({algo_count}) in range {start} : {end} on {dt}"
Returns a dict object of the form:
"""
period_label = self.last_return_date.strftime("%Y-%m")
dt = self.latest_dt
rval = {
'trading_days': len(self.algorithm_returns.valid()),
'benchmark_volatility':
self.metrics.benchmark_volatility[self.latest_dt],
self.metrics.benchmark_volatility[dt],
'algo_volatility':
self.metrics.algorithm_volatility[self.latest_dt],
self.metrics.algorithm_volatility[dt],
'treasury_period_return': self.treasury_period_return,
'algorithm_period_return': self.algorithm_period_returns[-1],
'benchmark_period_return': self.benchmark_period_returns[-1],
'beta': self.metrics.beta[self.latest_dt],
'alpha': self.metrics.alpha[self.latest_dt],
'excess_return': self.excess_returns[-1],
'algorithm_period_return': self.algorithm_period_returns[dt],
'benchmark_period_return': self.benchmark_period_returns[dt],
'beta': self.metrics.beta[dt],
'alpha': self.metrics.alpha[dt],
'excess_return': self.excess_returns[dt],
'max_drawdown': self.max_drawdown,
'period_label': period_label
}
rval['sharpe'] = self.metrics.sharpe[self.latest_dt]
rval['sharpe'] = self.metrics.sharpe[dt]
rval['sortino'] = self.sortino[-1]
rval['information'] = self.information[-1]
@@ -256,30 +258,27 @@ algorithm_returns ({algo_count}) in range {start} : {end} on {dt}"
compound = 0.0
# BUG? Shouldn't this be set to log(1.0 + 0) ?
if len(self.compounded_log_returns) == 0:
self.compounded_log_returns.append(compound)
if len(self.compounded_log_returns[:self.latest_dt]) == 0:
self.compounded_log_returns[self.latest_dt] = compound
else:
self.compounded_log_returns.append(
self.compounded_log_returns[-1] +
compound
)
self.compounded_log_returns[self.latest_dt] = \
self.compounded_log_returns[self.latest_dt] + compound
def calculate_period_returns(self, returns):
returns = np.array(returns)
return (1. + returns).prod() - 1
def update_current_max(self):
if len(self.compounded_log_returns) == 0:
return
if self.current_max < self.compounded_log_returns[-1]:
self.current_max = self.compounded_log_returns[-1]
if self.current_max < self.compounded_log_returns[self.latest_dt]:
self.current_max = self.compounded_log_returns[self.latest_dt]
def calculate_max_drawdown(self):
if len(self.compounded_log_returns) == 0:
return self.max_drawdown
cur_drawdown = 1.0 - math.exp(
self.compounded_log_returns[-1] -
self.compounded_log_returns[self.latest_dt] -
self.current_max)
if self.max_drawdown < cur_drawdown:
@@ -292,7 +291,7 @@ algorithm_returns ({algo_count}) in range {start} : {end} on {dt}"
http://en.wikipedia.org/wiki/Sharpe_ratio
"""
return sharpe_ratio(self.metrics.algorithm_volatility[self.latest_dt],
self.algorithm_period_returns[-1],
self.algorithm_period_returns[self.latest_dt],
self.treasury_period_return)
def calculate_sortino(self, mar=None):
@@ -303,7 +302,7 @@ algorithm_returns ({algo_count}) in range {start} : {end} on {dt}"
mar = self.treasury_period_return
return sortino_ratio(np.array(self.algorithm_returns),
self.algorithm_period_returns[-1],
self.algorithm_period_returns[self.latest_dt],
mar)
def calculate_information(self):
@@ -318,9 +317,9 @@ algorithm_returns ({algo_count}) in range {start} : {end} on {dt}"
"""
http://en.wikipedia.org/wiki/Alpha_(investment)
"""
return alpha(self.algorithm_period_returns[-1],
return alpha(self.algorithm_period_returns[self.latest_dt],
self.treasury_period_return,
self.benchmark_period_returns[-1],
self.benchmark_period_returns[self.latest_dt],
self.metrics.beta[dt])
def calculate_volatility(self, daily_returns):