趋势过滤:避免被“假突破“反复打脸

你有没有过这样的经历?

某个下午,你盯着一只股票,价格在关键支撑位上来回试探。突然,一根大阳线拔地而起,突破了阻力位。你兴奋地点下买入,心想"终于等到了"。

结果呢?第二天,价格掉头向下,直接跌回原来的区间。你被挂在了最高点。

更让人崩溃的是,这种事不是偶尔发生------是反复发生。一次、两次、五次、十次。每次突破你都追进去,每次都被打回来。你开始怀疑自己是不是被市场针对了。

真相是:你不是运气差,你是缺少一个趋势过滤器。

市场大部分时间(大约70%)都处于震荡状态,真正的趋势行情只占30%左右。如果你在震荡市里不断追逐"突破信号",就会被反复假突破打脸。

今天这篇文章,就是帮你解决这个问题。我们会讲清楚:假突破到底是什么、为什么会出现、怎么用ADX指标判断趋势强度、双滤心法则怎么用、多周期过滤怎么做。

Why:为什么假突破是趋势跟踪的头号杀手?

假突破有多常见?

先给你一个数据感受一下。

有研究对过去20年A股主要指数的突破信号做了统计。以20日高点突破为例,大约有40%-60%的突破是假突破------也就是价格突破后短期内又回到了原区间。

换句话说,你每追一次突破,就有将近一半的概率被假突破打脸。

这个比例比你想象的高吧?

假突破的三大成因

成因一:震荡市中的反复试探

在震荡行情中,价格会反复测试支撑和阻力位。每次测试看起来都像是要突破,但最终都会回来。

想象一个乒乓球在桌面上来回弹跳。每次弹到边缘,看起来都像要飞出去,但大部分时候它都会弹回来。这就是震荡市里的"假突破"。

成因二:流动性不足导致的毛刺

当市场流动性不足时(比如开盘前、收盘前、节假日前后),少量的买单或卖单就能让价格出现剧烈波动。这种波动会制造出"突破"的假象,但很快价格就会回到正常水平。

特别是在A股市场,9:25-9:30的集合竞价、14:57-15:00的收盘集合竞价,以及一些低流动性个股的日常交易中,毛刺现象非常普遍。

成因三:主力资金的故意诱骗

这是最不厚道的一种。主力资金知道很多交易者会用突破策略,于是故意制造假突破来"收割"这些跟风盘。

具体做法是:先把价格推到关键阻力位上方,引诱突破交易者追入;然后反手卖出,把价格打回去。追突破的人被全部套住。

这种现象在期货市场中尤其常见,专业术语叫"扫止损"(stop hunting)。

假突破的代价

假突破不只是让你亏一笔钱那么简单。它还有几个隐性代价:

  1. 手续费和滑点损耗:每次假突破都会产生交易成本,频繁假突破会不断侵蚀你的本金

  2. 心理打击:连续被假突破打脸后,你会开始怀疑所有信号,甚至错过真正的突破

  3. 策略失效:如果你因为几次假突破就不断修改策略参数,最终会把策略改废

所以,趋势过滤不是锦上添花,而是趋势跟踪策略的生死线。

What:趋势过滤的核心工具

一、ADX指标:判断趋势强度的"温度计"

ADX(Average Directional Index,平均趋向指数)是判断趋势强度最经典的指标。它由技术分析大师 J. Welles Wilder 在1978年发明。

ADX的核心思想是:趋势有强弱之分,ADX告诉你当前趋势有多强。

ADX的解读标准

| ADX 值 | 市场状态 | 操作建议 | | --- | --- | --- | | < 20 | 震荡市,无明显趋势 | 不做趋势跟踪,改用震荡策略或观望 | | 20-25 | 趋势可能正在形成 | 开始关注,但暂不入场 | | 25-50 | 明确趋势 | 可以做趋势跟踪 | | 50-75 | 强趋势 | 趋势跟踪的最佳时机 | | > 75 | 极端趋势 | 警惕反转,谨慎追高 |

