Home > Mobile >  R: Portfolio should start in the middle of the year (individually set by me) and not on January 1st
R: Portfolio should start in the middle of the year (individually set by me) and not on January 1st

Time:12-09

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)")
  • Related