March 17, 2019

Stocks and gganimate

tidyquant

Automates a lot of equity research and calculation using tidy concepts. Here, I will first use it to get the components of the S and P 500 and pick out those with weights over 1.25 percent. In the next step, I download the data and finally calculate daily returns and a cumulative wealth index.

library(tidyquant)
library(tidyverse)
tq_index("SP500") %>% filter(weight > 0.0125) %>% select(symbol,company) -> Tickers
Tickers <- Tickers %>% filter(symbol!="BRK.B") %>% filter(symbol!="GOOGL")
Eq.P <- Tickers %>%  tq_get(., from="2018/01/01", to="2019/03/14") 
Returns <- Eq.P %>% group_by(symbol) %>% tq_transmute(., adjusted, periodReturn, period="daily")
C.Returns <- Eq.P %>% 
  group_by(symbol) %>% 
  tq_transmute(., adjusted, periodReturn, period="daily", type = "log", col_rename = "returns") %>% 
  mutate(wealth.index = 100 * cumprod(1 + returns))
library(skimr)
Returns %>% skim()
Table 1: Data summary
Name Piped data
Number of rows 2400
Number of columns 3
_______________________
Column type frequency:
Date 1
numeric 1
________________________
Group variables symbol

Variable type: Date

skim_variable symbol n_missing complete_rate min max median n_unique
date AAPL 0 1 2018-01-02 2019-03-13 2018-08-06 300
date AMZN 0 1 2018-01-02 2019-03-13 2018-08-06 300
date FB 0 1 2018-01-02 2019-03-13 2018-08-06 300
date GOOG 0 1 2018-01-02 2019-03-13 2018-08-06 300
date JNJ 0 1 2018-01-02 2019-03-13 2018-08-06 300
date JPM 0 1 2018-01-02 2019-03-13 2018-08-06 300
date MSFT 0 1 2018-01-02 2019-03-13 2018-08-06 300
date TSLA 0 1 2018-01-02 2019-03-13 2018-08-06 300

Variable type: numeric

skim_variable symbol n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
daily.returns AAPL 0 1 0 0.02 -0.10 -0.01 0 0.01 0.07 ▁▁▇▇▁
daily.returns AMZN 0 1 0 0.02 -0.08 -0.01 0 0.01 0.09 ▁▂▇▁▁
daily.returns FB 0 1 0 0.02 -0.19 -0.01 0 0.01 0.11 ▁▁▂▇▁
daily.returns GOOG 0 1 0 0.02 -0.05 -0.01 0 0.01 0.06 ▁▃▇▁▁
daily.returns JNJ 0 1 0 0.01 -0.10 -0.01 0 0.01 0.04 ▁▁▁▇▂
daily.returns JPM 0 1 0 0.01 -0.05 -0.01 0 0.01 0.04 ▁▂▇▃▁
daily.returns MSFT 0 1 0 0.02 -0.05 -0.01 0 0.01 0.08 ▁▅▇▁▁
daily.returns TSLA 0 1 0 0.04 -0.14 -0.02 0 0.02 0.17 ▁▃▇▁▁

Animating a plot

The goal of this was to play with gganimate. I will take the big components and go through and plot them. It is a big animation because it involves over a year of data. The basic idea for the graphic was borrowed from a gganimate sample.

library(gganimate)
library(ggrepel)
p <- ggplot(C.Returns, aes(date, wealth.index, group = symbol, colour=symbol)) + 
  geom_point(size = 2) + 
  geom_line() + 
  geom_segment(aes(xend = as.Date("2019-03-15"), yend = wealth.index), linetype = 2) + 
    geom_text_repel(aes(y = wealth.index, x = as.Date("2019-03-15"), label = symbol), hjust = 1, nudge_x = 8) +
  transition_reveal(date) + 
  coord_cartesian(clip = 'off') + 
  labs(title = 'Cumulative Wealth Index for S&P Top 10', subtitle="Begins January 1, 2018: Base 100", y = 'Cumulative Change', x = 'Date') +
  theme_minimal() + theme(legend.position = "none")
animate(p, nframes=300)
## Warning: ggrepel: 8 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Warning: ggrepel: 8 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Warning: ggrepel: 8 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Warning: ggrepel: 8 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Warning: ggrepel: 8 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Warning: ggrepel: 8 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning: ggrepel: 7 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning: ggrepel: 6 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Warning: ggrepel: 6 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Warning: ggrepel: 6 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps

## Warning: ggrepel: 6 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning: ggrepel: 7 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning: ggrepel: 5 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning: ggrepel: 4 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning: ggrepel: 2 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps