0

我为我正在努力解决的优化问题创建了一些示例代码。这个想法是我有一个长度为 100 的向量,它代表各种资产。每个资产都有一个与之相关的因素。有一个持有的流动资产及其分配百分比的向量。由于这是更大预算的一部分,因此该分配的总和小于 100%。目标是移动资产,使分配(在这个问题中为 70%)保持不变,并尽可能接近目标加权平均因子值。另一个限制是不能进行超过 5 个事务。这意味着您可以减少一项资产并添加另一项资产,这将是 2 笔交易。

问题是当我运行这个优化时,它会产生初始权重。我怀疑这是因为一旦进行更改,就会违反 value_constraint。有没有人对如何解决这个问题有任何建议?

这是您可以用来运行模型的代码,我包含了一个虚构的场景(测试用例),其中两种资产被交易为 2 种不同的资产,如果它对您没有帮助,请随意忽略它,但这种场景同时满足约束,并且使用种子(1)会产生更差的结果。

set.seed(1)

number_of_assets <- 100
max_transactions <- 5
sum_of_assets_value <- 0.70

factors <- runif(number_of_assets, 0, 10)

current_weights <- c(rep(sum_of_assets_value/5, 5), rep(0, number_of_assets-5))
current_factor <- current_weights %*% factors

lower_bound <- -current_weights
upper_bound <- rep(sum_of_assets_value, number_of_assets)


#test model manually with simple scenario
weights <- c(rep(0, 2), rep(sum_of_assets_value/5, 5), rep(0, number_of_assets-7)) #test case for functionality
change_count_constraint <- sum((current_weights^2 - weights^2)^2 > 0) <= max_transactions #constraint should be met with only 4 assets changed
total_value_constraint <- sum(weights) == sum_of_assets_value # constraint is met since weights sum to desired amount
new_factor <- weights %*% factors #new factor from the test case
target_factor <- 1.5 #target factor for testing
difference <- (target_factor - new_factor)^2 #square the difference, since we are attempting to minimize the absolute value of the difference
#end test case


 #this is the function for the optimization, includes the two constraints and assigns a penalty if violated
evalFunc <- function(optweights){
  new_factor <- optweights %*% factors

  count_constraint <- sum((current_weights^2 - optweights^2)^2 > 0) <= max_transactions
  value_constraint <- sum(optweights) == sum_of_assets_value
  if(count_constraint == FALSE | value_constraint == FALSE){penalty <- 100000}

  result <- (target_factor - new_factor)^2 + penalty
  result
}


optimization <- optim(current_weights, #starting weights
                      evalFunc, 
                      lower=lower_bound, upper=upper_bound, 
                      method="L-BFGS-B", 
                      control= list(maxit=5000))
4

0 回答 0