记住这个关键阈值:ADX > 25 做趋势,ADX < 20 做震荡或观望。

ADX的计算原理(通俗版)

ADX的计算基于三个概念:

  1. +DI(正向方向指标):衡量上涨方向的力量

  2. -DI(负向方向指标):衡量下跌方向的力量

  3. DX(方向指数):|+DI - -DI| / (+DI + -DI) × 100

ADX就是DX的14周期移动平均。

通俗理解:

• 当 +DI 远大于 -DI 时,说明上涨力量远大于下跌力量,ADX 会上升

• 当 +DI 和 -DI 差不多时,说明多空力量均衡,ADX 会下降

• ADX上升 = 趋势在加强;ADX下降 = 趋势在减弱

ADX的Python实现

// python

import pandas as pd

import numpy as np

def calculate_adx(df, period=14):

"""计算ADX指标"""

计算 True Range

df'high_low' = df'high' - df'low'

df'high_close' = abs(df'high' - df'close'.shift(1))

df'low_close' = abs(df'low' - df'close'.shift(1))

df'true_range' = df\['high_low', 'high_close', 'low_close'].max(axis=1)

计算 +DM 和 -DM

df'up_move' = df'high' - df'high'.shift(1)

df'down_move' = df'low'.shift(1) - df'low'

df'plus_dm' = np.where(

(df'up_move' > df'down_move') & (df'up_move' > 0),

df'up_move', 0

)

df'minus_dm' = np.where(

(df'down_move' > df'up_move') & (df'down_move' > 0),

df'down_move', 0

)

平滑计算(使用 Wilder 平滑法)

atr = df'true_range'.rolling(window=period).sum()

plus_di = 100 * (df'plus_dm'.rolling(window=period).sum() / atr)

minus_di = 100 * (df'minus_dm'.rolling(window=period).sum() / atr)

计算 DX 和 ADX

dx = 100 * abs(plus_di - minus_di) / (plus_di + minus_di)

df'ADX' = dx.rolling(window=period).mean()

df'plus_DI' = plus_di

df'minus_DI' = minus_di

return df

使用示例

df = pd.read_csv('stock_data.csv')

df = calculate_adx(df)

判断当前趋势状态

latest_adx = df'ADX'.iloc-1

if latest_adx > 25:

print(f"当前ADX={latest_adx:.1f},处于趋势市场,可以做趋势跟踪")

elif latest_adx < 20:

print(f"当前ADX={latest_adx:.1f},处于震荡市场,建议观望或做震荡策略")

else:

print(f"当前ADX={latest_adx:.1f},趋势尚不明确,继续观察")

二、双滤心法则:时间和幅度的双重确认

双滤心法则是过滤假突破的实战利器。核心思想很简单:不要相信第一次突破,要等时间和幅度的双重确认。

滤心一:时间过滤(隔日确认)

假突破通常持续时间很短------可能就是一根K线的毛刺。真正的突破则会持续多天。

所以最简单的过滤方法是:突破后要等至少1-2天的确认。

// python

def time_filter_breakout(df, breakout_day, confirm_days=2):

"""时间过滤:突破后等待N天确认"""

breakout_price = df'close'.ilocbreakout_day

检查后续N天是否保持在突破位之上

for i in range(1, confirm_days + 1):

if breakout_day + i >= len(df):

return False, "数据不足"

if df'close'.ilocbreakout_day + i < breakout_price:

return False, f"第{i}天收盘价回落,假突破"

return True, f"突破已确认{confirm_days}天,为有效突破"

示例

confirmed, msg = time_filter_breakout(df, breakout_day=100, confirm_days=2)

print(f"突破确认结果:{msg}")

时间过滤的优缺点:

• 优点:简单有效,能过滤掉大部分毛刺型假突破

• 缺点:入场会延迟1-2天,可能错过部分利润空间

滤心二:幅度过滤(突破X%才认定)

另一个过滤方式是要求突破必须达到一定幅度。小幅度的突破不算突破,可能是噪音。

