0. 本栏目因子汇总表
1. 因子简述
MESA自适应移动平均线(MESA Adaptive Moving Average, MAMA)是由John Ehlers开发的一种高级技术指标。它使用MESA(Maximum Entropy Spectral Analysis)算法来自适应地调整移动平均的速度,能够快速响应市场变化同时保持良好的平滑性。MAMA包含两条线:MAMA(主线)和FAMA(跟随线)。
2. 因子计算逻辑
MAMA的计算基于复杂的MESA算法,核心步骤包括:
P h a s e = a r c t a n 2 ( I m s m o o t h , R e s m o o t h ) D e l t a P h a s e = P h a s e t − P h a s e t − 1 A l p h a = F a s t L i m i t / exp ( D e l t a P h a s e ) M A M A t = α × P r i c e + ( 1 − α ) × M A M A t − 1 F A M A t = 0.5 × α × M A M A t + ( 1 − 0.5 × α ) × F A M A t − 1 \begin{align*} Phase &= arctan2(Im_{smooth}, Re_{smooth}) \\ DeltaPhase &= Phase_t - Phase_{t-1} \\ Alpha &= FastLimit / \exp(DeltaPhase) \\ MAMA_t &= \alpha \times Price + (1-\alpha) \times MAMA_{t-1} \\ FAMA_t &= 0.5 \times \alpha \times MAMA_t + (1-0.5 \times \alpha) \times FAMA_{t-1} \end{align*} PhaseDeltaPhaseAlphaMAMAtFAMAt=arctan2(Imsmooth,Resmooth)=Phaset−Phaset−1=FastLimit/exp(DeltaPhase)=α×Price+(1−α)×MAMAt−1=0.5×α×MAMAt+(1−0.5×α)×FAMAt−1
MAMA因子的计算:
M
A
M
A
f
a
c
t
o
r
=
C
l
o
s
e
−
M
A
M
A
σ
n
(
C
l
o
s
e
)
MAMA_{factor} = \frac{Close - MAMA}{\sigma_n(Close)}
MAMAfactor=σn(Close)Close−MAMA
其中:
- Phase为价格序列的相位
- DeltaPhase为相位变化率
- Alpha为自适应因子
- σ_n(Close)为n周期收盘价的滚动标准差
- n为计算标准差的周期参数
3. 因子应用场景
-
趋势跟踪:
- MAMA上穿FAMA,产生做多信号
- MAMA下穿FAMA,产生做空信号
-
市场状态判断:
- MAMA与FAMA快速分离表示趋势加速
- MAMA与FAMA交织表示市场盘整
-
价格突破确认:
- 价格突破MAMA,趋势确认信号
- MAMA斜率变化,趋势强度信号
-
组合策略:
- 与其他技术指标配合使用
- 用于多周期分析和市场结构判断
4. 因子优缺点
优点:
- 自适应性强:能根据市场状态调整响应速度
- 噪音过滤:具有优秀的信号平滑特性
- 趋势敏感:对趋势变化反应迅速
- 双线系统:提供更可靠的交叉信号
缺点:
- 计算复杂:需要较强的计算能力
- 参数敏感:不同参数组合效果差异大
- 延迟现象:在剧烈波动时可能出现滞后
- 使用门槛:需要深入理解MESA算法原理
5. 因子代码实现
def MAMA_factor(df, fast_limit=0.5, slow_limit=0.05, n=20):
"""
计算MESA自适应移动平均线(MAMA)因子
参数:
df (DataFrame): 输入数据
- code: 证券代码,如'600036.SH'
- date: 日期,格式为'YYYY-MM-DD'
- close: 收盘价
fast_limit (float): 快速限制参数,默认0.5
slow_limit (float): 慢速限制参数,默认0.05
n (int): 标准差计算周期,默认20
返回:
DataFrame: 包含原有列和MAMA因子值,理论取值范围(-∞,+∞),实际大多在[-3,3]之间
"""
import numpy as np
import pandas as pd
def calculate_mama(group):
# 1. 价格平滑处理
price = group['close'].values
smooth = (4*price + 3*np.roll(price,1) + 2*np.roll(price,2) + np.roll(price,3))/10.0
# 2. 计算去趋势序列
detrender = np.zeros_like(smooth)
for i in range(7, len(smooth)):
detrender[i] = (0.0962*smooth[i] + 0.5769*smooth[i-2] - 0.5769*smooth[i-4] - 0.0962*smooth[i-6])*0.075
# 3. 计算Q1 - 提前90度的移相版本
Q1 = np.zeros_like(smooth)
for i in range(7, len(smooth)):
Q1[i] = (0.0962*detrender[i] + 0.5769*detrender[i-2] - 0.5769*detrender[i-4] - 0.0962*detrender[i-6])*0.075
# 4. 计算I1 - 同相版本
I1 = np.roll(detrender, 3)
# 5. 计算抑制因子jI和jQ
jI = np.zeros_like(smooth)
jQ = np.zeros_like(smooth)
for i in range(7, len(smooth)):
jI[i] = (0.0962*I1[i] + 0.5769*I1[i-2] - 0.5769*I1[i-4] - 0.0962*I1[i-6])*0.075
jQ[i] = (0.0962*Q1[i] + 0.5769*Q1[i-2] - 0.5769*Q1[i-4] - 0.0962*Q1[i-6])*0.075
# 6. 计算相位和相位差
phase = np.where(I1 != 0, np.arctan(Q1/I1), 0)
deltaPhase = phase - np.roll(phase, 1)
deltaPhase[0] = deltaPhase[1]
# 7. 计算alpha - 自适应因子
alpha = fast_limit / np.exp(abs(deltaPhase))
alpha = np.clip(alpha, slow_limit, fast_limit)
# 8. 计算MAMA和FAMA
mama = np.zeros_like(price)
fama = np.zeros_like(price)
mama[0] = price[0]
fama[0] = price[0]
for i in range(1, len(price)):
mama[i] = alpha[i] * price[i] + (1-alpha[i]) * mama[i-1]
fama[i] = 0.5 * alpha[i] * mama[i] + (1-0.5*alpha[i]) * fama[i-1]
# 计算n周期滚动标准差
rolling_std = group['close'].rolling(window=n).std()
# 计算因子值:使用滚动标准差标准化的价格偏离度
# 处理标准差为0的情况
group['MAMA'] = np.where(
rolling_std != 0,
(group['close'] - mama) / rolling_std,
0
)
return group
df_copy = df.copy()
# 检查code格式
valid_codes = df_copy['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_copy['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_copy = df_copy.sort_values(['code', 'date'], ascending=[True, False])
# 按code分组计算
df_copy = df_copy.groupby('code', group_keys=False).apply(calculate_mama)
# 按照最终要求重新排序并重置索引
df_copy = df_copy.sort_values(['code', 'date'], ascending=[True, False]).reset_index(drop=True)
return df_copy
测试数据:
6. 因子取值范围及其含义
MAMA因子的取值范围理论上是(-∞,+∞),但实际上大多数值会落在[-3,3]区间内:
- 取值 > 2:表示价格显著高于MAMA(超过2个标准差),强烈超买信号
- 取值在(1,2]之间:表示价格高于MAMA一个标准差以上,偏多信号
- 取值在[-1,1]之间:表示价格在MAMA一个标准差范围内波动,震荡区间
- 取值在[-2,-1)之间:表示价格低于MAMA一个标准差以上,偏空信号
- 取值 < -2:表示价格显著低于MAMA(超过2个标准差),强烈超卖信号
7. 因子函数参数建议
-
n (标准差计算周期):
- 默认值:20
- 建议范围:[5, 20]
- 参数说明:用于计算价格偏离度的标准化窗口
- 选择建议:
- 日线数据建议使用10-15
- 小时线数据建议使用15-20
- 分钟线数据建议使用5-10
-
fast_limit (快速限制参数):
- 默认值:0.5
- 建议范围:[0.3, 0.9]
- 参数说明:决定MAMA对快速市场变化的反应速度
- 选择建议:
- 高波动市场使用较小值
- 低波动市场使用较大值
- 不建议超过0.9,可能产生过度敏感
-
slow_limit (慢速限制参数):
- 默认值:0.05
- 建议范围:[0.01, 0.1]
- 参数说明:决定MAMA在慢速市场中的平滑程度
- 选择建议:
- 趋势市场使用较小值
- 震荡市场使用较大值
- 通常保持在fast_limit的1/10左右