
简介这份文档面向对量化投资与Python股票分析感兴趣的投资者聚焦网格交易策略中网格大小固定所导致的过早满仓或空仓问题给出一种可落地的自适应调整思路。内容以收盘价、最高价和最低价的标准差衡量市场波动波动剧烈时放大网格、波动平缓时缩小网格并借助KDJ指标中的RSV值对买入与卖出网格实行差异化设置使策略在上升与下降趋势中分别偏向买入或卖出文中还以0.5元初始网格、RSV为0.85等具体算例演示参数换算过程。资源包共1个docx文件约165KB为纯文档形式便于直接阅读与对照实践。目前已有6372人学习下载适合希望理解网格交易改进逻辑、并借助Python构建股票分析工具的初中级读者参考可从中获取波动率度量、RSV联动网格及差异化买卖网格的完整设计思路。1. 固定网格为什么会在极端行情里翻车做量化策略的人大多有过这样的经历回测曲线漂亮得像一条直线实盘跑三个月却回撤得让人怀疑人生。网格交易就是典型——原理简单到用一句话就能讲清价格跌一格买一份涨一格卖一份靠波动吃饭。但真正上手之后你会发现固定网格大小这件事本身就是个玄学。震荡市里网格设大了小波动根本吃不到趋势市里网格设小了价格一路单边下跌你在半山腰就把子弹打光满仓套牢反过来一路暴涨你又早早卖飞眼睁睁看着主升浪从手里溜走。这套方案要解决的就是这个问题让网格大小跟着市场波动自动调整波动剧烈时放大网格避免过早满仓或空仓波动平缓时缩小网格把细碎利润舔干净。适合正在做量化投资课程设计、毕设或者想用 Python 搭一套股票分析工具的同学参考。整套思路来自一个开源股票分析项目的实战总结核心就两件事——用标准差定基准网格用 RSV 做买卖网格的差异化拆分。2. 策略总体设计两层自适应与三个核心指标2.1 从固定网格到自适应网格的演进逻辑传统网格的致命伤在于参数是静态的。你设 0.5 元一格这个 0.5 在接下来半年里不会变但市场波动率每天都在变。波动率高的阶段0.5 元可能半小时就被穿透好几格仓位迅速打满波动率低的阶段价格在 0.5 元区间里磨一个月你一笔都成交不了。所以自适应网格的第一层设计就是让基准网格大小与近期波动率挂钩。这里选标准差作为波动率的度量理由很直接标准差衡量的是价格偏离均值的离散程度离散程度大说明价格上下翻腾得厉害网格就该放大离散程度小说明价格黏在一起网格就该收窄。这和布林带的思路一脉相承——布林带宽度随波动率伸缩网格大小也应该如此。具体取近 N 个交易日的收盘价、最高价、最低价计算标准差得到一个能反映当前市场“脾气”的基准网格值。第二层设计解决的是另一个问题即便基准网格对了买卖对称仍然会在趋势行情里吃亏。上涨趋势中价格重心不断上移如果买卖网格一样大你会频繁卖出、少量买入母仓越卖越少最后空仓踏空下跌趋势中反过来你会频繁买入、少量卖出母仓越买越多最后满仓套牢。所以买卖网格必须差异化——上涨时买入网格小、卖出网格大让策略“易买难卖”下跌时买入网格大、卖出网格小让策略“易卖难买”。这个差异化的依据用 KDJ 指标里的 RSV 值来刻画。2.2 三个核心指标的计算口径整套策略依赖三个量基准网格、RSV 值、买卖网格拆分系数。先把计算口径定清楚后面写代码才不会乱。基准网格由标准差映射而来。设近 N 日收盘价序列为 (C)最高价序列为 (H)最低价序列为 (L)分别计算标准差 (\sigma_C)、(\sigma_H)、(\sigma_L)取三者均值作为波动率度量 (\sigma)。基准网格 (G_{base} k \cdot \sigma)其中 (k) 是缩放系数通常取 0.5 到 1.5 之间需要根据标的的价格量级调。这个 (k) 不是拍脑袋定的后面验收章节会给调参方法。RSV 值的定义是 (RSV (C_t - L_n) / (H_n - L_n))其中 (C_t) 是当日收盘价(L_n) 和 (H_n) 是近 N 日的最低和最高价。RSV 落在 0 到 1 之间越接近 1 说明收盘价越靠近区间高点处于上涨趋势越接近 0 说明收盘价越靠近区间低点处于下跌趋势。买卖网格拆分规则设基准网格为 (G_{base})则买入网格 (G_{buy} G_{base} \times (1 - RSV))卖出网格 (G_{sell} G_{base} \times RSV)。注意这里 (G_{buy} G_{sell} G_{base})两者之和恒等于基准网格。当 RSV0.85 时买入网格只有基准的 15%卖出网格占 85%策略明显偏向买入持有当 RSV0.15 时反过来买入网格占 85%卖出网格只占 15%策略偏向卖出减仓。这个设计的好处是网格总宽度不变但买卖的“胃口”随趋势倾斜。提示RSV 的 N 值和标准差的 N 值可以不同。标准差看的是波动幅度通常取 20 到 30 日RSV 看的是趋势位置KDJ 默认取 9 日。两个窗口分开调不要图省事用同一个值。2.3 模块划分与数据流整套策略拆成四个模块职责边界清晰方便单独测试和替换。模块职责输入输出数据层拉取日线行情清洗缺失值股票代码、日期范围收盘/最高/最低价序列指标层计算标准差、RSV、基准网格价格序列波动率、RSV、网格参数决策层根据当前价与网格线比较生成买卖信号网格参数、持仓、现金买/卖/持有信号回测层模拟成交、记录净值与回撤信号序列、初始资金收益曲线、最大回撤数据流是单向的数据层喂给指标层指标层算出当日网格参数喂给决策层决策层输出信号给回测层。这样设计的好处是每一层都能单独写单元测试——比如指标层给定一组构造好的价格序列标准差和 RSV 的输出应该是确定的测试起来没有歧义。决策层最容易出 bug因为涉及持仓状态和边界条件单独抽出来测能省很多排查时间。3. 核心算法实现标准差定网格与 RSV 拆买卖3.1 基准网格的标准差计算先写指标层的核心函数。这里用 pandas 做滚动窗口计算注意标准差要分别对收盘、最高、最低价算再取平均不能只算收盘价的标准差——最高最低价携带了日内波动的信息只用收盘价会低估真实波动。import pandas as pd import numpy as np def calc_base_grid(df, window25, k1.0): 根据近 window 日价格标准差计算基准网格大小。 df 需包含列: close, high, low k 为缩放系数控制网格相对波动率的粗细 # 分别计算收盘、最高、最低价的滚动标准差 std_close df[close].rolling(window).std() std_high df[high].rolling(window).std() std_low df[low].rolling(window).std() # 三者取均值作为综合波动率度量 sigma (std_close std_high std_low) / 3.0 # 基准网格 缩放系数 × 综合波动率 base_grid k * sigma return base_grid这段代码的关键在rolling(window).std()它算的是样本标准差默认 ddof1窗口内前 window-1 个值是 NaN回测时要跳过。k的取值直接影响网格粗细k 太小网格过密交易频繁、手续费吃掉利润k 太大网格过疏一个月成交不了几次。经验上 k 取 1.0 左右是个合理起点但不同价格量级的标的要微调——低价股波动绝对值小k 可以适当放大高价股反过来。还有一个细节标准差算出来是绝对价格单位和股价本身量级相关。如果标的从 10 元涨到 50 元同样的波动率百分比对应的标准差绝对值会变大网格自然变粗这其实是符合直觉的——高价股的绝对波动本来就大。但如果你希望网格按百分比而非绝对值调整可以在算标准差之前先对价格做归一化这个取舍看策略目标本方案按绝对值处理。3.2 RSV 值与买卖网格差异化拆分RSV 的计算依赖近 N 日的最高最低价注意这里的 N 是 RSV 窗口和标准差的窗口独立。def calc_rsv(df, window9): 计算 RSV 值反映收盘价在近 window 日价格区间中的相对位置。 RSV 接近 1 表示强势收盘靠近区间高点接近 0 表示弱势。 low_n df[low].rolling(window).min() high_n df[high].rolling(window).max() # 防止分母为 0一字板等极端情况 denom (high_n - low_n).replace(0, np.nan) rsv (df[close] - low_n) / denom return rsv.clip(0, 1) # 截断到 [0,1]防止异常值 def split_grid(base_grid, rsv): 将基准网格按 RSV 拆分为买入网格和卖出网格。 上涨趋势RSV 高→ 买入网格小、卖出网格大 → 易买难卖 下跌趋势RSV 低→ 买入网格大、卖出网格小 → 易卖难买 buy_grid base_grid * (1 - rsv) sell_grid base_grid * rsv return buy_grid, sell_gridcalc_rsv里那个replace(0, np.nan)是血泪经验——遇到连续一字涨停或停牌复牌最高价等于最低价分母为 0 直接除出 inf后面整个信号序列全乱。截断到 [0,1] 也是同理正常 RSV 不会越界但数据异常时截断能兜底。split_grid的逻辑值得多说一句。假设基准网格算出 0.5 元当前 RSV0.85则买入网格 0.5×0.15 0.075 元卖出网格 0.5×0.85 0.425 元。意思是股价每跌 7 分 5 就买一份每涨 4 毛 2 才卖一份。在上涨趋势里价格回踩的幅度通常浅、频率低小买入网格能让你在浅回撤时就接到货而卖出网格大避免价格刚涨一点就卖飞。这个不对称正是策略适应趋势的核心。3.3 信号生成与回测循环决策层要把网格参数翻译成具体的买卖动作。这里采用“网格线触发”的方式以当前持仓成本为基准价格跌破买入网格线就买涨破卖出网格线就卖。为了简化每次交易固定股数母仓单独管理。def generate_signals(df, base_grid, buy_grid, sell_grid, lot100): 逐日遍历根据价格与网格线的关系生成买卖信号。 简化处理以昨日收盘价为参考锚点跌破买入网格买、涨破卖出网格卖。 signals [] anchor df[close].iloc[0] # 初始锚点 for i in range(1, len(df)): price df[close].iloc[i] bg buy_grid.iloc[i] sg sell_grid.iloc[i] if pd.isna(bg) or pd.isna(sg): signals.append(0) # 指标未预热不交易 continue if price anchor - bg: signals.append(1) # 买入信号 anchor price # 锚点下移 elif price anchor sg: signals.append(-1) # 卖出信号 anchor price # 锚点上移 else: signals.append(0) # 持有 return signals这段代码是策略的骨架但有几个工程上的取舍要讲清楚。锚点用昨日收盘价而非持仓成本是为了让网格跟随价格移动避免成本价被套牢后网格线永远触发不了。每次触发后锚点更新到当前价保证网格是“滚动”的而不是“固定”的。lot100是 A 股一手的最小单位回测时按手数取整实盘还要考虑资金是否够一手。回测循环本身不复杂但成交价的处理容易翻车。用当日收盘价成交是理想化假设实盘会有滑点。回测层里通常加一个滑点参数买入价 收盘价 × (1 slippage)卖出价 收盘价 × (1 - slippage)slippage 取 0.001 到 0.002 比较贴近实际。手续费按万三双边算这些细节不写进核心算法但回测结果的可信度全靠它们。4. 避坑与常见问题排查4.1 指标预热期信号全空现象回测前 30 个交易日一笔交易都没有净值曲线是一条水平线。原因标准差窗口 25 日、RSV 窗口 9 日滚动计算前若干行是 NaNgenerate_signals里遇到 NaN 直接跳过。解决回测起始日期往前多取至少 max(标准差窗口, RSV 窗口) 个交易日的数据做预热信号序列从预热结束之后才开始统计。我一般会在数据层直接多拉 60 个自然日宁可多算不可漏算。4.2 一字板导致 RSV 分母为零现象某只股票连续涨停RSV 算出 inf 或 NaN后续网格参数全乱回测报错或收益异常。原因连续一字板时最高价等于最低价high_n - low_n 0。解决代码里已经用replace(0, np.nan)兜底但更稳妥的做法是在数据层过滤掉连续一字板的交易日或者对分母加一个极小值1e-8。另外 RSV 截断到 [0,1] 也是必要的异常数据不该污染信号。4.3 网格过密导致手续费吞噬利润现象回测收益看着不错扣掉手续费后所剩无几换手率高得离谱。原因k取值太小基准网格过细价格稍微波动就触发交易。解决先统计标的近一年的日均振幅基准网格不应小于日均振幅的 1/3否则交易频率会失控。实操中把k从 0.5 往上调观察换手率和净收益的平衡点通常 k 在 0.8 到 1.2 之间比较健康。4.4 锚点更新逻辑导致连续同向信号现象价格单边下跌时连续出现买入信号仓位迅速打满。原因锚点每次触发后更新到当前价但买入网格在下跌趋势中本来就大RSV 低时买入网格占基准的 85%两者叠加导致买入过于激进。解决给单日交易次数或单周累计仓位设上限比如单日最多触发 2 次买入累计仓位不超过总资金的 80%。这是策略层面的风控不是代码 bug但必须在回测里体现否则实盘会吃亏。4.5 回测用未来数据现象回测收益好得不真实实盘完全对不上。原因计算当日 RSV 和标准差时用了当日收盘价但信号又在当日收盘价成交等于用收盘价预测收盘价。解决信号基于 T 日收盘数据计算成交放在 T1 日开盘或收盘回测里把信号序列整体后移一天。这个坑几乎每个做量化的人都踩过回测框架里加一行signals signals.shift(1)就能避免但忘了这一行整份方案的可信度归零。5. 验收与答辩怎么证明这套自适应网格真的有效验收这套方案核心不是看某一段回测赚了多少而是看自适应机制在极端行情里是否真的缓解了满仓和空仓问题。我一般会设计三组对照固定网格、仅标准差自适应、标准差加 RSV 双重自适应跑同一段包含明显趋势和震荡的行情比较三组的最大回撤、空仓天数和满仓天数。验收指标固定网格仅标准差自适应双重自适应最大回撤基准应下降应进一步下降满仓天数占比高中低空仓天数占比高中低年化换手率不稳定较稳定稳定答辩时最容易被问的两个问题提前准备好答案。第一个是“k 和窗口参数怎么定的”不要答“试出来的”要答“先按日均振幅的 1/3 定 k 的下界再在验证集上网格搜索选换手率和回撤的帕累托最优点”。第二个是“RSV 拆分比例有没有理论依据”答“RSV 本质是价格在区间中的分位数用它做买卖网格的权重分配等价于让仓位调整速度与趋势强度成正比趋势越强逆向网格越粗、顺向网格越细”。还有一个答辩技巧准备一张图把同一段行情里固定网格和自适应网格的买卖点标在价格曲线上。固定网格的买卖点密集堆在趋势中段自适应网格的买卖点明显向两端分散——上涨时卖点稀疏、下跌时买点稀疏这张图比任何文字都有说服力。从那以后我每次做策略验收都强制要求自己先跑一遍“极端行情切片”把单边上涨、单边下跌、横盘震荡各截一段单独看而不是只看全周期净值曲线。全周期曲线会掩盖局部翻车切片才能暴露问题。希望这套结构和验收方法帮到你拿去改改参数就能跑自己的标的。本文还有配套的精品资源点击获取