rquantmodtidyquant

Is there a way to create a column based on a stock's return over a user-defined period?


EDIT:

I've did tried changes and opted for the tidyquant package shared in the comments below.

This time I've set a range with variables, but I think I'm having trouble turning it into a function or a vector. This could either be the result of me not writing a bad for loop orrr a limitation with the underlying library.

The idea behind this loop is that it pulls the adjusted prices for the period and then takes the first and last price to calculate a change (aka the return in share price.)

I'm not sure, but would love some thoughts!

start_date = "2019-05-20"
end_date = "2019-05-30"

Symbol_list <- c("CTVA","IBM", "GOOG", "GE")

range_returns <- for (Symbol in Symbol_List) {
  frame <- tq_get(Symbol, get = "stock.prices", from = start_date, to = end_date, complete_cases = FALSE)[,7]
  (frame[nrow(frame),] - frame[1,]) / frame[1,]
}

Old stuff


Let's say I've got a dataframe

symbol <- c("GOOG", "IBM","GE","F","BKR")
name <- c("Google", "IBM","General Electric","Ford","Berkshire Hathaway")

df <- cbind(symbol, name)

And I want to create a third column - df$custom_return that's defined based on my personal time frame.

I've tried working with the quantmod package and I'm having some trouble with it's constraints.

Where I'm at:

I have to pull the entire price history first which prohibits the ability create a new column like so:

start_date <- "2003-01-05"
end_date <- "2019-01-05"

df$defined_period_return <- ROC(getSymbol(df$symbol, src = yahoo, from = start_date, to = end_date, periodicity = "monthly"))

I know that I only want the adjusted close which is the 6th column for the Yahoo source. So, I could add the following and just pull the records into an environment.

price_history <- null

for (Symbol in sp_500$Symbol)
        price_history <- cbind(price_history,
                           getSymbols(df$symbol, from = start_date, 
                           to = end_date, periodicity = "daily", 
                           auto.assign=FALSE)[,6])

Ok, that seems feasible, but it's not exactly seamless and now I run into an issue if one of my symbols (Tickers) falls outside of the range of dates provided. For example CTVA is one of them and it didn't start trading until after the the end date. The whole scrape stops in motion right there. How do I skip over that error?

And let's say we solve the "snag" of not finding relevant records...how would you calculate the return for each symbol over different timelines? For example - Google didn't start trading until 2004. getSymbol does pull the price history once it starts trading, but that return timeline is different than GE which had data at the start of my range.


Solution

  • No need for a for loop. You can do everything with tidyquant and dplyr. For the first and last observations of a group you can use the functions first and last from dplyr. See code below for a working example.

    library(tidyquant)
    library(dplyr)
    
    start_date = "2019-05-20"
    end_date = "2019-05-30"
    
    Symbol_list <- c("CTVA","IBM", "GOOG", "GE")
    
    stocks <- tq_get(Symbol_list, get = "stock.prices", from = start_date, to = end_date, complete_cases = FALSE)
    
    stocks %>% 
      group_by(symbol) %>% 
      summarise(returns = (last(adjusted) / first(adjusted)) - 1) # calculate returns
    
    # A tibble: 4 x 2
      symbol returns
      <chr>    <dbl>
    1 CTVA   -0.0172
    2 GE     -0.0516
    3 GOOG   -0.0197
    4 IBM    -0.0402