I have the following code that creates a stock chart using data from Yahoo using the R package quantmod. The symbol retrieved in the code is "KR" in my example.
How can I change the code so that I can retrieve other stock symbols without having to replace each incidence of "KR" with the new stock symbol?
library(quantmod)
library(TTR)
getSymbols("KR", src="yahoo")
KR <- adjustOHLC(KR, use.Adjusted=TRUE)
KR.EMA.9<- EMA(KR$KR.Close, n=5)
KR.EMA.34<- EMA(KR$KR.Close, n=50)
KR.EMA.200 <- EMA(KR$KR.Close, n=200)
candleChart(KR, theme="white",
subset='2015-09::2015-10')
addTA(KR.EMA.9, on=1, col = "red")
addTA(KR.EMA.34, on=1, col = "blue")
addTA(KR.EMA.9 - KR.EMA.34,col='blue', type='h',legend="9-34 MA")
This can be achieved with the option auto.assign=FALSE. Here's an example.
library(quantmod)
my_tickers <- c("KR","AAPL", "MSFT") #store the tickers in a vector
my_xts <- getSymbols(my_tickers[1], src="yahoo", auto.assign=FALSE)
tail(my_xts)
# KR.Open KR.High KR.Low KR.Close KR.Volume KR.Adjusted
#2016-03-16 37.87 38.69 37.82 38.61 6208100 38.61
#2016-03-17 38.45 38.56 37.98 38.09 9445400 38.09
#2016-03-18 38.14 38.88 38.00 38.56 9809000 38.56
#2016-03-21 38.38 38.60 38.09 38.13 5911400 38.13
#2016-03-22 38.18 38.32 37.69 37.95 7988000 37.95
#2016-03-23 37.92 38.02 37.35 37.59 9089000 37.59
The same code can be used to select another ticker by just changing the index of my_tickers[]:
my_xts <- getSymbols(my_tickers[2], src="yahoo", auto.assign=FALSE)
tail(my_xts)
# AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
#2016-03-16 104.61 106.31 104.59 105.97 37893800 105.97
#2016-03-17 105.52 106.47 104.96 105.80 34244600 105.80
#2016-03-18 106.34 106.50 105.19 105.92 43402300 105.92
#2016-03-21 105.93 107.65 105.14 105.91 35180800 105.91
#2016-03-22 105.25 107.29 105.21 106.72 32232600 106.72
#2016-03-23 106.48 107.07 105.90 106.13 25452600 106.13
Therefore the code could be run, for example, with a loop of the type
for (i in 1:length(my_tickers)) {
my_xts <- getSymbols(my_tickers[i], src="yahoo", auto.assign=FALSE)
# perform analysis of the time series my_xts here
}
The closing price can be selected using Cl() (there are corresponding functions to select other columns, see ?OHLC.Transformations for more details).
It is thereby possible to calculate the EMA and other indicators based on the close data like this:
EMA.9 <- EMA(Cl(my_xts), 9)
tail(EMA.9)
# EMA
#2016-03-16 102.6959
#2016-03-17 103.3167
#2016-03-18 103.8374
#2016-03-21 104.2519
#2016-03-22 104.7455
#2016-03-23 105.0224
Related
I downloaded 50 stocks and their prices. I would like to merge all those 50 stocks into one sample. How can I do that? My current code is (for 3 stocks):
library("PerformanceAnalytics")
library("tseries")
library("zoo")
library("quantmod")
#
getSymbols("AAPL")
getSymbols("ABBV")
getSymbols("ABT")
... etcetera
#
price_AAPL <- AAPL$AAPL.Close
price_ABBV <- ABBV$ABBV.Close
price_ABT <- ABT$ABT.Close
... etcetera
###
Thus, I would like to merge those "price_xxx". How can I do that ?
Here is what price_AAPL looks like
Thank you very much!
You can use Reduce with merge :
out <- Reduce(merge, mget(ls(pattern = "price_")))
out
# AAPL.Close ABBV.Close ABT.Close
#2007-01-03 11.97143 NA 23.49581
#2007-01-04 12.23714 NA 23.94202
#2007-01-05 12.15000 NA 23.94202
#2007-01-08 12.21000 NA 24.02838
#2007-01-09 13.22429 NA 24.23950
#2007-01-10 13.85714 NA 24.17712
#...
#...
1) Download the quotes into an environment stockEnv and then eapply over that using Cl to extract the closes and use merge to merge the result together giving the xts object stockCl . Note that unlike base merge, here multi-way merge is supported.
(Also, full ticker data for particular stocks can be accessed using, for example, stockEnv$AAPL. Use Ad in place of Cl if you want the adjusted close.)
library(quantmod)
symbolList <- c("AAPL","ABBV","ABT","IBM","MSFT","GOOG")
getSymbols(symbolList, env = stockEnv <- new.env())
stockCl <- do.call("merge", eapply(stockEnv, Cl))
2) Alternately download the symbols directly into the workspace, apply Cl to each and merge:
library(quantmod)
symbolList <- c("AAPL","ABBV","ABT","IBM","MSFT","GOOG")
getSymbols(symbolList)
stockCl <- do.call("merge", lapply(mget(symbolList), Cl))
Here's a Base R solution that automates download of a set of symbols, merges and renames the close to price_symbol
library("PerformanceAnalytics")
library("tseries")
library("zoo")
library("quantmod")
#
symbolList <- c("AAPL","ABBV","ABT","IBM","MSFT","GOOG")
prices <- lapply(symbolList,function(x){
getSymbols(x,auto.assign = FALSE)[,4]
})
priceData <- do.call(merge,prices)
names(priceData) <- paste0("price_",symbolList)
head(priceData)
...and the output:
> head(priceData)
price_AAPL price_ABBV price_ABT price_IBM price_MSFT price_GOOG
2007-01-03 11.97143 NA 23.49581 97.27 29.86 232.9220
2007-01-04 12.23714 NA 23.94202 98.31 29.81 240.7277
2007-01-05 12.15000 NA 23.94202 97.42 29.64 242.6853
2007-01-08 12.21000 NA 24.02838 98.90 29.93 240.8871
2007-01-09 13.22429 NA 24.23950 100.07 29.96 241.8435
2007-01-10 13.85714 NA 24.17712 98.89 29.66 243.8161
>
By default, data returned by getSymbols is returned to the default environment. However, with auto.assign = FALSE, results are explicitly returned as an xts time series. Using this approach, a possible solution is:
library(quantmod)
tickers <- c("AAPL", "ABBV", "ABT")
prices <- xts()
for( ticker in tickers) prices <- merge(prices, getSymbols(ticker, auto.assign = FALSE)[,4])
A variation using Reduce rather than the for loop:
library(quantmod)
tickers <- c("AAPL", "ABBV", "ABT")
prices <- Reduce(f = function(x,y) { xx = getSymbols(y, auto.assign = FALSE)[,4]; merge(x, xx) },
x = tickers, init = xts())
I created a for loop for 100 companies and plotted Bollinger bands, volume, commodity channel index, MACD, and relative strength index. For all the metrics I mentioned how can I convert that table into a table?
For loop Script:
for (stock in ls(stockEnv)){
chartSeries(stockEnv[[stock]], theme="white", name=stock,
TA="addVo();addBBands();addCCI();addSMA(20, col='blue');
addSMA(5, col='red');addMACD();addRSI();addROC()", subset='last 30 days')
}
The plot is attached. What I am trying to do is bind all the data together for the other 99 stock tickers I have into a tabular format for the metrics you see in the image.
I found your code was sourced from this SO answer.
I think this approach should work for you.
library(quantmod)
library(data.table)
stockEnv <- new.env()
stocks <- c("AAPL","MSFT","FB")
getSymbols(stocks, src='yahoo', env=stockEnv)
datalist <- list()
for(stock in ls(stockEnv)){
table <- as.data.frame(stockEnv[[stock]])
date = rownames(table)
rownames(table) <- NULL
colnames(table) <- c("Open","High","Low","Close","Volume","Adjusted")
bound.table <- data.frame(Symbol = stock, date ,table)
datalist[[stock]] <- bound.table
}
Result <- rbindlist(datalist,fill=TRUE)
Result
# Symbol date Open High Low Close Volume Adjusted
# 1: AAPL 2007-01-03 12.32714 12.36857 11.70000 11.97143 309579900 10.39169
# 2: AAPL 2007-01-04 12.00714 12.27857 11.97429 12.23714 211815100 10.62234
# 3: AAPL 2007-01-05 12.25286 12.31428 12.05714 12.15000 208685400 10.54669
# 4: AAPL 2007-01-08 12.28000 12.36143 12.18286 12.21000 199276700 10.59878
# 5: AAPL 2007-01-09 12.35000 13.28286 12.16429 13.22429 837324600 11.47922
# ---
#8652: MSFT 2020-03-30 152.44000 160.60001 150.01000 160.23000 63420300 160.23000
#8653: MSFT 2020-03-31 159.39999 164.78000 156.56000 157.71001 77927200 157.71001
#8654: MSFT 2020-04-01 153.00000 157.75000 150.82001 152.11000 57969900 152.11000
#8655: MSFT 2020-04-02 151.86000 155.48000 150.36000 155.26000 49630700 155.26000
#8656: MSFT 2020-04-03 155.10001 157.38001 152.19000 153.83000 41212700 153.83000
These lines of code will add the Bollinger bands.
Result[,(c("dn","mavg","up","pctB")):=
apply(BBands(.SD),2,function(x){as.list(x)}),
by = "Symbol",
.SDcols = c("High","Low","Close")]
You can also easily add any of the other TTR functions results. You just need to know the columns it accepts as inputs and how many it outputs.
For MACD:
Result[,(c("macd","signal")):=
apply(MACD(.SD,type="EMA"),2,function(x){as.list(x)}),
by = "Symbol",
.SDcols = c("Close")]
Note there is a slight variation for single column outputs like CCI.
Thus, for Commodity Channel Index.
Result[,(c("CCI")):= list(as.vector(CCI(.SD))),by = "Symbol", .SDcols = c("High","Low","Close")]
Or for Relative Strength Index
Result[,(c("RSI")):= list(as.vector(RSI(.SD, maType="EMA"))),by = "Symbol", .SDcols = c("Close")]
See the help for all other TTR functions, help(SMA) for example.
So, I want to download an index's data but can't get the data. The problem is that Yahoo.finance sees index's tickers as having a ^ before them, for example, ^VIX not VIX. Unfotunentally, my code doesn't like that. I can't find any functions or alternative ways to call this data. Also, I really don't want to change the platform from which I get my data from, that would be a HUGE pain in the butt for the rest of my code.
I have tried putting in the ^ with the asset, and it won't download data. I've also tried calling the data without the ^ and that gives the wrong data.
asset <- "VIX"
ticker <- "VIX"
start.date <- as.Date('2009-09-01')
getSymbols(ticker, src='yahoo', from=start.date)
Adj.Close <- get(ticker)[,6]
When I put this in I end up getting this message:
Error in get(ticker) : object '^VIX' not found
Thank you for your time, regardless of whether or not you know a solution.
I cannot confirm your issue. There is no need here for a leading "^" symbol.
Running
library(quantmod)
ticker <- "VIX"
start.date <- as.Date('2009-09-01')
getSymbols(ticker, src='yahoo', from=start.date)
will automatically store the output in an xts object called VIX
head(get(ticker))
# VIX.Open VIX.High VIX.Low VIX.Close VIX.Volume VIX.Adjusted
#2014-12-04 28200.4 30096.9 27953.0 28447.7 811330 28447.7
#2014-12-05 26551.2 27540.7 25974.0 26056.5 377529 26056.5
#2014-12-08 25231.9 26056.5 23582.8 23582.8 367585 23582.8
#2014-12-09 23582.8 23582.8 21274.0 21274.0 570963 21274.0
#2014-12-10 19789.7 20202.0 19212.5 19295.0 539795 19295.0
#2014-12-11 18635.3 19295.0 17398.5 17728.3 1053637 17728.3
Note that can you avoid the get step if you avoid auto-assigning the output of getSymbols to the current environment:
res <- getSymbols("VIX", src='yahoo', from=start.date, auto.assign = FALSE)
I assume Maurits seeks data for the VIX Index, in which case I find it necessary to include the carat in the ticker. Building on the previous answer we can see that a valid object is returned when we use the "^VIX" ticker.
library(quantmod)
start.date <- as.Date('2009-09-01')
ticker <- "^VIX"
getSymbols(ticker, src='yahoo', from=start.date)
[1] "^VIX"
However, getis unable to find that object:
head(get(ticker))
Error in get(ticker) : object '^VIX' not found
But, using "VIX" rather than "^VIX" with getreturns the desired result:
head(get("VIX"))
VIX.Open VIX.High VIX.Low VIX.Close VIX.Volume VIX.Adjusted
2009-09-01 26.01 29.23 26.00 29.15 0 29.15
2009-09-02 29.14 29.57 28.41 28.90 0 28.90
2009-09-03 28.90 28.90 26.98 27.10 0 27.10
2009-09-04 26.98 26.98 24.86 25.26 0 25.26
2009-09-08 25.26 26.15 25.26 25.62 0 25.62
2009-09-09 25.66 25.93 24.23 24.32 0 24.32
I've my own csv file with a list of stocks that I use to download tickers data from yahoo.
For that purpose I use the following code(Correct):
library(quantmod)
Tickers <- read.csv("nasdaq_tickers_list.csv", stringsAsFactors = FALSE)
getSymbols(Tickers$Tickers,from="2018-01-01", src="yahoo" )
The result is that 55 tickers have been loaded correctly.
Now I'd like to make some calculations, I need to create a new column on each ticker with the substract of the (High Price - Open Price)
I need something like this, for example AABA ticker:
New column name= AABA.Range
AABA.Range =(AABA$AABA.High - AABA$AABA.Open)
How can I get this applied and get a new column for the 55 tickers?
I was able to create the new column one by one, but how to do it for all of them with one function?
Is that possible?
Thanks a lot for your help.
One of the problems you have is that all the stock information is in the global environment. So first we need to pull all of them into a giant list. Next I created a range function that returns the stock data plus the range column with the correct name.
# Put all stocks in big list, by checking which xts objects are in the global environment.
stock_data = sapply(.GlobalEnv, is.xts)
all_stocks <- do.call(list, mget(names(stock_data)[stock_data]))
# range function
stock_range <- function(x) {
stock_name <- stringi::stri_extract(names(x)[1], regex = "^[A-Z]+")
stock_name <- paste0(stock_name, ".range")
column_names <- c(names(x), stock_name)
x$range <- quantmod::Hi(x) - quantmod::Lo(x)
x <- setNames(x, column_names)
return(x)
}
# calculate all ranges and add them to the data
all_stocks <- lapply(all_stocks, stock_range)
head(all_stocks$MSFT)
MSFT.Open MSFT.High MSFT.Low MSFT.Close MSFT.Volume MSFT.Adjusted MSFT.range
2007-01-03 29.91 30.25 29.40 29.86 76935100 22.67236 0.850000
2007-01-04 29.70 29.97 29.44 29.81 45774500 22.63439 0.529998
2007-01-05 29.63 29.75 29.45 29.64 44607200 22.50531 0.299999
2007-01-08 29.65 30.10 29.53 29.93 50220200 22.72550 0.569999
2007-01-09 30.00 30.18 29.73 29.96 44636600 22.74828 0.450000
2007-01-10 29.80 29.89 29.43 29.66 55017400 22.52049 0.459999
It might be better that when you load the data just run a lapply to get all the data in a list. That way the first step is not needed and you can use all the TTR functions with lapply (or Map)
my_stock_data <- lapply(Tickers , getSymbols, auto.assign = FALSE)
names(my_stock_data) <- Tickers
I download some stock data with quantmod and retrieve the closing prices:
require(quantmod)
tickers<-c('AAPL','GOOGL')
getSymbols(tickers, from="2014-03-01")
close <- do.call(merge, lapply(tickers, function(x) Cl(get(x))))
head(close)
AAPL.Close GOOGL.Close
2014-03-03 527.76 1202.69
2014-03-04 531.24 1214.91
2014-03-05 532.36 1218.26
2014-03-06 530.75 1219.61
2014-03-07 530.44 1214.79
2014-03-10 530.92 1211.57
Is there a way to run getSymbols so that the most recent dates output is first?
The final result is the xts object. xts is "fanatic" about order. But you can access the data with function coredata (for data part) and time for time vector.
Try for example:
res <- data.frame( time = time(close), coredata(close))
res <- res[nrow(res):1,]