%matplotlib inline
# importing libraries
import matplotlib.pyplot as plt
import plotly.graph_objs as go
import plotly.offline as py
import cufflinks as cf
import seaborn as sns
import pandas as pd
import numpy as np
import quandl
import plotly
import time
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
from IPython.display import Markdown, display
from matplotlib.ticker import FuncFormatter
from pandas.core.base import PandasObject
from datetime import datetime
# Setting pandas dataframe display options
pd.set_option("display.max_rows", 20)
pd.set_option('display.width', 800)
pd.set_option('max_colwidth', 800)
# Set plotly offline
init_notebook_mode(connected=True)
# Set matplotlib style
plt.style.use('seaborn')
# Set cufflinks offline
cf.go_offline()
# Defining today's Date
from datetime import date
today = date.today()
#### Functions ####
def compute_drawdowns(dataframe):
'''
Function to compute drawdowns of a timeseries
given a dataframe of prices
'''
return (dataframe / dataframe.cummax() -1) * 100
def compute_max_DD(dataframe):
return compute_drawdowns(dataframe).min()
def compute_cagr(dataframe, years=0):
'''
Function to calculate CAGR given a dataframe of prices
'''
years = len(pd.date_range(dataframe.index[0], dataframe.index[-1], freq='D')) / 365
return (dataframe.iloc[-1].div(dataframe.iloc[0]).pow(1 / years)).sub(1).mul(100)
def compute_mar(dataframe):
'''
Function to calculate mar: Return Over Maximum Drawdown
given a dataframe of prices
'''
return compute_cagr(dataframe).div(compute_drawdowns(dataframe).min().abs())
def compute_StdDev(dataframe, freq='days'):
'''
Function to calculate annualized standart deviation
given a dataframe of prices. It takes into account the
frequency of the data.
'''
if freq == 'days':
return dataframe.pct_change().std().mul((np.sqrt(252))).mul(100)
if freq == 'months':
return dataframe.pct_change().std().mul((np.sqrt(12))).mul(100)
def compute_sharpe(dataframe, years=0, freq='days'):
'''
Function to calculate the sharpe ratio given a dataframe of prices.
'''
return compute_cagr(dataframe, years).div(compute_StdDev(dataframe, freq))
def compute_return(dataframe):
'''
Function to calculate the sharpe ratio given a dataframe of prices.
'''
return round(dataframe.iloc[-1] / dataframe.iloc[0] - 1, 4) * 100
def compute_performance_table(dataframe, years='si', freq='days'):
'''
Function to calculate a performance table given a dataframe of prices.
Takes into account the frequency of the data.
'''
if years == 'si':
years = len(pd.date_range(dataframe.index[0], dataframe.index[-1], freq='D')) / 365
df = pd.DataFrame([compute_cagr(dataframe, years), compute_StdDev(dataframe, freq),
compute_sharpe(dataframe, years, freq), compute_max_DD(dataframe), compute_mar(dataframe)])
df.index = ['CAGR', 'StdDev', 'Sharpe', 'Max DD', 'MAR']
df = round(df.transpose(), 2)
# Colocar percentagens
df['CAGR'] = (df['CAGR'] / 100).apply('{:.2%}'.format)
df['StdDev'] = (df['StdDev'] / 100).apply('{:.2%}'.format)
df['Max DD'] = (df['Max DD'] / 100).apply('{:.2%}'.format)
# Return object
return df
else:
df = pd.DataFrame([compute_cagr(dataframe, years), compute_StdDev(dataframe, freq),
compute_sharpe(dataframe, years, freq), compute_max_DD(dataframe), compute_mar(dataframe)])
df.index = ['CAGR', 'StdDev', 'Sharpe', 'Max DD', 'MAR']
df = round(df.transpose(), 2)
# Colocar percentagens
df['Return'] = (df['Return'] / 100).apply('{:.2%}'.format)
df['CAGR'] = (df['CAGR'] / 100).apply('{:.2%}'.format)
df['StdDev'] = (df['StdDev'] / 100).apply('{:.2%}'.format)
# Return object
return df
def filter_by_date(dataframe, years=0, previous_row=False):
last_date = dataframe.tail(1).index
year_nr = last_date.year.values[0]
month_nr = last_date.month.values[0]
day_nr = last_date.day.values[0]
new_date = str(year_nr - years) + '-' + str(month_nr) + '-' + str(day_nr)
if previous_row == False:
return dataframe.loc[new_date:]
elif previous_row == True:
return pd.concat([dataframe.loc[:new_date].tail(1), dataframe.loc[new_date:]])
def get(quotes):
# resample quotes to business month
monthly_quotes = quotes.resample('BM').last()
# get monthly returns
returns = monthly_quotes.pct_change()
# get close / first column if given DataFrame
if isinstance(returns, pd.DataFrame):
returns.columns = map(str.lower, returns.columns)
if len(returns.columns) > 1 and 'close' in returns.columns:
returns = returns['close']
else:
returns = returns[returns.columns[0]]
# get returnsframe
returns = pd.DataFrame(data={'Retornos': returns})
returns['Ano'] = returns.index.strftime('%Y')
returns['Mês'] = returns.index.strftime('%b')
# make pivot table
returns = returns.pivot('Ano', 'Mês', 'Retornos').fillna(0)
# order columns by month
returns = returns[['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']]
return returns
def plot(returns,
title="Monthly Returns (%)",
title_color="black",
title_size=12,
annot_size=10,
figsize=None,
cmap='RdYlGn',
cbar=False,
square=False):
returns = get(returns)
returns *= 100
if figsize is None:
size = list(plt.gcf().get_size_inches())
figsize = (size[0], size[0] // 2)
plt.close()
fig, ax = plt.subplots(figsize=figsize)
ax = sns.heatmap(returns, ax=ax, annot=True,
annot_kws={"size": annot_size}, fmt="0.2f", linewidths=0.4, center=0,
square=square, cbar=cbar, cmap=cmap)
ax.set_title(title, fontsize=title_size, color=title_color, fontweight="bold")
fig.subplots_adjust(hspace=0)
plt.yticks(rotation=0)
plt.show()
plt.close()
PandasObject.get_returns_heatmap = get
PandasObject.plot_returns_heatmap = plot
def calendarize(returns):
'''
The calendarize function is an slight adaption of ranaroussi's monthly-returns-heatmap
You can find it here: https://github.com/ranaroussi/monthly-returns-heatmap/
It turns monthly data into a 12 columns(months) and yearly row seaborn heatmap
'''
# get close / first column if given DataFrame
if isinstance(returns, pd.DataFrame):
returns.columns = map(str.lower, returns.columns)
if len(returns.columns) > 1 and 'close' in returns.columns:
returns = returns['close']
else:
returns = returns[returns.columns[0]]
# get returnsframe
returns = pd.DataFrame(data={'Retornos': returns})
returns['Ano'] = returns.index.strftime('%Y')
returns['Mês'] = returns.index.strftime('%b')
# make pivot table
returns = returns.pivot('Ano', 'Mês', 'Retornos').fillna(0)
# order columns by month
returns = returns[['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']]
return returns
def plotly_table(df, width=990, height=500, columnwidth=[25], title=None , index=True, header=True,
header_alignment=['center'], header_line_color='rgb(100, 100, 100)', header_font_size=[12],
header_font_color=['rgb(45, 45, 45)'], header_fill_color=['rgb(200, 200, 200)'],
cells_alignment=['center'], cells_line_color=['rgb(200, 200, 200)'], cells_font_size=[11],
cells_font_color=['rgb(45, 45, 45)'], cells_fill_color=['rgb(245, 245, 245)','white' ]):
# Making the header bold and conditional
if (header == False and index == False):
lst = list(df.columns[0 + i] for i in range(len(df.columns)))
header = [[i] for i in lst]
header = list([str( '<b>' + header[0 + i][0] + '</b>') for i in range(len(df.columns))])
header = [[i] for i in header]
header.pop(0)
header = [[]] + header
trace = go.Table(
columnwidth = columnwidth,
header=dict(values=header,
line = dict(color=header_line_color),
align = header_alignment,
font = dict(color=header_font_color, size=header_font_size),
height = 22,
fill = dict(color=header_fill_color)),
cells=dict(values=df.transpose().values.tolist(),
line=dict(color=cells_line_color),
align = cells_alignment,
height = 22,
font = dict(color=cells_font_color, size=cells_font_size),
fill = dict(color = [cells_fill_color * len(df.index)]),
),
)
# Making the header bold and conditional
if (header == True and index == True):
lst = list(df.columns[0 + i] for i in range(len(df.columns)))
header = [[i] for i in lst]
header = list([str( '<b>' + header[0 + i][0] + '</b>') for i in range(len(df.columns))])
header = [[i] for i in header]
header = [['']] + header
# Making the index Bold
lst_i = list(df.index[0 + i] for i in range(len(df.index)))
index = [[i] for i in lst_i]
index = list([[ '<b>' + str(index[0 + i][0]) + '</b>' for i in range(len(df.index))]])
trace = go.Table(
columnwidth = columnwidth,
header=dict(values=header,
line = dict(color=header_line_color),
align = header_alignment,
font = dict(color=header_font_color, size=header_font_size),
height = 22,
fill = dict(color=header_fill_color)),
cells=dict(values=index + df.transpose().values.tolist(),
line=dict(color=cells_line_color),
align = cells_alignment,
height = 22,
font = dict(color=cells_font_color, size=cells_font_size),
fill = dict(color = [cells_fill_color * len(df.index)]),
),
)
# Making the header bold and conditional
if (header == False and index == True):
lst = list(df.columns[0 + i] for i in range(len(df.columns)))
header = [[i] for i in lst]
header = list([str( '<b>' + header[0 + i][0] + '</b>') for i in range(len(df.columns))])
header = [[i] for i in header]
header = [[]] + header
lst_i = list(df.index[0 + i] for i in range(len(df.index)))
index = [[i] for i in lst_i]
index = list([[ '<b>' + str(index[0 + i][0]) + '</b>' for i in range(len(df.index))]])
trace = go.Table(
columnwidth = columnwidth,
header=dict(values=header,
line = dict(color=header_line_color),
align = header_alignment,
font = dict(color=header_font_color, size=header_font_size),
height = 22,
fill = dict(color=header_fill_color)),
cells=dict(values=index + df.transpose().values.tolist(),
line=dict(color=cells_line_color),
align = cells_alignment,
height = 22,
font = dict(color=cells_font_color, size=cells_font_size),
fill = dict(color = [cells_fill_color * len(df.index)]),
),
)
# Making the header bold and conditional
if (header == True and index == False):
lst = list(df.columns[0 + i] for i in range(len(df.columns)))
header = [[i] for i in lst]
header = list([str( '<b>' + header[0 + i][0] + '</b>') for i in range(len(df.columns))])
header = [[i] for i in header]
header = header
trace = go.Table(
columnwidth = columnwidth,
header=dict(values=header,
line = dict(color=header_line_color),
align = header_alignment,
font = dict(color=header_font_color, size=header_font_size),
height = 22,
fill = dict(color=header_fill_color)),
cells=dict(values=df.transpose().values.tolist(),
line=dict(color=cells_line_color),
align = cells_alignment,
height = 22,
font = dict(color=cells_font_color, size=cells_font_size),
fill = dict(color = [cells_fill_color * len(df.index)]),
),
)
if title == None:
layout = go.Layout(
autosize=False,
height=height,
width=width,
margin=go.Margin( l=0, r=0, b=0, t=0, pad=0),
)
else:
layout = go.Layout(
autosize=False,
height=height,
width=width,
title=title,
margin=go.Margin( l=0, r=0, b=0, t=25, pad=0),
)
data = [trace]
fig = go.Figure(data=data, layout=layout)
py.iplot(fig, show_link=False, config={'modeBarButtonsToRemove': ['sendDataToCloud','hoverCompareCartesian'],
'displayModeBar': False})
def Portfolio_Calculate(quotes, weights):
# Anos do Portfolio
Years = quotes.index.year.unique()
# Dicionário com Dataframes anuais das cotações dos quotes
Years_dict = {}
k = 0
for Year in Years:
# Dynamically create key
key = Year
# Calculate value
value = quotes.loc[str(Year)]
# Insert in dictionary
Years_dict[key] = value
# Counter
k += 1
# Dicionário com Dataframes anuais das cotações dos quotes
Quotes_dict = {}
Portfolio_dict = {}
k = 0
for Year in Years:
n = 0
#Setting Portfolio to be a Global Variable
global Portfolio
# Dynamically create key
key = Year
# Calculate value
if (Year-1) in Years:
value = Years_dict[Year].append(Years_dict[Year-1].iloc[[-1]]).sort_index()
else:
value = Years_dict[Year].append(Years_dict[Year].iloc[[-1]]).sort_index()
# Set beginning value to 100
value = (value / value.iloc[0]) * 100
#
for column in value.columns:
value[column] = value[column] * weights[n]
n +=1
# Get Returns
Returns = value.pct_change()
# Calculating Portfolio Value
value['Portfolio'] = value.sum(axis=1)
# Creating Weights_EOP empty DataFrame
Weights_EOP = pd.DataFrame()
# Calculating End Of Period weights
for Name in Nomes:
Weights_EOP[Name] = value[Name] / value['Portfolio']
# Calculating Beginning Of Period weights
Weights_BOP = Weights_EOP.shift(periods=1)
# Calculatins Portfolio Value
Portfolio = pd.DataFrame(Weights_BOP.multiply(Returns).sum(axis=1))
Portfolio.columns=['Simple']
# Transformar os simple returns em log returns
Portfolio['Log'] = np.log(Portfolio['Simple'] + 1)
# Cumsum() dos log returns para obter o preço do Portfolio
Portfolio['Price'] = 100*np.exp(np.nan_to_num(Portfolio['Log'].cumsum()))
Portfolio['Price'] = Portfolio['Price']
# Insert in dictionaries
Quotes_dict[key] = value
Portfolio_dict[key] = Portfolio
# Counter
k += 1
# Making an empty Dataframe for Porfolio data
Portfolio = pd.DataFrame()
for Year in Years:
Portfolio = pd.concat([Portfolio, Portfolio_dict[Year]['Log']])
# Delete repeated index values in Portfolio
Portfolio.drop_duplicates(keep='last')
# Naming the column of log returns 'Log'
Portfolio.columns= ['Log']
# Cumsum() dos log returns para obter o preço do Portfolio
Portfolio['Price'] = 100*np.exp(np.nan_to_num(Portfolio['Log'].cumsum()))
# Round Portfolio to 2 decimals and eliminate returns
Portfolio = pd.DataFrame(round(Portfolio['Price'], 2))
# Naming the column of Portfolio as 'Portfolio'
Portfolio.columns= ['Porfolio']
return Portfolio
# Multi_period_return (in CAGR)
def multi_period_return(df, years = 1, days=252):
shifted = df.shift(days * years)
One_year = (((1 + (df - shifted) / shifted) ** (1 / years))-1) * 100
return One_year
def compute_drawdowns_i(dataframe):
'''
Function to compute drawdowns based on
the inicial value of a timeseries
given a dataframe of prices
'''
return (dataframe / 100 -1) * 100
def print_title(string):
display(Markdown('**' + string + '**'))
def all_percent(df):
for column in df.columns:
df[column] = df[column].apply( lambda x : str(x) + '%')
return df
dimensions=(990, 500)
colorz = ['royalblue', 'orange', 'dimgrey', 'darkorchid']
def preview(df):
return pd.concat([df.iloc[:3], df.iloc[-3:]])
class color:
PURPLE = '\033[95m'
CYAN = '\033[96m'
DARKCYAN = '\033[36m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
END = '\033[0m'
### print color.BOLD + 'Hello World !' + color.END
def compute_time_period(timestamp_1, timestamp_2):
year = timestamp_1.year - timestamp_2.year
month = timestamp_1.month - timestamp_2.month
day = timestamp_1.day - timestamp_2.day
if month < 0:
year = year - 1
month = 12 + month
if day < 0:
day = - day
# Returns datetime object in years, month, days
return(str(year) + ' Years ' + str(month) + ' Months ' + str(day) + ' Days')
def compute_time_series(dataframe):
(np.exp(np.log1p(dataframe).cumsum())) * 100
##################################################
### Begin of compute_drawdowns_table function ####
##################################################
### Função auxiliar 1
def compute_time_period(timestamp_1, timestamp_2):
year = timestamp_1.year - timestamp_2.year
month = timestamp_1.month - timestamp_2.month
day = timestamp_1.day - timestamp_2.day
if month < 0:
year = year - 1
month = 12 + month
if day == 0:
day = - day
if day < 0:
month = month - 1
if timestamp_1.month not in [1, 3, 5, 7, 8, 10, 12]:
day = 31 + day
else:
day = 30 + day
# Returns datetime object in years, month, days
return(str(year) + ' Years, ' + str(month) + ' Months, ' + str(day) + ' Days')
### Função auxiliar 2
def compute_drawdowns_periods(df):
# Input: df of max points in drawdowns (where dd == 0)
drawdown_periods = list()
for i in range(0, len(df.index)):
drawdown_periods.append(compute_time_period(df.index[i], df.index[i - 1]))
drawdown_periods = pd.DataFrame(drawdown_periods)
return (drawdown_periods)
### Função auxiliar 3
def compute_max_drawdown_in_period(prices, timestamp_1, timestamp_2):
df = prices[timestamp_1:timestamp_2]
max_dd = compute_max_DD(df)
return max_dd
### Função auxiliar 4
def compute_drawdowns_min(df, prices):
# Input: df of max points in drawdowns (where dd == 0)
drawdowns_min = list()
for i in range(0, len(df.index) - 1):
drawdowns_min.append(compute_max_drawdown_in_period(prices, df.index[i], df.index[i + 1]))
drawdowns_min = pd.DataFrame(drawdowns_min)
return(drawdowns_min)
### Função principal
def compute_drawdowns_table(prices, number=5):
# input: df of prices
dd = compute_drawdowns(prices)
max_points = dd[dd == 0].dropna()
data = [0.0]
# Create the pandas DataFrame
new_data = pd.DataFrame(data, columns = ['New_data'])
new_data['Date'] = prices.index.max()
new_data.set_index('Date', inplace=True)
max_points = pd.DataFrame(pd.concat([max_points, new_data], axis=1).iloc[:, 0])
dp = compute_drawdowns_periods(max_points)
dp.set_index(max_points.index, inplace=True)
df = pd.concat([max_points, dp], axis=1)
df.index.name = 'Date'
df.reset_index(inplace=True)
df['End'] = df['Date'].shift(-1)
df[0] = df[0].shift(-1)
df['values'] = round(compute_drawdowns_min(max_points, prices), 2)
df = df.sort_values(by='values')
df['Number'] = range(1, len(df) + 1)
df.reset_index(inplace=True)
df.columns = [['index', 'Begin', 'point', 'Length', 'End', 'Depth', 'Number']]
df = df[['Begin', 'End', 'Depth', 'Length']].head(number)
df.iloc[:, 2] = df.iloc[:, 2].apply( lambda x : str(x) + '%')
df.set_index(np.arange(1, number + 1), inplace=True)
for index, row in df['End'].iterrows():
if ( (row[0] == prices.index.max())):# & (prices.iloc[-1][0] < prices.max()) ):
df.iloc[index-1, 1] = float('NaN')
return(df)
################################################
### End of compute_drawdowns_table function ####
################################################
def compute_r2(x, y, k=1):
xpoly = np.column_stack([x**i for i in range(k+1)])
return sm.OLS(y, xpoly).fit().rsquared
def compute_r2_table(df, benchmark):
# df of prices
lista = []
for i in np.arange(0, len(df.columns)):
lista.append(compute_r2(benchmark, df.iloc[: , i]))
Dataframe = pd.DataFrame(lista)
Dataframe.index = df.columns
Dataframe.columns = [benchmark.name]
return(round(Dataframe.transpose(), 3))
# Downloading funds and creating quotes and returns dataframes
# End = '2017-08-20' # Só activas se quiseres que acabe num dia especifíco
ISINs = ['LEGATREH', 'BTSYTREH']
Nomes = ['BGB' , 'BGT']
fundos = pd.read_csv('C:/Users/Luis/Google Drive/_GitHub/Backtester/Data/Cotacoes_diarias_all.csv',
index_col = 'Date', parse_dates = True)[ISINs]
fundos.columns = Nomes
fundos = fundos.dropna()
#### Normalization to 100 ####
fundos = round((fundos / fundos.iloc[0] * 100), 2)
Begin = fundos.head(1).index
Begin = str(Begin.strftime('%Y-%m-%d'))[8:18]
Dica: A interactividade dos gráficos da plotly permite:
. Zoom (mantenham o clique e arrastem o cursor em simultâneo, em cima do gráfico);
. Tem uma lista de opções que aparece se forem com o cursor ao canto superior direito;
. Façam duplo clique no gráfico ou seleccionem a opção Autoscale/Reset Axes para voltar ao normal;
. Alterem a opção de 'Compare data on hoover' para 'Show closest data on hoover' se vos for mais conveniente;
. Se clicarem num nome na legenda esse fundo desaparece (clicando de novo ele volta a apetecer).
# Making Color Palette
Palette = ['rgb(255, 153, 51)', # 1 - orange
'royalblue', # 2 - Royalblue
'#708090', # 3 - Grey
'rgb(128, 0, 128)', # 4 - Indigo
'rgb(219, 64, 82)', # 5 - Red
'rgb(0, 128, 128)', # 6 - Teal
'#191970', # 7 - Navy
'rgb(128, 128, 0)', # 8 - Olive
'#00BFFF', # 9 - Water Blue
'rgb(128, 177, 211)'] # 10 -
fundos.iplot(title='Performance dos fundos desde ' + Begin, yTitle='Valor de cada €100 investidos', color=['royalblue', 'dimgrey'], dimensions=dimensions)
print_title('Valores finais dos fundos tendo começado em ' + Begin + ' com 100 euros')
fundos.tail(1)
Valores finais dos fundos tendo começado em 2001-01-31 com 100 euros
BGB | BGT | |
---|---|---|
Date | ||
2020-07-06 | 218.29 | 211.77 |
DD = compute_drawdowns(fundos)
DD = DD /100
layout = go.Layout(
title='Drawdown dos portfolios desde ' + Begin,
plot_bgcolor='#f5f5f5',
paper_bgcolor='#f5f5f5',
width=990,
height=500,
xaxis=dict(
title='',
showgrid=True,
titlefont=dict(size=12),
),
yaxis=dict(
title='',
showgrid=True,
zeroline=True, # Adicionar ou não a zero line
tickformat=".1%" # tickformat=".2%" se quiseres mais casas decimais
))
trace0 = go.Scatter(
x = DD.index,
y = DD.iloc[:, 0],
name = fundos.columns[0],
line = dict(
color = 'royalblue',
width = 1.3)
)
trace1 = go.Scatter(
x = DD.index,
y = DD.iloc[:, 1],
name = fundos.columns[1],
line = dict(
color = 'dimgrey',
width = 1.3)
)
data = [trace0, trace1]
fig = go.Figure(data=data, layout=layout)
py.iplot(fig)
print_title('Drawdown actual (' + str(DD.iloc[-1].name)[0:10] + ')')
DD = compute_drawdowns(fundos)
DD = DD /100
round(DD.tail(1), 5).applymap(lambda x: "{0:.2f}%".format(x*100))
Drawdown actual (2020-07-06)
BGB | BGT | |
---|---|---|
Date | ||
2020-07-06 | -0.94% | -1.51% |
layout = go.Layout(
title='Diferencial de performance entre os ETFs desde ' + Begin,
plot_bgcolor='#f5f5f5',
paper_bgcolor='#f5f5f5',
width=990,
height=500,
xaxis=dict(
title='<b>Nota:</b> Subida a favor de ' + fundos.columns[0] + ', descida a favor de ' + fundos.columns[1],
showgrid=True,
titlefont=dict(size=12),
),
yaxis=dict(
title='',
showgrid=True,
zeroline=True, # Adicionar ou não a zero line
tickformat=".1%" # tickformat=".2%" se quiseres mais casas decimais
))
trace0 = go.Scatter(
x = fundos.index,
y = (round(((fundos.iloc[:, 0]/fundos.iloc[:, 1])- 1), 5)),
name = 'Portfolio',
line = dict(
color = 'darkorchid',
width = 1.3)
)
data = [trace0]
fig = go.Figure(data=data, layout=layout)
py.iplot(fig)
print_title('Performance dos fundos desde ' + Begin)
compute_performance_table(fundos)
Performance dos fundos desde 2001-01-31
CAGR | StdDev | Sharpe | Max DD | MAR | |
---|---|---|---|---|---|
BGB | 4.10% | 2.11% | 1.94 | -5.24% | 0.78 |
BGT | 3.93% | 2.18% | 1.80 | -6.15% | 0.64 |
print_title('Performance a 12 meses')
fundos_1 = filter_by_date(fundos, years=1)
compute_performance_table(fundos_1)
Performance a 12 meses
CAGR | StdDev | Sharpe | Max DD | MAR | |
---|---|---|---|---|---|
BGB | 3.60% | 3.03% | 1.19 | -5.24% | 0.69 |
BGT | 3.46% | 3.27% | 1.06 | -4.29% | 0.81 |
print_title('Performance a 3 anos')
fundos_3 = filter_by_date(fundos, years=3)
compute_performance_table(fundos_3)
Performance a 3 anos
CAGR | StdDev | Sharpe | Max DD | MAR | |
---|---|---|---|---|---|
BGB | 2.63% | 2.08% | 1.26 | -5.24% | 0.50 |
BGT | 2.77% | 2.19% | 1.26 | -4.29% | 0.65 |
print_title('Performance a 5 anos')
fundos_5 = filter_by_date(fundos, years=5)
compute_performance_table(fundos_5)
Performance a 5 anos
CAGR | StdDev | Sharpe | Max DD | MAR | |
---|---|---|---|---|---|
BGB | 2.32% | 2.10% | 1.10 | -5.24% | 0.44 |
BGT | 2.38% | 2.24% | 1.06 | -6.15% | 0.39 |
print_title('Performance a 10 anos')
fundos_10 = filter_by_date(fundos, years=10)
compute_performance_table(fundos_10)
Performance a 10 anos
CAGR | StdDev | Sharpe | Max DD | MAR | |
---|---|---|---|---|---|
BGB | 3.02% | 2.00% | 1.51 | -5.24% | 0.58 |
BGT | 2.94% | 2.08% | 1.41 | -6.15% | 0.48 |
print_title('Performance a 15 anos')
fundos_15 = filter_by_date(fundos, years=15)
compute_performance_table(fundos_15)
Performance a 15 anos
CAGR | StdDev | Sharpe | Max DD | MAR | |
---|---|---|---|---|---|
BGB | 3.41% | 2.08% | 1.64 | -5.24% | 0.65 |
BGT | 3.32% | 2.12% | 1.57 | -6.15% | 0.54 |
fundos_norm = fundos.copy()
# Resampling to yearly (business year)
yearly_quotes_fundos = fundos_norm.resample('BA').last()
# Adding first quote (only if start is in the middle of the year) ### Falta trabalho para automatizar #####
yearly_quotes_fundos = pd.concat([yearly_quotes_fundos.iloc[:1], yearly_quotes_fundos])
yearly_quotes_fundos = pd.concat([pd.DataFrame(fundos_norm.iloc[0]).transpose(), yearly_quotes_fundos.iloc[1:]])
# Returns
yearly_returns_fundos = ((yearly_quotes_fundos / yearly_quotes_fundos.shift(1)) - 1) * 100
yearly_returns_fundos = yearly_returns_fundos.set_index([list(range(fundos_norm.index[0].year - 1, fundos_norm.index[-1].year + 1))]).drop(fundos_norm.index[0].year - 1)
# Calcular em valores percentuais
yearly_returns_fundos = yearly_returns_fundos / 100
# Sns heatmap
fig, ax = plt.subplots()
fig.set_size_inches(16,2.5)
ax = sns.heatmap(yearly_returns_fundos.transpose(), annot=True, cmap="RdYlGn", linewidths=.2, cbar=False, center=0.02, fmt='.2%')
plt.yticks(rotation=360)
plt.title('Yearly performance by asset')
plt.show()
# Turning daily quotes into monthly
Portfolio_M = fundos.resample('BM').last()
# Monthly returns
Portfolio_ret_M = Portfolio_M.pct_change()
my_pal = ["royalblue", "orange", "dimgrey"]
ax = sns.swarmplot(data=Portfolio_ret_M, orient='v', linewidth=1, palette=my_pal)
ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
ax.set_title("Swarmplot das rentabilidades mensais")
ax.set_xlabel('')
ax.set_ylabel('Variação')
plt.show()
# Compute monthly returns table
nr = 0
plot(fundos.iloc[:, nr], title= 'Retornos mensais para ' + fundos.iloc[:, nr].name , figsize=(15, len(np.unique(fundos.index.year))))
# Compute monthly returns table
nr = 1
plot(fundos.iloc[:, nr], title= 'Retornos mensais para ' + fundos.iloc[:, nr].name , figsize=(15, len(np.unique(fundos.index.year))))
from IPython.display import display
from IPython.display import HTML
import IPython.core.display as di # Example: di.display_html('<h3>%s:</h3>' % str, raw=True)
# This line will hide code by default when the notebook is exported as HTML
di.display_html('<script>jQuery(function() {if (jQuery("body.notebook_app").length == 0) { jQuery(".input_area").toggle(); jQuery(".prompt").toggle();}});</script>', raw=True)
# This line will add a button to toggle visibility of code blocks, for use with the HTML export version
di.display_html('''<button onclick="jQuery('.input_area').toggle(); jQuery('.prompt').toggle();">Código ON/OFF</button>''', raw=True)