Mostrar código
atualizar_base <- FALSE
baixar_cvm <- FALSE
overwrite_download <- FALSE
periodo_inicial <- "2015-01"
periodo_final <- "2022-12"
source("script_captacao_multimercado.R")Lemuel Lemos
14 de junho de 2026
Entre 2022 e 2025, os fundos multimercados acumularam um dos maiores ciclos de saída de recursos da história recente da indústria de fundos brasileira. Depois de quase uma década de crescimento relativamente contínuo — período em que o patrimônio líquido agregado do setor chegou a superar R$ 1,7 trilhão —, os fluxos se inverteram de forma abrupta, e uma parcela expressiva dos recursos captados nos anos anteriores foi devolvida aos cotistas.
O ponto aqui não é fechar um diagnóstico definitivo, e sim organizar os dados para entender a escala e a natureza dessa reversão. A análise está dividida em quatro frentes: a captação anual, a trajetória acumulada dos fluxos, a evolução do patrimônio líquido e a distribuição dos retornos.
A primeira leitura é a da captação líquida anual. Nesse recorte, os ciclos da indústria aparecem com mais nitidez e o ruído de curto prazo perde relevância.
Antes dos gráficos, há uma escolha metodológica importante. Para evitar que categorias residuais distorçam a leitura, o recorte mantém abertas apenas as classes que tiveram mais de 100 fundos em todos os anos da amostra. Com isso, a análise passa a girar em torno de Multimercados Investimento no Exterior, Multimercados Livre e Multimercados Macro; o restante fica concentrado em Outros.
contagem_tipos_anual |>
dplyr::rename(Tipo = `Tipo ANBIMA`) |>
gt::gt(rowname_col = "Tipo") |>
gt::fmt_number(columns = where(is.numeric), decimals = 0) |>
gt::tab_header(
title = gt::md("**Fundos por Tipo ANBIMA — 2015 a 2025**"),
subtitle = "Critério de agrupamento: categorias com mais de 100 fundos em todos os anos da amostra"
) |>
gt::tab_options(
table.font.size = gt::px(13),
table.border.top.style = "none",
table.border.bottom.style = "none",
heading.align = "left",
heading.border.bottom.style = "solid",
heading.border.bottom.color = "#e0e0e0",
heading.border.bottom.width = gt::px(1),
column_labels.border.top.style = "none",
column_labels.border.bottom.style = "solid",
column_labels.border.bottom.color = "#e0e0e0",
column_labels.border.bottom.width = gt::px(1),
column_labels.font.weight = "bold",
column_labels.background.color = "#fafafa",
stub.border.style = "none",
stub.font.weight = "bold",
data_row.padding = gt::px(8),
table_body.border.bottom.color = "#e0e0e0",
row.striping.background_color = "#f5f5f5"
) |>
gt::opt_row_striping()| Fundos por Tipo ANBIMA — 2015 a 2025 | |||||||||||
| Critério de agrupamento: categorias com mais de 100 fundos em todos os anos da amostra | |||||||||||
| 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Multimercados Balanceados | 22 | 22 | 22 | 22 | 22 | 24 | 26 | 29 | 29 | 26 | 27 |
| Multimercados Capital Protegido | 18 | 20 | 20 | 20 | 20 | 20 | 21 | 29 | 31 | 30 | 30 |
| Multimercados Dinâmico | 83 | 90 | 106 | 123 | 158 | 194 | 244 | 262 | 279 | 273 | 222 |
| Multimercados Estratégia Específica | 61 | 68 | 83 | 97 | 136 | 198 | 280 | 347 | 409 | 423 | 406 |
| Multimercados Investimento no Exterior | 2,195 | 2,617 | 3,086 | 3,457 | 3,982 | 4,709 | 5,753 | 6,506 | 7,230 | 7,749 | 6,628 |
| Multimercados Juros e Moedas | 94 | 107 | 114 | 122 | 124 | 140 | 150 | 153 | 160 | 155 | 152 |
| Multimercados Livre | 1,172 | 1,325 | 1,532 | 1,753 | 2,103 | 2,558 | 3,148 | 3,741 | 4,353 | 4,757 | 4,451 |
| Multimercados Long and Short - Direcional | 29 | 35 | 47 | 57 | 77 | 90 | 105 | 120 | 125 | 124 | 127 |
| Multimercados Long and Short - Neutro | 11 | 11 | 15 | 16 | 21 | 22 | 23 | 25 | 29 | 29 | 29 |
| Multimercados Macro | 173 | 221 | 305 | 447 | 569 | 664 | 779 | 841 | 896 | 923 | 883 |
| Multimercados Trading | 7 | 7 | 7 | 7 | 8 | 10 | 10 | 12 | 12 | 12 | 11 |
dados_captacao_anual <- dados_fundos_multimercado |>
dplyr::mutate(Ano = lubridate::year(DT_COMPTC)) |>
dplyr::filter(Ano >= 2015, Ano <= 2025) |>
dplyr::summarise(
NET_CAPTACAO = sum(NET_CAPTACAO, na.rm = TRUE) / 1e9,
.by = c("Ano", "Tipo_Ajustado")
) |>
dplyr::arrange(Ano)
dados_captacao_anual_grafico <- dados_captacao_anual |>
tidyr::pivot_wider(
names_from = Tipo_Ajustado,
values_from = NET_CAPTACAO,
values_fill = 0
) |>
dplyr::mutate(
Total = `Multimercados Investimento no Exterior` +
`Multimercados Livre` +
`Multimercados Macro` +
Outros,
Ano = as.character(Ano)
)
dados_captacao_anual_grafico |>
echarts4r::e_charts(Ano) |>
echarts4r::e_bar(
`Multimercados Investimento no Exterior`,
stack = "total",
name = "Multimercados Investimento no Exterior"
) |>
echarts4r::e_bar(
`Multimercados Livre`,
stack = "total",
name = "Multimercados Livre"
) |>
echarts4r::e_bar(
`Multimercados Macro`,
stack = "total",
name = "Multimercados Macro"
) |>
echarts4r::e_bar(
Outros,
stack = "total",
name = "Outros"
) |>
echarts4r::e_line(
Total,
name = "Total",
symbol = "circle",
symbolSize = 8,
color = "#111111",
lineStyle = list(width = 3)
) |>
echarts4r::e_tooltip(
trigger = "axis",
formatter = htmlwidgets::JS(
"function(params){ var eixo = params[0].axisValueLabel || params[0].axisValue || ''; return eixo + '<br/>' + params.map(function(p){ var valor = Array.isArray(p.value) ? p.value[p.value.length - 1] : p.value; return p.marker + ' ' + p.seriesName + ': R$ ' + Number(valor).toFixed(2) + ' bi'; }).join('<br/>'); }"
)
) |>
echarts4r::e_title(
text = "Captação Líquida Anual por Categoria",
subtext = "Fundos multimercados | Valores em R$ bilhões | 2015–2025"
) |>
echarts4r::e_y_axis(
name = "Captação líquida (R$ bi)",
axisLabel = list(
formatter = htmlwidgets::JS(
"function(v){ return 'R$ ' + v.toFixed(0) + ' bi'; }"
)
)
) |>
echarts4r::e_legend(orient = "horizontal", bottom = 10, left = "center") |>
echarts4r::e_grid(bottom = 120, top = 60)dados_captacao_anual |>
tidyr::pivot_wider(
names_from = Ano,
values_from = NET_CAPTACAO,
values_fill = 0
) |>
dplyr::rename(Tipo = Tipo_Ajustado) |>
dplyr::rowwise() |>
dplyr::mutate(
Total = sum(dplyr::c_across(-Tipo), na.rm = TRUE)
) |>
dplyr::ungroup() |>
dplyr::relocate(Total, .after = last_col()) |>
gt::gt(rowname_col = "Tipo") |>
gt::fmt_number(columns = where(is.numeric), decimals = 2) |>
gt::data_color(
columns = where(is.numeric),
palette = c("#c0392b", "#ffffff", "#27ae60")
) |>
gt::tab_style(
style = list(
gt::cell_borders(sides = "left", color = "#d0d0d0", weight = gt::px(1)),
gt::cell_text(weight = "bold")
),
locations = gt::cells_body(columns = Total)
) |>
gt::tab_style(
style = gt::cell_text(weight = "bold"),
locations = gt::cells_column_labels(columns = Total)
) |>
gt::tab_header(
title = gt::md("**Captação Líquida Anual por Categoria**"),
subtitle = gt::md(
"Valores em R$ bilhões · 🟢 captação positiva · 🔴 saída líquida"
)
) |>
gt::tab_options(
table.font.size = gt::px(13),
table.border.top.style = "none",
table.border.bottom.style = "none",
heading.align = "left",
heading.border.bottom.style = "solid",
heading.border.bottom.color = "#e0e0e0",
heading.border.bottom.width = gt::px(1),
column_labels.border.top.style = "none",
column_labels.border.bottom.style = "solid",
column_labels.border.bottom.color = "#e0e0e0",
column_labels.border.bottom.width = gt::px(1),
column_labels.font.weight = "bold",
column_labels.background.color = "#fafafa",
stub.border.style = "none",
stub.font.weight = "bold",
data_row.padding = gt::px(8),
table_body.border.bottom.color = "#e0e0e0"
)| Captação Líquida Anual por Categoria | ||||||||||||
| Valores em R$ bilhões · 🟢 captação positiva · 🔴 saída líquida | ||||||||||||
| 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | Total | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Multimercados Livre | −2.86 | 6.63 | 36.83 | 56.84 | 95.91 | 129.78 | 8.71 | −118.64 | −73.67 | −106.56 | −80.44 | −47.47 |
| Multimercados Macro | −8.66 | 21.90 | 69.30 | 74.98 | 47.32 | −8.86 | −32.43 | −14.52 | −95.15 | −146.46 | −74.78 | −167.37 |
| Multimercados Investimento no Exterior | 29.79 | 27.22 | 35.08 | 18.35 | 44.55 | 52.74 | 90.72 | −9.79 | −55.59 | −200.96 | −19.35 | 12.76 |
| Outros | −2.21 | 6.43 | 23.43 | 0.78 | 17.89 | 33.39 | 30.78 | −13.57 | −43.92 | −39.74 | −30.44 | −17.18 |
O quadro anual mostra que o movimento ficou concentrado em poucas classes. Multimercados Livre e Multimercados Macro lideraram a captação no ciclo de expansão e passaram a concentrar também as maiores saídas a partir de 2022. É nelas, portanto, que a mudança de regime aparece de forma mais nítida.
Para localizar melhor a inflexão, vale descer ao dado mensal e colocar captação bruta e resgates na mesma série. É nesse confronto que o desequilíbrio começa a aparecer.
dados_fundos_multimercado |>
dplyr::mutate(
Ano = lubridate::year(DT_COMPTC),
Mes = lubridate::month(DT_COMPTC)
) |>
dplyr::filter(Ano >= 2015, Ano <= 2025) |>
dplyr::summarise(
Captacao = sum(CAPTC_DIA, na.rm = TRUE) / 1e9,
Resgates = -sum(RESG_DIA, na.rm = TRUE) / 1e9,
.by = c("Ano", "Mes")
) |>
dplyr::mutate(
Competencia = as.Date(paste(Ano, Mes, "01", sep = "-")),
CAPTC_LIQ = Captacao + Resgates
) |>
dplyr::arrange(Competencia) -> captacao_mensal
captacao_mensal |>
echarts4r::e_charts(Competencia) |>
echarts4r::e_bar(
Captacao,
name = "Captação bruta",
color = "steelblue",
stack = "total"
) |>
echarts4r::e_bar(
Resgates,
name = "Resgates",
color = "tomato",
stack = "total"
) |>
echarts4r::e_line(
CAPTC_LIQ,
name = "Captação líquida",
color = "darkgreen"
) |>
echarts4r::e_title(
text = "Captação Bruta e Resgates Mensais — Fundos Multimercados",
subtext = "Valores em R$ bilhões | 2015–2025"
) |>
echarts4r::e_legend(right = TRUE) |>
echarts4r::e_tooltip(
trigger = "axis",
formatter = htmlwidgets::JS(
"function(params){ var eixo = params[0].axisValueLabel || params[0].axisValue || ''; return eixo + '<br/>' + params.map(function(p){ var valor = Array.isArray(p.value) ? p.value[p.value.length - 1] : p.value; return p.marker + ' ' + p.seriesName + ': R$ ' + Number(valor).toFixed(2) + ' bi'; }).join('<br/>'); }"
)
) |>
echarts4r::e_y_axis(
axisLabel = list(
formatter = htmlwidgets::JS(
"function(v){ return 'R$ ' + v.toFixed(0) + ' bi'; }"
)
)
) |>
echarts4r::e_x_axis(axisLabel = list(rotate = 45)) |>
echarts4r::e_grid(left = "10%", right = "10%")O gráfico mensal divide a década em dois momentos. De 2015 até meados de 2021, a captação bruta superou os resgates na maior parte do tempo. A partir do segundo semestre de 2021, essa relação começa a se inverter; em 2022, o saldo negativo deixa de ser exceção e passa a se repetir com regularidade.
Como a série mensal é volátil, a leitura seguinte usa uma janela móvel de 12 meses. Esse recorte suaviza a sazonalidade e mostra com mais clareza quando a perda de fôlego deixa de ser episódica e passa a caracterizar uma mudança de tendência.
dados_fundos_multimercado |>
dplyr::mutate(
Ano = lubridate::year(DT_COMPTC),
Mes = lubridate::month(DT_COMPTC)
) |>
dplyr::filter(Ano >= 2015, Ano <= 2025) |>
dplyr::summarise(
CAPTC_LIQ = sum(NET_CAPTACAO, na.rm = TRUE) / 1e9,
.by = c("Ano", "Mes", "Tipo_Ajustado")
) |>
dplyr::mutate(Competencia = as.Date(paste(Ano, Mes, "01", sep = "-"))) |>
dplyr::arrange(Tipo_Ajustado, Competencia) |>
dplyr::group_by(Tipo_Ajustado) |>
dplyr::mutate(
Captacao_12m = as.numeric(stats::filter(CAPTC_LIQ, rep(1, 12), sides = 1))
) |>
dplyr::filter(!is.na(Captacao_12m)) |>
dplyr::ungroup() |>
dplyr::group_by(Tipo_Ajustado) |>
echarts4r::e_charts(Competencia) |>
echarts4r::e_line(Captacao_12m, smooth = TRUE) |>
echarts4r::e_tooltip(
trigger = "axis",
formatter = htmlwidgets::JS(
"function(params){ var eixo = params[0].axisValueLabel || params[0].axisValue || ''; return eixo + '<br/>' + params.map(function(p){ var valor = Array.isArray(p.value) ? p.value[p.value.length - 1] : p.value; return p.marker + ' ' + p.seriesName + ': R$ ' + Number(valor).toFixed(2) + ' bi'; }).join('<br/>'); }"
)
) |>
echarts4r::e_title(
text = "Captação Líquida por Categoria — Janela Móvel de 12 Meses",
subtext = "Soma dos últimos 12 meses | Valores em R$ bilhões | 2016–2025"
) |>
echarts4r::e_y_axis(
axisLabel = list(
formatter = htmlwidgets::JS(
"function(v){ return 'R$ ' + v.toFixed(0) + ' bi'; }"
)
)
) |>
echarts4r::e_x_axis(axisLabel = list(rotate = 45)) |>
echarts4r::e_mark_line(
data = list(yAxis = 0),
lineStyle = list(color = "#cc3333", type = "dashed", width = 1.5),
label = list(show = FALSE),
title = ""
) |>
echarts4r::e_legend(orient = "horizontal", bottom = 10, left = "center") |>
echarts4r::e_grid(bottom = 120, top = 60)O ponto central está no momento em que as curvas passam a rodar abaixo de zero, em diferentes momentos entre 2022 e 2023, a depender da categoria. Nesse trecho, a indústria deixa de registrar episódios isolados de resgate e passa a exibir um padrão persistente de saídas em base anualizada.
Depois de mapear o comportamento anual e mensal, faz sentido olhar para o saldo acumulado de cada classe ao longo da década. É esse recorte que mostra o tamanho efetivo do avanço e, depois, da devolução de recursos.
captacao_mensal |>
dplyr::mutate(Acumulado = cumsum(CAPTC_LIQ)) |>
echarts4r::e_charts(Competencia) |>
echarts4r::e_line(
Acumulado,
name = "Captação líquida acumulada",
color = "#1a1a2e",
smooth = TRUE
) |>
echarts4r::e_area(
Acumulado,
name = "Captação líquida acumulada",
color = "#1a1a2e",
itemStyle = list(opacity = 0.15)
) |>
echarts4r::e_title(
text = "Captação Líquida Acumulada — Fundos Multimercados",
subtext = "Base: janeiro de 2015 | Valores em R$ bilhões"
) |>
echarts4r::e_tooltip(
trigger = "axis",
formatter = htmlwidgets::JS(
"function(params){ var eixo = params[0].axisValueLabel || params[0].axisValue || ''; return eixo + '<br/>' + params.map(function(p){ var valor = Array.isArray(p.value) ? p.value[p.value.length - 1] : p.value; return p.marker + ' ' + p.seriesName + ': R$ ' + Number(valor).toFixed(2) + ' bi'; }).join('<br/>'); }"
)
) |>
echarts4r::e_y_axis(
axisLabel = list(
formatter = htmlwidgets::JS(
"function(v){ return 'R$ ' + v.toFixed(0) + ' bi'; }"
)
)
) |>
echarts4r::e_x_axis(axisLabel = list(rotate = 45)) |>
echarts4r::e_grid(left = "12%", right = "10%") |>
echarts4r::e_legend(show = FALSE)A curva acumulada resume a história da década em um único traço. Entre 2015 e 2021, o movimento é de alta quase contínua, refletindo uma indústria que ainda atraía capital de forma recorrente. A partir do pico, em torno de 2021, a trajetória se inverte e a devolução de recursos ganha velocidade.
Desagregando por categoria, os padrões se diferenciam:
dados_fundos_multimercado |>
dplyr::mutate(
Ano = lubridate::year(DT_COMPTC),
Mes = lubridate::month(DT_COMPTC)
) |>
dplyr::filter(Ano >= 2015, Ano <= 2025) |>
dplyr::summarise(
CAPTC_LIQ = sum(NET_CAPTACAO, na.rm = TRUE) / 1e9,
.by = c("Ano", "Mes", "Tipo_Ajustado")
) |>
dplyr::mutate(Competencia = as.Date(paste(Ano, Mes, "01", sep = "-"))) |>
dplyr::arrange(Competencia) |>
dplyr::group_by(Tipo_Ajustado) |>
dplyr::mutate(Acumulado = cumsum(CAPTC_LIQ)) |>
dplyr::ungroup() |>
dplyr::group_by(Tipo_Ajustado) |>
echarts4r::e_charts(Competencia) |>
echarts4r::e_line(Acumulado, smooth = TRUE) |>
echarts4r::e_tooltip(
trigger = "axis",
formatter = htmlwidgets::JS(
"function(params){ var eixo = params[0].axisValueLabel || params[0].axisValue || ''; return eixo + '<br/>' + params.map(function(p){ var valor = Array.isArray(p.value) ? p.value[p.value.length - 1] : p.value; return p.marker + ' ' + p.seriesName + ': R$ ' + Number(valor).toFixed(2) + ' bi'; }).join('<br/>'); }"
)
) |>
echarts4r::e_title(
text = "Captação Líquida Acumulada por Categoria",
subtext = "Base: janeiro de 2015 | Valores em R$ bilhões"
) |>
echarts4r::e_y_axis(
name = "Acumulado (R$ bi)",
axisLabel = list(
formatter = htmlwidgets::JS(
"function(v){ return 'R$ ' + v.toFixed(0) + ' bi'; }"
)
)
) |>
echarts4r::e_legend(orient = "horizontal", bottom = 10, left = "center") |>
echarts4r::e_grid(bottom = 120, top = 60)Entre as classes abertas no gráfico, Multimercados Livre concentram o maior ganho acumulado no ciclo de expansão e também a correção mais intensa depois de 2022. Multimercados Macro seguem a mesma direção, mas em escala menor. Multimercados Investimento no Exterior avançam com força entre 2018 e 2021, no auge da demanda por exposição externa, e depois entram no mesmo processo de reversão. Já Outros têm trajetória mais estável e peso marginal tanto na fase de entrada quanto na de saída.
Captação não é sinônimo de patrimônio. O estoque de recursos também responde ao desempenho dos ativos e, por isso, pode cair menos do que os fluxos sugerem. O gráfico a seguir mostra como o patrimônio líquido de cada categoria evoluiu ao longo do período.
pl_fechamento_fundo_anual <- dados_fundos_multimercado |>
dplyr::mutate(
Ano = lubridate::year(DT_COMPTC)
) |>
dplyr::filter(Ano >= 2015, Ano <= 2025) |>
dplyr::group_by(Ano, CNPJ_FUNDO, Tipo_Ajustado) |>
dplyr::slice_max(DT_COMPTC, n = 1, with_ties = FALSE) |>
dplyr::ungroup() |>
dplyr::transmute(
Ano,
CNPJ_FUNDO,
Tipo_Ajustado,
Competencia = DT_COMPTC,
PL = VL_PATRIM_LIQ / 1e9
) |>
dplyr::arrange(Ano, Tipo_Ajustado, CNPJ_FUNDO)
dados_pl_anual <- pl_fechamento_fundo_anual |>
dplyr::summarise(
PL = sum(PL, na.rm = TRUE),
Competencia = max(Competencia),
.by = c("Ano", "Tipo_Ajustado")
) |>
dplyr::arrange(Ano)
dados_pl_anual_grafico <- dados_pl_anual |>
tidyr::pivot_wider(
names_from = Tipo_Ajustado,
values_from = PL,
values_fill = 0
) |>
dplyr::mutate(
Total = `Multimercados Investimento no Exterior` +
`Multimercados Livre` +
`Multimercados Macro` +
Outros,
Ano = as.character(Ano)
)
dados_pl_anual_grafico |>
echarts4r::e_charts(Ano) |>
echarts4r::e_bar(
`Multimercados Investimento no Exterior`,
stack = "total",
name = "Multimercados Investimento no Exterior"
) |>
echarts4r::e_bar(
`Multimercados Livre`,
stack = "total",
name = "Multimercados Livre"
) |>
echarts4r::e_bar(
`Multimercados Macro`,
stack = "total",
name = "Multimercados Macro"
) |>
echarts4r::e_bar(
Outros,
stack = "total",
name = "Outros"
) |>
echarts4r::e_line(
Total,
name = "Total",
symbol = "circle",
symbolSize = 8,
color = "#111111",
lineStyle = list(width = 3)
) |>
echarts4r::e_tooltip(
trigger = "axis",
formatter = htmlwidgets::JS(
"function(params){ var eixo = params[0].axisValueLabel || params[0].axisValue || ''; return eixo + '<br/>' + params.map(function(p){ var valor = Array.isArray(p.value) ? p.value[p.value.length - 1] : p.value; return p.marker + ' ' + p.seriesName + ': R$ ' + Number(valor).toFixed(2) + ' bi'; }).join('<br/>'); }"
)
) |>
echarts4r::e_title(
text = "Patrimônio Líquido por Categoria",
subtext = "Valores em R$ bilhões | 2015–2025"
) |>
echarts4r::e_y_axis(
name = "PL (R$ bi)",
axisLabel = list(
formatter = htmlwidgets::JS(
"function(v){ return 'R$ ' + v.toFixed(0) + ' bi'; }"
)
)
) |>
echarts4r::e_x_axis(axisLabel = list(rotate = 45)) |>
echarts4r::e_legend(orient = "horizontal", bottom = 10, left = "center") |>
echarts4r::e_grid(bottom = 120, top = 60)O patrimônio encolhe menos do que a captação isolada faria supor. A explicação é direta: captação mede fluxo; patrimônio mede estoque. Para aproximar essas duas dimensões, o gráfico seguinte decompõe a variação anual do PL entre captação líquida e um resíduo tratado aqui como rentabilidade implícita.
pl_fechamento_anual_total <- pl_fechamento_fundo_anual |>
dplyr::summarise(
Competencia = max(Competencia),
PL = sum(PL, na.rm = TRUE),
.by = Ano
) |>
dplyr::arrange(Ano)
captacao_anual_total <- dados_fundos_multimercado |>
dplyr::mutate(Ano = lubridate::year(DT_COMPTC)) |>
dplyr::filter(Ano >= 2015, Ano <= 2025) |>
dplyr::summarise(
Captacao_Liquida = sum(NET_CAPTACAO, na.rm = TRUE) / 1e9,
.by = Ano
)
reconciliacao_pl <- pl_fechamento_anual_total |>
dplyr::left_join(captacao_anual_total, by = "Ano") |>
dplyr::mutate(
Variacao_PL = PL - dplyr::lag(PL),
Rentabilidade_Implicita = Variacao_PL - Captacao_Liquida
) |>
dplyr::filter(!is.na(Variacao_PL)) |>
dplyr::mutate(Ano = as.character(Ano))
reconciliacao_pl |>
echarts4r::e_charts(Ano) |>
echarts4r::e_bar(
Captacao_Liquida,
stack = "componentes",
name = "Captação líquida",
color = "#4c78a8"
) |>
echarts4r::e_bar(
Rentabilidade_Implicita,
stack = "componentes",
name = "Rentabilidade implícita",
color = "#f58518"
) |>
echarts4r::e_line(
Variacao_PL,
name = "Variação do PL",
color = "#1f1f1f",
lineStyle = list(width = 3)
) |>
echarts4r::e_tooltip(
trigger = "axis",
formatter = htmlwidgets::JS(
"function(params){ var eixo = params[0].axisValueLabel || params[0].axisValue || ''; return eixo + '<br/>' + params.map(function(p){ var valor = Array.isArray(p.value) ? p.value[p.value.length - 1] : p.value; return p.marker + ' ' + p.seriesName + ': R$ ' + Number(valor).toFixed(2) + ' bi'; }).join('<br/>'); }"
)
) |>
echarts4r::e_title(
text = "Reconciliação da Variação do PL",
subtext = "Variação do PL = captação líquida + rentabilidade implícita | Valores em R$ bilhões | 2016–2025"
) |>
echarts4r::e_y_axis(
name = "Variação anual (R$ bi)",
axisLabel = list(
formatter = htmlwidgets::JS(
"function(v){ return 'R$ ' + v.toFixed(0) + ' bi'; }"
)
)
) |>
echarts4r::e_x_axis(axisLabel = list(rotate = 45)) |>
echarts4r::e_legend(orient = "horizontal", bottom = 10, left = "center") |>
echarts4r::e_grid(bottom = 120, top = 60)A decomposição melhora a leitura do ajuste. Em vários anos, a rentabilidade implícita funciona como colchão: mesmo com saídas líquidas relevantes, o retorno dos ativos ajuda a preservar parte do patrimônio. É importante, porém, tratar esse número com cautela. Não se trata de uma medida direta de performance, mas de um resíduo que também absorve diferenças de cobertura entre as bases. Isso é particularmente relevante em fundos encerrados ao longo do ano, cujo PL pode permanecer registrado na última data disponível, enquanto os resgates já aparecem integralmente na série de captação. Ainda assim, a ordem de grandeza sugere que olhar apenas para os fluxos exagera a contração do estoque de recursos da indústria.
Fluxo não explica tudo. Para entender por que o investidor saiu, é preciso olhar também para o que os fundos entregaram em retorno num ambiente em que o CDI voltou a competir com força.
O gráfico abaixo traz a distribuição dos retornos anuais por categoria, com o CDI como referência de custo de oportunidade. Os outliers foram retirados pelo critério do IQR para evitar que poucos casos extremos contaminem a leitura do conjunto.
rentabilidade_plot |>
ggplot2::ggplot(ggplot2::aes(x = Ano, y = Retorno, fill = Ano)) +
ggplot2::geom_boxplot(
outlier.shape = NA
) +
ggplot2::geom_segment(
data = linhas_cdi,
ggplot2::aes(
x = x_num - 0.4,
xend = x_num + 0.4,
y = CDI,
yend = CDI
),
inherit.aes = FALSE,
color = "#8b0000",
linewidth = 1
) +
ggplot2::geom_point(
data = linhas_cdi,
ggplot2::aes(
x = x_num,
y = CDI
),
inherit.aes = FALSE,
color = "#8b0000",
fill = "#ffd9d9",
shape = 21,
stroke = 0.4,
size = 1.8
) +
ggplot2::geom_hline(
yintercept = 0,
linetype = "dashed",
color = "#cc3333",
linewidth = 0.4
) +
ggplot2::facet_wrap(
~Tipo,
scales = "free_y",
ncol = 2,
labeller = ggplot2::label_wrap_gen(width = 25)
) +
ggplot2::scale_y_continuous(
labels = function(x) paste0(round(x, 0), "%")
) +
ggplot2::theme_minimal(base_size = 10) +
ggplot2::labs(
title = "Distribuição de Rentabilidade Anual por Categoria",
subtitle = "Fundos multimercados | agrupamento em Outros | 2015–2025",
x = NULL,
y = "Rentabilidade (%)"
) +
ggplot2::theme(
legend.position = "none",
axis.text.x = ggplot2::element_text(angle = 45, hjust = 1, size = 8),
strip.text = ggplot2::element_text(face = "bold"),
panel.grid.minor = ggplot2::element_blank()
)
Os retornos ajudam a entender por que a captação piorou. No ciclo de juros mais baixos, entre 2017 e 2020, as medianas eram mais favoráveis e a dispersão entre gestores indicava espaço para diferenciação. A partir de 2022, esse quadro muda: as medianas comprimem e, em vários casos, passam a orbitar o CDI ou ficar abaixo dele.
Sozinho, esse dado não encerra a discussão. Mas ele reforça um ponto central: com juros altos, taxa de administração, come-cotas e risco de execução passaram a cobrar um preço maior. Se o retorno mediano não entrega prêmio claro sobre o CDI, o resgate deixa de ser exceção e passa a ser uma decisão economicamente racional.
Os dados dividem a década em dois períodos muito claros. Até 2021, a indústria expandiu patrimônio e captou recursos de forma recorrente. A partir de 2022, o sinal virou: os resgates passaram a dominar a dinâmica do setor e a perda de tração apareceu em praticamente todas as categorias relevantes.
O patrimônio caiu menos do que a captação isolada sugeriria, o que indica que a rentabilidade ainda funcionou, em parte do período, como amortecedor das saídas.
Três elementos parecem ter contribuído para essa inversão, ainda que seja difícil isolar o peso de cada um:
📈 Nível de juros: A elevação da Selic aumentou o custo de oportunidade de permanecer em fundos multimercados. Com o CDI entregando retornos reais positivos e sem as taxas de administração características desses veículos, a vantagem relativa dos multimercados sobre alternativas de renda fixa ficou menos evidente para boa parte dos investidores.
🧾 Tributação: A extensão do come-cotas para fundos exclusivos — anunciada em 2023 — removeu um dos incentivos tributários que historicamente justificavam a permanência em determinados veículos, especialmente para investidores de maior patrimônio.
📉 Desempenho relativo: A incapacidade de parcela relevante dos fundos de superar o CDI de forma consistente após 2022 pode ter reforçado a decisão de resgate. Quando o retorno do fundo fica sistematicamente abaixo do custo de oportunidade, a racionalidade econômica favorece a saída.
O próximo capítulo depende de duas variáveis: juros e entrega. Uma queda mais consistente da taxa básica tende a aliviar o custo de oportunidade, mas isso talvez não baste. Para recuperar fluxo, a indústria precisará voltar a oferecer retorno que justifique complexidade, taxa e iliquidez relativa. Por ora, os dados ainda descrevem um setor em ajuste, e não uma retomada.