// python

def magnitude_filter_breakout(current_price, resistance_level, threshold=0.02):

"""幅度过滤:突破幅度必须超过阈值"""

breakout_pct = (current_price - resistance_level) / resistance_level

if breakout_pct >= threshold:

return True, f"突破幅度{breakout_pct*100:.2f}%,超过阈值{threshold*100:.1f}%"

else:

return False, f"突破幅度{breakout_pct*100:.2f}%,未达阈值{threshold*100:.1f}%"

示例

resistance = 50.0 # 阻力位50元

current = 50.8 # 当前价50.8元

confirmed, msg = magnitude_filter_breakout(current, resistance, threshold=0.02)

print(f"突破确认:{msg}")

输出:突破幅度1.60%,未达阈值2.0% → 假突破

幅度阈值怎么定?

这取决于品种的波动特性:

• 波动小的品种(如大盘蓝筹股):1%-2%

• 波动中等的品种(如中小盘股):2%-3%

• 波动大的品种(如创业板、期货):3%-5%

双滤心联合使用

最佳实践是把时间过滤和幅度过滤结合使用:

// python

def dual_filter_breakout(df, breakout_day, resistance,

confirm_days=2, threshold=0.02):

"""双滤心法则:时间+幅度双重确认"""

幅度检查

breakout_pct = (df'close'.ilocbreakout_day - resistance) / resistance

if breakout_pct < threshold:

return {

'confirmed': False,

'reason': f'幅度不足:{breakout_pct*100:.2f}% < {threshold*100:.1f}%',

'action': '不操作'

}

时间检查

for i in range(1, confirm_days + 1):

if breakout_day + i >= len(df):

return {

'confirmed': False,

'reason': '确认天数不足,继续观察',

'action': '等待'

}

if df'close'.ilocbreakout_day + i < resistance:

return {

'confirmed': False,

'reason': f'第{i}天回落,假突破',

'action': '不操作'

}

return {

'confirmed': True,

'reason': f'幅度{breakout_pct*100:.2f}%,已确认{confirm_days}天',

'action': '可以入场'

}

三、多周期过滤:从大到小确认趋势

单看一个时间周期容易被骗。多周期过滤就是用大周期定方向,小周期找入场点。

多周期过滤的逻辑

• 大周期(如周线、日线):判断大趋势方向

• 中周期(如4小时、2小时):确认趋势的持续性

• 小周期(如1小时、30分钟):找具体的入场点

规则很简单:

• 大周期趋势向上 → 只找做多机会

• 大周期趋势向下 → 只找做空机会

• 大周期震荡 → 不做趋势跟踪

多周期过滤代码实现

// python

def multi_timeframe_filter(daily_data, weekly_data):

"""多周期趋势过滤"""

大周期(周线)判断趋势方向

weekly_adx = calculate_adx(weekly_data.copy())'ADX'.iloc-1

weekly_ma20 = weekly_data'close'.rolling(20).mean().iloc-1

weekly_price = weekly_data'close'.iloc-1

if weekly_adx < 20:

return {

'trend': '震荡',

'direction': '无',

'action': '观望,不做趋势跟踪'

}

if weekly_price > weekly_ma20 and weekly_adx >= 25:

big_trend = '上升'

elif weekly_price < weekly_ma20 and weekly_adx >= 25:

big_trend = '下降'

else:

big_trend = '不明朗'

小周期(日线)寻找入场时机

daily_adx = calculate_adx(daily_data.copy())'ADX'.iloc-1

daily_price = daily_data'close'.iloc-1

daily_ma20 = daily_data'close'.rolling(20).mean().iloc-1

if big_trend == '上升' and daily_price > daily_ma20:

return {

'trend': '上升',

'direction': '做多',

'action': '周线上升趋势确认,日线出现买入信号,可以入场做多'

}

elif big_trend == '下降' and daily_price < daily_ma20:

