I have the following code to give me a graph of the portfolio performance vs. a benchmark.
library(quantmod)
library(PerformanceAnalytics)
library(dygraphs)
#Portfolio
daily_returns <- function(ticker, base_year)
{
# Obtain stock price data from Yahoo! Finance
stock <- getSymbols(ticker, src = "yahoo", auto.assign = FALSE)
# Remove missing values
stock <- na.omit(stock)
# Keep only adjusted closing stock prices
stock <- stock[, 6]
# Confine our observations to begin at the base year and end at the last available trading day
horizon <- paste0(as.character(base_year), "/", as.character(Sys.Date()))
stock <- stock[horizon]
# Calculate daily arithmetic returns
data <- periodReturn(stock, period = "daily", type = "arithmetic")
# Assign to the global environment to be accessible
assign(ticker, data, envir = .GlobalEnv)
}
daily_returns("ALPN.SW", 2019)
daily_returns("AUTN.SW", 2019)
daily_returns("BAER.SW", 2019)
daily_returns("DKSH.SW", 2019)
#Get the benchmark
daily_returns("CHSPI.SW", 2019)
# Merge all the data and rename columns
returns <- merge.xts(ALPN.SW, AUTN.SW, BAER.SW, DKSH.SW, CHSPI.SW)
colnames(returns) <- c("ALPN", "AUTN", "BAER", "DKSH", "SPI")
# Assign weights
wts <- c(1/4, 1/4, 1/4, 1/4)
# Construct a portfolio using our returns object and weights
# Only select first three columns to isolate our individual stock data
portfolio_returns <- Return.portfolio(R = returns[,1:4], weights = wts, wealth.index = TRUE)
# Then isolate our SPI data
benchmark_returns <- Return.portfolio(R = returns[,5], wealth.index = TRUE)
# Merge the two
comp <- merge.xts(portfolio_returns, benchmark_returns)
colnames(comp) <- c("Portfolio", "Benchmark")
# Build an interactive graph to compare performance
dygraph(comp, main = "Portfolio Performance vs. Benchmark") %>%
dyAxis("y", label = "Amount (CHF)")
The problem that I have/need to change is that the portfolio with this code starts basically on 2019-01-01. But I need it to start on 2019-04-01 (first of April). If I write 2019-04-01 in this section here:
daily_returns("ALPN.SW", 2019)
daily_returns("AUTN.SW", 2019)
daily_returns("BAER.SW", 2019)
daily_returns("DKSH.SW", 2019)
Instead of the current 2019, my portfolio starts in 2014 or 2015.
Can someone help me, so that my portfolio starts on April 1st, 2019 instead of January 1st, 2019?
Another way to get the prices I found online would be this code with tidyquant:
getSymbols("AAPL", from = '2019-04-01',
to = "2021-11-30",warnings = FALSE,
auto.assign = TRUE)
Is there a way to work this into the function "daily_returns"? I tried to paste it in behind src = yahoo, but then I get a dimension error for stock<- stock[,6]. It would be nice if I could get it done with a function, as I will have around 30 stocks in total in my final code.
Thanks alot!
CodePudding user response:
I did find a solution:
I had to adapt this part of the code
# Confine our observations to begin at the base year and end at the last available trading day
horizon <- paste0(as.character(base_year), "/", as.character(Sys.Date()))
stock <- stock[horizon]
To this:
#set the time frame for observations
stock <- stock["2019-04-01/2021-11-30"]
This works, but probably only as I have a set timeframe.
CodePudding user response:
I don't use those packages, but xts
provides a window
method that you can use to extract time windows. So for example, before you plot, you could say something like
comp <- window(comp, start = as.Date("2019-04-01"))
or
PMwR::scale1(window(comp, start = as.Date("2019-04-01")))
The function scale1
normalises the series, so both start at 1.
Alternatively, you could apply window
in your function directly after you have downloaded the whole series (and pass start
and end
as arguments to daily_returns
).
For completeness, here would be a complete example for an equal-weight portfolio that is rebalanced every day.
library("PMwR")
library("dygraphs")
library("quantmod")
First we fetch data. To add more stocks, simply add the tickers.
I find it convenient to use the first column for the benchmark. In that way, series[, 1]
gets the benchmark and series[, -1]
gets the stock data.
tickers <- c(
"CHSPI.SW",
"ALPN.SW",
"AUTN.SW",
"BAER.SW",
"DKSH.SW"
)
Set the starting date.
start <- as.Date("2019-04-01")
## fetch data
data <- list()
for (t in tickers)
data[[t]] <- getSymbols(t, src = "yahoo", auto.assign = FALSE)[, 6]
series <- do.call(merge, data)
series <- window(series, start = start)
## equal-weight portfolio
k <- ncol(series) - 1
weights <- rep(1/k, k)
Here I use function returns
from package PMwR
, which I maintain. To choose an alternative rebalancing schedule, specify rebalance.when
(e.g. as a vector of dates).
## when to rebalance
portfolio <- cumprod(1 returns(series[, -1], pad = 0,
weights = weights,
rebalance.when = index(series)))
Plot the series. I use the new |>
operator (built into R >= 4.1.0
).
dygraph(scale1(cbind(portfolio, series[, 1])),
main = "Portfolio Performance vs. Benchmark") |>
dyAxis("y", label = "Amount (CHF)")