欢迎光临
我们一直在努力

Momentum:SQUEEZE_PRO(多尺度波动挤压指标)技术指标详解

Momentum:SQUEEZE_PRO(多尺度波动挤压指标)技术指标详解

一、SQUEEZE_PRO的定义

SQUEEZE_PRO(多尺度波动挤压指标,简称SQZPRO) 是John Carter经典TTM Squeeze指标的升级版本。该指标同样基于John Carter所著的《Mastering the Trade》第11章中讨论的TTM Squeeze概念,通过引入三档肯特纳通道(宽/正常/窄) 来细分波动压缩的等级,帮助交易者更早识别潜在的爆发性行情。

核心思想

经典Squeeze指标仅判断布林带是否完全落入肯特纳通道内部,这种单一的二元判断可能遗漏“轻度压缩”带来的提前信号。SQUEEZE_PRO通过设置三组不同宽度的肯特纳通道(宽通道乘数2.0、正常通道乘数1.5、窄通道乘数1.0),将波动压缩程度细分为三级预警:

  • 窄挤压(Narrow Squeeze):最敏感,通常是行情发酵初期,波动已经开始收敛
  • 正常挤压(Normal Squeeze):波动进一步压缩,爆发概率上升
  • 宽挤压(Wide Squeeze):布林带极度收缩,往往是“临门一脚”的引爆点

同时,SQUEEZE_PRO通过动量柱(Momentum Histogram)显示价格动能的方向和强度,帮助交易者判断突破方向。

SQUEEZE vs SQUEEZE_PRO

对比维度SQUEEZE(经典)SQUEEZE_PRO(升级版)
肯特纳通道层级 单层(乘数1.5) 三层(乘数2.0/1.5/1.0)
挤压细分程度 二元判断(开/关) 三级预警(宽/正常/窄)
预警能力 单一阶段 逐级递进,提前预警
信号可靠性 中等 更高(多重确认)

SQUEEZE_PRO的核心组件

组件类型字段名称功能描述
多尺度动量柱 SQZPRO 平滑后的动量值,正值多头、负值空头,绝对值越大动能越强
宽挤压信号 SQZPRO_ON_WIDE 布林带完全落入宽KC(2×ATR),波动率极低,红灯预警
正常挤压信号 SQZPRO_ON_NORMAL 布林带落入正常KC(1.5×ATR),压缩加剧黄灯预警
窄挤压信号 SQZPRO_ON_NARROW 布林带落入窄KC(1×ATR),轻度压缩绿灯闪烁
挤压释放信号 SQZPRO_OFF 布林带折返并突破最宽KC,动能即将爆发
无挤压状态 SQZPRO_NO 市场正常波动,三档信号均为0

二、SQUEEZE_PRO的计算方法

1. 核心计算框架

SQUEEZE_PRO的计算包含四个层次:布林带计算、三档肯特纳通道计算、挤压状态判断、动量柱计算。

2. 详细计算步骤

步骤一:计算布林带(Bollinger Bands)

设周期bb_length=20,标准差倍数bb_std=2.0:

首先计算20周期简单移动平均线(SMA):
BB_MIDt=SMA20(Close)t
\\mathrm{BB\\_MID}_t = \\mathrm{SMA}_{20}(\\mathrm{Close})t
BB_MIDt=SMA20(Close)t

计算20周期收盘价的标准差:

σt=120∑i=019(Closet−i−BB_MIDt)2
\\sigma_t = \\sqrt{\\frac{1}{20} \\sum_{i=0}^{19} (\\mathrm{Close}_{t-i} – \\mathrm{BB\\_MID}_t)^2}
σt=201i=019(ClosetiBB_MIDt)2

布林带上下轨:
BB_HIGHt=BB_MIDt+2.0×σt
\\mathrm{BB\\_HIGH}_t = \\mathrm{BB\\_MID}_t + 2.0 \\times \\sigma_t
BB_HIGHt=BB_MIDt+2.0×σt

BB_LOWt=BB_MIDt−2.0×σt
\\mathrm{BB\\_LOW}_t = \\mathrm{BB\\_MID}_t – 2.0 \\times \\sigma_t
BB_LOWt=BB_MIDt2.0×σt

步骤二:计算三档肯特纳通道(Keltner Channels)

肯特纳通道以20周期指数移动平均线(EMA)为中轴:
KC_MIDt=EMA20(Close)t
\\mathrm{KC\\_MID}_t = \\mathrm{EMA}_{20}(\\mathrm{Close})_t
KC_MIDt=EMA20(Close)t

