4. 网格搜索法:穷举搜索原理、参数空间定义、并行计算加速、结果可视化

网格搜索,说白了就是最笨也最靠谱的方法。你想想看,调参这事儿,很多时候我们凭感觉试,试来试去也不知道最优解在哪。网格搜索的思路特别简单——把所有可能的参数组合都跑一遍,哪个好就用哪个。

我刚开始做量化策略的时候,总觉得网格搜索太low,不够智能。后来被市场狠狠教育了一顿,才发现很多时候简单粗暴的方法反而最有效。嗯,这里要注意,网格搜索虽然基础,但它是理解更高级调参方法的基石。

4.1 穷举搜索原理

穷举搜索,就是遍历所有可能性。比如你有两个参数要调:移动平均线周期(5到50)和止损比例(1%到5%),网格搜索会把这两个参数的所有组合都试一遍。

核心思想:参数空间中的每一个点,都是一个候选策略。网格搜索就是把这些点全部跑一遍,找到表现最好的那个。

我在项目中遇到过一个问题:参数太多,组合爆炸。比如5个参数,每个参数取10个值,那就是10万种组合。跑一遍下来,服务器都要冒烟了。

所以网格搜索虽然原理简单,但实际应用时要注意几个关键点:

  • 参数范围要合理——别从1到10000瞎试,先凭经验缩小范围
  • 步长要合适——步长太小,组合太多;步长太大,可能错过最优解
  • 评估指标要明确——夏普比率?最大回撤?年化收益?得先定好

4.2 参数空间定义

参数空间,就是你要搜索的所有参数及其取值范围。定义得好,事半功倍;定义得差,浪费时间。

我个人习惯把参数分成三类:

参数类型 例子 搜索策略
连续型参数 止损比例、仓位比例 等间距取点,比如0.01, 0.02, 0.03...
离散型参数 移动平均周期、RSI周期 取整数值,比如5, 10, 20, 30
类别型参数 入场信号类型、出场规则 枚举所有类别

举个例子,假设我们要优化一个双均线策略:

# 参数空间定义
param_grid = {
    'fast_ma': [5, 10, 15, 20, 25],      # 快线周期
    'slow_ma': [30, 40, 50, 60, 70],     # 慢线周期
    'stop_loss': [0.01, 0.02, 0.03],     # 止损比例
    'take_profit': [0.03, 0.05, 0.07]    # 止盈比例
}

# 总组合数:5 * 5 * 3 * 3 = 225种

小技巧:我建议先做粗搜索,找到大致范围,再做细搜索。比如先步长10试一遍,找到最优区域后,再步长1精细搜索。这样能省不少时间。

4.3 并行计算加速

网格搜索最大的痛点就是慢。225种组合,如果每种跑1分钟,那就是将近4个小时。你想想看,谁等得起?

好在网格搜索天然适合并行计算——每种参数组合之间没有依赖关系,完全可以同时跑。

我曾经用单核跑一个网格搜索,跑了整整一个周末。后来改成并行,同样的任务,2小时搞定。嗯,从那以后我再也不单核跑了。

Python里实现并行很简单,用multiprocessing或者joblib都行:

from joblib import Parallel, delayed
import itertools

def evaluate_strategy(params):
    fast_ma, slow_ma, stop_loss, take_profit = params
    # 这里跑策略回测
    sharpe = run_backtest(fast_ma, slow_ma, stop_loss, take_profit)
    return (params, sharpe)

# 生成所有参数组合
param_combinations = list(itertools.product(
    param_grid['fast_ma'],
    param_grid['slow_ma'],
    param_grid['stop_loss'],
    param_grid['take_profit']
))

# 并行计算,n_jobs=-1表示使用所有CPU核心
results = Parallel(n_jobs=-1)(
    delayed(evaluate_strategy)(params) 
    for params in param_combinations
)

避坑指南:我曾经并行跑的时候没注意内存,一下子开了100个进程,结果服务器直接卡死。建议n_jobs不要超过CPU核心数的2倍,不然内存会爆。

4.4 结果可视化

跑完网格搜索,你会得到一大堆数据。光看数字很难看出规律,这时候就需要可视化。

我个人最喜欢用热力图——横轴一个参数,纵轴另一个参数,颜色深浅代表策略表现。一眼就能看出哪个区域表现好。

下面是我用SVG画的一个网格搜索结果热力图示例:

网格搜索结果热力图 快线周期 vs 慢线周期 - 夏普比率 1.5 1.2 0.9 0.6 0.3 0.0 70 60 50 40 30 5 10 15 20 25 快线周期 慢线周期 ★ 最优参数组合:快线=10, 慢线=60, 夏普=1.42

从这张图能看出什么?

  • 颜色越绿,表现越好。左上角区域(快线10-15,慢线50-60)明显是甜区
  • 右下角一片红,说明快线太大、慢线太小的时候策略表现很差
  • 最优解在快线10、慢线60附近,夏普比率1.42

除了热力图,我还会用平行坐标图来看多维参数的关系。不过说实话,对于大多数场景,热力图已经够用了。

我的习惯:先画热力图找到甜区,然后在甜区附近再做一次精细网格搜索。这样既不会漏掉最优解,又不会浪费算力。

网格搜索法虽然基础,但它是所有调参方法的起点。你想想看,连所有可能性都没试过,怎么知道哪个参数好?当然,参数多了之后网格搜索就不太现实了,那时候我们会用随机搜索或者贝叶斯优化。但那是后面章节的内容了。

记住一句话:先穷举,再优化。这是量化调参的铁律。


公众号:蓝海资料掘金营,微信deep3321