当前位置:首页>python>用 Python 实现自适应趋势跟踪策略:FRAMA 指标详解

用 Python 实现自适应趋势跟踪策略:FRAMA 指标详解

  • 2026-09-04 01:12:41
用 Python 实现自适应趋势跟踪策略:FRAMA 指标详解

2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含300篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!

引言

在量化交易领域,移动平均线是最常用的技术指标之一。然而,传统移动平均线面临一个两难困境:短周期响应快但容易产生虚假信号,长周期稳定但滞后严重。有没有一种方法能够两全其美呢?

分形自适应移动平均线(Fractal Adaptive Moving Average,简称 FRAMA)正是为解决这一问题而诞生的。它能够根据市场结构动态调整自身的响应速度——在趋势行情中快速跟随,在震荡行情中保持稳定。

本文将基于一篇最新的量化策略研究,带你了解 FRAMA 的核心原理,并提供完整的 Python 实现代码。

FRAMA 的核心原理

什么是分形维度

FRAMA 的理论基础是分形维度(Fractal Dimension),它用于衡量价格走势的复杂程度。算法将价格序列分为两半,然后比较各部分的波动范围与整体范围的关系。

分形维度的取值范围在 1 到 2 之间:

当市场处于趋势行情时,价格沿单一方向运动,复杂度低,维度接近 1。

当市场处于震荡行情时,价格上下波动,复杂度高,维度接近 2。

分形维度直接控制平滑系数 alpha,从而创建一个在趋势中加速、在噪音中减速的移动平均线。

关键参数说明

FRAMA 有两个核心参数:

N(周期)表示计算分形维度的回溯窗口,常用值包括 10、20、40、60、80、100 天。

FC(快速常数)控制响应速度,数值越大适应越快,常用值包括 1、4、8、16、32。

Python 实现

下面是 FRAMA 指标的核心计算代码:

import numpy as npimport pandas as pdclass FRAMAIndicator:    """分形自适应移动平均线指标类"""    def __init__(self, n: int = 40, fc: int = 4):        """        初始化 FRAMA 指标        参数:            n: 计算分形维度的回溯周期            fc: 快速常数,控制响应速度        """        self.n = n        self.fc = fc    def calculate(self, prices: pd.Series) -> pd.Series:        """        计算 FRAMA 值        参数:            prices: 价格序列        返回:            FRAMA 值序列        """        df = pd.DataFrame({'price': prices})        # 计算整个周期的最高价和最低价        high = df['price'].rolling(window=self.n).max()        low = df['price'].rolling(window=self.n).min()        # 计算半周期长度        n1 = self.n // 2        # 计算前半周期的最高价和最低价        high1 = df['price'].rolling(window=n1).max()        low1 = df['price'].rolling(window=n1).min()        # 计算后半周期的最高价和最低价        high2 = df['price'].shift(n1).rolling(window=n1).max()        low2 = df['price'].shift(n1).rolling(window=n1).min()        # 计算各部分的价格范围        n_range = (high - low) / self.n        n1_range = (high1 - low1) / n1        n2_range = (high2 - low2) / n1        # 计算分形维度        dimension = np.log(n1_range + n2_range) - np.log(n_range)        dimension = dimension / np.log(2)        dimension = dimension.clip(1.0, 2.0)  # 限制在 1 到 2 之间        # 根据分形维度计算平滑系数 alpha        alpha = np.exp(-self.fc * (dimension - 1))        alpha = alpha.clip(0.01, 1.0)  # 限制在合理范围内        # 计算 FRAMA 值        frama = pd.Series(index=prices.index, dtype=float)        frama.iloc[:self.n] = np.nan        for i in range(self.n, len(prices)):            if pd.isna(alpha.iloc[i]) or pd.isna(frama.iloc[i-1]):                frama.iloc[i] = prices.iloc[i]            else:                # FRAMA 的递推公式                frama.iloc[i] = alpha.iloc[i] * prices.iloc[i] + \                               (1 - alpha.iloc[i]) * frama.iloc[i-1]        return frama.dropna()

交易策略示例

基于 FRAMA 指标,我们可以构建一个简单的趋势跟踪策略:

import yfinance as yfdef simple_frama_strategy(ticker: str = 'SPY',                           start_date: str = '2020-01-01',                          end_date: str = '2024-12-31'):    """    简单的 FRAMA 交易策略示例    参数:        ticker: 股票代码        start_date: 开始日期        end_date: 结束日期    返回:        策略收益率序列    """    # 获取股票数据    data = yf.download(ticker, start=start_date, end=end_date, progress=False)    data.columns = [col[0] if isinstance(col, tuple) else col for col in data.columns]    # 计算 FRAMA 指标    frama = FRAMAIndicator(n=40, fc=4)    frama_values = frama.calculate(data['Close'])    # 生成交易信号    signals = pd.Series(index=frama_values.index, dtype=float)    for i in range(1, len(frama_values)):        # 使用 T-1 时刻的数据生成 T 时刻的信号,避免未来函数        price_t1 = data['Close'].loc[frama_values.index[i-1]]        frama_t1 = frama_values.iloc[i-1]        if price_t1 > frama_t1:            # 价格在 FRAMA 上方,做多            signals.iloc[i] = 1.0        elif price_t1 < frama_t1:            # 价格在 FRAMA 下方,空仓            signals.iloc[i] = 0.0        else:            # 价格等于 FRAMA,保持前一状态            signals.iloc[i] = signals.iloc[i-1] if i > 0 else 0.0    signals = signals.dropna()    # 计算收益率    returns = data['Close'].pct_change().dropna()    aligned_returns = returns.reindex(signals.index).dropna()    signals = signals.reindex(aligned_returns.index)    # 信号需要延迟一天,避免使用当天信号买入当天    strategy_returns = signals.shift(1).dropna() * aligned_returns    strategy_returns = strategy_returns.dropna()    return strategy_returns# 运行策略示例if __name__ == "__main__":    returns = simple_frama_strategy()    # 计算累计收益    cum_returns = (1 + returns).cumprod()    total_return = cum_returns.iloc[-1] - 1    print(f"策略总收益率:{total_return*100:.2f}%")

