跳到正文

研究指南

股票组合与模拟研究

组合优化没有可行解怎么办:先查约束再查降级结果

组合没有输出可能有几种原因:约束互相矛盾、输入不足、求解器不能运行,或搜索网格漏掉连续可行点。应分别标记。等权降级即使数字相加为一,只要行业超限,就不能叫优化成功,更不能带着警告继续当成合法下单目标。

本文交付约束账、简短冲突证书和重新校验后的结果。标准库例在三只虚构股票上搜索多头权重,不运行SciPy,也不证明Vibe或CoTrading接入了这些约束。诊断与搜索属于外部扩展,同市场同币种分别研究。

把要求写成明确约束

列证券身份、行业、单股上下限、现金政策、回报风险门槛和目标,区分硬要求与探索假设。“分散一些”不能在优化器内部悄悄变成一个没记录的数字。约束名称应能连接输入来源与验收残差,方便定位到底哪条不满足。

篮子A、B属于Tech,C属于Health。股票权重非负,单股不超过零点六,股票合计一,现金零;示意最低预期回报零点〇五五。这些是合成政策,不是预测或监管上限。不能把虚构输入包装成真实股票的风险预算。

单位和版本一起保存。零点六表示同一组合分母的百分之六十,行业也按这个分母加总。允许现金时明确范围,不先把股票部分归一化为一,再隐藏未配置资金。现金上限与最低股票投资要求可能直接决定可行性。

先验证输入,再求解

权重、限额、回报和风险数值先查有限性,再比较求和。独立 valid() 复核器还会自行检查行业名称、有限非负行业帽、有限非负预算及单股帽,以及有限收益门槛,再验证权重,不依赖 solve() 外层先清理输入。只有abs(sum(weights)-1)>tol不能拦住所有NaN路径,因为与NaN比较可能是假。Python isfinite文档给出显式排除无穷和NaN的接口,样例实际使用。

本例行业映射完整,不认识的受限行业名称拒绝。真实未知分类需要未解决政策,不能假设暴露为零。输入不足也不等于数学无解:缺历史、估计失败、单位未确认,都应先返回数据状态,不交给求解器制造模糊错误。

模式有效与经济假设可信分开。对角方差为正、样本数组齐全,只让玩具目标可计算,不证明预测合理。真实研究保留估计方法、观测窗口和时点,不能因算法返回一个向量,就宣称有可靠投资依据。

准确描述有限搜索

权重只取零至一的零点一步长,穷举三元组,保留满足资金、单股、行业和回报的点,再最小化0.04wA²+0.01wB²+0.0025wC²。没有运行连续规划,也没有完整协方差矩阵,搜索名称与能力必须如实。

预期回报假设为零点〇八、零点〇六、零点〇三。Tech帽零点七、Health帽零点六时,选中[0.2,0.5,0.3],示意预期回报百分之五点五,方差零点〇〇四三二五。代码实际计算并断言这些数,不只复述常量。

这是有限网格最优,不证明连续全局最优。样例的求解器可用标志是注入分支,用来检查状态处理,没有探测用户机器是否安装外部求解库。实际系统应记录真实加载结果,不能拿这次模拟缺失当成环境诊断。

返回向量必须重新验收

成功标志不能替代约束检查,降级向量也走同一验证器。关键顺序如下,再检查每股帽、行业合计与回报门槛:

if any(not isfinite(w) or w < 0 for w in weights):
    return False
if abs(sum(weights) - 1) > tolerance:
    return False

保留逐字段残差,说明失败来自预算、哪股、哪个行业还是回报。本例有明确小容差,不授权放宽实质限制。向量符合要求,也只证明可行;迭代超限或数值异常时,不能因为临时点恰好合规,就说优化已完成。

真实输出还要检查证券顺序与向量长度。把A、B位置交换,权重和仍一,行业或风险含义却可能改变。映射引用和字段单位与数值一起交付,避免一份形式完整的数组在接入时施加到错误证券。

解析冲突证书

把两个行业帽都改为零点四,仍要求股票合计一且不能留现金。Tech与Health覆盖全篮子,最多承载零点八,因而无论网格多细,都无法满足三个要求。这个证明独立于评分和方差,也不依赖运行收益好坏。

