量化研究 | 黄金拥挤度的量价识别,构建领先指标(源码)

松鼠Quant
2025-11-12


图片
量化策略开发,高质量社群,交易思路分享等相关内容

工具推荐

👉· 参数筛选工具

👉 ·Ai帮你编写策略

👉· 订单流图表

👉· 加入2025俱乐部

👉· Ai投研助手课程


『正文』

ˇ

昨天群里小伙伴分享了一篇研报,《中信建投海外丨拥挤度的量价识别(2):黄金》今天我们将它的逻辑和代码复现一下。由于研报内有些地方只做了逻辑描述,没有公式因此复现的源码不一定百分百一致。

重点是逻辑的复现,以下是对研报萃取和总结:

📄 研报核心内容总结

1. 研究背景与目的

  • 背景:黄金市场关注度极高,但传统宏观逻辑对短期价格波动的解释力下降。

  • 目的:通过量化技术指标(量价、波动、动量等)识别黄金短期(5-20日)交易拥挤度,补充宏观分析的不足,预警技术性回调风险。

  • 标的与数据:以沪金期货为研究对象,结合日频和分钟频K线数据。

2. 核心逻辑黄金作为动量型资产,其拥挤度本质是刻画“动能由盛转衰”的过程。当资金在单一方向过度集中时,趋势可持续性减弱,易引发获利回吐和技术性回撤(如2016年、2025年的案例)。

3. 指标体系与信号生成研报将拥挤度指标分为五类,并进一步合成领先型(提前预警)和同步型(确认风险)综合指标:

  • 领先指标:量价相关性、局部极值动量、筹码类因子(信号触顶预示趋势衰减)。

  • 同步指标:调整极差、动量偏度、量比(触顶对应短期拥挤释放)。

  • 信号生成规则

  • 使用63日滚动窗口的Z-score标准化因子值。

  • 信号需满足:①得分超过历史均值1倍标准差;②为局部极值点。

  • 回测采用事件驱动框架(T+2确认执行),聚焦过去20日涨幅超5%的高动能阶段。

4. 关键结论

  • 综合指标表现

  • 同步指标在短期(5日)识别拥挤风险效果最佳,赔率76%;

  • 领先指标在中期(20日)表现更优,赔率68%。

  • 当前走势(截至2025年10月):领先指标已触顶,同步指标出现拐点,预示金价可能在月度级别进入震荡回调阶段。


📊 拥挤度计算公式详解

以下是研报中涉及的各类拥挤度因子的具体计算方法:

指标类别

公式/构建方法

含义与作用

1. 量价相关性

- 日间相关性:计算近1个月换手率与涨跌幅的相关系数。
-日内相关性:选取分钟K线中价量齐升的区间,计算20日滚动相关性。

衡量资金流向与价格趋势的同步性,高相关性预示单边拥挤。

2. 波动率类(调整极差)

`调整极差 = max(H_t - L_t,H_t - C_{t-1})


3. 动量类

- 局部极值动量:近20日中涨幅最高的5日平均收益。<br>- 动量偏度:近20日收益序列的偏度计算。

局部动量衡量动能集中度;偏度负值预示收益结构恶化。

4. 量比类

量比 = 最近20日成交量均值 / 120日成交量均值

反映交易活跃度是否过度饱和,量比高企预示增量资金枯竭。

5. 筹码类

计算多头平均持仓成本和空头平均持仓成当价格显著高于中性区间时触发信号。

价格脱离中性区间表明多头浮盈过度,回撤压力上升。

指标类别

公式/构建方法

含义与作用

1. 量价相关性

- 日间相关性:计算近1个月换手率与涨跌幅的相关系数。

- 日内相关性:选取分钟K线中价量齐升的区间,计算20日滚动相关性。

衡量资金流向与价格趋势的同步性,高相关性预示单边拥挤。

2. 波动率类(调整极差)

`调整极差 = max(H_t - L_t,H_t - C_{t-1})

3. 动量类

- 局部极值动量:近20日中涨幅最高的5日平均收益。<br>- 动量偏度:近20日收益序列的偏度计算。

局部动量衡量动能集中度;偏度负值预示收益结构恶化。

4. 量比类

量比 = 最近20日成交量均值 / 120日成交量均值

反映交易活跃度是否过度饱和,量比高企预示增量资金枯竭。

5. 筹码类

计算多头平均持仓成本和空头平均持仓成本中性价格 ≈ (P_{long} + P_{short})/2,当价格显著高于中性区间时触发信号。

价格脱离中性区间表明多头浮盈过度,回撤压力上升。

综合拥挤度合成方法

  • 领先指标(量价相关性、局部极值动量、筹码)等权合成,并滞后5日对齐信号。

  • 同步指标(调整极差、动量偏度、量比)等权合成。

  • 两类指标相关性较弱(-0.6~0.4),形成多周期互补。


1. 量价相关性指标






















    def price_volume_correlation_metrics(self, window=20):        """        1. 量价相关性指标        分为日间相关性和日内相关性两个维度        """        df = self.data.copy()                # 日间相关性:换手率与涨跌幅的相关性(月频)        df['daily_return'] = df['close'].pct_change()        df['volume_change'] = df['volume'].pct_change()        df['interday_corr'] = df['daily_return'].rolling(window).corr(df['volume_change'])                # 日内相关性:价格波动与成交量的相关性(日频)        df['intraday_range'] = (df['high'] - df['low']) / df['close']        df['intraday_corr'] = df['intraday_range'].rolling(window).corr(df['volume'])                # Z-score标准化        self.results['interday_correlation'] = self.calculate_z_score(df['interday_corr'])        self.results['intraday_correlation'] = self.calculate_z_score(df['intraday_corr'])                return df[['interday_corr', 'intraday_corr']]