前向分析优化

为了避免过度拟合,文章采用了前向分析(Walk-Forward Analysis)方法进行参数优化。这种方法的核心思想是:

首先使用历史数据进行参数优化(样本内期间)。

然后用优化后的参数在未来数据上进行测试(样本外期间)。

不断向前滚动这个过程,使用扩展窗口持续重新优化。

文章采用的具体设置是:初始训练期 3 年,样本外窗口 6 个月,每 6 个月重新优化一次。

为什么选择 Calmar 比率

在参数优化时,文章选择 Calmar 比率(年化收益率除以最大回撤)作为目标函数,而非常见的 Sharpe 比率。主要原因包括:

Calmar 比率直接惩罚深度回撤,对资金保护更为重视。

它不会惩罚上行波动,而 Sharpe 比率会将上涨也视为风险。

更适合收益分布非正态的趋势跟踪策略。

策略表现

根据文章的回测结果,FRAMA 策略在 2013 年至 2024 年期间表现如下:

总收益率为 224.31%,年化收益率为 10.80%。

波动率为 10.45%,Sharpe 比率为 0.84。

最大回撤仅为 18.57%,Calmar 比率为 0.58。

虽然年化收益略低于基准的 12.27%,但最大回撤控制得更好,风险调整后的表现较为稳健。

策略的优势与局限

优势

扩展窗口提供越来越稳健的参数估计。

Calmar 比率优化在收益与尾部风险之间取得平衡。

二元仓位管理使策略简单透明。

严格的 T-1 规则完全消除未来函数。

局限

趋势跟踪策略在长期横盘市场表现不佳。

不做空限制了熊市中的盈利能力。

参数稳定性依赖于市场环境的一致性。

过去的表现不能保证未来的结果。

总结

FRAMA 是一种优雅的自适应技术指标,通过分形数学原理解决了传统移动平均线的固有矛盾。它在趋势明显时快速响应,在市场噪音中保持稳定,为趋势跟踪交易提供了一个原则性的框架。

结合前向分析优化和 Calmar 比率最大化,我们可以构建一个既适应市场变化,又注重风险控制的量化策略。虽然没有任何策略能在所有市场环境中奏效,但 FRAMA 的自适应特性为应对趋势跟踪的永恒挑战提供了有力工具。

希望这篇文章能够帮助你理解 FRAMA 的核心概念,并为你的 Python 量化交易学习之路提供参考。

参考文章

加入专注于财经数据与量化投研的知识星球【数据科学实战】,获取本文完整研究解析、代码实现细节。

财经数据与量化投研知识社区

2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:

  1. 1. 双典系统赋能:获赠《财经数据宝典》与《量化投研宝典》完整文档,凝练多年实战经验,构建系统化知识框架;
  2. 2. 量化因子日更教程(2026重磅新增):每日更新「量化因子专题教程」,配套完整可运行代码与实战案例,深度拆解因子构建、回测与优化全流程;
  3. 3. 量化文章专题教程库:300+篇星球独有高质量教程式文章,系统覆盖策略开发、因子研究、风险管理等核心领域,内容基本每日更新,并配套精选学习资料与实战参考;
  4. 4. PyBroker实战课程:赠送《PyBroker-入门及实战》视频课程,手把手教学,快速掌握量化策略开发技能;
  5. 5. 财经数据支持:定期更新国内外财经数据,为策略研发提供精准、可靠的数据基础;
  6. 6. 顶尖学者与行业专家分享:年度邀请学术界博士与业界资深专家开展前沿论文精讲与实战案例分享,不少于4场,直击研究前沿与产业实践;专家直连答疑:与核心开发者及领域专家实时互动,高效解决投研实战难题;
  7. 7. 专业社群与专属福利:加入高质量交流社群,获取课程折扣及更多独家资源。

星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!

好文推荐

1. 用 Python 打造股票预测系统:Transformer 模型教程(一)

2. 用 Python 打造股票预测系统:Transformer 模型教程(二)

3. 用 Python 打造股票预测系统:Transformer 模型教程(三)

4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)

5. 揭秘隐马尔可夫模型:因子投资的制胜武器

6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用

7. 金融 AI 助手:FinGPT 让你轻松掌握市场分析

8. 量化交易秘籍:为什么专业交易员都在用对数收益率?

9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解

10. 掌握金融波动率模型:完整 Python 实现指南

好书推荐

最新文章

随机文章