From 5b591e61a72ac50c6e8680fed1cf663c56faed99 Mon Sep 17 00:00:00 2001 From: Noel Date: Mon, 14 Sep 2020 17:05:52 -0300 Subject: [PATCH] implementa rolling_sharpe (#17) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * implementa rolling_sharpe * remove comentários de célula p/ ipython --- turingquant/metrics.py | 50 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/turingquant/metrics.py b/turingquant/metrics.py index 9ecd7b5..b7233e3 100644 --- a/turingquant/metrics.py +++ b/turingquant/metrics.py @@ -48,7 +48,6 @@ def alpha(end_price, dps, start_price): return(end_price + dps - start_price) / start_price -# %% def rolling_beta(returns, benchmark, window, plot=True): """ Plota o beta móvel para um ativo e um benchmark de referência, na forma de séries de retornos. @@ -71,7 +70,7 @@ def rolling_beta(returns, benchmark, window, plot=True): # que itera entre (window, len) e calcula o beta pros últimos `window` dias merged['rolling_beta'] = np.append(np.full(window, np.nan), [beta(merged.iloc[i - window:i, 0], merged.iloc[i - window:i, 1]) - for i in range(window, len(merged))] + for i in range(window, len(merged))] ) merged = merged[window:] if plot: @@ -103,7 +102,52 @@ def rolling_beta(returns, benchmark, window, plot=True): return merged['rolling_beta'] -# %% +def rolling_sharpe(returns, window, risk_free=0, plot=True): + """ + Plota o beta móvel para um ativo e um benchmark de referência, na forma de séries de retornos. + + Parâmetros: + returns (array): série de retornos para o qual o Sharpe Ratio será calculado. + window (int): janela móvel para calcular o Sharpe ao longo do tempo. + risk_free (float): valor da taxa livre de risco para cálculo do Sharpe. + plot (bool): se `True`, plota um gráfico de linha com o Sharpe ao longo do tempo. + + Retorna: + rolling_beta (pd.Series): uma série com os valores do Beta para os últimos `window` dias. + A série não possui os `window` primeiros dias. + + """ + rolling_sharpe = pd.Series([sharpe_ratio(returns[i - window:i], risk_free) + for i in range(window, len(returns))], returns[window:].index) + if plot: + fig = px.line(rolling_sharpe, title="Sharpe móvel") + overall_sharpe = sharpe_ratio(returns, risk_free) + fig.update_layout(shapes=[ + dict( + type='line', + xref='paper', x0=0, x1=1, + yref='y', y0=overall_sharpe, y1=overall_sharpe, + line=dict( + color='grey', + width=2, + dash='dash' + ) + ) + ], annotations=[ + dict( + text='sharpe total: %.3f' % overall_sharpe, + xref='paper', x=0.05, + yref='y', y=overall_sharpe, + xanchor='left' + ) + ]) + fig.update_layout(showlegend=False) + fig.update_xaxes(title_text='Tempo') + fig.update_yaxes(title_text='Sharpe móvel: ' + str(window) + ' períodos') + fig.show() + return rolling_sharpe + + def test_metrics(): """ Essa função define uma série aleatória de 50 elementos de retornos de um ativo fictício e de um índice de mercado e, a partir deles,