
2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含300篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!
很多交易策略看起来很复杂,因为它们包含了大量的技术指标。但趋势跟踪其实可以很简单。
今天我们来拆解一个基于 R²(决定系数)的简单趋势跟踪算法。这个策略的核心思想是:只在价格呈现强趋势时入场,当价格相对于移动平均线走弱时离场。
这篇文章将帮助你理解这个策略的原理,并提供完整的 Python 实现代码。
大多数交易者使用移动平均线来判断趋势方向,但移动平均线并不能告诉你趋势的强度。
R²(决定系数)可以做到这一点:
简单来说,我们不是靠猜测趋势是否"真实",而是用数学方法来测量它。
这个策略有几个可调节的参数:
系统等待以下条件同时满足:
非常简单:
没有追踪止损,没有 ATR,没有波动率过滤器。极简主义风格。
import pandas as pdimport numpy as np# === 策略参数 ===R2_LENGTH = 18 # R² 计算周期SMOOTH = 3 # 平滑窗口TREND = 0.42 # R² 入场阈值R2_MAX = 0.85 # R² 最大值限制MAB = 50 # 移动平均线周期LR_CRIT = 10 # 线性回归斜率阈值# 加载价格数据df = pd.read_csv("data.csv")# 计算移动平均线df['MA'] = df['Close'].rolling(MAB).mean()# ==== R² 滚动计算函数(滚动线性回归)====def rolling_r2(series, length): """ 计算滚动 R² 值 参数: series: 价格序列 length: 计算窗口长度 返回: R² 值列表 """ x = np.arange(length) # 创建自变量序列 r2_vals = [np.nan] * length # 前 length 个值为空 for i in range(length, len(series)): y = series[i-length:i] # 获取窗口内的价格数据 # 线性拟合 slope, intercept = np.polyfit(x, y, 1) y_pred = slope * x + intercept # 预测值 # 计算残差平方和与总平方和 ss_res = np.sum((y - y_pred)**2) ss_tot = np.sum((y - np.mean(y))**2) # 计算 R² r2_vals.append(1 - ss_res/ss_tot) return r2_vals# 计算 R² 并平滑处理df['R2'] = rolling_r2(df['Close'].values, R2_LENGTH)df['R2_smooth'] = df['R2'].rolling(SMOOTH).mean()# === 计算线性回归斜率 ===df['LR'] = df['Close'].rolling(R2_LENGTH).apply( lambda x: np.polyfit(range(len(x)), x, 1)[0] * 100 # 斜率乘以 100 放大)# === 入场条件 ===# 做多条件:R² 在阈值范围内,价格在均线上方,斜率为正df['long_entry'] = ( (df['R2_smooth'] > TREND) & (df['R2_smooth'] < R2_MAX) & (df['Close'] > df['MA']) & (df['LR'] > LR_CRIT))# 做空条件:R² 在阈值范围内,价格在均线下方,斜率为负df['short_entry'] = ( (df['R2_smooth'] > TREND) & (df['R2_smooth'] < R2_MAX) & (df['Close'] < df['MA']) & (df['LR'] < -LR_CRIT))# === 离场条件 ===df['exit_long'] = df['Close'] < df['MA'] # 价格跌破均线,平多df['exit_short'] = df['Close'] > df['MA'] # 价格突破均线,平空# 打印信号统计print(f"做多信号数量:{df['long_entry'].sum()}")print(f"做空信号数量:{df['short_entry'].sum()}")假设你有一个包含股票或加密货币价格数据的 CSV 文件,格式如下:
Date,Open,High,Low,Close,Volume2025-01-01,100.0,102.5,99.5,101.2,10000002025-01-02,101.2,103.0,100.8,102.5,1200000...运行上述代码后,你可以查看哪些时间点触发了入场信号:
# 查看做多信号long_signals = df[df['long_entry'] == True]print("做多信号时间点:")print(long_signals[['Date', 'Close', 'R2_smooth', 'LR']])# 查看做空信号short_signals = df[df['short_entry'] == True]print("做空信号时间点:")print(short_signals[['Date', 'Close', 'R2_smooth', 'LR']])这个基础框架可以进一步改进:
记住:大多数盈利的系统都是简单规则加上聪明的风险管理,而不是复杂的指标堆砌。
这个基于 R² 的趋势跟踪策略有几个优点:
把这个策略当作一个起点,而不是终点。从小处着手,每次只添加一个改进,回测所有修改,然后在模拟盘上测试,最后再考虑实盘交易。
2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:
星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!
好文推荐
1. 用 Python 打造股票预测系统:Transformer 模型教程(一)
2. 用 Python 打造股票预测系统:Transformer 模型教程(二)
3. 用 Python 打造股票预测系统:Transformer 模型教程(三)
4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)
6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用
9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解
好书推荐