[Returnanalytics-commits] r2597 - pkg/PortfolioAnalytics/R
noreply at r-forge.r-project.org
noreply at r-forge.r-project.org
Fri Jul 19 03:58:32 CEST 2013
Author: rossbennett34
Date: 2013-07-19 03:58:31 +0200 (Fri, 19 Jul 2013)
New Revision: 2597
Modified:
pkg/PortfolioAnalytics/R/constraint_fn_map.R
Log:
modified rp_transform to better handle max_pos_long and max_pos_short cardinality constraints
Modified: pkg/PortfolioAnalytics/R/constraint_fn_map.R
===================================================================
--- pkg/PortfolioAnalytics/R/constraint_fn_map.R 2013-07-18 22:07:06 UTC (rev 2596)
+++ pkg/PortfolioAnalytics/R/constraint_fn_map.R 2013-07-19 01:58:31 UTC (rev 2597)
@@ -337,14 +337,20 @@
# in randomize_portfolio if min_sum and max_sum were satisfied, but the
# min/max constraints were violated.
+ # Set the tolerance to determine non-zero weights
tolerance=.Machine$double.eps^0.5
+
+ # Set value for max_pos if it is not specified
if(is.null(max_pos)) max_pos <- length(w)
+ # Determine maximum number of non-zero weights
if(!is.null(group_pos)) {
max_group_pos <- sum(group_pos)
} else {
max_group_pos <- length(w)
}
+
+ # Set maximum number of assets based on max_pos and group_pos
max_assets <- min(max_pos, max_group_pos)
# Create a temporary min vector that will be modified, because a feasible
@@ -405,6 +411,45 @@
# violation of any(tmp_w < tmp_min)
tmp_min[not_index] <- 0
+ # Transform weights to satisfy max_pos_long and max_pos_short before being
+ # passed into the main loops
+ # Both max_pos_long and max_pos_short should be specified
+ if(!is.null(max_pos_long) & !is.null(max_pos_short)){
+ pos_idx <- which(tmp_w > 0)
+ neg_idx <- which(tmp_w < 0)
+
+ # Check if number of positive weights exceeds max_pos_long
+ if(length(pos_idx) > max_pos_long){
+ # Randomly sample positive weights that cause violation of max_pos_long
+ # and replace with randomly sampled negative weights from weight_seq
+ make_neg_idx <- sample(pos_idx, length(pos_idx) - max_pos_long)
+ for(i in make_neg_idx){
+ tmp_idx <- weight_seq[weight_seq < 0 & weight_seq >= min[i]]
+ if(length(tmp_idx) > 0){
+ tmp_w[i] <- sample(tmp_idx, 1)
+ } else {
+ # This should never happen if the correct weight_seq and min is specified
+ tmp_w[i] <- -tmp_w[i]
+ }
+ }
+ }
+ # Check if number of negative weights exceeds max_pos_short
+ if(length(neg_idx) > max_pos_short){
+ # Randomly sample negative weights that cause violation of max_pos_short
+ # and replace with randomly sampled positive weights from weight_seq
+ make_pos_idx <- sample(neg_idx, length(neg_idx) - max_pos_short)
+ for(i in make_pos_idx){
+ tmp_seq <- weight_seq[weight_seq > 0 & weight_seq <= max[i]]
+ if(length(tmp_seq) > 0){
+ tmp_w[i] <- sample(tmp_seq, 1)
+ } else {
+ # This should never happen if the correct weight_seq and max is specified
+ tmp_w[i] <- -tmp_w[i]
+ }
+ }
+ }
+ }
+
i = 1
# while sum of weights is less than min_sum or tmp_min/max box or group constraint is violated
while ((sum(tmp_w) < min_sum | any(tmp_w < tmp_min) | any(tmp_w > max) | any(group_fail(tmp_w, groups, cLO, cUP, group_pos)) | (pos_limit_fail(tmp_w, max_pos, max_pos_long, max_pos_short))) & i <= length(tmp_w)) {
More information about the Returnanalytics-commits
mailing list