diff --git a/strategies/shared/signals/selectors.py b/strategies/shared/signals/selectors.py index 4797ffe..5f55cc6 100644 --- a/strategies/shared/signals/selectors.py +++ b/strategies/shared/signals/selectors.py @@ -205,8 +205,9 @@ class TopNSelector(SignalGenerator): return False # 组合完全相同,不调仓 # 计算新旧组合的总得分 - old_total = sum(float(row.get(col, 0)) for col in factor_cols if col in old_codes) - new_total = sum(float(row.get(col, 0)) for col in factor_cols if col in new_codes) + # 修复: 按实际份数计算得分(支持重复代码如"931862.CSI,931862.CSI") + old_total = sum(float(row.get(c, 0)) for c in old_codes) + new_total = sum(float(row.get(c, 0)) for c in new_codes) # 新组合得分需超过当前组合一定比例才调仓 # 即使 threshold=0,也要确保 new_total >= old_total @@ -247,15 +248,13 @@ class TopNSelector(SignalGenerator): selected = [code for code, score in sorted_champions[:self.select_num]] # V3: 空余仓位填充短债 + # 短债填充是防御机制,不应受阈值过滤影响 if cfg.get('fill_bond', False) and bond_code: n_bond_slots = self.select_num - len(selected) if n_bond_slots > 0: - # 检查短债是否满足阈值条件(需在原始scores中存在) - bond_score = scores.get(bond_code, None) - if bond_score is not None: - # 用短债代码填充空余仓位(可能重复填充多次) - for _ in range(n_bond_slots): - selected.append(bond_code) + # 修复: 无条件填充短债(防御仓位不应依赖动量阈值) + for _ in range(n_bond_slots): + selected.append(bond_code) return selected