2016-10-14 1 views
1

Я пытаюсь реплицировать следующий код (на основе финансовой оптимизации в R by @EnricoSchumann), но я получил следующую ошибку. Код пытается решить модель Марковица с ограничением мощности. Кроме того, он также пытается ограничить значение минимального веса (winf) отличным от нуля.R: Ошибка в sample.int(): пакет NMOF

Ошибка:

Error in sample.int(length(toSell), size = 1L) : invalid first argument

Код

library(NMOF) 
resample <- function(x,...) x[sample.int(length(x),...)] 
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.03,    ## minimum weight 
      wsup = 0.5,    ## maximum weight 
      lambda = 1) 
cat("The Portfolio will consist of at least ", ceiling(1/data$wsup), 
    " assets. \n", sep = "") 

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 
} 


#Initial Random Solution 
makex<-function(data){ 
    resample <- function(x,...) 
    x[sample.int(length(x),...)] 
    w0 <- numeric(data$na) 
    nAssets <- resample(ceiling(1/data$wsup):data$na,1L) 
    w0[sample(seq_len(data$na),nAssets)] <- runif(nAssets) 
    w0/sum(w0) 
} 
w0 <- makex(data) 
algo <- list(x0 = w0, neighbour = neighbour, nS = 5000L) 
system.time(sol1 <- LSopt(OF, algo, data)) 

Предложения приветствуются!

+0

Было бы хорошо, если бы вы показали, где в вашем коде произошла ошибка, это после 'makex (dat)' или ... ?? Можете ли вы поделиться примером «данных», чтобы мы могли видеть, есть ли все переменные, и код имеет смысл? спасибо – user20650

+1

@ user20650: Я редактировал свой вопрос, чтобы показать, где происходит ошибка. Я предполагаю, что это происходит при выполнении соседней функции, т. Е. «Сосед». Я использовал данные 'fundData' из пакета NMOF. Набор данных состоит из возвращаемых значений 200 активов. –

+1

Ваш 'сосед()' вызывает ошибку, т. Е. 'ToSell' или' toBuy' может стать 'integer (0)'. Если вы используете 'sample()' вместо 'sample.int()', ошибка не будет (но это не похоже на существенное решение). – cuttlefish44

ответ

2

Вам понадобится другая функция соседства для достижения того, чего вы хотите, или другого способа реализации ограничения.

Чтобы увидеть, что соседство не будет работать, установите

w0 <- numeric(data$na) 
w0[1:2] <- 0.5 

Что бы правильный шаг от этого портфеля? Функция уменьшит один из двух весов. Тогда он добавит к любому нулевому весу, потому что все они удовлетворяют w < data$wsup; но он полностью игнорирует winf, который вы установили. Это не ошибка в функции , потому что она просто не предназначалась для случая winf > 0.

Район, обеспечивающий максимальную мощность, составляет , указанный в Remarks on 'A comparison of some heuristic optimization methods'.

Но, наверное, самый простой способ пойти об этом, чтобы сделать его оптимизации два этапа: во внешней оптимизации, вы просто выбрать активы, которые должны быть введены в портфель. (Например, см. Asset selection with Local Search.) Затем, для данного выбора активов, решите свою проблему со средним дисперсией .

Смежные вопросы