8

Đây là một câu đố thú vị.tối ưu hóa quadprog

Dưới đây là R snippet xác định điểm tiếp tuyến của hàm bậc hai đối với một đường thẳng được vẽ từ điểm (0, rf) trên trục y.

Đối với những người quen thuộc với lý thuyết danh mục đầu tư, điểm này được trả lại và không gian rủi ro và giải pháp được đặt trọng số xác định danh mục tangency (tỷ lệ tối đa chia sẻ). Đoạn cho phép trọng âm (tức là quần short) và có một hạn chế trọng lượng bình đẳng đòi hỏi tổng trọng lượng = 1.

require(quadprog) 

# create artifical data 
nO  <- 100  # number of observations 
nA  <- 10  # number of assets 
mData <- array(rnorm(nO * nA, mean = 0.001, sd = 0.01), dim = c(nO, nA)) 
rf  <- 0.0001  # riskfree rate (2.5% pa) 
mu  <- apply(mData, 2, mean) # means 
mu2 <- mu - rf     # excess means 

# qp 
aMat <- as.matrix(mu2) 
bVec <- 1 # set expectation of portfolio excess return to 1 
zeros <- array(0, dim = c(nA,1)) 
solQP <- solve.QP(cov(mData), zeros, aMat, bVec, meq = 1) 

# rescale variables to obtain weights 
w <- as.matrix(solQP$solution/sum(solQP$solution)) 

# compute sharpe ratio 
SR <- t(w) %*% mu2/sqrt(t(w) %*% cov(mData) %*% w) 

Câu hỏi của tôi - làm thế nào để thích ứng với mã để giải quyết cho các thiết lập tối ưu trọng số sao cho tổng của các trọng số tổng cho một số tùy ý (bao gồm cả trường hợp góc của danh mục đầu tư tự tài trợ khi tổng trọng số = 0) trái với thống nhất? Ngoài ra, bạn có thể xem xét thêm một phần tử 'tiền mặt' vào ma trận hiệp phương sai với phương sai hiệp phương sai của 0, và thêm một ràng buộc bình đẳng yêu cầu trọng số trên tiền mặt = 1. Tuy nhiên ma trận này sẽ không được bán xác định dương . Ngoài ra, tôi cho rằng trọng số không dùng tiền mặt có thể không đáng kể.

+1

Trong cuộc gọi 'resolveQP' của bạn, tôi không thấy ràng buộc thực thi rằng trọng số tổng thành một. Thay vào đó, 'aMat, bVec, meq = 1' yêu cầu số dư danh mục đầu tư của bạn là một, bạn có thể kiểm tra bằng' sum (aMat * solQP $ solution) '. Bên trong cuộc gọi 'resolve.QP' của bạn, bạn không nên sử dụng một vectơ của những thay vì' aMat'? – flodel

+0

@flodel - bạn chính xác. Typo cố định, bắt tốt –

Trả lời

7

Trước tiên, hãy giải thích tại sao này thực sự tạo danh mục tỷ lệ tối đa Sharpe.

Chúng tôi muốn w để tối đa hóa w' mu/sqrt(w' V w). Nhưng số lượng đó là không thay đổi nếu chúng ta nhân w bởi một số (nó là "đồng nhất của độ 0"): do đó chúng ta có thể áp đặt w' mu = 1, và các vấn đề tối đa hóa 1/sqrt(w' V w) tương đương để giảm thiểu w' V w. Danh mục tỷ lệ Sharpe tối đa không phải là duy nhất: chúng tạo thành một dòng. Nếu chúng ta muốn trọng số tổng cộng lên đến 1 (hoặc bất kỳ số khác khác 0), chúng ta chỉ cần giải cứu chúng.

Nếu chúng ta muốn các trọng để tổng hợp lên đến 0, chúng ta có thể thêm ràng buộc cho vấn đề - nó chỉ hoạt động vì các hạn chế cũng là đồng nhất của độ 0. Bạn vẫn sẽ cần phải rescale trọng, ví dụ, dài 100% và ngắn 100%.

solQP <- solve.QP(cov(mData), zeros, 
    cbind(aMat,1), 
    c(bVec,0), 
    meq = 2 
) 

# Let us compare with another solver 
V <- cov(mData) 
library(Rsolnp) 
r <- solnp(
    rep(1/length(mu), length(mu)), 
    function(w) - t(w) %*% mu2/sqrt(t(w) %*% V %*% w), 
    eqfun = function(w) sum(w), 
    eqB = 0, 
    LB = rep(-1, length(mu)) 
) 
solQP$solution/r$pars # constant 
1

Xem liên kết bạn đã đưa vào. Rõ ràng, vai trò của aMat, bVec, meq = 1 bên trong cuộc gọi solve.QP là để sửa giá trị của tử số (lợi tức của bạn) trong công thức tỷ lệ Sharpe, do đó, tối ưu hóa tập trung vào việc giảm thiểu mẫu số. Trong một nghĩa nào đó, nó là hoàn toàn hợp pháp để sửa chữa tử số, nó giống như sửa chữa tổng kích thước của danh mục đầu tư của bạn. Danh mục đầu tư của bạn sau đó có thể được thu nhỏ lên hoặc xuống, nó sẽ giữ nguyên tỷ lệ Sharpe. Để giúp bạn nhận ra điều đó, bạn có thể chạy mã của mình ở trên cho bất kỳ giá trị nào của bVec (được cấp, khác 0) và bạn sẽ nhận được kết quả tương tự cho các trọng số w và tỷ lệ Sharpe SR.

Vì vậy, tôi cảm thấy bạn có thể hiểu sai khái niệm "trọng số danh mục đầu tư". Chúng là tỷ lệ đại diện cho danh mục đầu tư của bạn được tạo ra, và chúng nên tính một. Một khi bạn đã tìm được trọng số tối ưu, bạn đã có thể mở rộng danh mục của mình đến bất kỳ cấp độ nào bạn muốn, chỉ cần nhân w với giá trị hiện tại bạn muốn cho danh mục đầu tư của mình.

0

Đây không phải là kỹ thuật tốt cho danh mục dài.Ngay cả danh mục đầu tư hơn so với các cổ phiếu ngắn có thể phân bổ trọng số của các dấu hiệu sai sau khi bình thường hóa bằng tổng trọng số.

Những trường hợp này phát sinh với số dư vượt quá âm. Buộc w'mu = 1 đặt giải pháp ở bên trái gốc (rủi ro âm) trong những trường hợp này.

library(quadprog) 
nA = 2 # two assets 
mu2 = c(-.1,.1) # one negative excess return 
Dmat = matrix(c(1,0,0,10),2,2) 

aMat <- as.matrix(mu2) 
bVec <- 1 # set expectation of portfolio excess return to 1 
zeros <- array(0, dim = c(nA,1)) 
solQP <- solve.QP(Dmat, zeros, aMat, bVec, meq = 1) 

rawW = solQP$solution 
cat('\nraw weights ') 
cat(rawW) 

netW = rawW/sum(rawW) 
cat('\nnormalized weights ') 
cat(netW) 

portfReturn = sum(netW*mu2) 
cat('\nportfolio excess return ') 
cat(portfReturn)