Análise de Ações Brasileiras

Author

Igor Viveiros

1 Introdução

Nesta apresentação, analisamos as ações da Azul, Vale, Petrobrás e Itaú desde 2015, com: - preços semanais, - retornos logarítmicos, - estatísticas descritivas (média, desvio padrão, coeficiente de variação, razão de Sharpe ~ 1/CV), - histogramas com kernel e linha vertical na média, - e densidades sobrepostas.


2 Preços semanais das ações

3 Retornos (%)

4 Estatísticas resumo

5 Distribuição dos dados

6 Comparação das distribuições dos retornos

7 Códigos

Mostrar/ocultar códigos
# install.packages(c("quantmod","tidyverse","plotly","DT"))
library(quantmod)
library(tidyverse)
library(plotly)
library(DT)

# Download dos dados (Yahoo Finance)

tickers <- c("VALE3.SA","PETR4.SA","ITUB4.SA")
rotulos  <- c("VALE3.SA"="Vale", "PETR4.SA"="Petrobrás", "ITUB4.SA"="Itaú")

get_weekly_prices <- function(sym, from = "2015-01-01") {
  xt <- getSymbols(sym, src = "yahoo", from = from, auto.assign = FALSE)
  wk <- to.period(Ad(xt), period = "weeks", OHLC = FALSE)  # série semanal do preço ajustado
  tibble(
    date   = as.Date(index(wk)),
    price  = as.numeric(wk[, 1]),
    symbol = sym
  )
}

prices <- map_dfr(tickers, get_weekly_prices) %>%
  arrange(symbol, date)

# Retornos logarítmicos semanais

returns <- prices %>%
  group_by(symbol) %>%
  arrange(date, .by_group = TRUE) %>%
  mutate(ret = log(price / dplyr::lag(price))) %>%
  filter(!is.na(ret), is.finite(ret)) %>%
  ungroup()

# Funções auxiliares (gráficos)
# Preços: um painel por ativo
make_price_fig <- function(df_sym) {
  plot_ly(df_sym, x = ~date, y = ~price, type = "scatter", mode = "lines",
          name = rotulos[unique(df_sym$symbol)]) %>%
    layout(
      title = list(text = rotulos[unique(df_sym$symbol)]),
      yaxis = list(title = df_sym$symbol[1]),
      showlegend = FALSE
    )
}

# Retornos: um painel por ativo, com linha horizontal na média
make_return_fig <- function(df_sym) {
  m <- mean(df_sym$ret, na.rm = TRUE)
  plot_ly(df_sym, x = ~date, y = ~ret, type = "scatter", mode = "lines",
          name = rotulos[unique(df_sym$symbol)]) %>%
    layout(
      title = list(text = paste0(rotulos[unique(df_sym$symbol)], " — retornos (log)")),
      yaxis = list(title = df_sym$symbol[1]),
      showlegend = FALSE,
      shapes = list(list(
        type = "line", xref = "x", yref = "y",
        x0 = min(df_sym$date), x1 = max(df_sym$date),
        y0 = m, y1 = m,
        line = list(dash = "dash", width = 1)
      )),
      annotations = list(list(
        x = max(df_sym$date), y = .25, xref = "x", yref = "y",
        text = sprintf("média = %.4f", m), showarrow = FALSE,
        xanchor = "right", yanchor = "bottom"
      ))
    )
}

# Histograma + densidade + linha vertical na média (plotly)
make_hist_density <- function(vec, titulo, papel) {
  vec <- vec[is.finite(vec)]
  dens <- density(vec)
  m <- mean(vec, na.rm = TRUE)

  plot_ly() %>%
    add_histogram(x = vec,
                  histnorm = "probability density",
                  nbinsx = 50,
                  name = "Histograma",
                  showlegend = FALSE) %>%
    add_lines(x = dens$x, y = dens$y,
              name = "Densidade (kernel)",
              showlegend = FALSE) %>%
    layout(
      title = titulo,
      xaxis = list(title = paste("Retorno - ",papel)),
      yaxis = list(title = "Densidade"),
      # linha vertical na média (corrigido: shapes no plotly, yref = 'paper')
      shapes = list(list(
        type = "line",
        xref = "x", yref = "paper",
        x0 = m, x1 = m,
        y0 = 0, y1 = 1,
        line = list(dash = "dot", width = 1)
      )),
      annotations = list(list(
        x = m, y = 1, xref = "x", yref = "paper",
        text = sprintf("média = %.4f", m),
        showarrow = TRUE, ax = 0, ay = -20
      ))
    )
}


