I am new to quantmod
I am using quantmod to extract stock prices, however, I want to restrict my extraction only to closing prices. I am wondering if there is a way to do it instead of downloading all default columns.
This is the code I am using
tickers <- c("1COV.DE","ADS.DE","ALV.DE","BAS.DE")
from <- "2014-10-01"
to = "2021-07-29"
getSymbols(tickers,
src = "yahoo",
from = from,
to = to,
adjust = TRUE,
periodicity = "daily")
You can do it with this pattern:
tickers <- c("1COV.DE", "ADS.DE", "ALV.DE", "BAS.DE")
# Store all data in a new environment
e <- new.env()
getSymbols(tickers, from = "2014-10-01", adjust = TRUE, env = e)
# Combine close prices
prices <- do.call(merge, lapply(e, Cl))
# remove leading "X" created by make.names()
colnames(prices) <- gsub("^X", "", colnames(prices))
# remove ".Close" suffix
colnames(prices) <- gsub(".Close", "", colnames(prices), fixed = TRUE)
# reorder columns to match 'tickers'
prices <- prices[, tickers]
One way is to use tidyquant library and put all four stocks in one data frame. Then you can group by the symbol. In that way, you don't have problems with different lengths of symbols.
library(tidyquant)
tickers <- c("1COV.DE","ADS.DE","ALV.DE","BAS.DE")
from <- "2014-10-01"
to = "2021-07-29"
closed <- tq_get(tickers,
from = from,
to = to) %>%
select(symbol, date, close) %>%
arrange(date)
Related
I want to perform a function on my list, calculating the returns for my tickers. The aim is to add a column for each ticker in my list.
ticker = c("BTC-USD", "^GDAXI")
Stocks = lapply(ticker, getSymbols, source = "yahoo", auto.assign = FALSE)
names(Stocks) = ticker
Return_cal = function(x) {
x$Return_log = periodReturn(x[,1], period = "daily", type = "log")
}
How can I perform the return calculation for each element in my list, having at the end a column for each ticker?
Thank you
Please make sure to refer to functions with their respective package if they are not in the standard installation of R. For instance, we cannot know what getSymbols() does and what its output looks like since we do not know where you got that function from. Same thing for periodReturn.
You can indicate the package by either loading it in advance, e.g. library(mypackage), or you can prepend the package to the function call, e.g. mypackage::funnyfunction().
Now, I assume that getSymbols() returns a matrix or data frame such that the first column can be used as an argument in periodReturn(x[,1], ...). Then you can apply periodReturn() with your desired arguments to each element in Stocks as follows:
ticker <- c("BTC-USD", "^GDAXI")
Stocks <- lapply(ticker, getSymbols, source = "yahoo", auto.assign = FALSE)
names(Stocks) <- ticker
Return_cal <- function(x) {
# this only adds the new column to x but the function does not return anything yet:
x$Return_log <- periodReturn(x[,1], period = "daily", type = "log")
x # this returns x
}
Stocks <- lapply(Stocks, Return_cal) # apply Return_cal to each element of Stocks
I want to get the closing prices for all S&P 500 stocks for specific dates.
I've trawled SO for answers and they fall into the following:
Download specific stocks for S&P with start and end dates - returns more than closing price which would require a line to concatenate all stocks and slows it right down
Download all stocks for S&P with start and end dates - always gets "Error in download"
For instance:
library(BatchGetSymbols)
first.date <- Sys.Date() - 160
last.date <- Sys.Date() - 1
all_stocks <- GetSP500Stocks()
tickers <- all_stocks$tickers
show <- BatchGetSymbols(tickers = tickers,
first.date = first.date,
last.date = last.date)
This always returns:
"Adobe Systems Inc | yahoo (7|505) | Not Cached
- Error in download..
and so on.
I merely want three columns - ticker, first.date and last.date
Appreciate any help!
Use tickers as all_stocks$company instead of all_stocks$tickers
library(BatchGetSymbols)
tickers <- all_stocks$company
show <- BatchGetSymbols(tickers = tickers,
first.date = first.date,last.date = last.date)
It seems unconventional to me though that column with ticker information is given column name as company and column with company names is given name as tickers.
You can find constituents of the S&P 500 here.
https://en.wikipedia.org/wiki/List_of_S%26P_500_companies
library(quantmod)
e <- new.env()
getSymbols("MMM;ABT;ABBV;ABMD;ACN;
ATVI;ADBE;AMD;AAP;AES;AMG;AFL;A;APD;
AKAM;ALK;ALB;ARE;ALXN;ALGN;ALLE;AGN;ADS;
LNT;ALL;GOOGL", env = e)
pframe <- do.call(merge, as.list(e))
head(pframe)
Try this too.
library(quantmod)
Nasdaq100_Symbols <- c('GE','PG','MSFT','AAPL','PFE','AMD','DELL')
# put all stocks in one list object
stocks <- lapply(Nasdaq100_Symbols, getSymbols, auto.assign = FALSE)
# following is not needed but if you want to use the list for other purposes
# it is a good practice to name all the different list objects.
# names(stocks) <- Nasdaq100_Symbols
# merge all stocks into 1 xts object
nasdaq100 <- Reduce(merge, stocks)
# fill NA's with 0
nasdaq100 <- na.fill(nasdaq100, 0)
outcomeSymbol <- "GE.Volume" # <-- used GE as that data is available in the downloaded data set
# merge outcome to data
nasdaq100 <- merge(nasdaq100, lm1 = lag(nasdaq[, outcomeSymbol], -1))
# turn into data.frame
nasdaq100_df <- data.frame(date = index(nasdaq100), coredata(nasdaq100))
Finally, try this to get the tickers.
library(rvest)
url <- "https://en.wikipedia.org/wiki/List_of_S%26P_500_companies"
SP500 <- url %>%
html() %>%
html_nodes(xpath='//*[#id="mw-content-text"]/div/table[1]') %>%
html_table()
SP500 <- SP500[[1]]
SP500
As an alternative, see the links below for more ideas of how to do this.
https://www.r-bloggers.com/downloading-sp-500-stock-data-from-googlequandl-with-r-command-line-script/
https://www.business-science.io/investments/2016/10/23/SP500_Analysis.html
https://www.business-science.io/investments/2016/11/30/Russell2000_Analysis.html
I would like to retrieve stocks OHLC data based on a specific criterion, for example only s&p 500 that are above their own MA5. Is there a way to do it using quantmod? For example, can I enter an if function in the getSymbols function?
Attached is the code that I use without the criterion:
require(quantmod)
options(scipen=999)
spy <- getSymbols(c('SPY', 'IBM') , src = 'yahoo', from = '2007-01-01', auto.assign = T)
tail(cbind(SPY, IBM))
I don't think that this is possible. You have to get all symbols, compute the indicators of interest and then filter for the ones meeting your conditions.
Here is a way to retrieve all S&P500 symbols (takes approx 10 minutes because there is a pause of 1 second between the requests) and compute the 200-day sma for each of them.
library(rvest)
library(quantmod)
library(TTR)
tbl <- read_html('https://en.wikipedia.org/wiki/List_of_S%26P_500_companies') %>% html_nodes(css = 'table')
tbl <- tbl[1] %>% html_table() %>% as.data.frame()
tbl$Ticker.symbol <- gsub(pattern = '\\.', '-', tbl$Ticker.symbol) # BRK.B -> BRK-B (yahoo uses '-')
head(tbl$Ticker.symbol)
[1] "MMM" "ABT" "ABBV" "ACN" "ATVI" "AYI"
quotes <- new.env()
getSymbols(tbl$Ticker.symbol, src = 'yahoo', from = '2007-01-01', env = quotes)
sma_200 <- lapply(quotes, function(x) {
SMA(x[, 4], n = 200)
})
If I want to load stock data, this is how I do it (for Google as an example):
## most recent close price
getSymbols("GOOG")
last(GOOG)[,4]
## total equity
getFinancials("GOOG")
viewFinancials(GOOG.f, type='BS', period='A',subset = NULL)['Total Equity',1]
## Net Income
viewFinancials(GOOG.f, type='IS', period='Q',subset = NULL)['Net Income',1]
...the list goes on.
But it would be much more practical to have to type GOOG only once and then have it replaced with a generic name in the rest of the code. How can this be done in quantmod?
The option auto.assign=FALSE should solve the problem.
Below is a modified version of your code. Extending it to a larger number of tickers and treating them, e.g., in a loop should be straightforward.
library(quantmod)
CollectionOfTickers <- c("GOOG")
IndexOfCurrentTicker <- 1
# the part that follows could be extracted as a function
CurrentTicker <- getSymbols(CollectionOfTickers[IndexOfCurrentTicker], auto.assign=FALSE)
Cl(last(CurrentTicker)) ## most recent close price
## total equity
CurrentTickerFinancials <- getFinancials(CollectionOfTickers[IndexOfCurrentTicker], auto.assign=FALSE)
viewFinancials(CurrentTickerFinancials, type='BS', period='A',subset = NULL)['Total Equity',1]
## Net Income
viewFinancials(CurrentTickerFinancials, type='IS', period='Q',subset = NULL)['Net Income',1]
Note that "GOOG" is no longer hard-coded. It is defined only once, in the vector CollectionOfTickers and the entry of this vector is retrieved by using the variable IndexOfCurrentTicker which could represent a looping variable in a larger collection of tickers.
Edit
A variant of this code to perform a loop over several tickers could be programmed like this:
library(quantmod)
CollectionOfTickers <- c("GOOG","AAPL","TSLA","MSFT")
for (TickerName in CollectionOfTickers) {
CurrentTicker <- getSymbols(TickerName, auto.assign=FALSE)
cat("========\nData for ticker ", TickerName,"\n")
## most recent close price:
print(Cl(last(CurrentTicker)))
CurrentTickerFinancials <- getFinancials(TickerName, auto.assign=FALSE)
## total equity:
print(viewFinancials(CurrentTickerFinancials, type='BS', period='A',subset = NULL)['Total Equity',1])
## Net Income:
print(viewFinancials(CurrentTickerFinancials, type='IS', period='Q',subset = NULL)['Net Income',1])
cat("========\n")
}
The code quality could be improved by some further refactoring, but in any case this should work.
Hope this helps.
I think this is what you want. If you need something else...post back...
require(XML)
require(plyr)
getKeyStats_xpath <- function(symbol) {
yahoo.URL <- "http://finance.yahoo.com/q/ks?s="
html_text <- htmlParse(paste(yahoo.URL, symbol, sep = ""), encoding="UTF-8")
#search for <td> nodes anywhere that have class 'yfnc_tablehead1'
nodes <- getNodeSet(html_text, "/*//td[#class='yfnc_tablehead1']")
if(length(nodes) > 0 ) {
measures <- sapply(nodes, xmlValue)
#Clean up the column name
measures <- gsub(" *[0-9]*:", "", gsub(" \\(.*?\\)[0-9]*:","", measures))
#Remove dups
dups <- which(duplicated(measures))
#print(dups)
for(i in 1:length(dups))
measures[dups[i]] = paste(measures[dups[i]], i, sep=" ")
#use siblings function to get value
values <- sapply(nodes, function(x) xmlValue(getSibling(x)))
df <- data.frame(t(values))
colnames(df) <- measures
return(df)
} else {
# break
cat("Could not find",symbol,"\n")
return(data.frame(NA))
}
}
tickers <- c("AXP","BA","CAT","CSCO","CVX","DD","DIS","GE","GS","HD","IBM","INTC","JNJ","JPM","KO","MCD","MMM","MRK","MSFT","NKE","PFE","PG","T","TRV","UNH","UTX","V","VZ","WMT","XOM")
stats <- ldply(tickers, getKeyStats_xpath)
stats <- stats[!rowSums(is.na(stats)) == length(stats),]
rownames(stats) <- tickers
write.csv(t(stats), "FinancialStats_updated.csv",row.names=TRUE)
This is a newbie question in R. I am downloading yahoo finance monthly stock price data using R where the ticker names are read from a text file. I am using a loop to read the ticker names to download the data and putting them in a list. My problem is some ticker names may not be correct thus my code stops when it encounters this case. I want the following.
skip the ticker name if it is not correct.
Each element in the list is a dataframe. I want the ticker names to be appended to variable names in element dataframes.
I need an efficient way to create a dataframe that has the closing prices as variables.
Here is the sample code for the simplified version of my problem.
library(tseries)
tckk <- c("MSFT", "C", "VIA/B", "MMM") # ticker names defined
numtk <- length(tckk);
ustart <- "2000-12-30";
uend <- "2007-12-30" # start and end date
all_dat <- list(); # empty list to fill in the data
for(i in 1:numtk)
{
all_dat[[i]] <- xxx <- get.hist.quote(instrument = tckk[i], start=ustart, end=uend, quote = c("Open", "High", "Low", "Close"), provider = "yahoo", compression = "m")
}
The code stops at the third entry but I want to skip this ticker and move on to "MMM". I have heard about Trycatch() function but do not know how to use it.
As per question 2, I want the variable names for the first element of the list to be "MSFTopen", "MSFThigh", "MSFTlow", and "MSFTclose". Is there a better to way to do it apart from using a combination of loop and paste() function.
Finally, for question 3, I need a dataframe with three columns corresponding to closing prices. Again, I am trying to avoid a loop here.
Thank you.
Your best bet is to use quantmod and store the results as a time series (in this case, it will be xts):
library(quantmod)
library(plyr)
symbols <- c("MSFT","C","VIA/B","MMM")
#1
l_ply(symbols, function(sym) try(getSymbols(sym)))
symbols <- symbols[symbols %in% ls()]
#2
sym.list <- llply(symbols, get)
#3
data <- xts()
for(i in seq_along(symbols)) {
symbol <- symbols[i]
data <- merge(data, get(symbol)[,paste(symbol, "Close", sep=".")])
}
This also a little late...If you want to grab data with just R's base functions without dealing with any add-on packages, just use the function read.csv(URL), where the URL is a string pointing to the right place at Yahoo. The data will be pulled in as a dataframe, and you will need to convert the 'Date' from a string to a Date type in order for any plots to look nice. Simple code snippet is below.
URL <- "http://ichart.finance.yahoo.com/table.csv?s=SPY"
dat <- read.csv(URL)
dat$Date <- as.Date(dat$Date, "%Y-%m-%d")
Using R's base functions may give you more control over the data manipulation.
I'm a little late to the party, but I think this will be very helpful to other late comers.
The stockSymbols function in TTR fetches instrument symbols from nasdaq.com, and adjusts the symbols to be compatible with Yahoo! Finance. It currently returns ~6,500 symbols for AMEX, NYSE, and NASDAQ. You could also take a look at the code in stockSymbols that adjusts tickers to be compatible with Yahoo! Finance to possibly adjust some of the tickers in your file.
NOTE: stockSymbols in the version of TTR on CRAN is broken due to a change on nasdaq.com, but it is fixed in the R-forge version of TTR.
I do it like this, because I need to have the historic pricelist and a daily update file in order to run other packages:
library(fImport)
fecha1<-"03/01/2009"
fecha2<-"02/02/2010"
Sys.time()
y <- format(Sys.time(), "%y")
m <- format(Sys.time(), "%m")
d <- format(Sys.time(), "%d")
fecha3 <- paste(c(m,"/",d,"/","20",y), collapse="")
write.table(yahooSeries("GCI", from=fecha1, to=fecha2), file = "GCI.txt", sep="\t", quote = FALSE, eol="\r\n", row.names = TRUE)
write.table(yahooSeries("GCI", from=fecha2, to=fecha3), file = "GCIupdate.txt", sep="\t", quote = FALSE, eol="\r\n", row.names = TRUE)
GCI <- read.table("GCI.txt")
GCI1 <- read.table("GCIupdate.txt")
GCI <- rbind(GCI1, GCI)
GCI <- unique(GCI)
write.table(GCI, file = "GCI.txt", sep="\t", quote = FALSE, eol="\r\n", row.names = TRUE)
If your ultimate goal is to get the data.frame of three columns of closing prices, then the new package tidyquant may be better suited for this.
library(tidyquant)
symbols <- c("MSFT", "C", "VIA/B", "MMM")
# Download data in tidy format.
# Will remove VIA/B and warn you.
data <- tq_get(symbols)
# Ticker symbols as column names for closing prices
data %>%
select(.symbol, date, close) %>%
spread(key = .symbol, value = close)
This will scale to any number of stocks, so the file of 1000 tickers should work just fine!
Slightly modified from the above solutions... (thanks Shane and Stotastic)
symbols <- c("MSFT", "C", "MMM")
# 1. retrieve data
for(i in seq_along(symbols)) {
URL <- paste0("http://ichart.finance.yahoo.com/table.csv?s=", symbols[i])
dat <- read.csv(URL)
dat$Date <- as.Date(dat$Date, "%Y-%m-%d")
assign(paste0(symbols[i]," _data"), dat)
dat <- NULL
}
Unfortunately, URL "ichart.finance.yahoo.com" is dead and not working now. As I know, Yahoo closed it and it seems it will not be opened.
Several days ago I found nice alternative (https://eodhistoricaldata.com/) with an API very similar to Yahoo Finance.
Basically, for R-script described above you just need to change this part:
URL <- paste0("ichart.finance.yahoo.com/table.csv?s=", symbols[i])
to this:
URL <- paste0("eodhistoricaldata.com/api/table.csv?s=", symbols[i])
Then add an API key and it will work in the same way as before. I saved a lot of time for my R-scripts on it.
Maybe give the BatchGetSymbols library a try. What I like about it over quantmod is that you can specify a time period for your data.
library(BatchGetSymbols)
# set dates
first.date <- Sys.Date() - 60
last.date <- Sys.Date()
freq.data <- 'daily'
# set tickers
tickers <- c('FB','MMM','PETR4.SA','abcdef')
l.out <- BatchGetSymbols(tickers = tickers,
first.date = first.date,
last.date = last.date,
freq.data = freq.data,
cache.folder = file.path(tempdir(),
'BGS_Cache') ) # cache in tempdir()