Bootstrap

1.1 重叠因子:布林带(Bollinger Bands)概念与Python实战

0. 本栏目因子汇总表

【量海航行】

1. 因子简述

布林带(Bollinger Bands)是一种基于移动平均线的技术分析工具,由John Bollinger在1980年代创建。它由三条线组成:中轨(移动平均线)、上轨(中轨加上N倍标准差)和下轨(中轨减去N倍标准差)。布林带可以帮助识别市场的超买超卖状态,以及价格波动的收缩和扩张。

2. 因子计算逻辑

布林带的计算公式如下:

M i d d l e B a n d = S M A ( C l o s e , n ) U p p e r B a n d = M i d d l e B a n d + k × σ L o w e r B a n d = M i d d l e B a n d − k × σ \begin{align*} Middle Band &= SMA(Close, n) \\ Upper Band &= Middle Band + k \times \sigma \\ Lower Band &= Middle Band - k \times \sigma \\ \end{align*} MiddleBandUpperBandLowerBand=SMA(Close,n)=MiddleBand+k×σ=MiddleBandk×σ

其中:

  • SMA为简单移动平均
  • n为移动平均的周期(通常为20)
  • k为标准差的倍数(通常为2)
  • σ为n周期的标准差

布林带因子的计算:
B B A N D S = C l o s e − L o w e r B a n d U p p e r B a n d − L o w e r B a n d BBANDS = \frac{Close - Lower Band}{Upper Band - Lower Band} BBANDS=UpperBandLowerBandCloseLowerBand

3. 因子应用场景

  1. 趋势跟踪:

    • 当价格突破上轨时,可能表示上升趋势加强
    • 当价格突破下轨时,可能表示下降趋势加强
  2. 均值回归:

    • 当价格接近上轨时,可能出现超买
    • 当价格接近下轨时,可能出现超卖
  3. 波动率预测:

    • 布林带收窄表示波动率降低,可能预示趋势变化
    • 布林带扩张表示波动率增加,可能出现大幅度行情
  4. 市场状态判断:

    • 因子值接近1表示接近上轨,可能超买
    • 因子值接近0表示接近下轨,可能超卖
    • 因子值接近0.5表示接近中轨,处于中性状态

4. 因子优缺点

优点:

  1. 适应性强:布林带会根据市场波动自动调整带宽
  2. 直观易懂:上下轨提供了清晰的价格参考区间
  3. 多维度信息:同时提供趋势、波动率和价格极值信息
  4. 标准化输出:因子值在0-1之间,便于比较和构建组合

缺点:

  1. 滞后性:作为移动平均的衍生指标,存在一定滞后
  2. 参数敏感:不同的周期和标准差倍数可能产生不同结果
  3. 假信号:在震荡市场中可能产生较多假信号
  4. 单一维度:仅考虑价格信息,未考虑成交量等其他因素

5. 因子代码实现

def BBANDS_factor(df, n=20, k=3):
    """
    计算布林带因子
    
    参数:
    df (DataFrame): 输入数据
        - code: 证券代码,如'600036.SH'
        - date: 日期,格式为'YYYY-MM-DD'
        - close: 收盘价
    n (int): 移动平均周期,默认20
    k (float): 标准差倍数,默认3
    
    返回:
    DataFrame: 包含原有列和BBANDS因子值,取值范围[0,1]
    """
    import numpy as np
    import pandas as pd
    
    # 检查code格式
    valid_codes = df['code'].str.match(r'^(?:\d{6}\.(SH|SZ)|[A-Z]+/[A-Z]+|\w+\.(IB|CFE|US))$')
    if not valid_codes.all():
        raise ValueError("Invalid code format found")
    
    # 检查date格式
    valid_dates = df['date'].str.match(r'^\d{4}-\d{2}-\d{2}$')
    if not valid_dates.all():
        raise ValueError("Invalid date format found, expected 'YYYY-MM-DD'")
    
    # 排序(使用字符串比较)- 保持时间降序
    df = df.sort_values(['code', 'date'], ascending=[True, False])
    
    # 按code分组计算
    def calculate_bbands(group):
        # 计算移动平均线(中轨)
        middle = group['close'].rolling(window=n).mean()
        
        # 计算标准差
        std = group['close'].rolling(window=n).std()
        
        # 计算上轨和下轨
        upper = middle + k * std
        lower = middle - k * std
        
        # 计算因子值:价格在布林带中的相对位置
        group['BBANDS'] = np.clip(
            (group['close'] - lower) / (upper - lower),
            0,
            1
        )
        return group
    
    # 按code分组计算因子
    df = df.groupby('code', group_keys=False).apply(calculate_bbands)
    
    # 按照最终要求重新排序并重置索引
    df = df.sort_values(['date', 'code'], ascending=[False, True]).reset_index(drop=True)
    
    return df

测试数据:
在这里插入图片描述

6. 因子取值范围及其含义

BBANDS因子的取值范围为[0,1]:

  • 取值为0:表示价格位于或低于下轨,可能处于超卖状态
  • 取值为0.5:表示价格位于中轨,处于中性状态
  • 取值为1:表示价格位于或高于上轨,可能处于超买状态
  • 取值在(0,0.5)之间:表示价格位于下轨和中轨之间,偏向看空
  • 取值在(0.5,1)之间:表示价格位于中轨和上轨之间,偏向看多

7. 因子函数参数建议

  1. n (移动平均周期):

    • 默认值:20
    • 建议范围:[10, 30]
    • 参数说明:较小的n值对市场变化更敏感,较大的n值提供更平滑的信号
    • 选择建议:
      • 日线数据建议使用20
      • 小时线数据建议使用30
      • 分钟线数据建议使用10
  2. k (标准差倍数):

    • 默认值:3
    • 建议范围:[2, 3]
    • 参数说明:k值越大,布林带区间越宽,信号越保守
    • 选择建议:
      • 波动率大的市场使用3
      • 波动率小的市场使用2
      • 不建议使用超过3的值,可能错过交易机会

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;