首先计算真实波幅(True Range):

TRt=max⁡(Ht−Lt,∣Ht−Ct−1∣,∣Lt−Ct−1∣)
\\mathrm{TR}_t = \\max(H_t – L_t, |H_t – C_{t-1}|, |L_t – C_{t-1}|)
TRt=max(HtLt,HtCt1,LtCt1)

计算20周期平均真实波幅(使用EMA):
ATR20,t=EMA20(TR)t
\\mathrm{ATR}_{20,t} = \\mathrm{EMA}_{20}(\\mathrm{TR})_t
ATR20,t=EMA20(TR)t

三档通道的上下轨计算(分别对应乘数 k=2.0,1.5,1.0k = 2.0, 1.5, 1.0k=2.0,1.5,1.0):

宽通道(Wide):乘数 kwide=2.0k_{\\mathrm{wide}} = 2.0kwide=2.0
KC_HIGHwide,t=KC_MIDt+2.0×ATR20,t
\\mathrm{KC\\_HIGH}_{\\mathrm{wide},t} = \\mathrm{KC\\_MID}_t + 2.0 \\times \\mathrm{ATR}_{20,t}
KC_HIGHwide,t=KC_MIDt+2.0×ATR20,t

KC_LOWwide,t=KC_MIDt−2.0×ATR20,t
\\mathrm{KC\\_LOW}_{\\mathrm{wide},t} = \\mathrm{KC\\_MID}_t – 2.0 \\times \\mathrm{ATR}_{20,t}
KC_LOWwide,t=KC_MIDt2.0×ATR20,t

正常通道(Normal):乘数 knormal=1.5k_{\\mathrm{normal}} = 1.5knormal=1.5
KC_HIGHnormal,t=KC_MIDt+1.5×ATR20,t
\\mathrm{KC\\_HIGH}_{\\mathrm{normal},t} = \\mathrm{KC\\_MID}_t + 1.5 \\times \\mathrm{ATR}_{20,t}
KC_HIGHnormal,t=KC_MIDt+1.5×ATR20,t

KC_LOWnormal,t=KC_MIDt−1.5×ATR20,t
\\mathrm{KC\\_LOW}_{\\mathrm{normal},t} = \\mathrm{KC\\_MID}_t – 1.5 \\times \\mathrm{ATR}_{20,t}
KC_LOWnormal,t=KC_MIDt1.5×ATR20,t

窄通道(Narrow):乘数 knarrow=1.0k_{\\mathrm{narrow}} = 1.0knarrow=1.0
KC_HIGHnarrow,t=KC_MIDt+1.0×ATR20,t
\\mathrm{KC\\_HIGH}_{\\mathrm{narrow},t} = \\mathrm{KC\\_MID}_t + 1.0 \\times \\mathrm{ATR}_{20,t}
KC_HIGHnarrow,t=KC_MIDt+1.0×ATR20,t

KC_LOWnarrow,t=KC_MIDt−1.0×ATR20,t
\\mathrm{KC\\_LOW}_{\\mathrm{narrow},t} = \\mathrm{KC\\_MID}_t – 1.0 \\times \\mathrm{ATR}_{20,t}
KC_LOWnarrow,t=KC_MIDt1.0×ATR20,t

步骤三:计算三级挤压状态

挤压状态的判断基于布林带与三档肯特纳通道的相对位置:

宽挤压开启(SQZPRO_ON_WIDE = 1):布林带完全落入宽KC通道内部
SQZPRO_ON_WIDEt=1{BB_LOWt>KC_LOWwide,t∧BB_HIGHt<KC_HIGHwide,t}
\\mathrm{SQZPRO\\_ON\\_WIDE}_t = \\mathbf{1}_{\\{\\mathrm{BB\\_LOW}_t > \\mathrm{KC\\_LOW}_{\\mathrm{wide},t} \\land \\mathrm{BB\\_HIGH}_t < \\mathrm{KC\\_HIGH}_{\\mathrm{wide},t}\\}}
SQZPRO_ON_WIDEt=1{BB_LOWt>KC_LOWwide,tBB_HIGHt<KC_HIGHwide,t}

