2
$\begingroup$

I am trying to merge a list of adjusted closes of a multitude of firms for my research on ESG, in relation to risk/reward. None of the firms seem to have a problem, except for the Berkshire Hathaway stock (BRK-A).

The code is as follows:

library(quantmod)
library(PerformanceAnalytics)

maxDate <- "2017-06-23"
minDate <- "2020-12-31" 

average <- c("BABA", "BRK-A", "V", "JNJ", "WMT", "JPM", "MA", "PG", "UNH", "DIS", "BAC", "VZ", "NKE", "NVS", "TM", "MRK", "T", "ABT", "ORCL", "ABBV", "TMO", "XOM", "ACN", "BHP", "CVX")
weights <- c(0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04)
getSymbols(average, from=maxDate, to=minDate)

# IMPORTANT: wait 30 seconds to let the source function finish! #
Port.prices <- na.omit(merge(Ad(BABA), Ad(BRK-A), Ad(V), Ad(JNJ), Ad(WMT), Ad(JPM), Ad(MA), Ad(PG), Ad(UNH), Ad(DIS), Ad(BAC), Ad(VZ), Ad(NKE), Ad(NVS), Ad(TM), Ad(MRK), Ad(T), Ad(ABT), Ad(ORCL), Ad(ABBV), Ad(TMO), Ad(XOM), Ad(ACN), Ad(BHP), Ad(CVX)))
Port.returns <- ROC(Port.prices, type="discrete")[-1,]
colnames(Port.returns) <- average 

Does anyone have a (preferably simple) solution to this problem? I am still a rookie when it comes to R, so some explanation would be great!

Thank you in advance!

Philip

$\endgroup$
2
  • 2
    $\begingroup$ Try replacing BRK-A with BRKA and Ad(BRK-A) with Ad(BRKA) respectively. The lexer parser may not like the minus character. $\endgroup$ Apr 10, 2021 at 11:16
  • $\begingroup$ Hello mister Rodionov, thank you for your response! Unfortunately, removing the "-" in either/both the average/getSymbols or/and merge functions did not work. However, the answer by @pleb did work and the problem is solved. Thank you for commenting! $\endgroup$
    – Philip
    Apr 12, 2021 at 8:27

2 Answers 2

2
$\begingroup$

When getting data using the quantmod package, it is a good idea to call the "Adjusted close" function Ad() directly on getSymbols(), since you might run into trouble otherwise (eg. loading prices into the R-environment directly, without saving it in a variable).

Ad-hoc solution using your own code:

As described above, you can call Ad() directly on getSymbols() for Berkshire Hathaway stock (BRK-A) only. This returns the adjusted close prices, which can be saved in a variable:

BRK <- Ad(getSymbols("BRK-A", from = maxDate, to = minDate, auto.assign = FALSE))

Now, replace Ad(BRK-A) in Port.prices with BRK and everything should work fine. Also, setting auto.assign = FALSE returns the prices instead of loading them into the R-environment (see documentation here).


Alternative solution method:

I've taken the liberty of providing another working solution (comments provided below the code), that resembles your own code:

library(quantmod)
library(PerformanceAnalytics)
library(xts)

maxDate <- "2017-06-23"
minDate <- "2020-12-31" 

tickers <- c("BABA", "BRK-A", "V", "JNJ", "WMT", "JPM", "MA", "PG", "UNH", "DIS", "BAC", "VZ", "NKE", "NVS", "TM", "MRK", "T", "ABT", "ORCL", "ABBV", "TMO", "XOM", "ACN", "BHP", "CVX")

n <- length(tickers)

prices <- xts()
weights <- rep(1/n, n)

for (i in 1:length(tickers)){

  getdata <- try(Ad(getSymbols(tickers[i], 
    from = maxDate, to = minDate, auto.assign = FALSE, silent = T)))

  prices <- cbind(prices, getdata)

  print(sprintf("%s", i))
}

# IMPORTANT: wait 30 seconds to let the source function finish! #
Port.returns <- ROC(prices, type="discrete")[-1,]

Providing some comments on my code, in order to alleviate confusion:

  1. Your equal weight vector, weights, can be generalized by dividing with the number of assets, n, and then repeating this number n amount of times.
  2. The library xts, is a multivariate time-series library and is a great tool for gathering all of your adjusted close prices into one matrix.
  3. The for loop can be explained as follows: For each ticker in tickers, we get the adjusted close prices, and save them in a variable called getdata. We then column-bind the getdata variable with the prices time-series matrix. Therefore, we do not need to call Ad() afterwards. At first, prices is just an empty matrix (time-series object), so calling cbind(prices, getdata) will net you the first adjusted close prices for "BABA". Now, the second iteration will column-bind prices (containing "BABA" adjusted closes) and getdata (containing adjusted closes for "BRK-A"), which will effectively update the prices variable, now containing both "BABA" and "BRK-A" on the columns (and daily closes on the rows). This will happen until the for-loop ends, giving you a matrix prices containing the close prices of all assets defined by their ticker in tickers.

The alternative solution saves you some minutes of manually constructing the pricing matrix, Port.prices, and is extendable for any amount of tickers (as long as the tickers are correct). I hope this helps!

$\endgroup$
1
  • 1
    $\begingroup$ Thank you very much for your clear answer and comprehensive comments! Amazing to see your alternative solution method; a LOT more streamlined than mine, quite helpful. Thank you for your time! - Philip $\endgroup$
    – Philip
    Apr 12, 2021 at 8:16
0
$\begingroup$

Very simple fix:

The Problem: For each symbol, getSymbols creates a data object in the environment by that name. Subsequent call to the data object BRK-A is interpreted by R as BRK minus A, and of course it does not find an object named BRK.

The Solution: Rename the object immediately after getSymbols call as follows. Using backticks (shift ~, not single quotes) so that interpreter takes the string in its entirety:

BRKA <- `BRK-A`

And for completeness, update your vector of symbols from BRK-A to BRKA as well so that subsequent calls to this vector look for BRKA and not BRK-A. Updated code:

library(quantmod)
library(PerformanceAnalytics)

maxDate <- "2017-06-23"
minDate <- "2020-12-31" 

average <- c("BABA", "BRK-A", "V", "JNJ", "WMT", "JPM", "MA", "PG", "UNH", "DIS", "BAC", "VZ", "NKE", "NVS", "TM", "MRK", "T", "ABT", "ORCL", "ABBV", "TMO", "XOM", "ACN", "BHP", "CVX")
weights <- c(0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04, 0.04)
getSymbols(average, from=maxDate, to=minDate)
BRKA <- `BRK-A`
average <- c("BABA", "BRKA", "V", "JNJ", "WMT", "JPM", "MA", "PG", "UNH", "DIS", "BAC", "VZ", "NKE", "NVS", "TM", "MRK", "T", "ABT", "ORCL", "ABBV", "TMO", "XOM", "ACN", "BHP", "CVX")
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.