R: Портфолио должно начинаться в середине года (индивидуально задается мной), а не 1 января

#r #portfolio

#r #Портфолио

Вопрос:

У меня есть следующий код, который дает мне график производительности портфеля по сравнению с эталоном.

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

Проблема, которую мне нужно / нужно изменить, заключается в том, что портфель с этим кодом начинается в основном с 2019-01-01. Но мне нужно, чтобы это началось 2019-04-01 (первого апреля). Если я напишу 2019-04-01 в этом разделе здесь:

 daily_returns("ALPN.SW", 2019)
daily_returns("AUTN.SW", 2019)
daily_returns("BAER.SW", 2019)
daily_returns("DKSH.SW", 2019)
 

Вместо текущего 2019 года мое портфолио начинается в 2014 или 2015 году.

Может ли кто-нибудь мне помочь, чтобы мое портфолио начиналось с 1 апреля 2019 года вместо 1 января 2019 года?

Другим способом получения цен, которые я нашел в Интернете, был бы этот код с помощью tidyquant:

 getSymbols("AAPL", from = '2019-04-01',
       to = "2021-11-30",warnings = FALSE,
       auto.assign = TRUE)
 

Есть ли способ включить это в функцию «daily_returns»? Я попытался вставить его за src = yahoo, но затем я получаю ошибку измерения для stock<- stock[,6] . Было бы неплохо, если бы я мог сделать это с помощью функции, так как в моем окончательном коде у меня будет около 30 акций.

Большое спасибо!

Ответ №1:

Я нашел решение:

Мне пришлось адаптировать эту часть кода

     # 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]
 

К этому:

 #set the time frame for observations
  stock <- stock["2019-04-01/2021-11-30"]
 

Это работает, но, вероятно, только при наличии установленных временных рамок.

Ответ №2:

Я не использую эти пакеты, но xts предоставляю window метод, который вы можете использовать для извлечения временных окон. Так, например, перед построением графика вы могли бы сказать что-то вроде

 comp <- window(comp, start = as.Date("2019-04-01"))
 

или

 PMwR::scale1(window(comp, start = as.Date("2019-04-01")))
 

Функция scale1 нормализует ряд, поэтому оба начинаются с 1.

В качестве альтернативы, вы можете подать window заявку в своей функции непосредственно после загрузки всей серии (и передать start and end в качестве аргументов daily_returns ).

Для полноты картины здесь будет приведен полный пример портфеля с равным весом, который перебалансируется каждый день.

 library("PMwR")
library("dygraphs")
library("quantmod")
 

Сначала мы извлекаем данные. Чтобы добавить больше акций, просто добавьте тикеры.
Я считаю удобным использовать первый столбец для бенчмарка. Таким образом, series[, 1] получает бенчмарк и series[, -1] получает данные о запасах.

 tickers <- c(
    "CHSPI.SW",
    "ALPN.SW",
    "AUTN.SW",
    "BAER.SW",
    "DKSH.SW"
)
 

Установите дату начала.

 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)
 

Здесь я использую функцию returns из пакета PMwR , который я поддерживаю. Чтобы выбрать альтернативный график перебалансировки, укажите rebalance.when (например, в виде вектора дат).

 ## when to rebalance
portfolio <- cumprod(1   returns(series[, -1], pad = 0,
                                 weights = weights,
                                 rebalance.when = index(series)))
 

Постройте серию. Я использую новый |> оператор (встроенный R >= 4.1.0 ).

 dygraph(scale1(cbind(portfolio, series[, 1])),
        main = "Portfolio Performance vs. Benchmark") |>
            dyAxis("y", label = "Amount (CHF)")
 

Комментарии:

1. Спасибо за ваш ответ! Я попробовал первый, и он устанавливает окно, которое отображается на графике, но не начальную точку графика (портфолио).

2. Первый не нормализует серию, чтобы начать с 1 или 100, скажем. Что и делает вторая строка кодов.