I am not able to get OHLCV data from yahoo for current day using Quantmod getSymbols() call. The data exists on yahoo and can also see today's OHLCV data in my charting platform. As workaround I got today's EOD quote from yahoo using getQuote(..) call. But when I tried to append this to the downloaded symbol data via rbind, the data object gets populated with NULLs.
I appreciate any suggestions on either how to append the today's quote to the downloaded historic symbol data or any R API's I can call after market hours to get symbol EOD (OHLCV data) including for today. Thanks.
library(quantmod)
library(blotter)
library(PerformanceAnalytics)
getSymbols("SPY")
spy.quote = getQuote("SPY", what = yahooQuote.EOD)
> tail(SPY, n=3)
SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted
2012-10-25 142.02 142.28 140.57 141.43 134457400 141.43
2012-10-26 141.30 141.84 140.39 141.35 146023500 141.35
2012-10-31 141.85 142.03 140.68 141.35 103341300 141.35
> spy.quote
Trade Time Open High Low Close Volume
SPY 2012-11-01 04:00:00 141.65 143.01 141.52 142.83 100990760
> SPY = rbind(SPY, spy.quote)
> tail(SPY, n=3)
SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted
NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL
spy.quote NULL NULL NULL NULL NULL NULL
You need to convert the quote data from a data.frame to an xts object and add a column for Adjusted price. Then you can rbind.
getSymbols("SPY", src='yahoo', to='2012-10-31')
spy.quote = getQuote("SPY", what = yahooQuote.EOD)
# convert to xts
xts.quote <- xts(spy.quote[, -1], as.Date(spy.quote[, 1])) # use Date for indexClass
xts.quote$Adjusted <- xts.quote[, 'Close'] # add an Adjusted column
tail(rbind(SPY, xts.quote), 3)
SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted
2012-10-26 141.30 141.84 140.39 141.35 146023500 141.35
2012-10-31 141.85 142.03 140.68 141.35 103341300 141.35
2012-11-01 141.65 143.01 141.52 142.83 100995568 142.83
Related
quantmode newbie here,
My end goal is to have a CSV file including monthly stock prices, I've downloaded the data using getSymbols using this code:
Symbols <- c("DIS", "TSLA","ATVI", "MSFT", "FB", "ABT","AAPL","AMZN",
"BAC","NFLX","ADBE","WMT","SRE","T","MS")
Data <- new.env()
getSymbols(c("^GSPC",Symbols),from="2015-01-01",to="2020-12-01"
,periodicity="monthly",
env=Data)
the line above works fine, now I need to create a data frame that only includes the adjusted prices for all the symbols with a data column ofc,
any help, please? :)
Desired output would be something similar to this
enter image description here
Another straightforward way to get your monthly data:
tickers <- c('AMZN','FB','GOOG','AAPL')
getSymbols(tickers,periodicity="monthly")
head(do.call("merge.xts",c(lapply(mget(tickers),"[",,6),all=FALSE)),3)
AMZN.Adjusted FB.Adjusted GOOG.Adjusted AAPL.Adjusted
2012-06-01 228.35 31.10 288.9519 17.96558
2012-07-01 233.30 21.71 315.3032 18.78880
2012-08-01 248.27 18.06 341.2658 20.46477
Note the logical argument all = FALSE is the equivalent of an innerjoin and you get data when all of your stocks have prices. all = TRUE fills data which is not available with NAs (outerjoin).
To write the file you can use:
write.zoo(monthlyPrices,file = 'filename.csv',sep=',',quote=FALSE)
First get your data from the environment:
require(quantmod)
# your code
dat <- mget(ls(Data), env=Data)
Then draw the data from the Objects:
newdat <- as.data.frame(sapply( names(dat), function(x) coredata(dat[[x]])[,1] ))
Note that this takes the Opening values (see: dat[[x]])[,1]), the Objects have more, e.g.:
names(dat[["AAPL"]])
[1] "AAPL.Open" "AAPL.High" "AAPL.Low" "AAPL.Close"
[5] "AAPL.Volume" "AAPL.Adjusted"
Last, get the dates (assumes symmetric dates for all symbols):
rownames(newdat) <- index(dat[["AAPL"]])
# OR, more universal, by extracting from the complete list:
rownames(newdat) <-
as.data.frame( sapply( names(dat), function(x) as.character(index(dat[[x]])) ) )[,1]
head(newdat, 3)
AAPL ABT ADBE AMZN ATVI BAC DIS FB GSPC MS
2015-01-01 27.8475 45.25 72.70 312.58 20.24 17.99 94.91 78.58 2058.90 39.05
2015-02-01 29.5125 44.93 70.44 350.05 20.90 15.27 91.30 76.11 1996.67 33.96
2015-03-01 32.3125 47.34 79.14 380.85 23.32 15.79 104.35 79.00 2105.23 35.64
MSFT NFLX SRE T TSLA WMT
2015-01-01 46.66 49.15143 111.78 33.59 44.574 86.27
2015-02-01 40.59 62.84286 112.38 33.31 40.794 84.79
2015-03-01 43.67 67.71429 108.20 34.56 40.540 83.93
Writing the csv:
write.csv(newdat, "file.csv")
I am looking for a way to rename the columns of several objects with a for loop or other method in R. Ultimately, I want to be able to bind the rows of each Stock object into one large data frame, but cannot due to differing column names. Example below:
AAPL <-
Date AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted Stock pct_change
2020-05-14 304.51 309.79 301.53 309.54 39732300 309.54 AAPL 0.61
2020-05-15 300.35 307.90 300.21 307.71 41561200 307.71 AAPL -0.59
GOOG <-
Date GOOG.Open GOOG.High GOOG.Low GOOG.Close GOOG.Volume GOOG.Adjusted Stock pct_change
2020-05-14 1335.02 1357.420 1323.910 1356.13 1603100 1356.13 GOOG 0.50
2020-05-15 1350.00 1374.480 1339.000 1373.19 1705700 1373.19 GOOG 1.26
For this example I have 2 objects (AAPL and GOOG), but realistically I would be working with many more. Can I create a for loop to iterate through each object, and rename the 2nd column of each to "Open", 3rd column to "High", 4th column to "Low",.... etc so I can then bind all these objects together?
I already have a column named "Stock", so I do not need the Ticker part of the column name.
Using quantmod we can read a set of stock ticker symbols, clean their names & rbind() into a single data frame.
There are three key features illustrated within this answer, including:
Use of get() to access the objects written by quantmod::getSymbols() once they are loaded into memory.
Use of the symbol names passed into lapply() to add a symbol column to each data frame.
Conversion of the dates stored as row names in the xts objects written by getSymbols() to a data frame column.
First, we'll use getSymbols() to read data from yahoo.com.
library(quantmod)
from.dat <- as.Date("12/02/19",format="%m/%d/%y")
to.dat <- as.Date("12/06/19",format="%m/%d/%y")
theSymbols <- c("AAPL","AXP","BA","CAT","CSCO","CVX","XOM","GS","HD","IBM",
"INTC","JNJ","KO","JPM","MCD","MMM","MRK","MSFT","NKE","PFE","PG",
"TRV","UNH","UTX","VZ","V","WBA","WMT","DIS","DOW")
getSymbols(theSymbols,from=from.dat,to=to.dat,src="yahoo")
# since quantmod::getSymbols() writes named data frames, need to use
# get() with the symbol names to access each data frame
head(get(theSymbols[[1]]))
> head(get(theSymbols[[1]]))
AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
2019-12-02 267.27 268.25 263.45 264.16 23621800 262.8231
2019-12-03 258.31 259.53 256.29 259.45 28607600 258.1370
2019-12-04 261.07 263.31 260.68 261.74 16795400 260.4153
2019-12-05 263.79 265.89 262.73 265.58 18606100 264.2359
Having illustrated how to access the symbol objects in the global environment, we'll use lapply() to extract the dates from the row names, clean the column headings, and write the symbol name as a column for each symbol's data object.
# convert to list
symbolData <- lapply(theSymbols,function(x){
y <- as.data.frame(get(x))
colnames(y) <- c("open","high","low","close","volume","adjusted")
y$date <- rownames(y)
y$symbol <- x
y
})
Finally, we convert the list of data frames to a single data frame.
#combine to single data frame
combinedData <- do.call(rbind,symbolData)
rownames(combinedData) <- 1:nrow(combinedData)
...and the output:
> nrow(combinedData)
[1] 120
> head(combinedData)
open high low close volume adjusted date symbol
1 267.27 268.25 263.45 264.16 23621800 262.8231 2019-12-02 AAPL
2 258.31 259.53 256.29 259.45 28607600 258.1370 2019-12-03 AAPL
3 261.07 263.31 260.68 261.74 16795400 260.4153 2019-12-04 AAPL
4 263.79 265.89 262.73 265.58 18606100 264.2359 2019-12-05 AAPL
5 120.31 120.36 117.07 117.26 5538200 116.2095 2019-12-02 AXP
6 116.04 116.75 114.65 116.57 3792300 115.5256 2019-12-03 AXP
>
If you can guarantee the order of these columns this should do it:
for(df in list(AAPL, GOOG))
colnames(df) <- c("Date", "Open", "High", "Low", "Close", "Volume", "Adjusted", "Stock", "pct_change")
With lapply, we can loop over the list and remove the prefix in the column names with sub. This can be done without any external packages
lst1 <- lapply(list(AAPL, GOOG), function(x) {
colnames(x) <- sub(".*\\.", "", colnames(x))
x})
I'm running quantmod and I want to read in a list of stocks and their prices as of a certain date. I then want to keep those stocks that meet a specific threshold.
My code starts:
library(quantmod)
s = c("AAPL","FB","GOOG", "CRM")
e = new.env() #environment in which to store data
getSymbols(s, src="yahoo", env=e)
prices = do.call(merge, eapply(e, Cl)[s])
today = prices["2017-04-07",]
today
The output is:
AAPL.Close FB.Close GOOG.Close CRM.Close
2017-04-07 143.34 140.78 824.67 84.38
I want to keep only those with a price >140 so it should read:
AAPL.Close GOOG.Close
2017-04-07 143.34 824.67
You already have prices as of a certain date in today. So you just need to subset today by the columns with a close price > 140. You can do that by subsetting the columns with a logical vector.
R> today[, today > 140]
AAPL.Close FB.Close GOOG.Close
2017-04-07 143.34 140.78 824.67
I am downloading some data using R package tseries,
require('tseries')
tickers<- c('JPM','AAPL','MSFT','FB','GE');
prices = matrix(NA,nrow=40,ncol=6)
startdate<-'2015-02-02'
enddate<-'2015-03-30'# 40 rows dim()
for(i in 1:5){
prices[,i]<-get.hist.quote(
instrument=tickers[i],
start=startdate,
end=enddate,
quote='AdjClose',
provider='yahoo')
}
colnames(prices)<-c('JPM','AAPL','MSFT','FB','GE');
I want to construct a matrix saving the adjclose price and date information, but I don't know how to access the zoo date column, say when I construct a zoo object using get.hist.quote(), I can view the object like this
But when I save them to matrix, the date column is missing
Here Map applied to get.hist.quote will create a zoo object for each ticker. Then we use zoo's multiway merge.zoo to merge them all together creating a final zoo object prices:
prices <- do.call(merge,
Map(get.hist.quote, tickers,
start=startdate,
end=enddate,
quote='AdjClose',
provider='yahoo')
)
I would probably keep all the series in a zoo object. This can be done like in the following code, thereby also avoiding your for-loop etc. You can always convert this object to a matrix by as.matrix() afterwards.
prices <-lapply(tickers, get.hist.quote, start=startdate, end=enddate, quote='AdjClose')
prices <- Reduce(cbind, prices)
names(prices) <- tickers
prices <- as.matrix(prices)
head(prices)
JPM AAPL MSFT FB GE
2015-02-02 55.10 118.16 40.99 74.99 23.99
2015-02-03 56.35 118.18 41.31 75.40 24.25
2015-02-04 56.01 119.09 41.54 75.63 23.94
2015-02-05 56.40 119.94 42.15 75.61 24.28
2015-02-06 57.51 118.93 42.11 74.47 24.30
2015-02-09 57.44 119.72 42.06 74.44 24.42
I have a data frame in the following form
SPY.Open SPY.High SPY.Low SPY.Close SPY.Volume SPY.Adjusted
2007-01-03 142.25 142.86 140.57 141.37 94807600 125.38
2007-01-04 141.23 142.05 140.61 141.67 69620600 125.65
2007-01-05 141.33 141.40 140.38 140.54 76645300 124.64
2007-01-08 140.82 141.41 140.25 141.19 71655000 125.22
2007-01-09 141.31 141.60 140.40 141.07 75680100 125.11
2007-01-10 140.58 141.57 140.30 141.54 72428000 125.53
however the command index(DATA.FRAME) return integers rather than dates. What function should I use to get a list of dates instead of integers?
EDIT:
The output of dput(DATA.FRAME) is
structure(list(SPY.Open = c(142.25, 141.23, 141.33, 140.82, 141.31,
140.58), SPY.High = c(142.86, 142.05, 141.4, 141.41, 141.6, 141.57
), SPY.Low = c(140.57, 140.61, 140.38, 140.25, 140.4, 140.3),
SPY.Close = c(141.37, 141.67, 140.54, 141.19, 141.07, 141.54
), SPY.Volume = c(94807600, 69620600, 76645300, 71655000,
75680100, 72428000), SPY.Adjusted = c(125.38, 125.65, 124.64,
125.22, 125.11, 125.53)), .Names = c("SPY.Open", "SPY.High",
"SPY.Low", "SPY.Close", "SPY.Volume", "SPY.Adjusted"), row.names = c("2007-01-03",
"2007-01-04", "2007-01-05", "2007-01-08", "2007-01-09", "2007-01-10"
), class = "data.frame")
I'm not familiar with the command index in R. It looks like the dates are stored as the rownames of your data frame.
I would try:
as.Date(rownames(DataFrameName))
Alternatively, you can turn integers into dates in R. I forget exactly how, but basically you just need one conversation factor (say 15344 = Oct. 9th 2007 or something) - it should be in ?as.Date or ?as.POSIXct
rownames(DATA.FRAME) #results in character vector
#[1] "2007-01-03" "2007-01-04" "2007-01-05" "2007-01-08" "2007-01-09" "2007-01-10"
as.Date(rownames(DATA.FRAME)) #convert to date