正常挤压开启(SQZPRO_ON_NORMAL = 1):布林带落入正常KC通道内部
SQZPRO_ON_NORMALt=1{BB_LOWt>KC_LOWnormal,t∧BB_HIGHt<KC_HIGHnormal,t}
\\mathrm{SQZPRO\\_ON\\_NORMAL}_t = \\mathbf{1}_{\\{\\mathrm{BB\\_LOW}_t > \\mathrm{KC\\_LOW}_{\\mathrm{normal},t} \\land \\mathrm{BB\\_HIGH}_t < \\mathrm{KC\\_HIGH}_{\\mathrm{normal},t}\\}}
SQZPRO_ON_NORMALt=1{BB_LOWt>KC_LOWnormal,tBB_HIGHt<KC_HIGHnormal,t}

窄挤压开启(SQZPRO_ON_NARROW = 1):布林带落入窄KC通道内部
SQZPRO_ON_NARROWt=1{BB_LOWt>KC_LOWnarrow,t∧BB_HIGHt<KC_HIGHnarrow,t}
\\mathrm{SQZPRO\\_ON\\_NARROW}_t = \\mathbf{1}_{\\{\\mathrm{BB\\_LOW}_t > \\mathrm{KC\\_LOW}_{\\mathrm{narrow},t} \\land \\mathrm{BB\\_HIGH}_t < \\mathrm{KC\\_HIGH}_{\\mathrm{narrow},t}\\}}
SQZPRO_ON_NARROWt=1{BB_LOWt>KC_LOWnarrow,tBB_HIGHt<KC_HIGHnarrow,t}

挤压释放(SQZPRO_OFF = 1):布林带突破宽KC通道边界
SQZPRO_OFFt=1{BB_LOWt<KC_LOWwide,t∨BB_HIGHt>KC_HIGHwide,t}
\\mathrm{SQZPRO\\_OFF}_t = \\mathbf{1}_{\\{\\mathrm{BB\\_LOW}_t < \\mathrm{KC\\_LOW}_{\\mathrm{wide},t} \\lor \\mathrm{BB\\_HIGH}_t > \\mathrm{KC\\_HIGH}_{\\mathrm{wide},t}\\}}
SQZPRO_OFFt=1{BB_LOWt<KC_LOWwide,tBB_HIGHt>KC_HIGHwide,t}

无挤压状态(SQZPRO_NO = 1):不满足上述任何条件
SQZPRO_NOt=1{−SQZPRO_ON_WIDE∧−SQZPRO_ON_NORMAL∧−SQZPRO_ON_NARROW∧−SQZPRO_OFF}
\\mathrm{SQZPRO\\_NO}_t = \\mathbf{1}_{\\{-\\mathrm{SQZPRO\\_ON\\_WIDE} \\land -\\mathrm{SQZPRO\\_ON\\_NORMAL} \\land -\\mathrm{SQZPRO\\_ON\\_NARROW} \\land -\\mathrm{SQZPRO\\_OFF}\\}}
SQZPRO_NOt=1{SQZPRO_ON_WIDE∧−SQZPRO_ON_NORMAL∧−SQZPRO_ON_NARROW∧−SQZPRO_OFF}

注意:同一根K线只会出现一类启动信号(窄/正常/宽),或处于OFF/NO状态之一。

步骤四:计算多尺度动量柱(SQZPRO)

动量柱的计算基于动量指标,然后进行平滑处理:

首先计算动量值(周期mom_length=12):
MOMt=Closet−Closet−11
\\mathrm{MOM}_t = \\mathrm{Close}_t − \\mathrm{Close}_{t−11}
MOMt=ClosetCloset11

对MOM进行指数移动平均平滑(mom_smooth=6):
SQZPROt=EMA6(MOM)t
\\mathrm{SQZPRO}_t = \\mathrm{EMA}_6(\\mathrm{MOM})t
SQZPROt=EMA6(MOM)t

3. 参数说明

参数类型默认值说明
bb_length int 20 布林带计算周期
bb_std float 2.0 布林带标准差倍数
kc_length int 20 肯特纳通道计算周期
kc_scalar_wide float 2.0 宽肯特纳通道ATR乘数
kc_scalar_normal float 1.5 正常肯特纳通道ATR乘数
kc_scalar_narrow float 1.0 窄肯特纳通道ATR乘数
mom_length int 12 动量计算周期
mom_smooth int 6 动量平滑周期
use_tr bool True 是否使用真实波幅
mamode str “sma” 动量平滑类型(‘ema’或’sma’)

三、SQUEEZE_PRO的使用方法

1. “三级爆破”交易流程

SQUEEZE_PRO的设计逻辑是“波动压缩等级递进→爆发确认”的完整周期。

