저는 가중치가있는 주식 포트폴리오와 일일 수익 기록이 있습니다. 가중치가 움직이지 않는다고 가정하고 누락 된 데이터를 0으로 대체한다고 가정하고 역사적 날마다 포트폴리오 수익률을 계산하려고합니다 (역사적 VaR 또는 Value at Risk 를 계산하려고합니다 ).
다음은 단순화 된 버전입니다.
# portfolio
pfolio = data.frame(ticker = c("stock_a", "stock_b", "stock_noob"), weight = c(0.25, 0.6, 0.15))
# Daily stock returns (with some NA values for one stock):
m = matrix(c(0.0016, 0.0037, -0.0042, -0.0096, -0.0006, -0.0043, -0.0292, -0.0158, 0.0128, 0.0113, 0.0016, 0.0042, NA, NA, 0.0168, -0.0293, 0.0037, -0.0083),
nrow = 6,
ncol = 3,
dimnames = list(c("2017-03-01", "2017-03-02", "2017-03-03", "2017-03-06", "2017-03-07", "2017-03-08"), c("stock_a", "stock_b", "stock_noob"))
)
영리한 방법 apply
이나 mapply
방법 을 사용하려고하는데 최선의 방법은 먼저 데이터를 정리 한 다음 for 루프를 적용하는 것입니다 (yuck).
m_clean = apply(m, c(1, 2), function(x) if (is.na(x)) 0 else x)
answer = numeric(0)
for (i in 1:nrow(m_clean)) {
answer = c(answer, sum(m_clean[i, pfolio$ticker] * pfolio$weight))
}
그래서 주요 질문은 :이 작업을 수행하는 깔끔한 한 줄 방법은 무엇입니까?
넌 할 수있어:
m_clean <- ifelse(is.na(m), 0, m) # or
m_clean <- m; m_clean[is.na(m_clean)] <- 0
그리고
answer <- apply(m_clean, 1, weighted.mean, w=pfolio$weight) # or
answer <- colSums(t(m_clean) * pfolio$weight) # or
answer <- tcrossprod(pfolio$weight, m_clean)
마지막은 행렬을 제공하는 것입니다.
#> tcrossprod(pfolio$weight, m_clean)
# 2017-03-01 2017-03-02 2017-03-03 2017-03-06 2017-03-07 2017-03-08
#[1,] -0.01712 -0.008555 0.00915 -1.5e-05 0.001365 2e-04
다른 솔루션은 명명 된 벡터를 제공합니다.
library("microbenchmark")
microbenchmark(
a= apply(m_clean, 1, weighted.mean, w=pfolio$weight),
c= colSums(t(m_clean) * pfolio$weight),
p= tcrossprod(pfolio$weight, m_clean),
m= m_clean %*% pfolio$weight
)
# Unit: microseconds
# expr min lq mean median uq max neval cld
# a 49.115 51.0590 54.46379 52.3685 53.9815 99.023 100 c
# c 12.688 13.8385 15.02912 14.8460 15.7560 32.366 100 b
# p 5.978 6.8955 7.75998 7.4170 7.8770 30.771 100 a
# m 5.438 6.4330 6.95056 6.8615 7.2710 17.109 100 a
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다