return {

'trend': '下降',

'direction': '做空',

'action': '周线下降趋势确认,日线出现卖出信号,可以入场做空'

}

else:

return {

'trend': big_trend,

'direction': '等待',

'action': '大小周期不一致,等待共振'

}

How:完整的趋势过滤系统实战

第一步:建立你的趋势过滤清单

每次做趋势跟踪交易前,过一遍这个清单:

| 检查项 | 通过标准 | 当前状态 | | --- | --- | --- | | ADX > 25? | 是→趋势市,继续 | | | 突破幅度 > 阈值? | 是→有效突破 | | | 突破持续 > 确认天数? | 是→确认突破 | | | 大周期趋势一致? | 是→顺势交易 | | | 成交量配合? | 放量突破更有效 | |

5项中至少4项通过,才值得入场。

第二步:ADX + 双滤心 + 多周期联合策略

// python

class TrendFilterSystem:

"""趋势过滤系统"""

def init(self, adx_period=14, adx_threshold=25,

breakout_threshold=0.02, confirm_days=2,

swing_order=5):

self.adx_period = adx_period

self.adx_threshold = adx_threshold

self.breakout_threshold = breakout_threshold

self.confirm_days = confirm_days

self.swing_order = swing_order

def check_signal(self, daily_data, weekly_data):

"""综合趋势过滤检查"""

result = {

'signal': '无',

'adx_ok': False,

'breakout_ok': False,

'time_ok': False,

'multi_tf_ok': False,

'details': \[\]

}

1. ADX 过滤

daily_with_adx = calculate_adx(daily_data.copy(), self.adx_period)

current_adx = daily_with_adx'ADX'.iloc-1

if current_adx >= self.adx_threshold:

result'adx_ok' = True

result'details'.append(f"✓ ADX={current_adx:.1f},趋势市场")

else:

result'details'.append(f"✗ ADX={current_adx:.1f},震荡市场,不建议趋势跟踪")

return result

2. 检测突破

highs = daily_data'high'.rolling(self.swing_order).max()

resistance = highs.iloc-self.confirm_days - 1 # 前N天的高点

current_price = daily_data'close'.iloc-1

breakout_pct = (current_price - resistance) / resistance

if breakout_pct >= self.breakout_threshold:

result'breakout_ok' = True

result'details'.append(f"✓ 突破幅度{breakout_pct*100:.2f}%")

else:

result'details'.append(f"✗ 突破幅度{breakout_pct*100:.2f}%不足")

return result

3. 时间确认

confirmed = True

for i in range(1, self.confirm_days + 1):

idx = len(daily_data) - 1 - i

if idx < 0 or daily_data'close'.ilocidx < resistance:

confirmed = False

break

if confirmed:

result'time_ok' = True

result'details'.append(f"✓ 已确认{self.confirm_days}天")

else:

result'details'.append(f"✗ 时间确认失败")

return result

4. 多周期过滤

weekly_with_adx = calculate_adx(weekly_data.copy(), self.adx_period)

weekly_adx = weekly_with_adx'ADX'.iloc-1

weekly_ma = weekly_data'close'.rolling(20).mean().iloc-1

weekly_price = weekly_data'close'.iloc-1

if weekly_price > weekly_ma and weekly_adx >= self.adx_threshold:

result'multi_tf_ok' = True

result'details'.append(f"✓ 大周期趋势向上")

else:

result'details'.append(f"✗ 大周期趋势不支持")

综合判断

checks_passed = sum([

result'adx_ok',

result'breakout_ok',

result'time_ok',

result'multi_tf_ok'

])

if checks_passed >= 3:

result'signal' = '做多'

else:

result'signal' = '观望'

return result

第三步:参数优化建议

不同的市场和品种,参数需要调整:

| 市场 | ADX周期 | ADX阈值 | 突破幅度 | 确认天数 | | --- | --- | --- | --- | --- | | A股日线 | 14 | 25 | 2%-3% | 2 | | A股周线 | 14 | 20 | 3%-5% | 1 | | 期货日线 | 14 | 25 | 1%-2% | 2 | | 外汇日线 | 14 | 25 | 0.5%-1% | 2-3 | | 加密货币 | 14 | 20 | 3%-5% | 1-2 |

