@@ -63,19 +63,11 @@ def rolling_beta(returns, benchmark, window, plot=True):
6363 A série não possui os `window` primeiros dias.
6464
6565 """
66- returns = pd .DataFrame (returns )
67- benchmark = pd .DataFrame (benchmark )
68- merged = returns .merge (benchmark , left_index = True , right_index = True )
69- # one-liner meio ilegível mas: pega um array de NaN de numpy e junta com uma lista
70- # que itera entre (window, len) e calcula o beta pros últimos `window` dias
71- merged ['rolling_beta' ] = np .append (np .full (window , np .nan ),
72- [beta (merged .iloc [i - window :i , 0 ], merged .iloc [i - window :i , 1 ])
73- for i in range (window , len (merged ))]
74- )
75- merged = merged [window :]
66+ rolling_beta = pd .Series ([beta (returns [i - window :i ], benchmark [i - window :i ])
67+ for i in range (window , len (returns ))], index = returns [window :].index )
7668 if plot :
77- fig = px .line (merged [ ' rolling_beta' ] , title = "Beta móvel" )
78- overall_beta = beta (merged . iloc [:, 0 ], merged . iloc [:, 1 ] )
69+ fig = px .line (rolling_beta , title = "Beta móvel" )
70+ overall_beta = beta (returns , benchmark )
7971 fig .update_layout (shapes = [
8072 dict (
8173 type = 'line' ,
@@ -99,7 +91,53 @@ def rolling_beta(returns, benchmark, window, plot=True):
9991 fig .update_xaxes (title_text = 'Tempo' )
10092 fig .update_yaxes (title_text = 'Beta móvel: ' + str (window ) + ' períodos' )
10193 fig .show ()
102- return merged ['rolling_beta' ]
94+ return rolling_beta
95+
96+
97+ def rolling_sharpe (returns , window , risk_free = 0 , plot = True ):
98+ """
99+ Plota o beta móvel para um ativo e um benchmark de referência, na forma de séries de retornos.
100+
101+ Parâmetros:
102+ returns (array): série de retornos para o qual o Sharpe Ratio será calculado.
103+ window (int): janela móvel para calcular o Sharpe ao longo do tempo.
104+ risk_free (float): valor da taxa livre de risco para cálculo do Sharpe.
105+ plot (bool): se `True`, plota um gráfico de linha com o Sharpe ao longo do tempo.
106+
107+ Retorna:
108+ rolling_beta (pd.Series): uma série com os valores do Beta para os últimos `window` dias.
109+ A série não possui os `window` primeiros dias.
110+
111+ """
112+ rolling_sharpe = pd .Series ([sharpe_ratio (returns [i - window :i ], risk_free )
113+ for i in range (window , len (returns ))], returns [window :].index )
114+ if plot :
115+ fig = px .line (rolling_sharpe , title = "Sharpe móvel" )
116+ overall_sharpe = sharpe_ratio (returns , risk_free )
117+ fig .update_layout (shapes = [
118+ dict (
119+ type = 'line' ,
120+ xref = 'paper' , x0 = 0 , x1 = 1 ,
121+ yref = 'y' , y0 = overall_sharpe , y1 = overall_sharpe ,
122+ line = dict (
123+ color = 'grey' ,
124+ width = 2 ,
125+ dash = 'dash'
126+ )
127+ )
128+ ], annotations = [
129+ dict (
130+ text = 'sharpe total: %.3f' % overall_sharpe ,
131+ xref = 'paper' , x = 0.05 ,
132+ yref = 'y' , y = overall_sharpe ,
133+ xanchor = 'left'
134+ )
135+ ])
136+ fig .update_layout (showlegend = False )
137+ fig .update_xaxes (title_text = 'Tempo' )
138+ fig .update_yaxes (title_text = 'Sharpe móvel: ' + str (window ) + ' períodos' )
139+ fig .show ()
140+ return rolling_sharpe
103141
104142
105143def rolling_sharpe (returns , window , risk_free = 0 , plot = True ):
0 commit comments