证书含全投资、Tech帽和Health帽。仅看这三个约束与基本非负股权界,删任一帽可构造可行点,删全投资可用零向量,因此属于这个子系统的极小冲突。回报门槛不在证书内,不应把证明扩大到全部模型删除一项后必然可行。

它不是搜索所有条件中全局最小冲突集,其他冲突可能同时存在。实用价值是给出一组清楚矛盾及范围,而不是输出无法检查的“优化失败”。需要更全面诊断时,按明确算法继续寻找其他证书,并保留约束版本。

反例:网格没有不代表连续无解

Tech帽零点六五、Health帽零点三五且全投资,会强制Health恰好零点三五,零点一网格无法表示,因此返回no_grid_candidate。但[0.4,0.25,0.35]通过连续约束检查,证明不能把空采样表说成数学无解。

应细化搜索或使用合适求解方法,再判断要求是否矛盾,不能为了粗网格能出一行就擅自放宽限制。记录分辨率和候选数,细化后新结果另立版本,不把早先空结果改写成仿佛一开始就用密网格。

求解器缺失与fallback

可行的零点七/零点六行业帽下,注入求解器不可用,等权经过复核可行,但状态为solver_unavailable_fallback,optimized=False。不能因为它满足限制,就升级成最小方差解;选点来源和完成状态都要保留。

Tech帽零点六时,等权两股Tech合计三分之二,fallback被拒。另有其他可行向量,所以不能据此宣布模型无解。样例不输出带警告的非法权重充数,而是明确没有可接受降级结果,等待其他方法或政策决定。

SciPy linprog文档区分成功、不可行、迭代限制和数值困难。这里只借鉴状态区分,没有执行SciPy,也不把其状态码直接冒充产品接口。真实环境异常与数学证书需独立证据。

约束变化是新的决策

允许至少零点二现金可能解除简单行业容量冲突,但已经改变全投资要求;提高帽或降低目标也改变委托政策,不能作为无痕技术修复。列出替代方案、决定依据和新上下文,保留原失败,便于解释为什么后来有解。

交付包含约束名、单位、来源、残差、状态、准入输出和冲突证书。非法fallback可以保留诊断,但明显标为不能执行。接手者应知道哪里已证明、哪里未知,而不是只拿到一串似乎和为一的权重。

逐项安排确认动作

对缺数据状态,先补齐同一冻结口径输入,不能顺便换股票;对求解器不可用,记录真正的加载错误和可选择方法;对有证书的冲突,交由政策决定,不继续反复重试相同矛盾。对网格未找到,记录搜索分辨率,再决定是否增加位置或更换方法。四种动作不同,不应统一成“自动重跑直到有结果”。

证书复核也要使用其自己的范围。样例为了证明三条约束的极小性,在构造删除一项后的可行点时,没有要求原回报门槛。它证明的是这三条的矛盾,不能据此宣称完整模型只要放宽任一项就一定成功。接手者应看到证书中的约束集合,以及未进入该集合但仍属于原模型的其他要求。

输出行可同时保存状态、是否优化完成、向量、各项检查及下一步。等权可行时,只有检查列通过,优化完成仍为假;等权不合规时,向量只留诊断,准入向量为空。这样的结构能防止下游忽略警告,直接把任意数值数组当作交易目标,也能在以后增加约束时明确哪些输出必须重新验收。

导出还应保存容差单位和检查器版本,避免另一个程序用不同标准重新解释相同向量。

下载完整示例。使用Python 3.12或更新版本,运行python R628.py。断言网格准确指标、解析帽冲突、网格漏点、数据不足、求解器缺失、fallback复核、非有限向量拒绝,以及直接传入NaN行业帽、预算、单股帽和未知行业的约束拒绝。全部合成,不验证真实收益或任意策略持续受约束。

篮子、现金、限制、估计或搜索方法变动后重建。只能接受已测范围,不能把本例几个约束的成功说成Vibe或CoTrading已经统一接入所有限制,也不能把可行配置当作盈利保证。

常见问题

没网格候选就证明无解吗?

不证明,连续可行点可能落在网格之间。

fallback合规就算优化完成吗?

不算,可行与优化完成分别标记。

相关阅读