关键原则:

• 波动大的品种:提高突破幅度阈值,避免噪音

• 流动性好的品种:可以降低确认天数

• 震荡频繁的市场:提高ADX阈值到30

第四步:回测验证过滤效果

// python

def backtest_with_filter(df, system):

"""回测对比:有过滤 vs 无过滤"""

无过滤:所有突破都交易

no_filter_signals = \[\]

resistance = df'high'.rolling(20).max().shift(1)

for i in range(21, len(df)):

if df'close'.iloci > resistance.iloci:

no_filter_signals.append(i)

有过滤:通过ADX+双滤心过滤

filtered_signals = \[\]

for i in range(21, len(df)):

if df'close'.iloci > resistance.iloci:

检查ADX

if df'ADX'.iloci >= 25:

检查幅度

pct = (df'close'.iloci - resistance.iloci) / resistance.iloci

if pct >= 0.02:

检查时间确认

if i >= 2 and df'close'.iloci-1 >= resistance.iloci-1:

filtered_signals.append(i)

return {

'no_filter_count': len(no_filter_signals),

'filtered_count': len(filtered_signals),

'reduction_rate': f"{(1 - len(filtered_signals)/len(no_filter_signals))*100:.1f}%"

}

根据历史数据回测,使用趋势过滤系统后:

• 交易次数减少约40%-60%

• 胜率提升约15%-25%

• 最大回撤降低约30%-40%

• 总体风险调整后收益显著提升

这说明:少做,反而做得更好。

总结

今天的内容核心就是一个字:滤。

趋势跟踪策略的死穴不是"抓不住趋势",而是"被假突破反复打脸"。过滤掉假突破,你的策略才能真正跑起来。

六条核心要点:

  1. 假突破是常态:大约40%-60%的突破是假的,不要每次突破都追

  2. ADX是最实用的趋势过滤器:ADX>25做趋势,<20做震荡或观望

  3. 时间过滤:突破后等1-2天确认,不追第一根突破K线

  4. 幅度过滤:突破幅度要达到阈值(通常2%-3%)才算有效

  5. 多周期过滤:大周期定方向,小周期找入场,顺大逆小

  6. 少做反而做得更好:过滤后交易次数减少,但胜率和风险调整收益显著提升

最后送你一句话:

在趋势跟踪的世界里,耐心比聪明更重要。能忍住不追假突破的人,才能抓住真突破的大行情。

下一期,我们进入趋势跟踪的实战风控篇------如何设计渐进式止损、如何管理仓位、如何在趋势反转时及时离场。这才是趋势跟踪能不能长期活下去的关键。

相关推荐
8年区块链老兵1 小时前
一篇文章教会你:用区块高度读懂比特币链上的每一笔交易
前端
xixichensh2 小时前
前端转做AI程序员第一步——开发一个AI流式对话Demo
前端
小羊没烦恼!2 小时前
系统内部模块(子系统)之间的耦合以及模块(子系统)划分
java·开发语言·前端·数据库·算法·c#
Leslie1652 小时前
聚合不只是 GROUP BY:HashAggregate 与 SortAggregate 的内存账本
前端
ITOM运维行者2 小时前
PHP性能监控怎么做?从响应时间到慢函数的6个关键指标
前端·javascript·后端
成旭先生3 小时前
AI 文本审核 API:一段中文文本判风险等级、命中标签与处置建议
java·前端·人工智能·api接口·内容风控·文本审核·ugc审核
liangshanbo12153 小时前
前端面试题:AI 对话中超长消息导致内存溢出,怎么解决?
java·开发语言·前端
静默回滚3 小时前
PDF能打开却不能复制,原来是权限密码
前端
律宏阔3 小时前
Dart FFI 内存管理:用 using + Arena 替代嵌套 try-finally
前端·flutter