阶段指标状态市场含义操作策略
① 窄挤压(绿灯) SQZPRO_ON_NARROW=1 波动开始收敛,多空力量趋于平衡,行情正在酝酿初期 保持关注,开始筛选交易机会
② 正常挤压(黄灯) SQZPRO_ON_NORMAL=1 多空双方进入拉锯,波动进一步压缩,爆发概率上升 准备交易计划,设置预警
③ 宽挤压(红灯) SQZPRO_ON_WIDE=1 波动率极低,“低压锅”达到极限,随时可能引爆 密切关注,等待突破信号
④ 爆发(释放) SQZPRO_OFF=1 布林带突破最宽KC,动能爆发 执行顺势交易

这一流程的核心逻辑像交通信号灯——红灯前亮起黄灯让你提前热身,而非等到最后一秒才冲刺。

2. 方向判断:动量柱 + 挤压释放

挤压释放(SQZPRO_OFF=1)本身只代表波动率将扩张,但扩张方向并不确定。必须结合动量柱(SQZPRO)的方向来判断:

信号组合市场含义操作建议
SQZPRO_OFF=1 + 动量柱为正值(SQZPRO>0) 多头动能爆发,上涨趋势启动 做多
SQZPRO_OFF=1 + 动量柱为负值(SQZPRO<0) 空头动能爆发,下跌趋势启动 做空

3. 动量柱的趋势强度判断

动量柱的数值大小反映趋势强度,绝对值越大,动能越强:

动量柱状态动能含义操作倾向
正值且持续扩大(绿色柱) 多头动能持续增强 顺势持仓
正值但持续缩小 多头动能减弱,上涨乏力 减仓预警
负值且持续扩大(红色柱) 空头动能持续增强 顺势持仓
负值但持续缩小 空头动能减弱,下跌放缓 空头平仓预警

4. 三级挤压的实战意义

不同层级的挤压状态具有不同的信号价值:

  • 窄挤压(最敏感):波动已经收敛到窄KC内部,往往是趋势启动的“先遣信号”,适合激进的交易者提前布局
  • 正常挤压(较可靠):波动进一步压缩,出现后胜率较窄挤压更高,适合大多数交易者关注
  • 宽挤压(最强信号):布林带完全被宽KC包裹,波动率极低,“弹簧”压缩到极致,一旦释放往往伴随剧烈单边行情

5. 多重过滤策略

为提高信号可靠性,建议加入额外的过滤条件:

均线过滤:

  • 做多信号:SQZPRO_OFF=1 + 动量柱>0 + 价格>MA50
  • 做空信号:SQZPRO_OFF=1 + 动量柱<0 + 价格<MA50

ADX过滤:

  • ADX<20时,市场处于震荡,挤压信号假突破概率较高
  • ADX>25时,市场处于趋势状态,挤压信号可靠性更高

成交量验证:

  • 挤压释放时若伴随成交量明显放大,突破的可信度显著提高

6. 注意事项与局限性

使用SQUEEZE_PRO前需了解以下要点:

局限性说明
滞后性质 挤压释放确认信号出现时,价格往往已启动一段距离
震荡市假信号 在趋势不明确的市场中,挤压可能被反复触发,导致假突破
参数敏感 不同品种可能需要调整KC乘数参数以获得最佳效果
需要组合使用 建议与均线系统、ADX趋势强度指标配合使用

四、使用pandas_ta计算SQUEEZE_PRO(附示例代码)

1. pandas_ta中的SQUEEZE_PRO函数

pandas_ta库内置了SQUEEZE_PRO指标的完整实现,位于momentum模块中。

2. 函数完整参数

pandas_ta.momentum.squeeze_pro(
high, low, close,
bb_length=None, bb_std=None,
kc_length=None,
kc_scalar_wide=None, kc_scalar_normal=None, kc_scalar_narrow=None,
mom_length=None, mom_smooth=None,
use_tr=None, mamode=None,
offset=None, **kwargs
)

参数详解:

参数类型默认值说明
high pd.Series 必需 最高价序列
low pd.Series 必需 最低价序列
close pd.Series 必需 收盘价序列
bb_length int 20 布林带计算周期
bb_std float 2.0 布林带标准差倍数
kc_length int 20 肯特纳通道周期
kc_scalar_wide float 2.0 宽通道ATR乘数
kc_scalar_normal float 1.5 正常通道ATR乘数
kc_scalar_narrow float 1.0 窄通道ATR乘数
mom_length int 12 动量计算周期
mom_smooth int 6 动量平滑周期
use_tr bool True 是否使用真实波幅(否则用High-Low)
mamode str “sma” 移动平均类型(‘ema’或’sma’)

