简介:这是一份详细讲解网格交易策略优化的技术文档,面向量化交易爱好者与Python股票分析学习者。内容以自动调整网格大小为核心,针对传统网格策略中网格固定导致过早满仓或空仓的缺陷,提出基于标准差与RSV指标动态调整买入、卖出网格的方法。文档不仅解释了标准差衡量波动性的原理,还说明了RSV值在上升和下降趋势中对买卖网格的差异化影响,使读者能根据市场环境动态调节仓位,降低回撤风险。文中包含具体公式、计算逻辑及实例,如初始网格0.5元、RSV=0.85时买入网格0.15元、卖出网格0.85元等,帮助读者理解并实现自适应网格策略。资源包共1个docx文件,大小165KB,内容完整精炼。已有6362人学习,适合具备一定Python基础、希望提升量化策略适应性的投资者参考。文档源自实战总结,结合统计学与技术分析,对于构建个人股票分析工具具有实用价值。
1. 网格交易最怕的不是单边行情,而是网格不会呼吸
网格交易最怕的不是单边行情,而是网格不会呼吸。固定网格在波动率放大时容易在一次快速行情中堆满逆势仓位,波动率收缩时又长时间不出单,资金闲置。自动调整网格大小这件事,核心不是把间距做成变量,而是让网格间距跟随市场波动率变化——波动率大就放宽、波动率小就收紧。这个方法适合那些已经跑过固定网格、被行情折磨过、想在不改交易逻辑的前提下提升策略自适应能力的从业者。下文从定价机制讲起,给出三种可落地的自动调整方案、一份最小可回测实现、五个高频翻车点,以及一个关于加仓节奏的进阶技巧。
2. 固定网格为什么在真实行情里总是先赚后亏:定价机制与失效点
2.1 网格定价模型:你赚的其实是波动率收益
网格交易的收益来源,本质是波动率的重复收割。策略在某个价格区间内均匀挂出买单和卖单,价格每向下穿越一格,成交一笔买入;每向上穿越一格,成交一笔卖出。只要价格仍在网格区间内来回运动,每一次穿越都完成一次完整的低吸高抛,落袋的利润等于网格间距乘以持仓数量,再扣除手续费。
单格收益 = 间距 × 仓位数量 ×(1 - 手续费率)。这是网格定价的基准公式。从这个公式能直接引出两个判断:第一,间距太小,单格利润被手续费侵蚀,成交量再大也白做;第二,间距太大,价格在两条网格线之间来回但碰不到边界,资金闲置。自动调整网格大小,就是在这个公式的两端找平衡点。
手续费率的影响常被低估,尤其在波动率收缩期。假设一个标的的单边手续费是0.05%,一次完整的买加卖需要吃掉0.1%的成本。如果网格间距是0.2%,单格毛利润只有0.2%,扣掉手续费只剩0.1%,再算上滑点,利润所剩无几。很多固定网格策略在震荡市里频繁成交却缓慢亏损,原因并不在方向判断,而在于间距设定低于了成本线。
2.2 固定网格的三个失效场景
场景一:波动率收缩。价格在两条网格线之间反复震荡但始终不触及边界,常见于节假日或大行情前夜。网格看起来一直在运行,实际没有任何成交,资金闲置。此时固定网格的问题是「间距太大、呼吸太慢」。时间一长,机会成本累积,资金占用在别处可能赚到更多。
场景二:波动率膨胀。某个数据发布或突发消息让价格在短时间内快速穿越多格。固定网格的买单被连续触发,持仓成本迅速抬升。如果之后行情没有回到原区间,账户就背着一堆亏损单。这里的问题是「间距太小、呼吸太快」。更麻烦的是,膨胀期往往伴随趋势启动,网格的逆势加仓逻辑在趋势里就是接飞刀。
场景三:波动率漂移。价格中枢从原来的锚定区间慢慢移开,网格线还是旧的。结果永远只有一侧订单在成交,另一侧长期挂空。这种情况最隐蔽,短线回测里很难暴露,因为回测区间内的漂移幅度往往不够大。等你在更长的历史数据里复盘时,才发现整个网格实际只在三分之一的价格范围内工作过。
2.3 自适应的真正目标
自适应的目标不是消灭风险,而是让网格的呼吸频率跟随市场波动率的实时状态。波动率数据本身具有自相关性和均值回归性:高波动率之后倾向于回归常态,低波动率之后倾向于放大。用波动率数据来校准网格间距,就是把「行情节奏」这个隐藏变量显式地塞进策略。
这里要澄清一个常见误用:自适应不等于每天都改网格,也不等于让网格间距变成一个随时抖动的随机值。理想的调整频率是「跟随但不追噪」——用一段时间的确认信号来调整,而不是用单根K线的瞬时波动来抖动。这个度的把握,决定了你的自适应是加分项还是负贡献。我在早期版本里吃过亏:把网格间距绑定在5周期ATR上,结果间距跟着单根阳线阴线来回跳,手续费损耗比固定网格还大。后来把ATR周期拉到14以上,才真正稳定下来。
3. 自动调整网格大小的三种主流方案:从波动率锚定到市场状态切换
3.1 方案一:用ATR动态计算网格间距
ATR(Average True Range,平均真实波幅)是衡量近期真实波动幅度最常用的指标,它同时考虑K线的上下影线和跳空,比单纯用标准差更贴近交易实际。常见做法是把网格间距设置成ATR乘以一个密度系数k,k通常取0.2到1.0之间的值。例如ATR当前是50,k取0.5,网格间距就是25个价格单位。
这个方案的优点是实现简单、参数少,只要把当前ATR带入公式即可。缺点是ATR是滞后指标,遇到波动率突变行情,网格调整会慢半拍;而且单一ATR没有「波动率处于什么水平」的信息,低波动期和高波动期的ATR绝对值差异很大,直接乘系数很难兼顾两端。比如同样的k值,在ATR为20的时候间距是10,在ATR为80的时候间距是40,后者对网格密度的控制明显偏松。
3.2 方案二:滚动窗口波动率百分位法
改进的方向是给波动率找一个历史位置。把过去N天的ATR序列存下来,计算当前ATR处于这段历史中的百分位。比如过去240个小时K线里,当前ATR比其中85%的时候都高,那百分位就是85%,说明波动率处于偏高水平,网格应该放宽。反过来,如果百分位只有15%,说明波动率压得很低,网格应该收窄。
百分位法的天然优势是标准化:不同标的、不同时间段的波动率绝对值差别大,但百分位始终在0到1之间,参数设置与标的价格水平无关,迁移到别的品种时只需重新计算窗口,不需要重新调间距的绝对数值。窗口长度一般取120到480之间,小时线我习惯用240,覆盖大约10个交易日的波动率分布,正好能包住一轮收缩-膨胀循环。
计算逻辑就是把历史ATR序列当成参考分布,当前值在分布里的排序位置就是百分位。这个方案在实盘里的表现比直接乘ATR稳定得多,因为它天然过滤了波动率的长期趋势偏移,只关注「相对自己的历史位置」。
3.3 方案三:多周期波动率状态机
更进一步的做法是把市场分成若干个波动率状态。常见做法是同时看短周期(比如4小时ATR)和中周期(比如日线ATR),再把价格相对均线的位置加进来,生成一个状态:低波动震荡、中波动震荡、高波动趋势、高波动震荡等。每个状态对应一组网格参数。
状态机的优势是显式地处理趋势风险:当识别到高波动趋势状态时,可以直接把网格间距拉大、层数减半,甚至暂停反向加仓。缺点是状态转换逻辑如果设计得不好,会产生频繁切换的乒乓效应,反而干扰交易。我见过一个小组把状态机做成四态,结果边界处的参数敏感性太高,一天之内状态翻转十几次,手续费损耗翻倍,最后只能把转换条件加上滞后确认才压住抖动。
3.4 三种方案选型对比
| 方案 | 核心变量 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|---|
| ATR直接乘系数 | 当期ATR | 实现简单、参数少 | 滞后、无波动率水平概念 | 快速验证、波动率相对稳定的标的 |
| 滚动窗口百分位 | ATR历史百分位 | 标准化、跨品种复用 | 需维护滚动窗口、窗口长度敏感 | 多品种复用的量化小组 |
| 多周期状态机 | 长短周期ATR + 价格位置 | 能处理趋势状态 | 状态切换可能抖动、调试复杂 | 单品种深耕、已有风控框架 |
选型建议:如果目标是先跑通自适应流程,从方案一开始;如果要在多个标的上复用,直接上方案二;如果已经有一套完整的量化框架,能接受更多调试成本,再考虑方案三。我在实际项目中,最终稳定使用的是方案二加一个简单的趋势过滤,方案三的概念吸收进来但没做完整状态机,因为维护成本太高。
4. 把方案落成可回测的代码:网格自适应最小实现
4.1 准备行情数据
自适应网格的回测,最基础的数据需求是K线,建议直接用小时线。小时线能在波动率变化时较快给出反应信号,又不像分钟线那样充满噪音。数据字段至少要包含时间、开盘、最高、最低、收盘、成交量。
常见做法是先从数据服务商导出CSV文件,本地做清洗。数据清洗有三件事必做:按时间排序、去掉重复K线、检查是否有缺失的时间戳。顺序错了会在后面计算ATR时出现连续错误。我一般会额外用 pandas 的 ffill 把缺失的K线做前向填充,避免因为数据空洞导致ATR出现跳变。
import pandas as pd import numpy as np def load_klines(path): """读取K线CSV,字段: datetime, open, high, low, close, volume""" df = pd.read_csv(path, parse_dates=['datetime']) df = df.sort_values('datetime').reset_index(drop=True) df = df.drop_duplicates(subset='datetime') df = df.ffill() return df逻辑说明:排序保证时间顺序正确,去重防止同一根K线被重复计数,ffill 用前一根K线的数据补上缺失的时间戳。这样清洗后的数据在计算ATR时不会出现因为索引错位而导致的跳变值。注意 ffill 只能用于修复零星缺失,如果某段行情整体缺失,前向填充会制造虚假的「无波动」区间,需要额外检查。
4.2 核心代码:波动率驱动的网格生成
下面是一套最小可回测的自适应网格实现,整体逻辑:前一根K线收盘后确认新的ATR,然后用这个ATR计算新的网格间距,生成新的网格线,再把未成交订单迁移到新网格上。
def calc_atr(df, period=14): """计算平均真实波幅,period为K线周期数,小时线一般取14~24""" prev_close = df['close'].shift(1) tr = pd.concat([ df['high'] - df['low'], (df['high'] - prev_close).abs(), (df['low'] - prev_close).abs() ], axis=1).max(axis=1) df['atr'] = tr.rolling(period).mean() return df def calc_spacing(atr_now, target_atr, base_pct=0.6, min_pct=0.3, max_pct=2.0): """把当期ATR映射到网格间距百分比。 atr_now: 当前确认的ATR target_atr: 参考基准ATR,一般取滚动窗口的中位数 """ vol_factor = atr_now / target_atr vol_factor = np.clip(vol_factor, 0.5, 3.0) spacing = base_pct * vol_factor spacing = np.clip(spacing, min_pct, max_pct) return round(spacing, 4)逻辑说明:calc_atr 里用三行分别计算真实波幅的三个候选值——当前K线高低价差、最高价相对前收盘的跳空、最低价相对前收盘的跳空——取最大值,再做滚动平均。calc_spacing 是关键映射函数,把ATR相对目标水平的比值压缩到0.5到3.0之间,再乘以基准网格间距,最后用上下限夹住。这样做的效果是网格间距只对波动率的中速变化产生响应,避免极端值导致间距失控。
def generate_grid(center, spacing_pct, up_levels=5, down_levels=5): """以center为中心生成网格线,返回价格列表,升序排列""" lines = [] for i in range(-down_levels, up_levels + 1): price = center * (1 + spacing_pct / 100.0 * i) lines.append(round(price, 6)) return sorted(lines) def remap_order_price(order_price, new_grid, tolerance_pct=0.15): """把旧订单价映射到最近的新网格线。 若新旧价格偏离超过 tolerance_pct,则返回 None 表示需要撤销重挂 """ nearest = min(new_grid, key=lambda x: abs(x - order_price)) diff_pct = abs(nearest - order_price) / order_price if diff_pct <= tolerance_pct: return nearest, 'keep' return None, 'cancel'逻辑说明:generate_grid 用等比方式生成网格线,而非等差方式,因为价格变动是按百分比理解的,等比网格在不同价位区间的实际间距比例一致。remap_order_price 解决的是网格重排后旧订单的去向问题——距离最近的网格线如果偏离不大就迁移过去,偏离太大就标记撤销,防止订单挂在一个明显不合理的价位上。
主循环里最需要注意的是未来函数。网格间距必须在当前K线收盘后,用已经确认的ATR来计算,再应用到下一根K线的交易中。如果直接用当前K线的最高最低算出ATR,再用它决定同一根K线的挂单,回测结果会非常好但实盘必崩。
def backtest(df, target_atr, init_price, atr_period=14, base_pct=0.6, up_levels=5, down_levels=5): """自适应网格回测主体,逐根K线执行订单迁移与成交判断。""" df = calc_atr(df, atr_period) # 初始化网格,使用第一根可用的ATR first_idx = atr_period spacing = calc_spacing(df['atr'].iloc[first_idx], target_atr, base_pct) grid = generate_grid(init_price, spacing, up_levels, down_levels) active_orders = [] equity_curve = [] for i in range(first_idx + 1, len(df)): row = df.iloc[i] # 用上一根K线确认的ATR更新网格,避免未来函数 atr_now = df['atr'].iloc[i - 1] spacing = calc_spacing(atr_now, target_atr, base_pct) new_grid = generate_grid(row['close'], spacing, up_levels, down_levels) # 迁移未成交订单 moved = [] for order in active_orders: new_price, action = remap_order_price(order['price'], new_grid) if action == 'keep': moved.append({**order, 'price': new_price}) active_orders = moved # 简化撮合:价格触及订单价即成交 filled = [] for order in active_orders: if order['side'] == 'buy' and row['low'] <= order['price']: order['filled_price'] = order['price'] filled.append(order) elif order['side'] == 'sell' and row['high'] >= order['price']: order['filled_price'] = order['price'] filled.append(order) # 补充新订单(简化:成交一笔补一笔同方向订单) for order in filled: active_orders.remove(order) new_order = {'side': order['side'], 'price': order['price'], 'filled': False} active_orders.append(new_order) # 记录净值,用于后续统计(此处省略持仓盈亏计算) equity_curve.append(len(active_orders)) return equity_curve这个回测骨架是高度简化的,省略了手续费、滑点和复杂补单逻辑,但核心机制已经完整:ATR驱动间距更新、订单迁移、避免未来函数。真实使用时要补上资金曲线计算和手续费扣除。注意撮合逻辑里用了row['low'] <= order['price'],表示只要K线最低价触及买单价格就算成交,这是常见的保守假设,但忽略了K线内部的路径顺序,极端行情下可能有偏差。
提示:生产级回测还需要处理交易手续费、滑点和补充挂单逻辑。上面这段骨架代码只能验证核心机制,不能直接作为资金管理工具。
4.3 参数标定:窗口长度、目标波动率、网格密度怎么设
参数设置是自适应网格里最容易被低估的部分。先看一张常用参数表:
| 参数 | 建议区间 | 默认值 | 调参方向 |
|---|---|---|---|
| ATR周期 | 7~30 | 14 | 越大越平稳,越小越灵敏;小时线建议14~24 |
| 基准网格间距 | 0.4%~1.0% | 0.6% | 与标的历史日均波幅成比例 |
| 间距下限 | 0.2%~0.5% | 0.3% | 下限必须覆盖双边手续费加滑点 |
| 间距上限 | 1.5%~3.0% | 2.0% | 控制单边行情中的单格亏损 |
| 网格层数 | 上下各4~10 | 5 | 层数决定最大持仓比例 |
ATR周期的选定原则是覆盖一个完整的波动率周期。波动率收缩-膨胀的循环,在小级别上通常需要几十根K线,所以14是一个经验起点。如果窗口太短,比如用3,网格间距会追着单根K线的噪音跑;如果太长,比如60,调整反应就会明显滞后,自适应演变成「慢半拍的大网格」。
基准网格间距建议取标的过去一段时间平均真实波幅的一半到三分之一。这个逻辑是:如果平均波幅是1%,那么0.5%的间距能在一次普通行情中触发两次成交,收益的覆盖密度比较理想。至于上下限,下限要覆盖双向手续费加上滑点的估计值,上限要控制在单边行情中一次穿越最多让账户承担两格亏损的范围内。
target_atr这个基准值怎么取?常见做法是取滚动窗口内ATR的中位数,而不是均值。因为ATR序列右偏——大波动率事件会把均值拉得很高,中位数更能代表「常态波动率」。我在实现里一般用过去240根K线的ATR中位数作为 target_atr,这样网格间距的高低锚点会随着市场整体波动水平的缓慢变化而自动漂移。
4.4 从回测到模拟盘:切换前必须检查的三个指标
跑完回测不要急着上模拟盘,先看三个指标。
第一个是最大回撤。自适应网格在波动率脉冲行情下会有明显的持仓堆积期,回撤会比固定网格更深一些,这是正常的。要确认深回撤具体发生在回测的哪个时段,并对照当时的波动率百分位,判断是否合理。如果深回撤出现在波动率百分位很低的位置,说明网格间距收得过窄,持仓没有及时建起来,反而是资金利用率的问题。
第二个是单边行情中的持仓峰值。把回测区间里持仓数量最大的时段单独拉出来,检查那段时间行情是否单边运行、网格是否处于完全逆势的状态。如果持仓峰值出现在波动率的快速放大期,说明自适应调整的响应速度还不够快,需要缩短ATR周期或调大间距上限。这两个改动方向是相反的,需要搭配调整,不要只动其中一个。
第三个是手续费损耗率。把回测中的总成交笔数乘以单笔手续费,再除以总盈利,看这个比例是否超过30%。如果超过,说明间距下限设置偏低,网格在低波动期过密,实际是在给交易所打工。这三个指标任何一个异常,都先不要上模拟盘,回测框架先改到正常为止。
模拟盘阶段还有一件事容易忽略:不要把自适应网格的自动调参和手动干预混在一起。模拟盘的意义是验证策略在无人值守状态下是否稳定。如果每天都手动改参数,模拟盘就失去了验证意义。我一般会让模拟盘跑满两周,期间只看日志不碰参数,除非出现极端行情触发了预警。
5. 网格自适应避坑指南:参数过拟合与网格漂移的典型翻车现场
5.1 网格间距追着噪音跑,低波动期疯狂成交
现象:波动率收缩时,ATR快速下降,网格间距被压缩到下限附近。间距变小导致成交频率大幅提高,但每一格的利润变薄,手续费损耗占比急剧上升,账户在一段看起来行情平稳的时间里缓慢失血。
原因:ATR窗口设置太短,比如用了5甚至3,波动率数据对单根K线的涨跌过度敏感,网格间距变成了高频抖动变量。加上间距下限没有覆盖手续费成本,低波动期变成「高成交低利润」的绞肉机。
解决:把ATR周期提到14以上,同时在calc_spacing函数里增加一个间距变化率限制,让每次调整幅度不超过当前间距的20%。这个变化率限制相当于给网格间距加了一个惯性,过滤掉单根K线引发的跳变。如果发现低波动期仍然成交频繁,把间距下限从0.3%上调到0.5%附近,用成本线反过来约束下限。
5.2 网格重排后订单迁移错位,挂在无人问津的价格上
现象:某个订单原本挂在网格的-2格位置,网格重排后它被迁移到新网格的-1格,但价格重心已经下移,这个订单实际上永远等不到成交,而真正的成交机会出现在更深的位置。
原因:remap_order_price的容忍度阈值设置过宽,比如0.3,订单被强行保留在了一个不合理的位置,而不是撤销重挂。旧订单占用了资金和网格槽位,新网格的对应位置又无法补单,整个网格密度被虚占。
解决:把 tolerance_pct 收紧到0.1到0.15之间。对于超过容忍度的订单,撤销后等待价格进入新网格边界内再重新挂出,而不是立即以当前价挂单。这个延迟重挂的细节,能显著减少网格重排时的无效订单。注意撤销重挂会产生撤单手续费和重新挂单的滑点,这也是为什么容忍度不能设得太小,要平衡迁移和重挂的成本。
5.3 回测收益曲线很漂亮,模拟盘完全走样:未来函数
现象:回测年化收益20%以上,最大回撤不到5%,上模拟盘后第一周就出现连续亏损,收益曲线和回测完全不在一个维度。
原因:最常见的是在回测中使用当根K线数据计算当根K线使用的ATR,也就是未来函数。比如用第i根K线的高低价算出的真实波幅,去决定第i根K线的网格位置,而实盘中第i根K线结束时你才知道它的真实波幅。这种情况在回测里通常以「每根K线都精准调整」的方式体现,收益会被显著夸大。
解决:统一用df['atr'].shift(1)来取ATR,保证决定网格用的ATR永远来自前一根已收盘的K线。回测完成后,随机抽出10个时间点,人工检查该时点网格间距使用的ATR数值是否来自上一个时间戳。这是检查未来函数最直接的方法。如果发现回测里某根K线的成交价格精确踩在当根K线波动区间的极值上,也要警惕路径依赖的过度理想化。
注意:未来函数是回测里最隐蔽的坑,自适应网格尤其容易踩,因为「用当期波动率决定当期网格」在直觉上太自然了。任何用到滚动统计量的策略,都要在代码里强制shift(1)。
5.4 震荡转单边时,自适应网格放大单边亏损
现象:市场从震荡切换到单边上涨时,波动率快速放大,自适应网格按照预期放宽了间距。间距变大让每次买入的触发距离变大,但价格一路向上,网格在每一格都成交买单,接飞刀的层数虽然因为间距变宽而变少,亏损幅度却因为间距扩大而更深。
原因:间距和层数是两个独立的维度,自适应只调整了间距,没有同步收缩层数和总仓位上限。价格快速穿越时,网格在更大间距上接货,单格亏损额 = 间距 × 仓位数,反而放大。这是自适应网格最常见的逻辑漏洞:以为间距已经自适应了,风险就自动控制了,实际上层数不变,总敞口不降,风险反而因为间距扩大而上升。
解决:在调整间距的同时,把网格层数与波动率百分位挂钩。波动率百分位超过70%时,层数从默认的5层减到3层,同时设置一个硬性的最大持仓比例限制。这样高波动时「间距放宽、层数收缩」,总风险被限制在一个可接受的范围内。更进一步可以加趋势过滤器:当价格突破网格最高线上方一定比例时,暂停新增买单,只保留已有持仓的卖出订单。
5.5 参数反复调优后的过拟合:walk-forward是后悔药
现象:某个开发者在回测里反复调参,把基准网格间距、ATR周期、上下限都调到了刚刚好,回测曲线完美得不可思议。上模拟盘后两个星期就出现了回测里没有过的连续亏损段。
原因:过拟合。参数是针对那段历史行情调出来的,行情结构一变,参数组合立刻失效。尤其是在波动率上做自适应的策略,天然比固定网格多了一组参数,过拟合空间更大,这点常被忽略。看起来像是「波动率自适应」,实际可能只是「对过去某段波动率形态的过拟合」。
解决:使用 walk-forward 前推验证。把历史数据按时间切成几个连续片段,比如每3个月一个窗口,用前9个月调参,在接下来3个月做验证,依次滚动。一个参数组合必须在至少三个不重叠的验证时段都展现出可接受的收益回撤比,才算初步通过。这个方法不能杜绝过拟合,但能把侥幸一次成功的概率大幅降下来。我在每次调参后都会跑一遍 walk-forward,这个过程虽然费时间,但能省掉模拟盘阶段的大量无效尝试。
6. 进阶:用波动率分位数决定加仓节奏,而不是只调网格间距
到这里,自适应网格的间距调整已经能稳定工作了,但还可以往上走一步:让仓位也随着波动率百分位变化。这个技巧的思想是「波动率高时,每一格的价格意义更大,应该重手但少格;波动率低时,每一格的价格意义更小,应该轻手但耐心等它恢复」。
具体做法是维护一个过去240根K线的ATR序列,计算当前ATR的百分位:
def calc_vol_percentile(atr_now, atr_history): """当前ATR在历史序列中的百分位,返回0~1之间的值""" return float((atr_history < atr_now).mean())然后设三档规则:百分位低于0.3,层数不变、单层仓位减半,网格间距取下限附近,等待波动率回归;百分位在0.3到0.7之间,用标准参数;百分位高于0.7,层数减半、单层仓位乘1.5,间距取上限附近,同时收紧总持仓上限。这个组合的精髓在于:高波动时赚到的每一格利润变大了,但整体暴露在单边行情下的总仓位反而更小。
把间距调整和仓位调整放在一起,回测结果通常会出现一个有意思的现象:收益不一定提高,但回撤会明显变小,因为高波动期的仓位暴露被主动压低了。这才是自适应网格真正的价值。固定网格赚的是波动率的钱,自适应网格赚的是「波动率变化规律」的钱。
我在实际项目里走过的弯路是:一开始只做了间距自适应,觉得这就是全部,结果在单边行情里被连续打脸;后来把层数和仓位纳入调整范围,才算是把这个问题想完整了。现在我的习惯是每次调整参数之前,先问自己一句:这个参数调整之后,是让网格更聪明了,还是只是让回测更好看了?如果是后者,宁可什么都不改。希望帮到你。
本文还有配套的精品资源,点击获取