2. 波动率类指标 - 调整极差




















    def volatility_metrics(self):        """        2. 波动率类指标 - 调整极差        Adjusted Range = max(H-L, |H-C_{t-1}|, |L-C_{t-1}|) / C_t        """        df = self.data.copy()                # 计算调整极差        term1 = df['high'] - df['low']   # 日内波动        term2 = abs(df['high'] - df['close'].shift(1))   # 隔夜波动(向上)        term3 = abs(df['low'] - df['close'].shift(1))   # 隔夜波动(向下)                df['adjusted_range'] = np.maximum(term1, np.maximum(term2, term3)) / df['close']        df['adjusted_range_20d'] = df['adjusted_range'].rolling(20).mean()                # Z-score标准化        self.results['adjusted_range'] = self.calculate_z_score(df['adjusted_range_20d'])                return df[['adjusted_range', 'adjusted_range_20d']]

3. 动量类指标






























    def momentum_metrics(self, window=20):        """        3. 动量类指标        - 局部极值动量:Top5日平均收益        - 收益率偏度:收益分布的偏度        """        df = self.data.copy()                # 局部极值动量        df['daily_return'] = df['close'].pct_change()                def top5_momentum(series):            """计算滚动窗口内涨幅最高的5日平均收益"""            if len(series) < 5:                return np.nan            return series.nlargest(5).mean()                df['top5_momentum'] = df['daily_return'].rolling(window).apply(            top5_momentum, raw=False        )                # 收益率偏度        df['return_skewness'] = df['daily_return'].rolling(window).skew()                # Z-score标准化        self.results['top5_momentum'] = self.calculate_z_score(df['top5_momentum'])        self.results['return_skewness'] = self.calculate_z_score(df['return_skewness'])                return df[['top5_momentum', 'return_skewness']]

4. 量比类指标



















    def volume_ratio_metrics(self):        """        4. 量比类指标        量比 = 20日成交量均值 / 120日成交量均值        """        df = self.data.copy()                df['volume_20d'] = df['volume'].rolling(20).mean()        df['volume_120d'] = df['volume'].rolling(120).mean()        df['volume_ratio'] = df['volume_20d'] / df['volume_120d']                # 处理无穷大值        df['volume_ratio'] = df['volume_ratio'].replace([np.inf, -np.inf], np.nan)                # Z-score标准化        self.results['volume_ratio'] = self.calculate_z_score(df['volume_ratio'])                return df[['volume_ratio']]

5. 筹码类指标





















    def position_metrics(self, short_window=20, long_window=60):        """        5. 筹码类指标        由于实际持仓数据难以获取,使用移动平均线模拟中性价格        """        df = self.data.copy()                # 模拟多头持仓成本(短期均线)        df['long_cost'] = df['close'].rolling(short_window).mean()        # 模拟空头持仓成本(长期均线)        df['short_cost'] = df['close'].rolling(long_window).mean()        # 中性价格        df['neutral_price'] = (df['long_cost'] + df['short_cost']) / 2        # 价格偏离度        df['price_deviation'] = (df['close'] - df['neutral_price']) / df['neutral_price']                # Z-score标准化        self.results['position_crowding'] = self.calculate_z_score(df['price_deviation'])                return df[['long_cost', 'short_cost', 'neutral_price', 'price_deviation']]

6.合成综合拥挤度指标








































    def composite_crowding_index(self):        """        合成综合拥挤度指标        - 领先指标:量价相关性、局部极值动量、筹码        - 同步指标:调整极差、收益率偏度、量比        """        # 领先指标组合        leading_indicators = [            self.results.get('interday_correlation', pd.Series(index=self.data.index)),            self.results.get('top5_momentum', pd.Series(index=self.data.index)),            self.results.get('position_crowding', pd.Series(index=self.data.index))        ]                # 同步指标组合        synchronous_indicators = [            self.results.get('adjusted_range', pd.Series(index=self.data.index)),            self.results.get('return_skewness', pd.Series(index=self.data.index)),            self.results.get('volume_ratio', pd.Series(index=self.data.index))        ]                # 等权合成(处理NaN值)        leading_df = pd.concat(leading_indicators, axis=1)        synchronous_df = pd.concat(synchronous_indicators, axis=1)                leading_composite = leading_df.mean(axis=1)        synchronous_composite = synchronous_df.mean(axis=1)                # 领先指标滞后5天处理(研报方法)        leading_composite_lag5 = leading_composite.shift(5)                self.results['leading_composite'] = leading_composite        self.results['synchronous_composite'] = synchronous_composite        self.results['leading_composite_lag5'] = leading_composite_lag5                return {            'leading_composite': leading_composite,            'synchronous_composite': synchronous_composite,            'leading_composite_lag5': leading_composite_lag5        }
TBQuant复现:
图片
图片
图片
完整源码和工作区已经上传到2025俱乐部后台-研报栏,登录后台下载
图片

防迷路


           图片

微   信|小松鼠-松鼠Quant

微信号|viquant01

25俱乐部源码《拥挤度

加入2025量化俱乐部



分享