# Preços semanais

fig_preco_list <- prices %>%
  split(.$symbol) %>%
  lapply(make_price_fig) %>%
  unname()

fig_precos <- do.call(
  subplot,
  c(fig_preco_list,
    list(nrows = 3, shareX = TRUE, titleY = TRUE, margin = 0.03))
) %>%
  layout(title = "Preços (R$) semanais (ajustados)",
         xaxis = list(title = "Data"))


# Retornos semanais

fig_ret_list <- returns %>%
  split(.$symbol) %>%
  lapply(make_return_fig) %>%
  unname()

fig_retornos <- do.call(
  subplot,
  c(fig_ret_list,
    list(nrows = 3, shareX = TRUE, titleY = TRUE, margin = 0.03))
) %>%
  layout(title = "Retornos semanais (log - %) com linha de média",
         xaxis = list(title = "Data"))

# Estatísticas descritivas

resumo <- returns %>%
  group_by(symbol) %>%
  summarise(
    Empresa = rotulos[first(symbol)],
    `Média (log)` = mean(ret, na.rm = TRUE),
    `Mediana (log)` = median(ret, na.rm = TRUE),
    `Desvio Padrão` = sd(ret, na.rm = TRUE),
    `Coef. de Variação` = `Desvio Padrão` / abs(`Média (log)`),
    .groups = "drop"
  ) %>%
  select(Empresa, `Média (log)`,`Mediana (log)`, `Desvio Padrão`, `Coef. de Variação`)

TABELA <- datatable(
  resumo %>%
    mutate(
      `Média (log)`   = round(`Média (log)`, 5),
      `Mediana (log)`   = round(`Mediana (log)`, 5),
      `Desvio Padrão` = round(`Desvio Padrão`, 5),
      `Coef. de Variação` = round(`Coef. de Variação`, 2),
      `Razão de Sharpe = (1/CV)` = round(1/`Coef. de Variação`, 2)
    ),
  rownames = FALSE,
  options = list(pageLength = 5),
  caption = "Estatísticas dos retornos semanais (log - %) desde 2015"
)

# Histogramas dos retornos com densidade

hists <- returns %>%
  mutate(Empresa = rotulos[symbol]) %>%
  split(.$Empresa) %>%
  lapply(function(d) make_hist_density(d$ret, "", d$symbol[1])) %>%
  Filter(function(p) inherits(p, "plotly"), x = .) %>%
  unname()

fig_hist_lado_a_lado <- do.call(
  subplot,
  c(hists,
    list(nrows = 1, shareY = FALSE, titleX = TRUE, titleY = TRUE, margin = 0.03))
) 

# Densidades sobrepostas (comparação)

densidades <- returns %>%
  mutate(Empresa = rotulos[symbol]) %>%
  split(.$Empresa) %>%
  imap(~ {
    d <- density(.x$ret, na.rm = TRUE)
    tibble(x = d$x, y = d$y, Empresa = .y)
  }) %>%
  list_rbind()

fig_densidades <- plot_ly()
for (emp in unique(densidades$Empresa)) {
  df_emp <- filter(densidades, Empresa == emp)
  fig_densidades <- fig_densidades %>%
    add_lines(data = df_emp, x = ~x, y = ~y, name = emp)
}
fig_densidades <- fig_densidades %>%
  layout(title = "",
         xaxis = list(title = ""),
         yaxis = list(title = "Densidade"),
         legend = list(orientation = "h", x = 0.5, xanchor = "center"))