How to reverse chronological order with getSymbols in R - r

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,]

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

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

quantmod : can't generate daily returns for stock using OHLC

I'm attempting to get daily returns by using one BDH pull, but I can't seem to get it to work. I considered using quantmod's periodreturn function, but to no avail. I'd like the PctChg column populated, and any help is greatly appreciated.
GetReturns <- function(ticker, calctype, voldays) {
check.numeric <- function(N){
!length(grep("[^[:digit:]]", as.character(N)))}
isnumber <- function(x) is.numeric(x) & !is.na(x)
startdate <- Sys.Date()-20
enddate <- Sys.Date()
###############
GetData <- BBGPull <- bdh(paste(ticker," US EQUITY"), c("Open","High","Low","PX_Last"), startdate, enddate,
include.non.trading.days = FALSE, options = NULL, overrides = NULL,
verbose = FALSE, identity = NULL, con = defaultConnection())
##Clean Up Columns and Remove Ticker
colnames(GetData) <- c("Date","Open","High","Low","Close")
GetData[,"PctChg"] <- "RETURN" ##Hoping to populate this column with returns
GetData
}
I'm not married to the idea of using quantmod, and even would use LN(T/T-1) but im just unsure how to add a column with this data. Thank you !
You missed the (important) fact that bdh() still returns a data.frame object you need to transform first:
R> library(Rblpapi)
Rblpapi version 0.3.5 using Blpapi headers 3.8.8.1 and run-time 3.8.8.1.
Please respect the Bloomberg licensing agreement and terms of service.
R> spy <- bdh("SPY US EQUITY", c("Open","High","Low","PX_Last"), \
+ Sys.Date()-10, Sys.Date())
R> class(spy)
[1] "data.frame"
R> head(spy)
date Open High Low PX_Last
1 2016-12-05 220.65 221.400 220.420 221.00
2 2016-12-06 221.22 221.744 220.662 221.70
3 2016-12-07 221.52 224.670 221.380 224.60
4 2016-12-08 224.57 225.700 224.260 225.15
5 2016-12-09 225.41 226.530 225.370 226.51
6 2016-12-12 226.40 226.960 225.760 226.25
R> sx <- xts(spy[, -1], order.by=spy[,1])
R> colnames(sx)[4] <- "Close" ## important
R> sxret <- diff(log(Cl(sx)))
R> head(sxret)
Close
2016-12-05 NA
2016-12-06 0.00316242
2016-12-07 0.01299593
2016-12-08 0.00244580
2016-12-09 0.00602225
2016-12-12 -0.00114851
R> sxret <- ClCl(sx) ## equivalent shorthand using quantmod
This also uses packages xts and quantmod without explicitly loading them.

Create a trading day calendar from scratch

I just spent a day debugging some R code only to find that the problem I was having was caused by a missing date in the data returned by Yahoo using getSymbol. At the time I write this Yahoo is returning this:
QQQ.Open QQQ.High QQQ.Low QQQ.Close QQQ.Volume QQQ.Adjusted
2014-01-03 87.27 87.35 86.62 86.64 35723700 86.64
2014-01-06 86.66 86.76 86.00 86.32 32073100 86.32
2014-01-07 86.72 87.25 86.56 87.12 25860600 87.12
2014-01-08 87.14 87.55 86.95 87.31 27197400 87.31
2014-01-09 87.63 87.64 86.72 87.02 23674700 87.02
2014-01-13 87.18 87.48 85.68 86.01 48842300 86.01
2014-01-14 86.30 87.72 86.30 87.65 37178900 87.65
2014-01-15 88.03 88.54 87.94 88.37 39835600 88.37
2014-01-16 88.30 88.51 88.16 88.38 31630100 88.38
2014-01-17 88.11 88.37 87.67 87.88 36895800 87.88
which is missing 2014-01-10. That date is returned for other ETFs. I expect that Yahoo will fix the data one of these days (the data is on Google) but for now it is wrong which caused my code some fits.
To address this issue I want to check my data to ensure that there is data for all dates the markets were open. If there's a canned way to do this in some package I'd appreciate info on that but to that end I started writing some code using the timeDate package. However I have ended up with xts index questions I don't understand. The code follows:
library(timeDate)
library(quantmod)
MyZone = "UTC"
Sys.setenv(TZ = MyZone)
YearStart = "1990"
YearEnd = "2014"
currentYear = getRmetricsOptions("currentYear")
dateStart = paste0(YearStart, "-01-01")
dateEnd = paste0(YearEnd, "-12-31")
DayCal = timeSequence(from = dateStart, to = dateEnd, by="day", zone = MyZone)
TradingCal = DayCal[isBizday(DayCal, holidayNYSE())]
testSym = "QQQ"
getSymbols(testSym, src="yahoo", from = dateStart, to = dateEnd)
testData = get(testSym)
head(testData)
tail(testData, n=10)
#Save date range of data being checked
firstIndex = index(testData)[1]
lastIndex = index(testData)[nrow(testData)]
#Create an xts series covering all dates
AllDates = xts(x=rep(1, length.out=length(TradingCal)),
order.by=TradingCal, tzone = MyZone)
head(AllDates)
tail(AllDates)
index(AllDates)[1:20]
index(testData)[1:20]
tzone(AllDates)
tzone(testData)
#Create an xts object that has all dates covered
#by testSym but using calendar I created
CheckData = subset(AllDates, ((index(AllDates)>=firstIndex) &&
(index(AllDates)<=lastIndex))
)
class(index(AllDates))
class(index(testData))
The goal here was to create a 'known good calendar' which I could use to create a simple xts object. With that object I would then check whether every index in that object had a corresponding index in the data being tested. However I'm not getting that far as it appears my indexes are not compatible. When I run the code I get this at the end:
> CheckData = subset(AllDates, ((index(AllDates)>=firstIndex) && (index(AllDates)<=lastIndex))
+ )
Error in `>=.default`(index(AllDates), firstIndex) :
comparison (5) is possible only for atomic and list types
> class(index(AllDates))
[1] "timeDate"
attr(,"package")
[1] "timeDate"
> class(index(testData))
[1] "Date"
>
Can someone show me the errors of my ways here so that I can move forward? Thanks!
You need to convert TradingCal to Date:
TradingDates <- as.Date(TradingCal)
And here's another way to find index values in TradingDates that aren't in your testData index.
AllDates <- xts(,TradingDates)
testSubset <- paste(start(testData), end(testData), sep="/")
CheckData <- merge(AllDates, testData)[testSubset]
BadDates <- CheckData[is.na(rowSums(CheckData))]

Resources