返回值:pd.DataFrame——包含6列:

  • SQZPRO_{params}:多尺度动量柱(正值多头,负值空头)
  • SQZPRO_ON_WIDE:宽挤压启动(1=红灯/极度压缩)
  • SQZPRO_ON_NORMAL:正常挤压启动(1=黄灯/压缩加剧)
  • SQZPRO_ON_NARROW:窄挤压启动(1=绿灯/轻度压缩)
  • SQZPRO_OFF:挤压释放(1=爆发信号)
  • SQZPRO_NO:无挤压状态(1=正常波动)

3. 示例代码

import pandas as pd
import pandas_ta as ta
import numpy as np
import matplotlib.pyplot as plt

# ========== 第一步:准备数据 ==========
np.random.seed(42)
dates = pd.date_range(start='2023-01-01', end='2024-12-31', freq='D')
n = len(dates)

# 生成带趋势和周期波动的价格序列(包含低波动区间)
trend = np.linspace(0, 35, n)
cycle = np.sin(np.linspace(0, 4 * np.pi, n)) * 12
noise = np.random.randn(n) * 2
price_series = 100 + trend + cycle + noise

# 添加一个低波动率区间(模拟挤压状态)
low_vol_start = 300
low_vol_end = 400
price_series[low_vol_start:low_vol_end] = price_series[low_vol_start] + np.random.randn(low_vol_end low_vol_start) * 1

df = pd.DataFrame(index=dates[:n])
df['close'] = price_series[:n]
df['high'] = df['close'] + np.abs(np.random.randn(n)) * 2 + 1
df['low'] = df['close'] np.abs(np.random.randn(n)) * 2 1
df['volume'] = np.random.randint(5000000, 30000000, n)

print("=" * 70)
print("数据预览:")
print(df.head())
print("\\n" + "=" * 70 + "\\n")

# ========== 第二步:计算SQUEEZE_PRO(基础用法) ==========
# 使用默认参数(BB:20,2 | KC:20, 宽2/正常1.5/窄1 | 动量:12,6)
sqzpro_df = ta.squeeze_pro(df['high'], df['low'], df['close'])

# 查看返回的DataFrame结构
print("SQUEEZE_PRO返回列名称:")
print(sqzpro_df.columns.tolist())
print("\\n" + "=" * 70 + "\\n")

# 将计算结果添加到原DataFrame
# 根据列名特征提取各列
sqzpro_col = [col for col in sqzpro_df.columns if col.startswith('SQZPRO_') and '_ON_' not in col and '_OFF' not in col and '_NO' not in col]
sqzpro_on_wide_col = [col for col in sqzpro_df.columns if col.endswith('_ON_WIDE')]
sqzpro_on_normal_col = [col for col in sqzpro_df.columns if col.endswith('_ON_NORMAL')]
sqzpro_on_narrow_col = [col for col in sqzpro_df.columns if col.endswith('_ON_NARROW')]
sqzpro_off_col = [col for col in sqzpro_df.columns if col.endswith('_OFF')]
sqzpro_no_col = [col for col in sqzpro_df.columns if col.endswith('_NO')]

df['SQZPRO'] = sqzpro_df[sqzpro_col[0]] if sqzpro_col else sqzpro_df.iloc[:, 0]
df['SQZPRO_ON_WIDE'] = sqzpro_df[sqzpro_on_wide_col[0]] if sqzpro_on_wide_col else sqzpro_df.iloc[:, 1]
df['SQZPRO_ON_NORMAL'] = sqzpro_df[sqzpro_on_normal_col[0]] if sqzpro_on_normal_col else sqzpro_df.iloc[:, 2]
df['SQZPRO_ON_NARROW'] = sqzpro_df[sqzpro_on_narrow_col[0]] if sqzpro_on_narrow_col else sqzpro_df.iloc[:, 3]
df['SQZPRO_OFF'] = sqzpro_df[sqzpro_off_col[0]] if sqzpro_off_col else sqzpro_df.iloc[:, 4]
df['SQZPRO_NO'] = sqzpro_df[sqzpro_no_col[0]] if sqzpro_no_col else sqzpro_df.iloc[:, 5]

print("SQUEEZE_PRO计算结果(最近10行):")
print(df[['close', 'SQZPRO', 'SQZPRO_ON_WIDE', 'SQZPRO_ON_NORMAL', 'SQZPRO_ON_NARROW', 'SQZPRO_OFF']].tail(10))
print("\\n" + "=" * 70 + "\\n")

