From 596cb563d616cccc50951c66aebcd0a4d6e71127 Mon Sep 17 00:00:00 2001 From: Ryan Date: Wed, 5 Jan 2022 00:08:47 +0800 Subject: [PATCH 1/2] Bokeh fix future deprecating --- gemini/helpers/analyze.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gemini/helpers/analyze.py b/gemini/helpers/analyze.py index a8200f2..2e12669 100755 --- a/gemini/helpers/analyze.py +++ b/gemini/helpers/analyze.py @@ -41,7 +41,7 @@ def analyze_bokeh(algo, title=None, show_trades=False): continue p.line(records['date'], records[c], color='grey', - legend=c, y_range_name="Records") + legend_label=c, y_range_name="Records") # print(algo.data[['date', 'close', 'sma50', 'sma150']]) @@ -54,12 +54,12 @@ def analyze_bokeh(algo, title=None, show_trades=False): p.line(algo.data.index, algo.data['base_equity'], color='#CAD8DE', - legend='Buy and Hold') - # ,y_range_name="equity_y_axis") + legend_label='Buy and Hold') + # ,y_range_name="equity_y_axis") p.line(algo.data.index, algo.data['equity'], color='#49516F', - legend='Strategy') - #,y_range_name="equity_y_axis") + legend_label='Strategy') + #,y_range_name="equity_y_axis") cmo_above_50 = bokeh.models.Span(location=50, dimension="width", From f0ffc3f72e233091ff67a2452aebf3ddcf82f47d Mon Sep 17 00:00:00 2001 From: Ryan Date: Wed, 5 Jan 2022 00:09:13 +0800 Subject: [PATCH 2/2] avoid divide by zero error --- gemini/empyrical/stats.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/gemini/empyrical/stats.py b/gemini/empyrical/stats.py index 2f53420..aecb42d 100755 --- a/gemini/empyrical/stats.py +++ b/gemini/empyrical/stats.py @@ -378,7 +378,7 @@ def max_drawdown(returns, out=None): cumulative = np.empty( (returns.shape[0] + 1,) + returns.shape[1:], dtype='float64', - ) + ) cumulative[0] = start = 100 cum_returns(returns_array, starting_value=start, out=cumulative[1:]) @@ -627,7 +627,7 @@ def omega_ratio(returns, risk_free=0.0, required_return=0.0, return np.nan else: return_threshold = (1 + required_return) ** \ - (1. / annualization) - 1 + (1. / annualization) - 1 returns_less_thresh = returns - risk_free - return_threshold @@ -697,15 +697,19 @@ def sharpe_ratio(returns, returns_risk_adj = np.asanyarray(_adjust_returns(returns, risk_free)) ann_factor = annualization_factor(period, annualization) - np.multiply( - np.divide( - nanmean(returns_risk_adj, axis=0), - nanstd(returns_risk_adj, ddof=1, axis=0), + # handle 0. + if nanstd(returns_risk_adj, ddof=1, axis=0) == 0.0: + out = np.zeros_like(out) + else: + np.multiply( + np.divide( + nanmean(returns_risk_adj, axis=0), + nanstd(returns_risk_adj, ddof=1, axis=0), + out=out, + ), + np.sqrt(ann_factor), out=out, - ), - np.sqrt(ann_factor), - out=out, - ) + ) if return_1d: out = out.item() @@ -787,7 +791,10 @@ def sortino_ratio(returns, if _downside_risk is not None else downside_risk(returns, required_return, period, annualization) ) - np.divide(average_annual_return, annualized_downside_risk, out=out) + if annualized_downside_risk == 0.0: + out = np.zeros_like(out) + else: + np.divide(average_annual_return, annualized_downside_risk, out=out) if return_1d: out = out.item() elif isinstance(returns, pd.DataFrame): @@ -1508,7 +1515,7 @@ def tail_ratio(returns): return np.nan return np.abs(np.percentile(returns, 95)) / \ - np.abs(np.percentile(returns, 5)) + np.abs(np.percentile(returns, 5)) def capture(returns, factor_returns, period=DAILY):