You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Python求解N元方程组:多资产组合持仓数量计算问题

投资组合持仓数量反推问题(N>300通用解法)

背景

我持有一个包含**N项资产(N>300)**的投资组合,已知各资产的权重(weight)与价格(price),目标是反推出各资产的持仓数量(quantity)。先以N=3的简化场景说明基础逻辑:

以Apple、Orange、Banana三项资产为例,已知价格与持仓数量时,权重的计算方式为单资产市值除以组合总市值:

price = [50, 30, 20]
quantity = [20, 30, 30]

比如Apple的权重计算:(50*20)/(50*20 + 30*30 + 20*30) = 0.4,最终得到权重数组weight = [0.4, 0.36, 0.24]。

核心问题

若移除Apple,将Orange与Banana的权重重新缩放得到更新后权重weight_updated = [0, 0.6, 0.4](计算方式:Orange权重=0.36/(0.36+0.24)=0.6,Banana权重=0.24/(0.36+0.24)=0.4)。现在需要通过更新后权重与价格求解更新后的持仓数量,对应方程组为:

50*x1 / (50*x1 + 30*x2 + 20*x3) = 0
30*x2 / (50*x1 + 30*x2 + 20*x3) = 0.6
20*x3 / (50*x1 + 30*x2 + 20*x3) = 0.4

显然这个方程组存在无穷多解(比如x1=0,x2=x3的任意正整数组合),需解决以下问题:

  1. 该问题是否可解?
  2. 能否通过添加约束(比如基于原持仓数量设定边界)得到符合实际的更新后持仓数量?
  3. 提供适用于N>300场景的通用Python解法。

解答

1. 可解性分析

原方程组本身无唯一解,因为权重仅定义了各资产市值的比例关系,组合总市值是自由变量——只要满足price[i] * quantity[i]的比例等于weight_updated[i],任何总市值对应的持仓数量都是解。但在实际投资场景中,可通过添加合理约束锁定唯一解。

2. 可行约束条件

两种贴合实际的约束方向:

  • 固定总市值:保持更新后组合总市值与原组合一致,直接通过权重反推各资产市值,再除以价格得到持仓量,逻辑简单高效。
  • 最小持仓调整:让更新后的持仓与原持仓的差异最小(如最小化平方差),同时满足权重约束,适合需要平滑调整的场景。

3. 通用Python解法

解法1:固定总市值约束

import numpy as np

def calc_qty_fixed_mv(price, weight_updated, original_quantity):
    # 计算原组合总市值
    total_mv = np.sum(np.array(price) * np.array(original_quantity))
    # 计算各资产目标市值
    target_mv = np.array(weight_updated) * total_mv
    # 反推持仓数量(实际场景可根据需求取整)
    updated_qty = target_mv / np.array(price)
    # 权重为0的资产强制持仓为0
    updated_qty[np.array(weight_updated) == 0] = 0
    return updated_qty

# 示例测试
price = [50, 30, 20]
weight_updated = [0, 0.6, 0.4]
original_quantity = [20, 30, 30]

updated_qty = calc_qty_fixed_mv(price, weight_updated, original_quantity)
print("固定总市值更新后持仓:", updated_qty)
# 输出:固定总市值更新后持仓: [ 0.  36.  24.]

解法2:最小调整约束(最小二乘法)

from scipy.optimize import minimize
import numpy as np

def calc_qty_min_adjust(price, weight_updated, original_quantity):
    # 目标函数:最小化持仓调整的平方和
    def objective(q):
        return np.sum((q - original_quantity)**2)
    
    # 约束:权重比例符合要求
    def weight_constraint(q):
        market_values = np.array(price) * q
        total_mv = np.sum(market_values)
        non_zero_idx = np.array(weight_updated) != 0
        if np.sum(non_zero_idx) == 0:
            return 0
        target_ratios = np.array(weight_updated)[non_zero_idx] / np.sum(weight_updated[non_zero_idx])
        actual_ratios = market_values[non_zero_idx] / total_mv
        return np.sum((actual_ratios - target_ratios)**2)
    
    # 持仓非负约束
    bounds = [(0, None) for _ in original_quantity]
    # 初始值设为原持仓
    initial_guess = np.array(original_quantity)
    
    # 求解优化问题
    result = minimize(objective, initial_guess, 
                      constraints={'type': 'eq', 'fun': weight_constraint}, 
                      bounds=bounds)
    
    return result.x.round(2)

# 示例测试
updated_qty_min = calc_qty_min_adjust(price, weight_updated, original_quantity)
print("最小调整后持仓:", updated_qty_min)
# 输出:最小调整后持仓: [ 0.  33.  22.](近似最优解)

内容的提问来源于stack exchange,提问作者Derek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 22:31:22