# ========== 第三步:手动验证SQUEEZE_PRO核心逻辑 ==========
def manual_squeeze_pro(high, low, close,
bb_length=20, bb_std=2.0,
kc_length=20,
kc_scalar_wide=2.0, kc_scalar_normal=1.5, kc_scalar_narrow=1.0,
mom_length=12, mom_smooth=6):
"""手动验证SQUEEZE_PRO核心计算逻辑"""

# 1. 计算布林带
sma = close.rolling(window=bb_length).mean()
std = close.rolling(window=bb_length).std()
bb_high = sma + bb_std * std
bb_low = sma bb_std * std

# 2. 计算ATR(平均真实波幅)
tr1 = high low
tr2 = abs(high close.shift(1))
tr3 = abs(low close.shift(1))
tr = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1)
atr = tr.ewm(span=kc_length, adjust=False).mean()

# 3. 计算肯特纳通道中轨
kc_mid = close.ewm(span=kc_length, adjust=False).mean()

# 4. 计算三档肯特纳通道
kc_high_wide = kc_mid + kc_scalar_wide * atr
kc_low_wide = kc_mid kc_scalar_wide * atr
kc_high_normal = kc_mid + kc_scalar_normal * atr
kc_low_normal = kc_mid kc_scalar_normal * atr
kc_high_narrow = kc_mid + kc_scalar_narrow * atr
kc_low_narrow = kc_mid kc_scalar_narrow * atr

# 5. 判断三级挤压状态
sqz_on_wide = ((bb_low > kc_low_wide) & (bb_high < kc_high_wide)).astype(int)
sqz_on_normal = ((bb_low > kc_low_normal) & (bb_high < kc_high_normal)).astype(int)
sqz_on_narrow = ((bb_low > kc_low_narrow) & (bb_high < kc_high_narrow)).astype(int)
sqz_off = ((bb_low < kc_low_wide) | (bb_high > kc_high_wide)).astype(int)
sqz_no = ((sqz_on_wide == 0) & (sqz_on_normal == 0) & (sqz_on_narrow == 0) & (sqz_off == 0)).astype(int)

# 6. 计算动量柱
mom = close close.shift(mom_length 1)
sqzpro = mom.ewm(span=mom_smooth, adjust=False).mean()

return sqzpro, sqz_on_wide, sqz_on_normal, sqz_on_narrow, sqz_off, sqz_no

df['SQZPRO_manual'], df['WIDE_manual'], df['NORMAL_manual'], df['NARROW_manual'], df['OFF_manual'], df['NO_manual'] = manual_squeeze_pro(
df['high'], df['low'], df['close']
)

# 验证一致性
diff_sqz = (df['SQZPRO'] df['SQZPRO_manual']).abs().max()
print(f"pandas_ta与手动计算动量值的最大差异:{diff_sqz:.10f}")
print("\\n" + "=" * 70 + "\\n")

# ========== 第五步:挤压状态统计 ==========
print("挤压状态统计:")
print(f"窄挤压(轻度压缩-绿灯)天数:{df['SQZPRO_ON_NARROW'].sum()}")
print(f"正常挤压(中度压缩-黄灯)天数:{df['SQZPRO_ON_NORMAL'].sum()}")
print(f"宽挤压(极度压缩-红灯)天数:{df['SQZPRO_ON_WIDE'].sum()}")
print(f"挤压释放(爆发)天数:{df['SQZPRO_OFF'].sum()}")
print(f"无挤压天数:{df['SQZPRO_NO'].sum()}")
print("\\n" + "=" * 70 + "\\n")

# ========== 第六步:生成交易信号 ==========
# 买入信号:挤压释放 + 动量柱为正
df['buy_signal'] = (df['SQZPRO_OFF'] == 1) & (df['SQZPRO'] > 0)
# 卖出信号:挤压释放 + 动量柱为负
df['sell_signal'] = (df['SQZPRO_OFF'] == 1) & (df['SQZPRO'] < 0)

# 动能强度分类
df['momentum_strength'] = ''
df.loc[df['SQZPRO'] > 2, 'momentum_strength'] = '强多头动能'
df.loc[(df['SQZPRO'] > 0) & (df['SQZPRO'] <= 2), 'momentum_strength'] = '弱多头动能'
df.loc[(df['SQZPRO'] < 0) & (df['SQZPRO'] >= 2), 'momentum_strength'] = '弱空头动能'
df.loc[df['SQZPRO'] < 2, 'momentum_strength'] = '强空头动能'

