Quantmod: Create new column for multiple tickers in one time - r

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

Related

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

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

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.

How do I use an extracted string to call an xts data object?

I want to use a string of stock symbols and loop through it pulling pairs into a block of code for analysis. I can get the loop to pull in the data but then I want to assign the data to a generic data element so I can just run it through my code. Can't get hold of the xts object from the list programmatically and get it to execute - just returns the value.
library(quantmod)
library(xts)
asset1 = "ADBE"
asset2 = "VGT"
assets <- c(asset1, asset2)
assets # This returns [1] "ADBE "VGT"
getSymbols(assets[1]) # All good so far this returns an xts object [1:3247] [1:6] called ADBE
Manually if I enter:
df01 = ADBE # This makes df01 the same as the data values for ADBE.
df01 <- assets[1] # makes df01 a character string equal to "ADBE"
Question:
How do I make the df01 = ADBE piece happen programmatically using the values in assets. When I use assets[1] it fails and as I don't want to type the stock codes every time but assign it and as I loop through a list of assets(n) using generic code.
I realise this is probably a simple dumb question but its got me stumped and cannot find a solution on-line.
Keep the results in one list, by default getSymbols assigns every asset into the environment, we can change this by using auto.assign = FALSE, example:
myResult <- lapply(assets, getSymbols, auto.assign = FALSE)
myResult <- setNames(myResult, assets)
# access using names
myResult$ADBE
# ADBE.Open ADBE.High ADBE.Low ADBE.Close ADBE.Volume ADBE.Adjusted
# 2007-01-03 40.72 41.32 38.89 39.92 7126000 39.92
# ...
# or using a variable
assets[ 1 ]
# [1] "ADBE"
myResult[[ assets[ 1 ] ]]
# ADBE.Open ADBE.High ADBE.Low ADBE.Close ADBE.Volume ADBE.Adjusted
# 2007-01-03 40.72 41.32 38.89 39.92 7126000 39.92
# ...
If we do not wish to keep them in a list, then maybe use get:
getSymbols(assets)
df01 <- get(assets[ 1 ])
df01
# ADBE.Open ADBE.High ADBE.Low ADBE.Close ADBE.Volume ADBE.Adjusted
# 2007-01-03 40.72 41.32 38.89 39.92 7126000 39.92
# ...

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.

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