做交易的人大概都经历过这个阶段:盯着行情看半天,方向判断没错,可一走进去就被套。等到止损,行情又顺着原方向去了。复盘的时候发现,问题不在进场点,而在于根本没搞清楚当下到底处于什么行情里。
行情运行区间,简单说就是当前市场正处在上涨趋势、下跌趋势、还是横向震荡区间。这个概念和“涨跌方向”不是一回事。方向告诉你价格在往哪走,运行区间告诉你市场正以什么“姿态”在走。同样是上涨,如果是在震荡区间内部的小幅抬升,和真正进入单边趋势的上涨,策略思路和仓位设定完全不一样。
量化交易者的优势,就是把这种靠盘感判断的东西变成数据指标。这篇就讲我自己实际在用的三套划分方法:用移动平均线识别趋势区间、用波动率聚类识别动与不动、用价格极值统计识别震荡箱体。三招合起来,可以给每个交易日打上一个明确的“行情状态标签”,在趋势状态下积极一点,在震荡状态下收敛一点。适合正在写策略做回测的人,也适合主观交易者用来给自己定纪律。
1. 为什么要划分行情运行区间
1.1 行情状态和涨跌方向的本质区别
先想一个问题:当一个策略连续亏了几个月,很多人第一反应是调参数、换指标,但有时候问题根本不在策略本身,而是市场进入了一个不适合策略的行情状态。
方向可以用一句话概括:这里涨了、那里跌了。但运行区间包含的信息更丰富,它是价格在某个时间尺度上的“行为模式”。比如2022年那种单边下跌,几乎所有的“抄底”策略都会被埋。再比如长期横盘出利好的品种,追突破的策略会被反复止损。方向指标通常是震荡指标,比如RSI、KDJ;而运行区间指标回答的是“现在到底是趋势市还是震荡市”,这决定了你该用趋势跟踪还是均值回归。
换一种说法:开车的时候,方向灯只告诉你往左还是往右,但你是要上高速还是一直在市区里绕,考虑的完全是不同的问题。高速上有速度上限,可以定速巡航;市区里到处是红绿灯,要频繁起步刹车。前者对应趋势,后者对应震荡。一个只给油门刹车的方案,是没办法同时应付两种路况的。
1.2 状态划分到底有什么用
划分行情区间的作用是三层递进的。
第一层是择时。如果你想做趋势跟踪,最好只在确认进入趋势状态的交易日入场,震荡状态下空仓,或者干脆反向。这一下就能过滤掉大量假突破。
第二层是仓位管理。趋势状态下波动通常大,单位时间内的盈亏幅度也大,可以把目标仓位调高;震荡状态下趋势策略本来就容易吃亏,同时降低仓位可以减少无意义的损耗。比如同样的策略,只在趋势状态运行,和全天候运行相比,体验往往差距很大。
第三层是策略切换。你可以同时维护两套策略:一套追踪趋势,一套做区间回归。状态标签切到“趋势”,就启动趋势策略;切到“震荡”,就启动回归策略。这种做法的难点在于切换逻辑要干净,不能一天换三回。后面讲的三招,就是为解决这个问题设计的。
我之前带过一个模拟组合,就是用状态标签来决定仓位比例,结果最大回撤比无脑滚动降低了接近三成。当然这和数据窗口有关,但方向是对的——先认清状态,再谈其他。
2. 第一招:用移动平均线排列结构识别趋势区间
2.1 均线排列为什么能反映趋势状态
移动平均线本质上是一条平均成本线。价格在多条均线上方运行,说明近期的买入者大部分都浮盈;均线从短到长依次向上排开,也就是所谓的“多头排列”,代表市场的平均成本在逐步抬高。反过来,空头排列是成本结构不断下移。均线反复纠缠在一起,说明市场多空力量达到均衡,价格没有明确方向,这就对应震荡区间。
这里有个常见的认知误区:用一根均线做多空判断,比如价格站上20日均线就做多,其实是把趋势和方向混为一谈。单根均线可以快速给出上穿下穿信号,但它无法回答“趋势是否已经展开”这个问题。趋势的确立需要看到均线组的整体结构,而不仅仅是一条线。
我的习惯是观察三条均线:快线、中线、慢线。以日线级别为例,用8、21、55这组参数。当8大于21,且21大于55,三条线同时向上发散,定义为趋势偏多;反之为趋势偏空。如果三条线互相缠绕,或者只有两条交叉、第三条走平,就归为震荡区间。
2.2 参数选择不能一刀切
均线组参数的选择要看交易周期和品种特性,不能照搬别人平台上的参数。
在日线级别,我常用8、21、55;在小时线级别,换成5、13、34。参数不是拍脑袋来的,而是根据该品种平均持仓周期来定的。如果一个品种的平均单边行情持续15到20个交易日,那55日均线就能覆盖超过一段完整趋势,8日和21日均线则能反映中短期成本变化,这样组合出来的排列结构才识别得出“正在展开的趋势”。
这里要提醒一句:参数太短会产生大量交点,比如把参数改成3、5、8,均线一天可能要交叉好几次,震荡区间会被频繁切割成碎片,状态标签稳定性会很差。参数太长又会让趋势确认太慢,等你确认是趋势的时候,行情已经走完大半。
判断参数是否合适的办法很笨但有效:把状态标签可视化到行情图上,观察多头排列和空头排列的片段是否和实际明显的单边行情对齐。如果整段行情中状态标签频繁翻转,就要拉长慢线参数或增加一个“发散确认”条件。
2.3 实操细节:斜率与发散确认
只看排列顺序还不够,还需要看均线的斜率和发散程度。排列顺序解释的是“方向”,斜率解释的是“力度”。
我处理斜率的方法很简单:计算均线自身的“方向”,比如近10根K线上慢线上升的幅度。如果慢线走平,即使快线向上穿过中线,我也只会给一个“震荡偏强”的标签,而不是直接判定为趋势多头。另外,均线之间的距离也在起作用。多头排列初期,三条线逐步拉开,说明趋势在加速;如果三条线虽然保持多头排列,却越走越近,就是要变盘的迹象,通常后边会跟一大段震荡。
发散的度量,可以用三条均线之间的归一化距离,比如:
发散度 = (快线 - 慢线) / 慢线当发散度上升到一定水平,且持续保持,才确认趋势状态成立。有人喜欢用绝对差值,这不对,因为不同价格的品种基比较小、基差较大,直接算差值没有可比性,归一化之后才能在多个品种上通用。
趋势状态的退出条件同样关键。不能等均线回落到走平才切换。我个人的经验是:当价格跌破快线,同时快线斜率转负,就先降一半仓位,并观望观察;等到快线下穿中线,才正式把状态标签切为震荡或空头。这样做虽然会损失趋势后段的利润,但能避开最要命的深度回撤。
3. 第二招:用波动率聚簇识别“动与不动”的边界
3.1 波动率是行情状态的基础语言
行情状态变化在盘面上最早的信号不是价格本身,而是波动率。没有波动的市场根本不值得交易,但波动率不是均匀分布的,它带有明显的聚集性,高波动后面通常还是高波动,低波动后面也往往继续低波动。这就是波动率聚簇。
生活化一点解释:一个平时习惯安静的人突然连续几天情绪起伏很大,接下来一段时间大概率还是不太平静,因为内部的“惯性”还在。金融市场也一样,重大政策冲击、放量突破、恐慌踩踏都会让波动率自我强化。这种聚集性使得波动率可以作为行情状态的一个底层指标。
直接看价格也许看不出名堂,但看波动率就会发现,每一个震荡区间都对应着波动率的持续低位区间;每一次趋势拉升或跳水,都对应着波动率从低位迅速放大。所以波动率就是识别“动与不动”的天然边界。
3.2 怎么量化波动率状态
日内交易者喜欢盯着ATR看,也就是平均真实波幅。ATR的优势是它用真实波幅综合了跳空缺口和日内振幅,比单纯用标准差更贴近实际交易损耗。但ATR是绝对值,不同品种之间没法横向比,同一个品种在不同价格区间下也没有可比性。
所以我更常用两个归一化的波动率指标:
一是波动率百分位。取最近N根K线计算收益率标准差,再和过去更长时间窗口的分位数比较。比如过去250个交易日的滚动年化波动率,如果当前值处于历史分布的20%以下,就是低波状态;高于80%,就是高波状态。这个“分位”思路比直接看数值更直观。
二是布林带宽度。主题不是布林带上下轨是否穿越,而是带宽值本身:
带宽 = 2 * K * N周期标准差 / 中轨带宽收窄,代表市场进入低波状态,这往往出现在震荡区间的中后段;随后带宽放大,往往代表价格正在选择方向。这个特征可以作为行情即将变盘的一个预警。
3.3 把波动率映射到行情状态
实际操作中,我先把ATR和布林带宽度都标准化到0到1的范围,然后定义三个状态:
- 低波状态:波动率分位处于历史低位,带宽持续收窄。这个阶段大概率对应震荡区间,趋势策略容易反复止损,应减少操作频率。
- 扩张状态:波动率分位迅速抬升,带宽从低点放大。这往往是趋势启动或恐慌下跌的前段,可以确认进入“偏趋势”的初段。
- 高波状态:波动率分位处于历史高位,带宽明显扩张。趋势正在剧烈展开,交易机会多,但止损空间也要同步调大。
有个容易踩的坑:高波并不一定等于是单边趋势。价格在顶部宽幅振荡时,ATR一样很高。因此波动率指标必须和均线排列配合使用。单看波动率,你会把高位剧烈震荡误判成趋势;单看均线,又会把趋势启动初期当成震荡来回试探。这正是后面把三招合并起来的原因。
4. 第三招:用价格结构统计识别震荡区间上下沿
4.1 用极值分布描出箱体
震荡区间最直观的特征,就是价格在一个价格带里反复折返。识别这个价格带需要我们先找出最近一段时间的局部高低点,然后统计它们的分布。
什么是局部高低点?以日线为例,可以定义:当某根K线的最高价比它前后各5根K线的最高价都高,就是一个“局部高点”;同理,局部低点是最低价创出前后左右新低。把这套规则跑完,得到的摆动点再按时间排序。
然后,取出最近20到30个摆动高点,用它们的中位数作为箱体上沿,同理得到下沿。为什么不直接用最高点呢?因为最高点往往是一次极端冲击,代表不了常态的震荡边界。中位数更抗噪声,用四分位范围还可以给出边界的不确定性。如果上沿波动很宽,说明这段所谓“震荡区间”其实并不规则,状态标签就应当更谨慎一些。
4.2 用Hurst指数验证状态判断
如果你只需要一个指标来区分趋势和震荡,我会选Hurst指数。这是用重标极差分析算出的一个值,最初应用于河流水位等长记忆过程,后来被大量用于金融时间序列。
Hurst指数反映时间序列的自相关性:小于0.5说明序列倾向于均值回归,大于0.5说明序列有趋势延续性,等于0.5则是标准随机游走。用它判断行情区间的好处是它不依赖价格路径的具体形状,而是直接从数据里估计出“当前数据到底是趋势性的还是回归性的”。
计算的过程,这里不适合展开完整的公式,但在量化平台上常有现成的库可以直接调用。需要注意样本窗口,一般至少有250根K线以上的数据,结果才基本稳定。窗口太短算出来的Hurst指数会在0.4到0.6之间剧烈抖动,失去参考价值。
我在实盘中的用法是,把它作为第二招、第三招的“仲裁者”:波动率判断处于扩张,Hurst指数却还是持续低于0.5,那就不急着认定为大趋势,先按区间突破失败来处理。反过来,Hurst指数持续大于0.6,即使均线呈现缠绕,也可以考虑这很可能是趋势初期的中间调整。
4.3 突破确认和状态切换
震荡区间的上下沿识别清楚以后,接下来就是判断什么时候状态会切换。经典的规则是:收盘价向上突破上沿,且对应K线的波动率高于过去20日平均ATR,才算有效突破,行情状态由震荡切换为向上趋势。
光突破还不够,还要防止“假突破”。我个人的做法是连续两根K线收盘价都站在上沿之上,才算状态切换成功。如果只有一根K线突破,另一个更谨慎的做法是只把状态标签改成“震荡偏多”,仓位最多加到一半,等第二根确认后再拉满。
这种“两步确认”虽然会损失一些起步阶段的利润,但可以过滤掉大多数箱体边缘的假动作。特别是在窄幅震荡区间,价格经常先假突破再收回区间内部,一根K线就下结论,会导致状态标签一天变几次,后续策略根本没法稳定执行。
5. 三招合并落地:一个可复现的状态评分框架
5.1 如何生成综合状态标签
三招各自都有自己的识别逻辑,但市场是混沌的,它们给出的结论经常不一致。比如均线已经空头排列,但波动率还没有明显放大,那是已经进入趋势了,还是还在震荡下跌?所以需要把它们整合成一个综合状态标签。
我设计了一套简单的评分方式,每项都可以打在0到100分区间:
- 趋势分:主要看均线排列方向、慢线斜率和发散度。满分为趋势空头给0分,趋势多头给100分,震荡给50分左右浮动。
- 波动分:看波动率百分位和带宽扩张情况。低波状态给20分,高波状态给80分,中间线性插值。
- 结构分:看价格相对上下沿的位置。贴着下沿且Hurst指数低于0.5,说明处在回归状态,给40分以下;向上突破上沿且Hurst大于0.5,给80分以上。
最后总得分 = 趋势分 * 0.5 + 波动分 * 0.3 + 结构分 * 0.2。为什么这样配权重?因为趋势分直接决定方向,波动分决定趋势展开的可靠性,结构分更多负责在临界点处做修正。你当然可以根据自己的品种和风格调整权重,但不要同时调太多参数,否则一改全是噪声。
总分大于65,定义为“多头趋势区间”;低于35,定义为“空头趋势区间”;介于35到65之间,定义为“震荡区间”。震荡区间内部还可以再看波动分,细分是“窄幅震荡”还是“宽幅震荡”。
5.2 状态标签在回测里的正确用法
状态标签是T日收盘后生成的,做决策必须用在T+1日开盘或盘中,否则就是前视偏差。很多人在回测里故意忽略这一点,觉得“就差一天,没关系”,但在状态频繁切换的震荡市里,这一天的差别足以让回测结果从盈利翻成亏损。
以某个期货指数为例,我可以在回测中设定当时处于多头趋势状态时,趋势策略仓位为100%,单笔止损为2倍ATR;处于震荡状态时,趋势策略仓位下调到40%,止损收紧到1.5倍ATR,同时允许均值回归策略进场。要注意,两套策略不应同时持有反向仓位,状态标签一旦切到多头趋势,回归策略低吸的部分要按处理逻辑平仓,防止左右互搏。
运行下来,组合的回撤曲线明显更平滑,夏普比率比不区分状态时提高约30%到40%。更需要说明的是,这不是因为某一次行情里抓到了特别大的一段利润,而是因为把最容易亏钱的震荡状态仓位压低以后,体系整体的容错率提升了。
5.3 状态划分的稳定性检验
状态划分是否可靠,不是看它在历史K线图上看起来多准确,而是要做稳定性检验。重点看三件事。
第一,参数敏感性。把核心参数在合理范围内微调,比如慢线从55改成48或62,观察状态标签的总变化天数比例是否超过10%到15%。变化比例过高,说明该参数正好卡在一个临界区域,模型不稳健,需要调整窗口或改变参数组合。
第二,状态切换频率。统计每个状态标签的平均停留天数。如果“多头趋势”平均只停留3天就切回震荡,那这个标签就没有实际意义,因为它不足以支撑四次建仓。理想情况下,趋势状态平均应至少能保持10到20个交易日以上。
第三,样本外验证。把完整数据按时间切分,比如前80%用于确定参数,后20%用于验证。如果后20%的样本中状态标签分布与前半段严重不一致,说明策略被历史行情“训练”得太均匀了,而不是真正学会了识别状态。
6. 实操中的坑与排查建议
6.1 不同时间粒度可能得出相反结论
日线看是多头趋势,小时线看却是一个标准的震荡箱体,这是最常遇到的问题。原因是不同周期的波动率特征完全不同。解决办法不是强行统一,而是明确“主操作周期”到底是哪个,其他周期只作为风险提示。
我在做策略时把状态标签定义在策略持仓周期上。趋势策略持单3到5天,就只看日线状态;做日内短线,就只看小时线状态。把主要精力放在主周期上,长周期只用来决定最大允许仓位上限,短周期只用来做进场的微调,不要层层叠加多个完全独立的判定。
6.2 状态切换天然滞后,别追求“零延迟”
所有基于历史数据和均线的状态识别方法,天然无法做到零延迟。边界信号出现时,行情往往已经启动了一段。如果为了追求即时切换而把参数调得特别短,状态标签会变得极度不稳定,最后得到的是一条频繁翻转的状态序列,没有任何实盘价值。
我个人的取舍是,宁可多等两根K线确认,也不抢第一根K线。比如突破确认时要求两根K线收盘站稳,这个延迟最多不过两三个交易日,但换来的稳定性非常可观。趋势启动后的第一段利润确实会被让出去一部分,但从整个组合的角度看,减少假信号带来的长期收益更可观。
6.3 实盘中需要盯住的不只是账户净值
状态标签本身也可能出错。实盘运行中,我每周会看三个数值:一是最近5个交易日状态标签的切换次数,如果每周都切换很多次,说明市场处于状态识别的“模糊带”,这时应该进一步降低仓位;二是预测波动率和实际波动率的差值,如果实际波动率连续稳定放大,而状态标签还停留在震荡区间,说明参数窗口太保守;三是趋势状态下策略实际盈利比例,如果连续亏损且亏损频率升高,很可能行情已经进入状态标签识别不到的新模式。
这里还要提醒一点,所有基于统计和指标的状态划分都属于“概率性判断”,不是水晶球。状态标签给出的只是“当前样本数据更支持哪种行情模式”,不代表未来一定会延续。所以仓位管理和止损纪律永远比状态识别本身更重要。我见过很多亏大钱的场景,不是因为状态判断错了,而是因为判断错后不肯按纪律止损。
最后分享一个我自己的小习惯:每次跑完一段回测,不要只看收益曲线,我会把状态标签单独拉出来和行情K线并排看一遍,找找有没有明明是一段明显的单边行情,状态标签却在中间反复切换的地方。这种地方往往是参数过度拟合的起点,也是未来回撤的伏笔。把这几处修正对齐,比多调两个优化参数要值钱得多。