QuantMod: How do I get data in a tabular format? - r

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.

Related

Downloading multiple stock monthly prices with R using quantmod

I am trying to get stock prices of multiple tickers over long period, collecting them in a dataframe.
Here goes my code
library('quantmod')
symbol1 = c('SPY', # S$P500
'IEF', # 10Y treasury bond
'TLT', # 20Y treasury bond
'AGG', # Core U.S Aggregate Bond
'SHY', # Cash
'GLD', # Gold
'IWN') # Russell 2000 value
price = function(symbols){
loadSymbols(symbols, src = 'yahoo', from= '2000-11-01', periodicity = 'monthly')
prices = list()
for (i in 1:length(symbols)) {
prices[[i]] = Ad(get(symbols[i])[,6])
}
prices = do.call(cbind, prices)
colnames(prices) = gsub('\\.[A-z]*', '',colnames(prices))
prices = na.omit(prices)
return(prices)
}
a = price(symbol1)
I have two problems,
Error messages
To much differences between monthly prices
How can I solve this problems?
or is there any better and neat code to get time series monthly data (adjusted price) of multiple tickers?
Warnings about missing values:
If you take a look at one of the tickers,
loadSymbols('SPY', src = 'yahoo', from= '2000-11-01', periodicity = 'monthly')
> SPY[is.na(SPY$SPY.Open),]
SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted
2021-02-01 NA NA NA NA NA NA
You will notice that the Yahoo API has returned a missing value for month of 2021-02-01. This makes sense, because you have requested monthly averages, which you cannot calculate for the ongoing month.
You would want to filter your data to exclude the ongoing month. For instance, this runs without errors:
loadSymbols(symbols, src = 'yahoo', from= '2000-11-01',to='2021-01-31', periodicity = 'monthly')
Regarding your second issue, I was not able to replicate that:
a = price(symbol1)
a %>% tail(10)
SPY IEF TLT AGG SHY GLD IWN
2020-04-01 286.8316 120.6718 164.8157 115.0776 86.24834 158.80 90.90018
2020-05-01 300.4978 121.0832 161.9357 115.8682 86.21467 162.91 93.73619
2020-06-01 304.4870 121.1411 162.4827 116.6548 86.23647 167.37 95.97152
2020-07-01 323.8377 122.1878 169.7082 118.2020 86.32609 185.43 98.42319
2020-08-01 346.4406 121.0134 161.1535 117.2467 86.31715 184.83 103.70540
2020-09-01 332.1390 121.4210 162.3971 117.1425 86.31710 177.12 98.25503
2020-10-01 325.1540 119.7535 156.9142 116.4811 86.28612 176.20 102.47127
2020-11-01 360.5232 120.1606 159.5191 117.8953 86.30606 166.67 122.00240
2020-12-01 372.2931 119.7973 157.4051 117.8594 86.31503 178.36 131.08641
2021-01-01 370.0700 118.6400 152.0000 117.3100 86.40000 172.61 138.39999
Nonetheless, comparison to this chart clearly shows that the values you attached for TLT prior to 2021-02-01 are wrong.

How to merge stock prices?

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())

Calculate return for a set of securities downloaded using quantmod

I downloaded adjusted closing price using quantmod for a set of securities. I want to calculate daily/weekly/monthly return for all securities. Usual dailyReturn, weeklyReturn etc not working. What do I need to do? Here is my code.
tickers <- c('FB','MMM')
data_env <- new.env()
getSymbols(Symbols = tickers, env = data_env)
tempPort <- do.call(merge, eapply(data_env, Ad))
head(tempPort )
MMM.Adjusted FB.Adjusted
2007-01-03 57.00983 NA
2007-01-04 56.78401 NA
2007-01-05 56.39790 NA
2007-01-08 56.52174 NA
2007-01-09 56.58731 NA
2007-01-10 56.71116 NA
head(weeklyReturn(tempPort, type = 'log', leading=TRUE))
weekly.returns
2012-05-18 -0.010791856
2012-05-25 0.015093078
2012-06-01 -0.023027534
2012-06-08 0.037315263
2012-06-15 0.016605617
2012-06-22 -0.007000966
I want data with returns for MMM and FB in two different columns. In my actual problem I have 50+ tickers. Hence calculating returns individually is not a solution.
Do it in a loop as such:
library(PerformanceAnalytics)
prices <- list()
returns <- list()
for(i in 1:length(tickers)) {
getSymbols(tickers[i], adjusted = TRUE, output.size = "full")
prices[[i]] <- Ad(get(tickers[i])) # Gets the adjusted close column
ret <- Return.calculate(Ad(get(tickers[i])), method = "log")
returns[[i]] <- ret # Adds return calculation to the list
}
Also consider using the alpha vantage api. You would need to go to their site and get an api key, and set source='av' in the getSymbols() function call.
Then, merge your data afterwords like this:
returns <- do.call(cbind, returns)
You can use the quantmod add-in package qmao which has a built-in RF (stands for return frame) which does what you want. Assuming you have downloaded FB and AMZN this is the line to use:
library(qmao)
rets <- RF(c(‘FB’,’AMZN’), silent = TRUE, type = ‘discrete )
> tail(rets)
FB AMZN
2019-05-10 -0.001643 -0.005206
2019-05-13 -0.036105 -0.035609
2019-05-14 -0.004462 0.009568
2019-05-15 0.030654 0.016863
2019-05-16 0.003865 0.019464
2019-05-17 -0.009038 -0.020219
Have a look at ?RF to check the available argument options.

Quantmod: Create new column for multiple tickers in one time

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

Changing symbol in quantmod code

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

Resources