Downloading multiple stock monthly prices with R using quantmod - r

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.

Related

How to return weekly data starting from Monday in getSymbols

If run this getSymbols function on Saturday it will return data for only completed weeks i.e. it will omit current week data and will only return data till 15th May 2021
d <- as.data.frame(
getSymbols(
paste("WIPRO" , ".NS", sep = ""),
from ="2000-01-01",
periodicity = "weekly",
return.class = 'zoo',
env = NULL
)
)
If I want this function to return data till today or whichever is latest, how do I modify this function?
If I add to = "2021-05-22" parameter, it returns the record but it is filled with NA.
You can work around this by using the daily data and then rolling it up to weekly.
library(quantmod)
daily.x <- getSymbols(
paste("WIPRO" , ".NS", sep = ""),
from ="2000-01-01",
auto.assign = FALSE
)
weekly.x <- to.period(daily.x, period = "weeks")
tail(weekly.x)
x.Open x.High x.Low x.Close x.Volume x.Adjusted
2021-04-16 450.00 473.65 412.60 469.20 171627114 469.20
2021-04-23 463.00 494.50 461.10 475.70 117757478 475.70
2021-04-30 479.40 511.80 477.00 492.75 62896349 492.75
2021-05-07 487.95 516.55 477.80 515.25 67638876 515.25
2021-05-14 517.60 528.50 492.75 498.45 34864957 498.45
2021-05-21 498.45 517.80 495.00 512.70 34113599 512.70

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.

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.

Error in to.period.contributions() from PerformanceAnalytics sandbox

I've been trying to calculate my portfolio returns and the individual stock contributions. I stumbled along this post, which appears to be from the guy who help write PerformanceAnalytics.
At the end of the article he posts a link to r-forge with a sandbox file for some functions.
So I'm trying to convert my daily returns to the summed monthly returns via the to.monthly.contributions() function but I'm running into an xts error!
Here's my code:
library(PerformanceAnalytics)
library(quantmod)
stock.weights <- c(.15, .20, .25, .225, .175)
symbols <- c("GOOG", "AMZN", "BA", "FB", "AAPL")
getSymbols(symbols, src = 'google', from = "2016")
#xts with daily closing of each stock
merged.closing <- merge(GOOG[,4], AMZN[,4], BA[,4], FB[,4], AAPL[,4])
#xts with returns
merged.return <- na.omit(Return.calculate(merged.closing))
# weighted returns rebalanced quartely
portfolio.returns = Return.portfolio(merged.return, weights = stock.weights,
rebalance_on = "quarters", verbose = TRUE)
#to monthly contributions function
to.monthly.contributions(portfolio.returns$contributions)
However when I run the last line I get the following error message:
Error in inherits(x, "xts") :
argument "Contributions" is missing, with no default
5. inherits(x, "xts")
4. is.xts(x)
3. checkData(Contributions)
2. to.period.contributions(contributions = contributions, period = "months")
1. to.monthly.contributions(portfolio.returns$contributions)
I'm guessing that the error has something to do with the portfolio.returns$contributions not being an xts? But I'm not sure how to get around that.
On the side note, if anyone has any better ideas or sources for calculating portfolio returns by months/quarters/years I'm keen to hear, bearing in mind they need to account for weight changes, re-balances and contributions to changes!
Note that PerformanceAnalytics (and many other packages in that R-Forge repo) have moved to Brian Peterson's GitHub account. There you will see some changes to sandbox/to.period.contributions.R about a year ago. That might be causing you some issue(s).
Another issue is that the object returned by Return.portfolio() does not have a contributions element. The element name you want is contribution (singular).
After addressing those two issues, your to.monthly.contributions() call works.
R> to.monthly.contributions(portfolio.returns$contribution)
GOOG.Close AMZN.Close BA.Close FB.Close AAPL.Close Portfolio Return
2016-01-29 0.0002244419 -0.0156956938 -0.036245552 0.0219893367 -1.330565e-02 -0.043033115
2016-02-29 -0.0095461956 -0.0113127380 -0.003625779 -0.0121676134 -1.128288e-03 -0.037780614
2016-03-31 0.0103601952 0.0140210157 0.016927654 0.0171632715 2.218899e-02 0.080661130
2016-04-29 -0.0104584200 0.0222188532 0.015479754 0.0068624014 -2.448619e-02 0.009616397
2016-05-31 0.0085179936 0.0210895602 -0.016873347 0.0024024015 9.732993e-03 0.024869602
2016-06-30 -0.0084883795 -0.0023345382 0.007080427 -0.0086331655 -6.610526e-03 -0.018986182
2016-07-29 0.0166211530 0.0120706520 0.007295757 0.0190190760 1.576098e-02 0.070767622
2016-08-31 -0.0003521895 0.0027014233 -0.007568643 0.0040084230 3.231073e-03 0.002020086
2016-09-30 0.0020684771 0.0177517727 0.004108611 0.0039452914 1.185750e-02 0.039731657
2016-10-31 0.0013990917 -0.0113434690 0.020286170 0.0047711858 7.585139e-04 0.015871492
2016-11-30 -0.0050340240 -0.0092287866 0.015187074 -0.0217047070 -4.601884e-03 -0.025382327
2016-12-30 0.0026858660 -0.0001688763 0.009813394 -0.0059705490 8.286484e-03 0.014646319
2017-01-31 0.0048528154 0.0196327363 0.012429342 0.0298631030 8.355638e-03 0.075133635
2017-02-28 0.0047757941 0.0053484794 0.025108019 0.0094951963 2.198006e-02 0.066707545
2017-03-31 0.0010760715 0.0096512663 -0.004718775 0.0111011780 8.787645e-03 0.025897386
2017-04-28 0.0138145523 0.0086741715 0.011265973 0.0129883844 -1.218154e-05 0.046730900
2017-05-31 0.0101747490 0.0150069699 0.003781232 0.0018310137 1.060194e-02 0.041395909
2017-06-30 -0.0093108126 -0.0055092033 0.013123207 -0.0006974798 -9.767034e-03 -0.012161323
2017-07-31 0.0035934766 0.0040867769 0.056523388 0.0272271162 5.723163e-03 0.097153921
2017-08-31 0.0013284632 -0.0013521084 -0.003226369 0.0036945746 1.691168e-02 0.017356239
2017-09-19 -0.0025908954 -0.0019880088 0.014497492 0.0007343197 -5.737005e-03 0.004915902

How to reverse chronological order with getSymbols in 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,]

Resources