2016-10-13 3 views
1

제한된 최적화 문제를 해결하기 위해 메타 이론을 사용하기위한 단계를 밟고 있습니다. 나는, 람다는 0과 1 사이의 값을 사용 R.로컬 검색을 이용한 Markowitz 모델/포트폴리오 최적화

Min 
    lambda * [sum{i=1 to N}sum{j = 1 to N}w_i*w_i*Sigma_ij] - (1-lambda) * [sum{i=1 to N}(w_i*mu_i)] 
subject to 
    sum{i=1 to N}{w_i} = 1 
    0 <= w_i <= 1; i = 1,...,N 

NMOF 패키지를 사용하여 (아래) 기본 마코 위츠의 평균 - 분산 최적화 모델을 해결하기 위해 노력하고, N은 자산의 수입니다. 나는 목적 함수 (의) 람다를 포함하는 방법을 잘 모르겠습니다

library(NMOF) 

na <- dim(fundData)[2L] 
ns <- dim(fundData)[1L] 
Sigma <- cov(fundData) 
winf <- 0.0 
wsup <- 1.0 
m <- colMeans(fundData) 


resample <- function(x,...) x[sample.int(length(x),...)] 


data <- list(R = t(fundData), 
      m = m, 
      na = dim(fundData)[2L], 
      ns = dim(fundData)[1L], 
      Sigma = Sigma, 
      eps = 0.5/100, 
      winf = winf, 
      wsup = wsup, 
      nFP = 100) 

w0 <- runif(data$na); w0 <- w0/sum(w0) 

OF <- function(w,data){  
    wmu <- crossprod(w,m) 
    res <- crossprod(w, data$Sigma) 
    res <- tcrossprod(w,res) 
    result <- res - wmu 
    } 


neighbour <- function(w, data){ 
    toSell <- w > data$winf 
    toBuy <- w < data$wsup 
    i <- resample(which(toSell), size = 1L) 
    j <- resample(which(toBuy), size = 1L) 
    eps <- runif(1) * data$eps 
    eps <- min(w[i] - data$winf, data$wsup - w[j], eps) 
    w[i] <- w[i] - eps 
    w[j] <- w[j] + eps 
    w 
} 


algo <- list(x0 = w0, neighbour = neighbour, nS = 5000L) 
system.time(sol1 <- LSopt(OF, algo, data)) 

: (: 금융 수치 방법 및 최적화 도서 기준)에 따라

내 코드입니다. 위의 코드는 OF의 람다를 포함하지 않습니다. 나는 for 루프를 사용하여 시도하지만 다음과 같은 오류가 발생 :

OF <- function(w,data){ 

    lambdaSeq <- seq(.001,0.999, length = data$nFP) 
    for(lambda in lambdaSeq){ 
    wmu <- crossprod(w,m) 
    res <- crossprod(w, data$Sigma) 
    res <- tcrossprod(w,res) 
    result <- lambda*res - (1-lambda)*wmu 
    } 
} 

오류 : 누군가가이 점에서 나를 도울 수 있다면

Local Search. 
    Initial solution: 
     |                       | 0% 
    Error in if (xnF <= xcF) { : argument is of length zero 
    Timing stopped at: 0.01 0 0.03 

그것은 좋은 것입니다.

p.s : 또한이 문제는 2 차 프로그래밍을 사용하여 해결할 수 있음을 알고 있습니다. 이것은 다른 제약 조건을 포함하는 시작에 불과합니다.

+0

그렇다면 어떻게 내부 for 루프를 사용할 계획입니까? 지금은 순차적으로 최종'lambda '에 도달 할 때까지 반복합니다. 오류가 발생하지 않더라도 첫 번째 n-1 반복이 실제로 아무 것도하지 않기 때문에 점을 보지 못합니다. . 모든 반복 또는 "최소"결과를 찾고 싶습니까? –

+0

@ Hack-R : 아니요, 모든 반복의 '최소'결과가 아닙니다.나는 람다의 다른 값에 대해 목적 함수의 최소값을 찾고 싶다. 'lambda '의 값은 0에서 1까지입니다. –

+0

'for' 루프의 모든 반복의'min' 결과와 다른 점은 무엇입니까? 'for' 루프는 모든 목적 함수의 코드를 포함합니다. 그러므로 OF의 최소값을 람다보다 더 원한다면'for' 루프의 모든 반복의'min'은 여러분이 원하는 것입니다. 어쨌든, 현재는 모든 반복이 이전 반복을 덮어 쓰므로 마지막 반복의 값만 반환하므로 'lambda'는 1과 동일합니다. 또한이'for' 루프가' LSopt' 기능. –

답변

1

정확하게 이해한다면 지역 검색으로 평균 편차 효율적인 국경을 복제하고 싶습니까? 그런 다음 국경에 포함시키려는 lambda의 모든 값에 대해 지역 검색을 실행해야합니다.

다음 예는 여러분이 도움이 될 것입니다. 먼저 패키지를 첨부하고 목록 data을 설정합니다.

require("NMOF") 
data <- list(m = colMeans(fundData), ## expected returns 
      Sigma = cov(fundData), ## expected var of returns 
      na = dim(fundData)[2L], ## number of assets 
      eps = 0.2/100,   ## stepsize for LS 
      winf = 0,    ## minimum weight 
      wsup = 1,    ## maximum weight 
      lambda = 1) 

다음 I는 최소 분산 경우의 기준 (즉 lambda 한 동일) 계산.

## benchmark: the QP solution 
## ==> this will only work with a recent version of NMOF, 
## which you can get by saying: 
## install.packages('NMOF', type = 'source', 
##     repos = c('http://enricoschumann.net/R', 
##        getOption('repos'))) 
## 
require("quadprog") 
sol <- NMOF:::minvar(data$Sigma, 0, 1) 

객관적인 기능 및 인접 기능. 두 함수를 약간 단순화했습니다 (명확성을 위해 crossprod을 목적 함수로 사용하는 것이 더 효율적입니다).

OF <- function(w, data){ 
    data$lambda * (w %*% data$Sigma %*% w) - 
    (1 - data$lambda) * sum(w * data$m) 
} 

neighbour <- function(w, data){ 
    toSell <- which(w > data$winf) 
    toBuy <- which(w < data$wsup) 
    i <- toSell[sample.int(length(toSell), size = 1L)] 
    j <- toBuy[sample.int(length(toBuy), size = 1L)] 
    eps <- runif(1) * data$eps 
    eps <- min(w[i] - data$winf, data$wsup - w[j], eps) 
    w[i] <- w[i] - eps 
    w[j] <- w[j] + eps 
    w 
} 

이제 로컬 검색을 실행할 수 있습니다. 상당히 큰 데이터 세트 (자산이 200 개)이므로 QP 솔루션을 재현하려면 비교적 많은 단계가 필요합니다.

w0 <- runif(data$na) ## a random initial solution 
w0 <- w0/sum(w0) 
algo <- list(x0 = w0, neighbour = neighbour, nS = 50000L) 
sol1 <- LSopt(OF, algo, data) 

로컬 검색에서 얻는 가중치를 QP 솔루션과 비교할 수 있습니다. 당신은 전체 국경을 계산하려면

par(mfrow = c(3,1), mar = c(2,4,1,1), las = 1) 
barplot(sol, main = "QP solution") 
barplot(sol1$xbest, main = "LS solution") 
barplot(sol - sol1$xbest, 
     ylim = c(-0.001,0.001)) ## +/-0.1% 

마지막으로, 당신은 data$lambda의 다른 수준이 코드를 다시 실행해야합니다.