#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, скажем. Что и делает вторая строка кодов.