print("交易信号统计:")
print(f"买入信号(挤压释放+多头动量)数量:{df['buy_signal'].sum()}")
print(f"卖出信号(挤压释放+空头动量)数量:{df['sell_signal'].sum()}")

print("\\n最近10个交易信号:")
signals = df[df['buy_signal'] | df['sell_signal']].tail(10)
if not signals.empty:
for idx, row in signals.iterrows():
signal_type = "买入" if row['buy_signal'] else "卖出"
squeeze_level = []
if row['SQZPRO_ON_NARROW']: squeeze_level.append("窄挤压")
if row['SQZPRO_ON_NORMAL']: squeeze_level.append("正常挤压")
if row['SQZPRO_ON_WIDE']: squeeze_level.append("宽挤压")
level_str = "+".join(squeeze_level) if squeeze_level else "无"
print(f"{idx.date()}{signal_type} – SQZPRO: {row['SQZPRO']:.2f} – 挤压等级: {level_str}")
print("\\n" + "=" * 70 + "\\n")

# ========== 第七步:策略回测(挤压突破策略) ==========
# 策略:买入信号出现时买入,持有至卖出信号或动能转弱
df['position'] = 0
in_position = False

for i in range(1, len(df)):
if not in_position and df['buy_signal'].iloc[i]:
df.loc[df.index[i], 'position'] = 1
in_position = True
elif in_position and (df['sell_signal'].iloc[i] or df['momentum_strength'].iloc[i] == '弱多头动能'):
df.loc[df.index[i], 'position'] = 0
in_position = False
else:
df.loc[df.index[i], 'position'] = df['position'].iloc[i1]

# 计算收益
df['returns'] = df['close'].pct_change()
df['strategy_returns'] = df['position'].shift(1) * df['returns']

total_return_buyhold = (1 + df['returns']).prod() 1
total_return_strategy = (1 + df['strategy_returns']).prod() 1
win_rate = (df['strategy_returns'] > 0).sum() / (df['strategy_returns'] != 0).sum() if (df['strategy_returns'] != 0).sum() > 0 else 0

print("=" * 70)
print("策略绩效统计(SQUEEZE_PRO三级挤压突破策略回测):")
print(f"买入持有策略总收益率:{total_return_buyhold:.2%}")
print(f"SQUEEZE_PRO策略总收益率:{total_return_strategy:.2%}")
print(f"策略胜率:{win_rate:.2%}")
print("\\n注意:此为简化回测,仅供参考;实盘需考虑手续费、滑点等因素")
print("=" * 70 + "\\n")

# ========== 第八步:可视化 ==========
plt.figure(figsize=(14, 12))

# 子图1:价格走势 + 挤压状态标记
plt.subplot(3, 1, 1)
plt.plot(df.index[200:], df['close'][200:], label='Close Price',
linewidth=1.5, color='black')
# 标记不同等级的挤压状态
narrow_points = df[df['SQZPRO_ON_NARROW'] == 1]
normal_points = df[df['SQZPRO_ON_NORMAL'] == 1]
wide_points = df[df['SQZPRO_ON_WIDE'] == 1]
plt.scatter(narrow_points.index[200:], narrow_points['close'][200:],
color='green', s=15, label='窄挤压(绿灯)', alpha=0.7)
plt.scatter(normal_points.index[200:], normal_points['close'][200:],
color='yellow', s=20, label='正常挤压(黄灯)', alpha=0.7)
plt.scatter(wide_points.index[200:], wide_points['close'][200:],
color='red', s=25, label='宽挤压(红灯)', alpha=0.7)
plt.title('Price Chart with Squeeze Pro Signals (Last 200 days)', fontsize=14)
plt.ylabel('Price')
plt.legend()
plt.grid(True, alpha=0.3)

# 子图2:挤压状态指示(点阵图)
plt.subplot(3, 1, 2)
plt.plot(df.index[200:], df['SQZPRO_ON_NARROW'][200:], 'g.', markersize=3, label='窄挤压(绿灯)', alpha=0.7)
plt.plot(df.index[200:], df['SQZPRO_ON_NORMAL'][200:], 'y.', markersize=4, label='正常挤压(黄灯)', alpha=0.7)
plt.plot(df.index[200:], df['SQZPRO_ON_WIDE'][200:], 'r.', markersize=5, label='宽挤压(红灯)', alpha=0.7)
plt.plot(df.index[200:], df['SQZPRO_OFF'][200:], 'bo', markersize=4, label='挤压释放(爆发)', alpha=0.7)
plt.ylim(0.1, 1.1)
plt.title('Squeeze Pro State: Green=Narrow, Yellow=Normal, Red=Wide, Blue=Release', fontsize=12)
plt.ylabel('State')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)

