2026-04-16
遗传算法引入策略框架的系统性讨论
遗传算法引入策略框架的系统性讨论
首先厘清一个根本问题
在讨论"是否引入遗传算法"之前,必须先回答一个更基础的问题:
**你希望遗传算法优化什么?**
选项A:优化参数数值
例如:FIB_RETRACE_MIN从0.20优化到0.23
例如:VOL_RATIO_5M从1.3优化到1.47
→ 这是"参数优化",遗传算法是合适工具之一
选项B:优化策略结构
例如:Gate的顺序是否最优?
例如:哪些Gate可以删除或合并?
→ 这是"结构搜索",遗传算法可以做,但代价极高
选项C:优化信号权重
例如:评分系统中各因子的权重分配
→ 这是"权重学习",遗传算法合适,但机器学习更高效
选项D:以上全部
→ 这是"联合优化",问题空间爆炸,需要非常谨慎的设计
**我的判断:你的核心需求是A+C,即参数数值和因子权重的联合优化。**
第一部分:遗传算法适合做什么,不适合做什么
1.1 遗传算法的本质
遗传算法是一种"启发式搜索"方法
它不保证找到全局最优解
它擅长在"高维、非连续、非凸"的参数空间中找到"足够好的解"
类比:
梯度下降 = 沿坡度最陡的方向下山(快,但容易困在局部最低点)
遗传算法 = 同时派出100个人在山上随机游走,
好的位置多生孩子,差的位置淘汰
最终收敛到一个不错的山谷(不一定是最低点,但通常够好)
1.2 适合引入遗传算法的场景
✅ 参数空间是离散或混合类型
例如:FIB_RETRACE_MIN可以是[0.15, 0.20, 0.236, 0.25]中的一个
例如:MACD_SIGNAL可以是[3, 5, 8]中的一个
→ 无法用梯度方法,遗传算法合适
✅ 参数之间存在非线性相互作用
例如:FIB_RETRACE_MAX和DAYS_SINCE_LOW_MAX组合效果
不是两者分别最优的简单叠加
→ 需要联合搜索,遗传算法合适
✅ 目标函数计算代价适中(非实时)
例如:对历史数据跑一次回测,需要几秒到几分钟
→ 可以承受数百次迭代,遗传算法可行
✅ 有明确的适应度函数(Fitness Function)
例如:夏普率、盈亏比、胜率的加权组合
→ 可以量化评价,遗传算法有操作基础
1.3 不适合或需要谨慎的场景
⚠️ 过拟合风险极高
遗传算法会"找到"让历史数据表现最好的参数
这些参数不一定在未来有效
→ 必须配套严格的样本外验证机制
⚠️ 参数空间过大时计算量爆炸
本策略目前约有35个可调参数
如果每个参数有10个候选值
总参数空间 = 10^35(不可能穷举)
→ 必须先做"参数重要性分析",只优化关键参数
⚠️ 适应度函数设计不当会产生反效果
如果只优化胜率 → 算法会找到"低风险低收益"的参数,频繁小赚
如果只优化最大利润 → 算法会找到"高风险高波动"的参数
→ 适应度函数必须是多目标的,且权重经过深思熟虑
第二部分:策略框架与遗传算法的结合架构
2.1 整体架构设计
┌─────────────────────────────────────────────────────────┐
│ 遗传算法优化层 │
│ │
│ 种群初始化 → 适应度评估 → 选择 → 交叉 → 变异 → 迭代 │
│ ↑ │
│ 适应度函数(核心设计) │
└──────────────────────┬──────────────────────────────────┘
│ 优化后的参数集
▼
┌─────────────────────────────────────────────────────────┐
│ 策略回测引擎(适应度评估器) │
│ │
│ 历史数据(训练集) → 日线筛选层 → 5分钟执行层 → 绩效指标 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 样本外验证层(防过拟合) │
│ │
│ Walk-Forward验证 + 压力测试 + 参数稳定性分析 │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 实盘部署层 │
│ │
│ 定期重新优化(季度/半年) + 参数漂移监控 │
└─────────────────────────────────────────────────────────┘
2.2 "基因"的定义(染色体设计)
这是遗传算法设计中最关键的决策:**什么是一个个体(一套参数)?**
#### 第一层基因:日线筛选参数(结构类)
基因组1:波段结构基因
基因1-1: FIB_RETRACE_MIN 候选值: [0.15, 0.20, 0.236, 0.25, 0.30]
基因1-2: FIB_RETRACE_MAX 候选值: [0.50, 0.55, 0.618, 0.65]
基因1-3: DAYS_SINCE_LOW_MAX 候选值: [5, 6, 7, 8, 10, 13]
基因1-4: REBOUND_MIN 候选值: [0.01, 0.015, 0.02, 0.025]
基因1-5: REBOUND_MAX 候选值: [0.08, 0.10, 0.12, 0.15]
基因1-6: PEAK_SEARCH_WIN 候选值: [21, 26, 34, 42]
基因组2:趋势与均线基因
基因2-1: TREND_MA_FAST 候选值: [5, 8, 10]
基因2-2: TREND_MA_MID 候选值: [13, 15, 20]
基因2-3: TREND_MA_SLOW 候选值: [21, 25, 34]
基因2-4: MAX_DRAWDOWN_GATE1 候选值: [0.25, 0.30, 0.35, 0.40]
基因组3:洗盘质量基因
基因3-1: MAX_SINGLE_DROP 候选值: [-0.05, -0.07, -0.09]
基因3-2: VOL_CLIMAX_RATIO 候选值: [0.30, 0.40, 0.50, 0.60]
基因3-3: MA_SUPPORT_TOL 候选值: [0.02, 0.025, 0.035, 0.05]
#### 第二层基因:动量指标参数(信号类)
基因组4:MACD基因
基因4-1: MACD_FAST 候选值: [5, 8, 10, 12]
基因4-2: MACD_SLOW 候选值: [18, 21, 26]
基因4-3: MACD_SIGNAL 候选值: [3, 5, 6, 9]
约束条件: MACD_FAST < MACD_SLOW,MACD_SIGNAL < MACD_FAST
基因组5:RSI基因
基因5-1: RSI_PERIOD 候选值: [8, 10, 13, 14]
基因5-2: RSI_RECOVERY_MIN 候选值: [8, 10, 12, 15]
基因5-3: RSI_LAUNCH_MIN 候选值: [35, 38, 40, 42]
基因5-4: RSI_LAUNCH_MAX 候选值: [60, 65, 70]
#### 第三层基因:5分钟执行参数(执行类)
基因组6:5分钟入场基因
基因6-1: BODY_RATIO_5M 候选值: [0.35, 0.40, 0.45, 0.50]
基因6-2: CLOSE_POS_5M 候选值: [0.55, 0.60, 0.65, 0.70]
基因6-3: VOL_RATIO_5M 候选值: [1.1, 1.2, 1.3, 1.5, 1.8]
基因6-4: ENTRY_EARLIEST 候选值: ["09:40","09:45","09:50","10:00"]
基因6-5: OPEN_GAP_MAX 候选值: [0.005, 0.008, 0.010, 0.015]
基因组7:止损止盈基因
基因7-1: ENTRY_STOP_BUFFER 候选值: [0.001, 0.002, 0.003, 0.005]
基因7-2: PHASE2_PNL 候选值: [0.015, 0.02, 0.025, 0.03]
基因7-3: PHASE3_PNL 候选值: [0.04, 0.05, 0.06, 0.08]
基因7-4: TP1_PNL 候选值: [0.025, 0.03, 0.035, 0.04]
基因7-5: TP2_PNL 候选值: [0.05, 0.06, 0.07, 0.08]
基因7-6: TRAILING_BARS 候选值: [2, 3, 4, 5]
#### 第四层基因:评分权重基因(最重要)
基因组8:三维度内部权重基因
这一组是最有价值的优化对象
结构维度内部(总分固定40分,内部分配可变):
基因8-1: w_fib_zone 权重比例: [0.3~0.6](回撤位质量)
基因8-2: w_washout 权重比例: [0.2~0.4](洗盘质量)
基因8-3: w_ma_align 权重比例: [0.1~0.3](均线排列)
约束:三者之和=1.0
动量维度内部(总分固定40分,内部分配可变):
基因8-4: w_kline 权重比例: [0.3~0.5](K线形态)
基因8-5: w_rsi 权重比例: [0.2~0.4](RSI恢复)
基因8-6: w_macd 权重比例: [0.1~0.3](MACD)
基因8-7: w_vol_climax 权重比例: [0.05~0.2](量能枯竭)
约束:四者之和=1.0
三维度之间的相对权重:
基因8-8: w_struct 范围: [0.3~0.5]
基因8-9: w_momentum 范围: [0.3~0.5]
基因8-10: w_env 范围: [0.1~0.3]
约束:三者之和=1.0
第三部分:适应度函数设计(最关键的决策)
3.1 为什么适应度函数是最关键的
遗传算法的本质:让参数朝着"适应度函数最大化"的方向进化
如果适应度函数设计错误,算法会精确地找到错误的答案
常见错误设计及后果:
❌ 只用总收益率
后果:算法找到"极少数超大盈利+大量小亏损"的参数
看起来收益高,但风险极大,回撤巨大
❌ 只用胜率
后果:算法找到"频繁小赚"的参数
盈亏比很差,遇到一次大亏就全部吐回
❌ 只用夏普率
后果:算法找到"低波动但收益也低"的参数
夏普率高但绝对收益不足,实际价值有限
❌ 用训练集上的任何单一指标
后果:过拟合,参数完美适配历史,但对未来无效
3.2 推荐的多目标适应度函数
适应度函数设计原则:
1. 多目标加权:同时考虑收益、风险、稳定性
2. 惩罚过拟合:加入参数复杂度惩罚
3. 跨时期一致性:要求参数在不同市场状态下均有效
4. 样本外验证嵌入:适应度的一部分来自样本外表现
**具体公式:**
适应度函数 F =
主要目标(权重0.5):
F_main = Sharpe_ratio × (1 + sign(Calmar_ratio) × 0.3)
其中 Calmar_ratio = 年化收益 / 最大回撤
稳定性目标(权重0.3):
F_stable = 跨N个时间段的 min(Sharpe_ratio)
即:最差时间段的夏普率(越高越稳定)
样本外目标(权重0.2):
F_oos = 样本外期间的 Sharpe_ratio
(通过Walk-Forward验证获得)
惩罚项:
P_overfit = max(0, F_train - F_oos) × 0.5
即:训练集比样本外好太多时施加惩罚
P_complexity = 参数变动幅度 × 0.1
即:参数偏离"基准值"越远,惩罚越重
防止算法找到极端参数值
最终适应度:
F_final = 0.5×F_main + 0.3×F_stable + 0.2×F_oos
- P_overfit - P_complexity
3.3 适应度函数的约束条件
以下情况的参数组合直接淘汰(适应度=-∞):
硬性约束1:信号数量不足
if 回测期间总信号数 < 30:
return -INF
理由:样本太少,统计意义不足
硬性约束2:最大单笔亏损超限
if 最大单笔亏损 > 0.06: # 6%
return -INF
理由:止损失效,风险不可控
硬性约束3:连续亏损次数过多
if 最长连续亏损 > 8次:
return -INF
理由:策略在某段时期完全失效
硬性约束4:年化收益为负
if 年化收益 < 0:
return -INF
理由:策略无价值
软性约束(作为惩罚项而非直接淘汰):
胜率 < 0.45:惩罚 × 0.5
盈亏比 < 1.5:惩罚 × 0.7
最大回撤 > 0.20:惩罚 × 0.8
第四部分:遗传算法的运行机制设计
4.1 种群设计
种群大小:100~200个个体
太小(<50):遗传多样性不足,容易早熟(困在局部最优)
太大(>500):计算量过大,每代评估时间过长
初始化策略:混合初始化
方案A(70%个体):在参数合理范围内随机初始化
方案B(20%个体):以v7.0的基准参数为中心,小幅随机扰动
方案C(10%个体):基于领域知识的"专家解"
例如:已知斐波那契0.382是关键位,以此为种子
理由:纯随机初始化浪费进化资源;
全部用专家解初始化会丧失多样性,过早收敛
4.2 选择机制
推荐:锦标赛选择(Tournament Selection)
从种群中随机选取K个个体(K=5~8)
选择其中适应度最高的作为父代
优于轮盘赌选择(Roulette Wheel)的原因:
轮盘赌:高适应度个体被选中概率与适应度成比例
问题:当个别超高适应度个体存在时,会主导整个种群
("超级个体"垄断,多样性快速消失)
锦标赛:每次只在局部竞争,保留更多多样性
更适合金融回测这类"适应度函数有噪声"的场景
精英保留(Elitism):
每代强制保留前5%的最优个体(不参与交叉变异)
防止"好的参数被随机破坏"
4.3 交叉机制
单点交叉(不推荐用于本策略):
问题:把基因组8(评分权重)的三个约束条件切断
会生成"权重之和≠1.0"的非法个体
推荐:语义感知交叉(Semantics-Aware Crossover)
针对不同基因组使用不同交叉规则:
对基因组1~7(数值参数):均匀交叉
50%概率选父代1的值,50%概率选父代2的值
简单高效,不破坏各参数独立性
对基因组8(权重参数):狄利克雷混合交叉
用一个随机比例α混合两个父代的权重向量
new_weight = α × parent1_weight + (1-α) × parent2_weight
归一化后权重之和仍为1.0,不产生非法个体
不同基因组之间的交叉概率:
基因组1(波段结构):交叉率0.9(高度可交叉)
基因组8(评分权重):交叉率0.7(适当保守)
4.4 变异机制
变异率设计:
总变异率:0.05~0.10(每个基因有5%~10%概率发生变异)
太低:进化停滞,无法跳出局部最优
太高:接近随机搜索,失去进化意义
自适应变异率(推荐):
当种群多样性下降(个体之间适应度差异<5%)时
自动提高变异率至0.20,注入新鲜血液
防止过早收敛
变异方式:
数值型参数(如FIB_RETRACE_MIN):
高斯变异:new_value = old_value + N(0, σ),σ = 参数范围的10%
然后约束到合法范围内
离散型参数(如MACD_SIGNAL候选值列表):
随机替换:从候选值列表中重新随机选择一个值
权重型参数(基因组8):
Dirichlet变异:对权重向量施加小幅Dirichlet扰动
保证归一化约束不被破坏
4.5 终止条件
终止条件(满足任意一个即停止):
条件A:迭代次数达到上限
最大迭代数 = 200代
保证计算时间可控
条件B:适应度收敛
连续20代,最优个体适应度变化 < 0.001
说明已经收敛,继续迭代无意义
条件C:种群多样性极度下降
种群中90%以上个体的参数差异 < 5%
即使未收敛到最优,也说明已陷入局部最优的高密度区
此时应该重启(见多重启动策略)
多重启动策略:
运行3~5次独立的遗传算法(不同随机种子)
每次都运行到终止条件
最终选择5次中适应度最高的解
理由:遗传算法有随机性,单次运行不保证找到最好的结果
第五部分:防过拟合机制(最重要的配套设计)
5.1 数据分割方案
总历史数据(假设使用2015~2024年,10年数据):
┌─────────────────────────────────────────────────┐
│ 2015~2019(5年) 训练集 │
│ 用于遗传算法的适应度评估 │
└──────────────────────┬──────────────────────────┘
│
┌──────────────────────▼──────────────────────────┐
│ 2020~2022(3年) 验证集 │
│ 用于超参数调整(如种群大小、变异率) │
│ 遗传算法本身不能"看到"这段数据进行优化 │
└──────────────────────┬──────────────────────────┘
│
┌──────────────────────▼──────────────────────────┐
│ 2023~2024(2年) 测试集(神圣不可侵犯) │
│ 只在最终决策时使用一次 │
│ 一旦用于评估,该数据不得再用于任何调整 │
└─────────────────────────────────────────────────┘
重要:测试集在整个开发过程中必须"封印"
一旦你用测试集数据调整了任何参数或决策
它就不再是"样本外"数据了
5.2 Walk-Forward验证设计
Walk-Forward验证(滚动样本外验证):
┌──────┬──────┬──────┬──────┬──────┐
│ 训练 │ 训练 │ 训练 │ 验证 │ │ 第1窗口
└──────┴──────┴──────┴──────┘ │
│ │
├──────┬──────┬──────┬──────┤ 第2窗口
│ 训练 │ 训练 │ 训练 │ 验证 │
└──────┴──────┴──────┴──────┘
│
├──────┬──────┬──────┬──────┐ 第3窗口
│ 训练 │ 训练 │ 训练 │ 验证 │
└──────┴──────┴──────┴──────┘
每个窗口:训练期18个月,验证期6个月
窗口滑动:每次向前滑动6个月
共产生N个独立的样本外验证结果
评估标准:
所有验证窗口的 Sharpe_ratio 均值 > 0.8
所有验证窗口中,正收益窗口 > 70%
验证窗口与训练窗口的 Sharpe_ratio 比值 > 0.6
(即样本外至少保留训练集60%以上的性能)
5.3 参数稳定性检验
即使遗传算法找到了好的参数组合
还需要验证这组参数是否"稳健"(Robust)
稳健性的含义:
参数值小幅变动(±10%~20%)时,策略性能不会急剧恶化
稳健性检验方法:敏感性分析
对最优参数组合的每个参数:
原始值: 0.382(FIB_RETRACE_MIN示例)
测试范围: [0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50]
观察:当FIB_RETRACE_MIN在[0.30, 0.40]范围内变化时
Sharpe_ratio是否保持在1.0以上?
如果结论是:
"只有FIB_RETRACE_MIN=0.382时效果好,其他值都很差"
→ 这是过拟合的强烈信号,该参数值不可信
如果结论是:
"FIB_RETRACE_MIN在[0.25, 0.45]范围内表现都不错"
→ 这是稳健的参数,可以信任
第六部分:与策略框架的融合方式
6.1 遗传算法应该优化哪些层
建议优化范围(从高价值到低价值排序):
第一优先级(必须优化):
✅ 基因组8:评分权重
原因:权重是人工主观设定的,优化空间最大
回测验证权重设定是否合理
✅ 基因组1:波段结构参数(FIB区间、时效等)
原因:这是策略核心逻辑,对胜率影响最大
第二优先级(建议优化):
✅ 基因组6:5分钟入场参数
原因:直接决定实际成本,优化空间明确
✅ 基因组7:止损止盈参数
原因:直接决定盈亏比,与第一优先级联合优化效果更好
第三优先级(可选优化):
⚠️ 基因组4/5:MACD/RSI参数
风险:容易过拟合(技术指标参数的曲线拟合问题)
建议:只在候选值集合中选择,不使用连续优化
不建议优化(保持固定):
❌ 均线周期(F5/F8/F13/F21/F34)
原因:这些是斐波那契数列,有数学意义
改变它们等于改变策略的底层逻辑,不应被算法随意调整
❌ 大盘过滤的σ阈值
原因:这是风险管理的底线,不应该为了追求更高收益而放宽
6.2 优化周期与重新优化机制
初始优化(一次性):
使用全部训练集数据运行完整遗传算法
耗时:预计数小时到1天(取决于计算资源)
目的:找到初始最优参数
定期重新优化(持续性):
频率:每季度一次
方式:将最新季度数据加入训练集
以上次最优参数为初始种群(加速收敛)
运行较少代数(50代,而非初始的200代)
目的:适应市场风格的缓慢漂移
触发式重新优化(条件性):
触发条件:连续30个信号的实际胜率 < 0.45
或:实际夏普率比回测值低50%以上
动作:立即进行参数重新评估
原因:市场制度发生重大变化时,原参数可能快速失效
触发条件(更极端):连续5笔交易全部亏损
动作:暂停策略,进入人工审查模式
6.3 遗传算法的局限性与补充机制
局限性1:遗传算法优化的是"平均历史表现"
无法保证在"未见过的市场状态"下仍然有效
补充:在适应度函数中明确包含不同市场状态的表现
局限性2:遗传算法无法改变策略的逻辑结构
它只能在已有逻辑框架内优化参数
如果策略本身的逻辑有问题(如Gate-2的浪顶识别错误)
遗传算法会"修复"参数来绕开这个问题,而非发现问题
补充:结构性缺陷必须人工审查解决,不能依赖算法
局限性3:遗传算法的结果有随机性
每次运行结果略有不同
补充:多次运行(5次以上),取交集稳定参数
局限性4:计算资源需求
评估一个参数组合需要跑一次完整回测
100个个体×200代 = 20000次回测
如果每次回测需要10秒 → 总计55小时
补充:需要并行计算优化,或减少种群大小/迭代数
第七部分:其他算法方案对比
7.1 为什么选遗传算法而非其他方法
候选算法对比:
贝叶斯优化(Bayesian Optimization):
优点:样本效率高(需要的回测次数少,约100~500次)
对计算资源要求低
有成熟的开源实现(Optuna, scikit-optimize)
缺点:在高维参数空间(>20维)效果下降
不适合离散+约束混合的参数空间
适用:参数较少(<15个)、计算资源有限时
结论:与遗传算法相比,在本策略的参数规模下略处劣势
但可以作为快速验证工具
粒子群优化(PSO):
优点:收敛速度通常比遗传算法快
实现简单
缺点:容易早熟(陷入局部最优)
对离散参数支持不好
结论:不推荐,遗传算法在本场景更合适
强化学习(RL):
优点:可以学习动态决策规则(如何根据市场状态调整参数)
理论上最强大
缺点:需要大量训练数据(A股历史数据可能不足)
训练不稳定,超参数调试复杂
实现难度极高
在金融应用中过拟合风险极大
结论:目前阶段不推荐,作为长期演进方向
网格搜索(Grid Search):
优点:简单,结果可重复
缺点:参数空间爆炸(35个参数完全不可行)
结论:只适合2~3个参数的局部验证
遗传算法:
优点:
- 适合高维混合(离散+连续)参数空间
- 自然支持约束条件(权重归一化等)
- 种群多样性机制防止早熟
- 与策略框架的"基因组"设计天然契合
缺点:
- 计算资源需求较高
- 结果有随机性
- 调参(种群大小、变异率等)需要经验
结论:综合评估最适合本策略的优化工具
7.2 推荐的混合方案
实践中最有效的方案:两阶段混合优化
第一阶段:粗粒度搜索(遗传算法)
目的:在整个参数空间中找到"有希望的区域"
种群:100个个体,100代
输出:5~10个候选参数组合
第二阶段:精细优化(贝叶斯优化)
目的:在第一阶段找到的区域内精细搜索
输入:遗传算法输出的候选组合作为初始点
输出:每个候选区域的局部最优解
最终选择:
对第二阶段的输出,进行Walk-Forward验证
选择样本外表现最稳健的参数组合
结论与讨论优先级
引入遗传算法的整体判断
结论:值得引入,但需要配套机制,否则适得其反
值得引入的理由:
1. 本策略有35+个可调参数,人工调参效率极低
2. 参数之间存在非线性交互,单独调整无法找到最优组合
3. 评分权重的主观设定缺乏数据支撑,需要客观优化
4. 市场会缓慢漂移,需要定期自动重新优化
必须配套的机制:
1. 严格的样本外验证(否则遗传算法会精确地过拟合)
2. 参数稳定性检验(否则找到的是脆弱的历史最优)
3. 硬性约束条件(否则算法会找到"胜率高但风险失控"的参数)
4. 定期重新优化机制(否则参数会随市场变化而失效)
下一步需要明确的问题
在开始编码之前,以下问题需要你来确认:
问题1:计算资源
你有多少计算资源?(普通电脑、云服务器、GPU集群)
这决定种群大小和最大迭代数的上限
问题2:历史数据范围
你能获取多少年的历史数据?
数据越多,训练集/验证集/测试集的划分越合理
问题3:优化目标优先级
在以下目标中,你的优先级排序是什么?
胜率 / 盈亏比 / 最大回撤 / 夏普率 / 信号频率
问题4:重新优化频率
季度重新优化是否可接受?
还是希望更高频(月度)或更低频(半年)?
问题5:参数固定范围
哪些参数你有强烈的主观判断,不希望被算法改变?
例如:均线周期是否必须保持斐波那契数列?