BTCUSD时间序列线性回归线角度近90度问题及解决方案咨询
问题描述
交易BTCUSD时,使用TA-Lib库计算线性回归线的斜率与角度,希望对比10、50等不同周期的回归线角度,但输出结果几乎所有角度都接近±90度,斜率数值也极大。推测是x轴与y轴数值差异过大导致,需明确问题根源、验证推测,并获取可对比的合理角度及设置阈值的方法。
原代码
import pandas as pd import talib df = pd.read_csv(r'E:\filepath\Kucoin_BTCUSDT_d.csv') # 截取小部分数据方便打印结果 df = df[100:105] df.date = pd.to_datetime(df.date, format="%m/%d/%Y %H:%M") df = df.set_index("date") lrSlope = talib.LINEARREG_SLOPE(df['close'], timeperiod=5) lrAngle = talib.LINEARREG_ANGLE(df['close'], timeperiod=5) print(df['close']) print('Slope', lrSlope.iloc[-1]) print('Angle', lrAngle.iloc[-1])
运行结果
date 2018-02-03 9199.999443 2018-02-04 8117.000002 2018-02-05 6950.001000 2018-02-06 7676.000008 2018-02-07 7572.421893 Name: close, dtype: float64 Slope -369.61550939999984 Angle -89.84498583458068
问题根源与推测验证
你的推测方向正确,但细节需修正:
- TA-Lib计算线性回归时,x轴并非实际日期,而是序列的索引位置(0、1、2...这类小整数),但核心问题确实是x、y轴量级差异过大:y轴BTC价格是数千级别的数值,x轴是个位数小整数,导致斜率(Δy/Δx)的绝对值极大。
- 角度是通过
arctan(斜率)转换为度数得到的,当斜率绝对值极大时,arctan的结果会无限接近±90度,这就是你看到结果的原因。
解决方案:获取可对比的合理角度
要得到不同周期可对比的角度,需消除x、y轴的量级差异,以下两种方法最常用:
方法1:用价格收益率代替原始价格计算
收益率是价格的百分比变化,数值范围通常在[-0.1, 0.1]左右,和x轴的小整数量级匹配,计算出的角度能反映趋势强度,适合跨周期对比。
import pandas as pd import talib df = pd.read_csv(r'E:\filepath\Kucoin_BTCUSDT_d.csv') df = df[100:105] df.date = pd.to_datetime(df.date, format="%m/%d/%Y %H:%M") df = df.set_index("date") # 计算日收益率,dropna去除第一个空值 df['returns'] = df['close'].pct_change().dropna() # 收益率序列长度减少1,timeperiod对应调整为4 lrSlope = talib.LINEARREG_SLOPE(df['returns'], timeperiod=4) lrAngle = talib.LINEARREG_ANGLE(df['returns'], timeperiod=4) print('收益率序列:\n', df['returns']) print('Slope', lrSlope.iloc[-1]) print('Angle', lrAngle.iloc[-1])
方法2:对原始价格做标准化处理
将价格缩放到与x轴量级接近的区间(比如0-10),消除数值差异:
import pandas as pd import talib from sklearn.preprocessing import MinMaxScaler df = pd.read_csv(r'E:\filepath\Kucoin_BTCUSDT_d.csv') df = df[100:105] df.date = pd.to_datetime(df.date, format="%m/%d/%Y %H:%M") df = df.set_index("date") # 将价格缩放到0-10区间,匹配x轴数值范围 scaler = MinMaxScaler(feature_range=(0,10)) df['close_scaled'] = scaler.fit_transform(df[['close']]) lrSlope_scaled = talib.LINEARREG_SLOPE(df['close_scaled'], timeperiod=5) lrAngle_scaled = talib.LINEARREG_ANGLE(df['close_scaled'], timeperiod=5) print('标准化价格:\n', df['close_scaled']) print('Scaled Slope', lrSlope_scaled.iloc[-1]) print('Scaled Angle', lrAngle_scaled.iloc[-1])
角度阈值设置
使用上述方法得到合理角度后,可根据趋势强度设置阈值:
- 角度绝对值<30度:趋势极弱,处于震荡行情
- 30度≤角度绝对值<60度:中等强度趋势
- 角度绝对值≥60度:强趋势(上涨或下跌)
注意:跨周期对比时,必须使用同一种标准化方法,确保结果具备可比性。
内容的提问来源于stack exchange,提问作者Hamze Kabi
相关产品推荐
相关产品推荐

