Overlap:LINREG(线性回归均线)技术指标详解
一、LINREG的定义
LINREG(Linear Regression Moving Average,线性回归均线) 是一种基于统计学线性回归理论的趋势跟踪指标。它不是简单地对价格取平均(如SMA),而是使用最小二乘法对一段价格序列拟合出一条"最佳拟合线",用以捕捉该段区间内价格的整体走势。
核心设计理念
线性回归是一种统计工具,用于根据历史价格预测未来价格可能的走向。传统的线性回归在图表上绘制为一条直线,类似趋势线。但线性回归均线并不是画一条直线,而是通过滑动窗口,在每个时间点计算窗口内数据的回归线"终点值",从而形成一条平滑的曲线。
当价格上涨时,线性回归线会试图确定价格相对于当前价格的上升偏差;当价格下跌时,它会试图确定价格的下降偏差。一些分析师认为,当价格高于或低于线性回归线时,价格处于过度延伸状态,将开始向该线回归。
LINREG的核心特征
| 特征 | 说明 |
|---|---|
| 理论基础 | 最小二乘法线性回归 |
| 指标类型 | 趋势跟踪/重叠指标 |
| 核心原理 | 对滚动窗口内的价格进行线性拟合,取回归线的终点值 |
| 默认参数 | length=9或10 |
| 计算方式 | 滚动回归(Rolling Regression) |
| 核心优势 | 比移动平均线更贴近价格的实际变动路径 |
LINREG的衍生信息
由于LINREG的计算基于线性回归,它可以衍生出多个有价值的辅助指标:
| 衍生指标 | 说明 |
|---|---|
| 斜率(Slope) | 回归线的变化速率,正=上升趋势,负=下降趋势 |
| 角度(Angle) | 斜率的弧度或度数表示,更直观地反映趋势陡峭程度 |
| 截距(Intercept) | 回归线在价格轴上的起点位置 |
| 相关系数(R) | 衡量价格与回归线的拟合程度,反映趋势强度 |
二、LINREG的计算方法
1. 核心计算公式
对于长度为 n n n 的滚动窗口,价格序列为 P 1 , P 2 , . . . , P n P_1, P_2, ..., P_n P1,P2,...,Pn,对应的时间索引为 x i = i x_i = i xi=i(通常从 0 开始)。
斜率(Slope, a a a) 的计算公式为:
a = n ∑ ( i ⋅ P i ) − ∑ i ∑ P i n ∑ i 2 − ( ∑ i ) 2 a = \frac{n \sum (i \cdot P_i) - \sum i \sum P_i}{n \sum i^2 - (\sum i)^2} a=n∑i2−(∑i)2n∑(i⋅Pi)−∑i∑Pi
截距(Intercept, b b b) 的计算公式为:
b = ∑ P i − a ∑ i n b = \frac{\sum P_i - a \sum i}{n} b=n∑Pi−a∑i
当前窗口的回归线终点值(即LINREG输出值) 为:
L I N R E G = a ⋅ ( n − 1 ) + b \mathrm{LINREG} = a \cdot (n - 1) + b LINREG=a⋅(n−1)+b
其中 ( n − 1 ) (n - 1) (n−1) 是窗口内最后一个时间点的索引值。
2. 简化公式(时间索引从0开始)
当时间索引 i i i 从 0 开始时, ∑ i \sum i ∑i 和 ∑ i 2 \sum i^2 ∑i2 有如下性质:
∑ i = n ( n − 1 ) 2 \sum i = \frac{n(n - 1)}{2} ∑i=2n(n−1)
∑ i 2 = n ( n − 1 ) ( 2 n − 1 ) 6 \sum i^2 = \frac{n(n - 1)(2n - 1)}{6} ∑i2=6n(n−1)(2n−1)
斜率 a a a 与价格序列的协方差和方差直接相关。对于实际计算,使用通用公式即可。
3. 计算示例
假设窗口长度 n = 5 n=5 n=5,价格序列如下:
| 时间索引 i | 价格 Pi |
|---|---|
| 0 | 100 |
| 1 | 102 |
| 2 | 105 |
| 3 | 103 |
| 4 | 108 |
计算各项求和:
- n = 5 n=5 n=5
- ∑ i = 0 + 1 + 2 + 3 + 4 = 10 \sum i = 0+1+2+3+4 = 10 ∑i=0+1+2+3+4=10
- ∑ i 2 = 0 + 1 + 4 + 9 + 16 = 30 \sum i^2 = 0+1+4+9+16 = 30 ∑i2=0+1+4+9+16=30
- ∑ P i = 100 + 102 + 105 + 103 + 108 = 518 \sum P_i = 100+102+105+103+108 =518 ∑Pi=100+102+105+103+108=518
- ∑ ( i ⋅ P i ) = 0 × 100 + 1 × 102 + 2 × 105 + 3 × 103 + 4 × 108 = 1053 \sum (i \cdot P_i) = 0×100+1×102+2×105+3×103+4×108 =1053 ∑(i⋅Pi)=0×100+1×102+2×105+3×103+4×108=1053
计算斜率 a a a :
a = 5 × 1053 − 10 × 518 5 × 30 − 10 2 = 5265 − 5180 150 − 100 = 85 50 = 1.7 a = \frac{5 \times 1053 - 10 \times 518}{5 \times 30 - 10^2} = \frac{5265 - 5180}{150 - 100} = \frac{85}{50} = 1.7 a=5×30−1025×1053−10×518=150−1005265−5180=5085=1.7
计算截距 b b b :
b = 518 − 1.7 × 10 5 = 518 − 17 5 = 501 5 = 100.2 b = \frac{518 - 1.7 \times 10}{5} = \frac{518 - 17}{5} = \frac{501}{5} = 100.2 b=5518−1.7×10=5518−17=5501=100.2
计算LINREG值(回归线终点) :
L I N R E G = 1.7 × 4 + 100.2 = 6.8 + 100.2 = 107.0 \mathrm{LINREG} = 1.7 \times 4 + 100.2 = 6.8 + 100.2 = 107.0 LINREG=1.7×4+100.2=6.8+100.2=107.0
该值为107.0,略低于最新价格108.0,表明价格略高于回归趋势线的预测。
三、LINREG的使用方法
1. 趋势方向判断------最基础用法
LINREG线的方向直接反映了价格的趋势方向,这是最直观的应用:
| LINREG状态 | 趋势含义 | 操作倾向 |
|---|---|---|
| LINREG向上运行 | 上升趋势 | 以做多为主,寻找买入机会 |
| LINREG向下运行 | 下降趋势 | 以做空为主,寻找卖出机会 |
| LINREG走平 | 趋势可能减弱或进入盘整 | 观望,等待方向明确 |
2. 价格偏离与回归------超买超卖判断
一些分析师认为,当价格高于或低于线性回归线时,价格处于过度延伸状态,将开始向该线回归:
| 价格与LINREG的关系 | 市场含义 | 操作倾向 |
|---|---|---|
| 价格远高于LINREG | 价格过度延伸,可能回调 | 警惕超买,关注卖出机会 |
| 价格接近LINREG | 价格处于合理位置 | 观察趋势延续性 |
| 价格远低于LINREG | 价格过度下跌,可能反弹 | 关注超卖反弹机会 |
3. 斜率与角度------趋势强度量化
利用LINREG的衍生信息可以量化趋势强度:
| 斜率/角度状态 | 含义 | 操作策略 |
|---|---|---|
| 斜率为正且持续增大 | 上升趋势在加速 | 顺势持仓,趋势强劲 |
| 斜率为正但开始减小 | 上升趋势在减速 | 警惕趋势减弱 |
| 斜率从正转负 | 趋势由涨转跌 | 趋势反转信号 |
| 角度大于45度 | 趋势强劲 | 顺势交易 |
| 角度小于20度 | 趋势疲软 | 谨慎操作 |
4. 拟合度(相关系数R)------趋势强弱判断
通过计算相关系数 RR,可以判断当前回归趋势的拟合程度:
| R值范围 | 趋势强度 | 操作策略 |
|---|---|---|
| R > 0.7 | 趋势强,价格与回归线拟合度高 | 适合顺势交易,信号可靠 |
| 0.3 ≤ R ≤ 0.7 | 趋势中等 | 顺势操作,但需设置止损 |
| R < 0.3 | 趋势弱,可能震荡 | 不宜追单,建议观望 |
5. 时间序列预测(TSF)
利用tsf=True可以获取下一周期的预测价格,其原理是沿回归线外推一个单位:
T S F = a ⋅ n + b \mathrm{TSF} = a \cdot n + b TSF=a⋅n+b
即用斜率 a a a 乘以 n n n(窗口长度)再加截距 b b b,得到下一个周期的预测值。这一功能常与其他指标(如布林带、MACD)配合使用,形成趋势确认与价格预测的复合策略。
6. 注意事项与局限性
使用LINREG前需了解以下要点:
| 局限性 | 说明 |
|---|---|
| 本质仍是滞后指标 | 基于历史数据的统计拟合,对突发性价格变化反应滞后 |
| 窗口长度敏感 | 短窗口更灵敏但噪声多,长窗口更平滑但滞后明显 |
| 假设线性关系 | 金融市场是非线性的,线性回归只能近似拟合短期趋势 |
| 过度延伸不是精确信号 | 价格偏离回归线不一定立即回归,可能在强趋势中持续偏离 |
适用场景总结:
| 市场环境 | 适用性 | 说明 |
|---|---|---|
| 趋势行情 | 最佳适用 | 回归线能有效跟踪趋势方向 |
| 震荡行情 | 慎用 | 价格频繁穿越回归线,信号可靠性低 |
| 趋势强度判断 | 适用 | 通过R值和斜率量化趋势强弱 |
| 多指标组合 | 适用 | 适合与MACD、布林带等配合使用 |
四、使用pandas_ta计算LINREG
1. pandas_ta中的LINREG函数
pandas_ta库内置了LINREG指标的完整实现,函数位于overlap模块中。该函数可以输出回归线值及其多种衍生指标。
2. 函数完整参数
python
pandas_ta.overlap.linreg(close, length=None, offset=None, **kwargs)
参数详解:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
close |
pd.Series | 必需 | 收盘价序列 |
length |
int | 10 | 回归窗口长度 |
offset |
int | 0 | 结果偏移周期数 |
slope |
bool | False | 若为True,返回斜率值 |
intercept |
bool | False | 若为True,返回截距值 |
r |
bool | False | 若为True,返回相关系数(拟合度) |
angle |
bool | False | 若为True,返回斜率角度(弧度) |
degrees |
bool | False | 若为True,返回斜率角度(度) |
tsf |
bool | False | 若为True,返回时间序列预测值(未来一周期) |
3. 示例代码
python
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, 45, n)
cycle = np.sin(np.linspace(0, 6 * np.pi, n)) * 15
noise = np.random.randn(n) * 3
price_series = 100 + trend + cycle + noise
# 添加趋势变化区间
price_series = price_series.astype(float)
for i in range(300, 450):
price_series[i] = price_series[300] + (i-300) * 0.2 # 强势上涨段
for i in range(450, 600):
price_series[i] = price_series[450] - (i-450) * 0.15 # 强势下跌段
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(1000000, 25000000, n)
print("=" * 60)
print("数据预览:")
print(df.head())
print("\n" + "=" * 60 + "\n")
# ========== 第二步:计算LINREG(基础用法) ==========
# 使用默认参数 length=10
df['LINREG'] = ta.linreg(df['close'])
print("LINREG计算结果(最近10行):")
print(df[['close', 'LINREG']].tail(10))
print("\n" + "=" * 60 + "\n")
# ========== 第三步:计算衍生指标 ==========
# 同时获取回归线、斜率、角度、相关系数
linreg_result = ta.linreg(
df['close'],
length=10,
slope=True,
intercept=True,
r=True,
degrees=True,
tsf=True
)
# 查看返回的DataFrame结构
print("LINREG衍生指标返回列名称:")
print(linreg_result.columns.tolist())
print("\n" + "=" * 60 + "\n")
# 将计算结果添加到原DataFrame
df['LINREG'] = linreg_result['LINREG']
df['Slope'] = linreg_result['SLOPE']
df['Intercept'] = linreg_result['INTERCEPT']
df['R'] = linreg_result['R']
df['Angle_Deg'] = linreg_result['DEGREES']
df['TSF'] = linreg_result['TSF']
print("LINREG及衍生指标(最近10行):")
print(df[['close', 'LINREG', 'Slope', 'R', 'Angle_Deg', 'TSF']].tail(10))
print("\n" + "=" * 60 + "\n")
# ========== 第四步:不同周期的LINREG对比 ==========
# 短周期 (5)
df['LINREG_5'] = ta.linreg(df['close'], length=5)
# 标准周期 (10)
df['LINREG_10'] = ta.linreg(df['close'], length=10)
# 长周期 (20)
df['LINREG_20'] = ta.linreg(df['close'], length=20)
print("不同周期LINREG对比(最近5行):")
print(df[['close', 'LINREG_5', 'LINREG_10', 'LINREG_20']].tail())
print("\n" + "=" * 60 + "\n")
# ========== 第五步:计算传统均线进行对比 ==========
df['SMA_10'] = ta.sma(df['close'], length=10)
df['EMA_10'] = ta.ema(df['close'], length=10)
print("LINREG vs SMA vs EMA 对比(最近10行):")
print(df[['close', 'LINREG_10', 'SMA_10', 'EMA_10']].tail(10))
print("\n" + "=" * 60 + "\n")
# ========== 第六步:价格穿越信号 ==========
df['price_above_linreg'] = df['close'] > df['LINREG_10']
df['cross_above'] = (df['price_above_linreg'] == True) & (df['price_above_linreg'].shift(1) == False)
df['cross_below'] = (df['price_above_linreg'] == False) & (df['price_above_linreg'].shift(1) == True)
df['signal'] = ''
df.loc[df['cross_above'], 'signal'] = '买入(价格上穿LINREG)'
df.loc[df['cross_below'], 'signal'] = '卖出(价格下穿LINREG)'
print("价格穿越信号统计:")
print(f"买入信号数量:{df['cross_above'].sum()}")
print(f"卖出信号数量:{df['cross_below'].sum()}")
print("\n最近15个穿越信号:")
signals = df[df['signal'] != ''].tail(15)
if not signals.empty:
print(signals[['close', 'LINREG_10', 'signal']])
print("\n" + "=" * 60 + "\n")
# ========== 第七步:趋势强度分类 ==========
def classify_trend_strength(r_value, slope):
"""根据R值和斜率分类趋势"""
if r_value > 0.7 and slope > 0:
return '强上升趋势'
elif r_value > 0.7 and slope < 0:
return '强下降趋势'
elif r_value > 0.3 and slope > 0:
return '中等上升趋势'
elif r_value > 0.3 and slope < 0:
return '中等下降趋势'
else:
return '震荡/弱趋势'
df['trend_strength'] = df.apply(
lambda row: classify_trend_strength(row['R'], row['Slope']),
axis=1
)
print("趋势强度分布统计:")
print(df['trend_strength'].value_counts())
print("\n" + "=" * 60 + "\n")
# ========== 第八步:策略回测(价格穿越策略) ==========
# 策略:价格上穿LINREG买入,下穿LINREG卖出
df['position'] = 0
in_position = False
for i in range(1, len(df)):
if not in_position and df['cross_above'].iloc[i]:
df.loc[df.index[i], 'position'] = 1
in_position = True
elif in_position and df['cross_below'].iloc[i]:
df.loc[df.index[i], 'position'] = 0
in_position = False
else:
df.loc[df.index[i], 'position'] = df['position'].iloc[i-1]
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("=" * 60)
print("策略绩效统计(LINREG穿越策略回测):")
print(f"买入持有策略总收益率:{total_return_buyhold:.2%}")
print(f"LINREG穿越策略总收益率:{total_return_strategy:.2%}")
print(f"策略胜率:{win_rate:.2%}")
print("\n注意:此为简化回测,仅供参考")
print("=" * 60 + "\n")
# ========== 第九步:可视化 ==========
plt.figure(figsize=(14, 12))
# 子图1:价格走势与LINREG对比
plt.subplot(2, 1, 1)
plt.plot(df.index[-200:], df['close'][-200:], label='Close Price',
linewidth=1.5, color='black')
plt.plot(df.index[-200:], df['LINREG_10'][-200:], label='LINREG (10) - 线性回归均线',
linewidth=1.5, color='blue')
plt.plot(df.index[-200:], df['SMA_10'][-200:], label='SMA (10)',
linewidth=1, color='orange', alpha=0.7, linestyle='--')
plt.plot(df.index[-200:], df['EMA_10'][-200:], label='EMA (10)',
linewidth=1, color='green', alpha=0.7, linestyle=':')
plt.title('LINREG vs SMA vs EMA 对比 (Last 200 days)', fontsize=14)
plt.ylabel('Price')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图2:不同周期LINREG对比
plt.subplot(2, 1, 2)
plt.plot(df.index[-200:], df['close'][-200:], label='Close Price',
linewidth=1, alpha=0.5, color='black')
plt.plot(df.index[-200:], df['LINREG_5'][-200:], label='LINREG (5) - 短线',
linewidth=1, alpha=0.7)
plt.plot(df.index[-200:], df['LINREG_10'][-200:], label='LINREG (10) - 标准',
linewidth=1.5, color='blue')
plt.plot(df.index[-200:], df['LINREG_20'][-200:], label='LINREG (20) - 长线',
linewidth=1.5, color='green')
# 标记穿越信号
buy_signals = df[df['cross_above']]
sell_signals = df[df['cross_below']]
plt.scatter(buy_signals.index[-25:], buy_signals['close'][-25:],
color='green', marker='^', s=60, label='买入信号(价格上穿)', alpha=0.8)
plt.scatter(sell_signals.index[-25:], sell_signals['close'][-25:],
color='red', marker='v', s=60, label='卖出信号(价格下穿)', alpha=0.8)
plt.title('LINREG:不同周期对比与穿越信号', fontsize=14)
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# ========== 第十步:数据清洗提示 ==========
nan_count = df['LINREG_10'].isna().sum()
print(f"\nLINREG初始NaN数量:{nan_count}")
print("原因:LINREG需要至少length个周期的数据才能计算线性回归")
print("处理建议:df_clean = df.iloc[10:].copy()")
print("\n" + "=" * 60)
print("LINREG使用提示:")
print("1. LINREG是线性回归拟合的终点值曲线,比SMA更贴近价格路径")
print("2. 通过slope参数获取斜率,判断趋势方向和强度")
print("3. 通过r参数获取相关系数(R值),判断趋势强弱(R>0.7为强趋势)")
print("4. 价格偏离LINREG时可能发生回归,但强趋势中可能持续偏离")
print("5. 建议与MACD、布林带等指标配合使用")
print("6. tsf参数可获取下一周期的价格预测值")
print("=" * 60)
五、总结
LINREG(线性回归均线)是一种基于统计学线性回归理论的趋势跟踪指标,其核心价值与定位如下:
| 维度 | 特点 |
|---|---|
| 核心创新 | 用滑动窗口线性回归替代简单平均,更贴近价格路径 |
| 核心公式 | LINREG = a·(n-1) + b,其中a为斜率,b为截距 |
| 四大衍生指标 | 斜率(方向强度)、相关系数(拟合度)、角度(趋势陡峭度)、TSF(价格预测) |
| 默认参数 | length=10 |
| 最佳应用场景 | 趋势方向判断、趋势强度量化、多指标组合策略 |
| 主要局限 | 滞后性、窗口长度敏感、假设线性关系 |
实战使用三原则:
- 趋势方向看斜率,趋势强弱看R值:斜率正负决定多空方向,R值(>0.7为强趋势)决定持仓信心
- 价格回归是概率事件,非精确信号:价格偏离LINREG后可能回归,但在强趋势中可能持续偏离,需结合趋势强度判断
- 多周期综合判断:短周期LINREG(5-10)捕捉短期方向,长周期LINREG(20-50)确认主趋势,方向一致时信号更可靠
最后提醒:LINREG的本质是将统计学中的线性回归应用于技术分析,其核心价值在于提供一个比传统均线更"理性"的趋势参考线------它不仅告诉你价格在哪里,还告诉你价格正在以怎样的速度变化。结合斜率、R值等衍生信息,LINREG可以成为一个功能丰富的趋势分析工具,而非仅仅是一条均线。