首页 / 资讯中心 / 文章详情

网格交易如何自动调整网格大小?基于ATR波动率的自适应策略

网格交易如何自动调整网格大小?基于ATR波动率的自适应策略 ★ FEATURED ARTICLE
简介针对网格交易策略中固定网格大小易导致过早满仓或空仓的痛点这份文档系统讲解了一种基于波动率与RSV指标自动调整网格步长的量化方法适合使用Python进行股票分析、希望优化网格交易策略的投资者参考。资源为单个docx文档压缩包约165KB目前已有6360人学习浏览。文档从网格交易的基本原理与两大缺陷切入重点介绍魔灯提出的自适应方案一方面以收盘价、最高价、最低价的标准差衡量市场波动程度波动大时放大网格波动小时缩小网格另一方面将买入/卖出网格与RSV值挂钩上升趋势中买入网格变小、卖出网格变大下降趋势则反向设置。内容还包含“初始网格0.5元、RSV为0.85时买入网格0.15元、卖出网格0.85元”等具体计算案例并附有相关Python股票分析软件与社区交流信息便于读者理解思路后直接实践。1. 网格交易最该改的从来不是买卖点而是网格大小很多人做网格交易一上来就把精力花在选币、选区间、定上下边界上等行情一变化就被打回原形。震荡行情里跑得好好的固定网格换成单边行情或者波动率突然放大的阶段要么一单都成交不了要么连续成交后浮亏迅速堆满。真正让网格策略存活下来的其实是“自动调整网格交易策略中网格大小”这个能力K线波动变大的时候主动把网格拉宽波动收窄的时候把网格收紧让每一格利润始终覆盖得住成本同时又不至于在趋势行情里被反复打脸。这篇文章就是讲这套逻辑怎么落地面向的是手动维护网格参数已经维护到烦、以及想把参数从硬编码改成自适应计算的那批人。2. 自动调网格的理论基础波动率与网格间距的量化关系2.1 ATR动态网格一个被反复验证的基准方案网格大小之所以要跟着波动率走是因为网格交易的每一笔利润本质上来自“价格在网格间来回穿越”。价格波动幅度变小的时候固定的大网格会长时间不成交资金闲置价格波动幅度变大的时候固定的小网格会让价格连续穿过好几个格子每个格子都成交但每个格子赚的钱可能连手续费都不够填。所以网格间距必须和波动率挂上钩。衡量波动率最朴素也最常用的工具是ATR平均真实波幅。计算公式不复杂真实波幅TR取三个值中的最大值当前K线最高价减最低价、当前K线最高价减前一根K线收盘价的绝对值、当前K线最低价减前一根K线收盘价的绝对值。ATR就是TR在N个周期内的均值也可以用EMA来平滑。不要被公式吓住它做的事情很简单统计出“最近这根K线平均能跑多远”这个距离天然就是网格间距的量纲。网格间距和ATR的数量关系一般写成网格间距 ATR × 系数系数取0.3到0.8之间。为什么是这个区间系数太小一格只赚一点点波动成交频繁但利润被吃系数太大价格穿越一格要很久资金利用率太低。我用过的基准方案里1小时级别行情系数取0.4到0.6比较稳日线级别可以放宽到0.8。下面这张表是固定网格和ATR动态网格在行情波动率变化时的对比能比较直观地看出差异。行情状态固定网格表现ATR动态网格表现波动率收窄网格间距偏大长时间不成交资金闲置网格间距自动收紧保持合理成交频率波动率放大网格间距偏小成交次数暴增利润被手续费蚕食网格间距自动放宽过滤掉过度交易单边大涨/大跌价格穿过大量格子浮亏快速累积间距放宽后成交格数减少每格利润变厚这个表看起来简单却是整套自动调整策略的起点。你不需要另起炉灶ATR动态网格就是在固定网格的基础上多一步计算。2.2 从固定网格到自适应网格三档波动率分级策略ATR动态网格已经能解决“波动变大网格没跟上”的问题但直接连续调整网格大小在实盘里有隐患价格在某个区间反复抖动时ATR会跟着上下跳动网格大小也跟着反复横跳造成频繁撤单重挂。更稳的做法是分档调整把波动率状态切成低、中、高三档每档对应一组网格参数。分档的判断依据是ATR在历史分布中的位置。我的做法是取当前ATR值和过去100根K线的ATR序列做对比算一个分位。分位小于30%算低波动档30%到70%算中波动档大于70%算高波动档。为什么用分位而不是用ATR绝对值因为不同品种的ATR绝对值差很多BTC一小时级别的ATR可能是50美元某个小市值币的ATR可能是0.002美元直接比较绝对值没有意义分位把“当前波动相对过去是偏高还是偏低”这个问题统一成了一个尺度。波动档位ATR分位条件网格间距调整系数单档仓位建议低波动分位 30%0.5倍基础网格正常仓位中波动30% ≤ 分位 ≤ 70%1.0倍基础网格正常仓位高波动分位 70%1.52.0倍基础网格降低单格投入这里“基础网格”怎么定取决于你选的时间周期和品种。我一般先用过去一年的K线算一个ATR中位数乘以0.4作为基础网格。这个基准的意义是让网格大小在大多数行情下处于“合理偏宽”的状态再用分档调整去追波动率的变化。三档策略还有一个隐藏好处它天然带冷却效果。波动率从高档跌回中档需要一段时间不会因为一根大阳线就立刻把网格调小这比连续函数式的调整稳得多。如果你做的是自动化交易这个特性直接减少了很多无效的撤单和重挂。3. 实现自动调网格从指标计算到回测验证的具体步骤3.1 第一步确定波动率观测窗口与计算口径写代码之前先把两个口径定死用多少根K线算ATR用多少根K线当历史基准。ATR周期决定了“当前波动率”的敏感度。周期太短比如用7一根异常K线就能把ATR拉高50%网格跟着剧烈波动周期太长比如用50ATR反映的是半个月前的行情等它反应过来趋势已经走了一半。币圈1小时级别我一般用204小时级别用14日线级别用20。这个选择没有绝对正确但20是一个很好的起点因为它兼顾了敏感度和稳定性。历史基准窗口决定“当前波动率相对什么水平算高”。基准太短只有30根K线分位数很容易被最近的行情带偏基准太长比如250根如果品种在两个阶段之间出现过一次巨幅波动这个基准会一直偏高导致后续几个月都判定为“低波动”网格迟迟不肯放宽。100到200是相对稳妥的范围。计算口径上要注意一个细节用ATR中位数还是ATR均值。均值对极端值敏感一根插针就能把均值拉得很高中位数抗干扰能力强很多。在自动调网格的场景里我强烈建议用中位数做基准因为网格参数最怕的就是被单根异常K线触发大范围调整。3.2 第二步写出自动调整网格大小的核心逻辑把上面的思路转成代码并不复杂。下面这段Python代码做了三件事计算ATR序列、算出当前ATR相对历史中位数的倍率、把这个倍率映射到网格间距上并且加了钳位和冷却K线数的约束。import pandas as pd def compute_atr(df: pd.DataFrame, period: int 20) - pd.Series: 计算ATR序列。 df 需要包含 high, low, close 三列索引按时间升序。 prev_close df[close].shift(1) tr pd.concat([ df[high] - df[low], (df[high] - prev_close).abs(), (df[low] - prev_close).abs() ], axis1).max(axis1) # 用 rolling mean 平滑也可以用 ewm 替代 return tr.rolling(period).mean() def adjust_grid_pct(df: pd.DataFrame, base_pct: float 0.004, atr_period: int 20, ref_period: int 100, cooldown: int 5, min_pct: float 0.002, max_pct: float 0.01) - float: 根据最近一根K线收盘时的ATR分位返回新的网格间距百分比。 base_pct: 基础网格间距按当前价格的百分比表示。 min_pct/max_pct: 间距的上下限防止网格被推到极端值。 atr_series compute_atr(df, atr_period) current_atr atr_series.iloc[-1] # 基准用历史ATR的中位数抗单根插针 ref_mid atr_series.rolling(ref_period).median().iloc[-1] if ref_mid 0: return base_pct # 倍率限制在 0.5 ~ 2.0 之间对应低波动和高波动两档 ratio max(min(current_atr / ref_mid, 2.0), 0.5) new_pct base_pct * ratio return min(max(new_pct, min_pct), max_pct)这段代码里有几个参数值得单独说明。base_pct是基础网格间距用当前价格的百分比表示。假设价格是100 USDTbase_pct0.004表示基础网格间距是0.4%。这个值不是一个拍脑袋的数它应该至少满足单格利润能覆盖手续费和滑点。后面第5章会专门讲这笔账怎么算。ref_period是历史基准窗口代码里用rolling median。注意这里用的是中位数而不是均值就是为了防止某根异常K线把基准拉偏。current_atr / ref_mid算出来的倍率最终会被钳位在0.5到2.0之间这对应了低波动0.5倍、高波动2倍的调整上限。min_pct和max_pct是最后一道保险避免任何极端行情把网格间距推到毫无意义的值。cooldown参数在代码里没有直接用因为它需要有状态——记录上一次调整发生在第几根K线。实盘逻辑是当当前K线索引 - 上次调整K线索引 cooldown时跳过本次调整。这个冷却期防止价格在网格边界附近反复抖动时网格大小跟着反复变。3.3 第三步用历史数据回测验证调参是否真的有效参数写好了最后一步是验证这套自动调整逻辑是不是真的比固定网格强。回测最忌讳的就是只看总收益率一个指标成交次数和最大回撤必须一起看。我的验证流程分三步。第一步取同一段历史行情分别跑固定网格和自动调整网格记录总收益、最大回撤、总成交次数。第二步把这段行情按走势切成震荡、单边、V型反转三种类型分别对比两套参数的表现。第三步换品种验证在BTC上表现好的参数搬到ETH或者另一个波动结构不同的标的上看参数是否仍然有效。回测指标合格标准总收益率不低于固定网格或至少不显著跑输最大回撤小于固定网格至少不能明显放大总成交次数比固定网格少尤其在单边行情里收益/回撤比比固定网格高20%以上才算有效改进如果只满足“总成交次数减少”但收益反而下降说明网格拉得太宽该吃的波动没吃到此时应该缩小调整倍率的上限如果收益和回撤同时改善说明调整方向正确。最理想的结果是震荡行情里收益略降单边行情里回撤显著变小综合收益回撤比提升。拿不到这个结果就不要急着上实盘。4. 自动调整网格大小最容易踩的四个坑4.1 坑一震荡行情里网格被调得过密单笔收益被手续费和滑点吃光现象自动调整逻辑跑起来之后成交次数明显增多了但账户余额没怎么涨反而在小幅缩水。原因网格变密意味着每格的毛利变薄。当网格间距缩小到一定程度单格利润已经无法覆盖“买入手续费 卖出手续费 滑点”的总成本。很多人调网格只盯着波动率完全没把成本算进去结果就是把资金使用效率调高了但每一笔都在给交易所和流动性打工。解决给网格间距设一个硬下限下限的计算方式不是随便拍的而是根据成本算出来的。假设现货手续费双边合计0.1%滑点平均0.05%那么单格利润至少要高于0.15%才有意义。为了留出缓冲我一般要求单格利润至少是总成本的3倍也就是0.45%以上。所以网格间距不管怎样调整下限得定在0.4%到0.5%附近。这段校验逻辑要写进调整函数而不是靠肉眼盯着。提示网格间距的下限应该由成本结构决定而不是由波动率决定。先算账再调参数。4.2 坑二单边行情刚调大网格就撞上回撤止损形同虚设现象行情走单边时自动调整逻辑确实把网格拉宽了成交格数也减少了但浮亏比之前更大因为每个格子的投入金额没变而网格变宽导致单格浮亏区间变大止损迟迟不触发。原因网格间距变大解决了“成交太频繁”的问题但解决不了“趋势方向判断错误”的问题。单边行情里价格沿着一个方向连续扫过多个网格间距越大最后一格的浮亏越深。自动调网格只调整了间距没有调整单格仓位风险敞口反而被放大了。解决把“网格间距调整”和“仓位缩放”绑在一起。高波动档位下网格间距乘以1.5倍同时单格投入金额乘以0.6倍让总敞口不升反降。另外要加一道熔断逻辑当未实现浮亏超过账户总资金的一定比例比如5%时暂停新开单而不是继续按网格补仓。网格交易不是不能亏但不能在单边行情里无限加仓。4.3 坑三窗口参数选择不同同一段行情得出完全相反的调整结论现象同一段BTC历史行情用ATR周期20和ATR周期50分别回测一个显示动态网格大幅跑赢固定网格另一个显示大幅跑输两个结论互相矛盾。原因ATR窗口和基准窗口的组合决定了“当前波动率相对偏高还是偏低”。两个窗口在不同尺度上对行情做平滑20周期对短期波动更敏感50周期更接近中期波动。当市场处于短期波动放大但中期波动收窄的阶段时短窗口会告诉你“该调大了”长窗口会告诉你“该调小了”两个结论自然打架。解决不要试图找一个“万能窗口”而是固定一套口径后去做相对验证。我一般固定ATR周期20、基准窗口100先跑完回测然后只把基准窗口改成150或200再跑一遍观察结论方向是否一致。如果方向一致说明参数的调优结果不是偶然如果方向反转说明这套参数对窗口太敏感根基不稳不要实盘。另外一个技巧是把基准从均值改成中位数很多窗口敏感性问题会直接缓解。4.4 坑四在BTC上回测有效的参数换到其他标的上直接失效现象一套在BTC上表现得很好的自动调整参数搬到ETH上收益变成负的或者搬到某个A股ETF上成交次数骤降网格长期静默。原因不同标的的波动率分布和趋势结构差异很大。BTC的波动率是“高波动时间长、低波动时间短”而很多山寨币是“大部分时间低波动、偶尔脉冲式暴涨”。同样的ATR分位阈值在BTC上能稳定区分三种行情状态在山寨币上大部分时间都落在低波动档网格间距被压得很小一旦脉冲行情到来间距调整根本来不及。解决每个标的独立标定两组参数基础网格间距和分位阈值。基础网格间距用该标的过去一年的K线数据计算取ATR中位数乘以固定系数而不是沿用BTC上验证过的数值。分位阈值也要看该标的的历史波动率分布30%和70%的阈值可以微调到25%和75%。换标的之后至少要单独跑一遍3.3节的回测流程判定合格之后才算数。5. 把自动调网格做成可用实盘的参数账本5.1 每次调整前先算这笔账手续费、滑点、资金占用率自动调整网格大小听起来是“根据行情自动变参数”但落到实盘每个新参数背后都有一笔账要算清楚在这个间距下每一格成交的毛利够不够覆盖交易成本。以一个常见场景为例当前价格100 USDT基础网格间距0.4%手续费双边合计约0.1%滑点按0.03%估算。单格买入价99.6卖出价100毛利0.4%。扣除手续费0.1%和滑点0.03%之后净利是0.27%。如果网格间距被自动调整到0.2%毛利变成0.2%扣完成本只剩0.07%这时这格交易几乎就是在给市场交手续费。计算项数值说明单格毛利率0.4%由网格间距决定手续费双边0.1%按常见现货taker费率估算滑点损耗0.03%按流动性一般的标的估算单格净利率0.27%0.4% - 0.1% - 0.03%最低可接受净利率0.1%低于此值时停止缩小网格这个表就是调整网格大小的“成本底线”。我一般会在自动调整函数里写一个断言当计算出的网格间距对应的单格净利率低于0.1%时强制返回当前值并记一条日志而不是继续调小。实盘里日志里的这类记录比收益率曲线更能说明问题。5.2 参数速查表与调整边界自动调整网格大小的参数不算多但每个参数都有明确的调整边界。参数表的核心意义不是给你一个万能组合而是让每次调参都有一个看起来合理的起点。参数建议范围调整说明ATR周期14501小时级别取204小时级别取14历史基准窗口100200用中位数不用均值基础网格间距基准ATR × 0.30.5先按成本底线校验调整倍率范围0.52.0半档切换避免连续微调调整冷却K线数35防止网格边界抖动引发连续调整网格间距下限由费用滑点推算净利率低于0.1%时不可再调小网格间距上限基础间距 × 2超过之后资金利用率过低这套参数表里最容易被忽略的是“网格间距上限”。很多人在自动调整里只关心下限忽略了上限结果就是高波动档位下网格宽到价格几个月才穿一格网格变成了死钱。上限存在的意义是保证网格策略的基本交易频率间距再宽也不能宽到失去成交机会。实盘启动时我建议先只开启“半自动模式”自动计算新的网格间距但不自动挂单而是把结果写到日志里人工核对一两周确认计算结果和行情直觉一致之后再切换成全自动。这样做的原因是代码逻辑在回测里跑得通不代表实盘数据流没有坑先观察再上是个后悔药成本最低的路径。6. 让自适应网格真正“自动”起来的两个进阶技巧6.1 用滚动分位替代固定阈值基础方案里用的分档逻辑是“过去100根K线的ATR分位低于30%算低波动”这个阈值本身是固定的。但行情有趋势性牛市里波动率整体抬高熊市里整体走低固定阈值在牛市里可能长期处于高波动档网格一直被拉宽成交频率明显下降。进阶做法是把阈值也滚起来比如取近500根K线的ATR分布动态计算30%和70%分位点作为当前档位的判定边界。这样不管行情处于什么阶段网格大小永远在跟“最近的异常程度”做对比而不是跟一个几年前的绝对值做对比。6.2 把网格更新收进固定K线收盘的检查循环里很多实盘脚本喜欢在每笔成交后立刻重新计算一次ATR并调整网格这在高频数据流里会让网格参数跳得像心电图。更稳的做法是只在固定周期的K线收盘时检查一次调整条件取当前K线的最高、最低、收盘、前收计算当前ATR判断是否调整然后在下根K线开盘时执行。盘中不做任何ATE计算和网格修改。我自己做这个功能时踩过一个印象很深的坑一开始用tick级数据实时计算ATR结果每几秒钟网格就变一次挂单频繁撤换还没赚到钱先亏了一堆手续费。改成K线收盘检查后一天最多调整两三次参数稳定很多回测表现反而更好。这个教训让我明白自动调整网格大小的核心不是算得快而是算得稳。后来我把这套逻辑沉淀成了一个习惯每个周末都会把自动调整网格的净值和固定网格的净值拉出来对比一次连续三周跑不赢就回退到固定网格找原因再迭代。网格参数不是一劳永逸的但也不必天天折腾关键是让调整节奏跟得上行情又不被行情牵着鼻子走。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站