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
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 have more than 300 stocks downloaded with getsymbols() and I have the name of this stocks in a vector, for example:
USA_STOCKS = c("AAL","AAPL","ADBE","ADI","ADP","ADSK","ALGN",
"ALXN","AMAT","AMGN","AMZN","ASML","ATVI","AVGO",
"BIDU","BIIB") # This is just an extract from 300
getSymbols(AAL) # this is just one of the 300 "getsymbols"
With that, I have a XTS object called AAL and a vector USA_TOCKS with all the name of the XTS Objets.
I would like to do:
AAL = na.omit(AAL)
But, instead of use the Object AAL, I want to refer the object using the name inside the vector. Something like this:
USA_STOCKS[1] = na.omit(USA_STOCKS[1])
Obviusly if i did this, I will change only the name of "AAL" inside the vector. But what I want is to refer the object AAL.
Hmm, still a bit unclear, but I think you want to do something like this:
library(quantmod)
USA_STOCKS = c("AAL","AAPL","ADBE")
# Put all requested quotes in big list
stocks_usa <- lapply(USA_STOCKS,
getSymbols,
from = "2018-10-01",
to = "2018-11-01",
auto.assign = F)
# set the names of the list
names(stocks_usa) <- USA_STOCKS
#reference AAL
head(stocks_usa$AAL)
AAL.Open AAL.High AAL.Low AAL.Close AAL.Volume AAL.Adjusted
2018-10-01 41.41 41.75 39.60 39.61 7210700 39.50097
2018-10-02 39.60 39.60 38.40 38.50 7625000 38.39403
2018-10-03 38.70 39.26 38.42 38.80 6370300 38.69320
2018-10-04 38.80 39.01 37.48 37.92 5916500 37.81562
2018-10-05 37.93 38.13 36.21 36.44 9127000 36.33969
2018-10-08 36.44 36.85 35.60 35.90 7879300 35.80119
# more referencing
stocks_usa$AAL <- na.omit(stocks_usa$AAL)
I have 100+ csv files in the current directory, all with the same characteristics. Some examples:
ABC.csv
,close,high,low,open,time,volumefrom,volumeto,timestamp
0,0.05,0.05,0.05,0.05,1405555200,100.0,5.0,2014-07-17 02:00:00
1,0.032,0.05,0.032,0.05,1405641600,500.0,16.0,2014-07-18 02:00:00
2,0.042,0.05,0.026,0.032,1405728000,12600.0,599.6,2014-07-19 02:00:00
...
1265,0.6334,0.6627,0.6054,0.6266,1514851200,6101389.25,3862059.89,2018-01-02 01:00:00
XYZ.csv
,close,high,low,open,time,volumefrom,volumeto,timestamp
0,0.0003616,0.0003616,0.0003616,0.0003616,1412640000,11.21,0.004054,2014-10-07 02:00:00
...
1183,0.0003614,0.0003614,0.0003614,0.0003614,1514851200,0.0,0.0,2018-01-02 01:00:00
The idea is to build in R a time series dataset in xts so that I could use the PerformanceAnalyticsand quantmod libraries. Something like that:
## ABC XYZ ... ... JKL
## 2006-01-03 NaN 20.94342
## 2006-01-04 NaN 21.04486
## 2006-01-05 9.728111 21.06047
## 2006-01-06 9.979226 20.99804
## 2006-01-09 9.946529 20.95903
## 2006-01-10 10.575626 21.06827
## ...
Any idea? I can provide my trials if required.
A solution using base R
If you know that your files are formatted the same way then you can merge them. Below is what I would have done.
Get a list a files (this assumes that all the .csv files are the one you actually need and they are placed in the working directory)
vcfl <- list.files(pattern = "*.csv")
lapply() to open all files and store them as.data.frame:
lsdf <- lapply(lsfl, read.csv)
Merge them. Here I used the column high but you can apply the same code on any variable (there likely is a solution without a loop)
out_high <- lsdf[[1]][,c("timestamp", "high")]
for (i in 2:length(vcfl)) {
out_high <- merge(out_high, lsdf[[i]][,c("timestamp", "high")], by = "timestamp")
}
Rename the column using the vector of files' names:
names(lsdf)[2:length(vcfl)] <- gsub(vcfl, pattern = ".csv", replacement = "")
You can now use as.xts() fron the xts package https://cran.r-project.org/web/packages/xts/xts.pdf
I guess there is an alternative solution using tidyverse, somebody else?
Hope this helps.
I'm using the quantmodpackage. I've got a vector of tickers like this :
c("AAPL","GOOG","IBM","GS","AMZN","GE")
and I want to create a function to calculate the EBIT margin of a stock (= operating income / total revenue). So for a given stock, I use the following piece of code which only works for GE (provided a ".f" is added a the end of the ticker) :
require(quantmod)
getFinancials("GE",period="A")
ebit.margin <- function(stock.ticker.f){
return(stock.ticker$IS$A["Operating Income",]/stock.ticker$IS$A["Total Revenue",])
}
ebit.margin("GE")
I would like to generalize this function in order to use then the applyfunction. There are several difficulties :
when applying the quantmod::getFinancialfunction to a ticker, the financial statements of the stocks are saved in the default environment. The viewFinancialhas then to be used to get and print the financial statements. I need a way to get access to the financial statements directly into the function
The function's argument function is a string like "GE.f" but it would more convenient to enter directly the ticker ("GE"). I've tried to use the paste0 and gsub to get a string like "GE.f" it doesn't work because "GE.f" doesn't belong to the financials class.
To sum up, I'm a bit lost...
It's easier if you use auto.assign=FALSE
s <- c("AAPL","GOOG","IBM","GS","AMZN","GE")
fin <- lapply(s, getFinancials, auto.assign=FALSE)
names(fin) <- s
lapply(fin, function(x) x$IS$A["Operating Income", ] / x$IS$A["Total Revenue",])
#$AAPL
#2012-09-29 2011-09-24 2010-09-25 2009-09-26
# 0.3529596 0.3121507 0.2818704 0.2736278
#
#$GOOG
#2012-12-31 2011-12-31 2010-12-31 2009-12-31
# 0.2543099 0.3068724 0.3540466 0.3514585
#
#$IBM
#2012-12-31 2011-12-31 2010-12-31 2009-12-31
# 0.2095745 0.1964439 0.1974867 0.1776439
#
#$GS
#2012-12-31 2011-12-31 2010-12-31 2009-12-31
#0.2689852 0.1676678 0.2804621 0.3837401
#
#$AMZN
#2012-12-31 2011-12-31 2010-12-31 2009-12-31
#0.01106510 0.01792957 0.04110630 0.04606471
#
#$GE
#2012-12-31 2011-12-31 2010-12-31 2009-12-31
#0.11811969 0.13753327 0.09415548 0.06387029
Anaother option is to laod your tickers in an new environnement.
tickers <- new.env()
s <- c("AAPL","GOOG","IBM","GS","AMZN","GE")
lapply(s, getFinancials,env=tickers)
sapply(ls(envir=tickers),
function(x) {x <- get(x) ## get the varible name
x$IS$A["Operating Income", ] / x$IS$A["Total Revenue",]})
AAPL.f AMZN.f GE.f GOOG.f GS.f IBM.f
2012-09-29 0.3529596 0.01106510 0.11811969 0.2543099 0.2689852 0.2095745
2011-09-24 0.3121507 0.01792957 0.13753327 0.3068724 0.1676678 0.1964439
2010-09-25 0.2818704 0.04110630 0.09415548 0.3540466 0.2804621 0.1974867
2009-09-26 0.2736278 0.04606471 0.06387029 0.3514585 0.3837401 0.1776439
EDIT
No need to use ls, get.... just the handy eapply (thanks #GSee) which applies FUN to the named values from an environment and returns the results as a list
eapply(tickers, function(x)
x$IS$A["Operating Income", ] / x$IS$A["Total Revenue",])