在R中最大化约束下的股票组合收益:求解权重及optim函数用法
Absolutely! You can absolutely use R's optim() function to solve this portfolio optimization problem—let me walk you through how to set it up properly, since the multi-variable scenario just requires a small tweak to handle your constraint.
Step 1: Simplify the Equality Constraint
Since your weights must sum to 1 (w + x + y + z = 1), we can reduce the number of variables we need to optimize. For example, we can express z in terms of the other three:
z = 1 - w - x - y
This lets us focus on optimizing just w, x, and y—the fourth weight is automatically determined to satisfy the sum constraint, avoiding the need for complex constraint handling in optim().
Step 2: Define the Objective Function
optim() minimizes functions by default, but we want to maximize the portfolio return T. The workaround here is to define a function that returns the negative of T—minimizing this negative value is mathematically identical to maximizing the original portfolio return.
Here’s how to code this:
# Example: Assume we have known next-day returns for the 4 stocks daily_returns <- c(0.02, 0.015, 0.03, 0.025) # r1, r2, r3, r4 # Objective function: Negative of portfolio return (for minimization) objective_function <- function(params) { w <- params[1] x <- params[2] y <- params[3] z <- 1 - w - x - y # Enforce sum-to-1 constraint # Return negative return so optim() minimizes it = maximizing original T - (w*daily_returns[1] + x*daily_returns[2] + y*daily_returns[3] + z*daily_returns[4]) }
Step 3: Set Initial Parameter Values
We need to give optim() a starting point for w, x, and y. A simple choice is equal weights (since they sum to 0.75, z will start at 0.25):
initial_weights <- c(0.25, 0.25, 0.25) # Initial w, x, y
Step 4: Run the Optimization
We have two common scenarios to consider:
Scenario 1: Allow Shorting (Negative Weights)
If you’re allowed to short stocks (weights can be negative), use optim()’s default Nelder-Mead method:
result_unconstrained <- optim(par = initial_weights, fn = objective_function)
Scenario 2: No Shorting (Non-Negative Weights)
For most intraday trading strategies, you’ll want weights to be non-negative (no shorting). Use the L-BFGS-B method to set lower bounds of 0 for each weight:
result_constrained <- optim( par = initial_weights, fn = objective_function, method = "L-BFGS-B", lower = c(0, 0, 0), # w, x, y >= 0 upper = c(1, 1, 1) # Each weight can't exceed 1 (since sum to 1) )
Step 5: Extract and Interpret Results
Pull the optimal weights from the output and calculate z:
# For the constrained (no shorting) case optimal_w <- result_constrained$par[1] optimal_x <- result_constrained$par[2] optimal_y <- result_constrained$par[3] optimal_z <- 1 - optimal_w - optimal_x - optimal_y # Print results cat("Optimal Portfolio Weights:\n") cat(sprintf("w: %.4f\nx: %.4f\ny: %.4f\nz: %.4f\n", optimal_w, optimal_x, optimal_y, optimal_z)) cat(sprintf("Maximized Next-Day Return: %.4f\n", -result_constrained$value))
In our example, the highest return is from the third stock (0.03), so the optimal solution will put 100% weight on that stock (all other weights 0)—which makes intuitive sense when maximizing return without considering risk.
内容的提问来源于stack exchange,提问作者AKshayKulkarni