# 子图3:多尺度动量柱
plt.subplot(3, 1, 3)
colors = ['green' if val >= 0 else 'red' for val in df['SQZPRO'][200:]]
plt.bar(df.index[200:], df['SQZPRO'][200:], color=colors, alpha=0.7, width=0.8)
plt.axhline(y=0, color='gray', linestyle='-', linewidth=1)
plt.title('SQZPRO Momentum Histogram: 多头动能(绿色) vs 空头动能(红色)', fontsize=12)
plt.xlabel('Date')
plt.ylabel('SQZPRO Momentum')
plt.grid(True, alpha=0.3)

# 标记买入/卖出信号
buy_signals = df[df['buy_signal']]
sell_signals = df[df['sell_signal']]
plt.scatter(buy_signals.index[20:], [0.5] * min(20, len(buy_signals)),
color='green', marker='^', s=80, label='Buy Signal', alpha=0.8)
plt.scatter(sell_signals.index[20:], [0.5] * min(20, len(sell_signals)),
color='red', marker='v', s=80, label='Sell Signal', alpha=0.8)

plt.tight_layout()
plt.show()

# ========== 第九步:数据清洗提示 ==========
nan_count = df['SQZPRO'].isna().sum()
print(f"\\nSQUEEZE_PRO初始NaN数量:{nan_count}")
print("原因:SQUEEZE_PRO需要至少max(bb_length, kc_length, mom_length)个周期的数据")
print("处理建议:df_clean = df.iloc[20:].copy()")
print("\\n" + "=" * 70)
print("SQUEEZE_PRO使用提示:")
print("1. 三级挤压递进:窄挤压(绿灯)→正常挤压(黄灯)→宽挤压(红灯)")
print("2. 挤压释放(蓝点)+ 动量柱为正 = 多头突破信号")
print("3. 挤压释放(蓝点)+ 动量柱为负 = 空头突破信号")
print("4. 建议配合均线过滤,如价格>MA50时做多,<MA50时做空")
print("5. 在ADX<20的震荡市中,挤压信号假突破概率较高,谨慎使用")
print("=" * 70)

五、总结

SQUEEZE_PRO(多尺度波动挤压指标)是对经典Squeeze指标的全面升级,其核心价值与定位如下:

维度特点
核心创新 引入三档肯特纳通道(宽/正常/窄),细分波动压缩等级
三级预警 窄挤压(绿灯)→正常挤压(黄灯)→宽挤压(红灯)
核心公式 BB完全落入KC_Narrow/Normal/Wide → 对应等级挤压
六组件系统 动量柱 + 宽/正常/窄三档挤压 + 释放 + 无挤压
默认参数 (20,2,20,2.0,1.5,1.0,12,6)
最佳应用场景 趋势品种的爆发点识别、多空切换判断
主要局限 滞后性、震荡市假信号、需配合其他指标

实战使用三原则:

  • 三级递进提前热身:从窄挤压(绿灯)到宽挤压(红灯),波动压缩程度逐级加深,信号可靠性逐级提高。红灯亮起时往往是最佳准备时机
  • 挤压释放+动量柱=方向确认:释放(SQZPRO_OFF=1)本身只意味着波动即将扩张,需结合动量柱的正负判断方向:正→做多,负→做空
  • 多指标过滤提高胜率:建议加入ADX过滤震荡市假信号,或结合均线系统(如价格>MA50时只做多)增强信号可靠性
  • 最后提醒:SQUEEZE_PRO的核心价值在于将“波动压缩”这一连续过程量化为逐级递进的预警信号,帮助交易者提前布局而非被动等待。它本质上回答了交易中的核心问题:“弹簧”压缩到什么程度了?什么时候可能爆发? 然而,如所有技术指标一样,SQUEEZE_PRO并非圣杯——在震荡市中假突破信号仍然存在。建议将其作为完整交易系统的“触发器”,配合趋势确认工具(如ADX、均线)和严格的风控管理使用。

    赞(0)
    未经允许不得转载:171主机测评 » Momentum:SQUEEZE_PRO(多尺度波动挤压指标)技术指标详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址