0. 本栏目因子汇总表
1. 因子简述
三重指数移动平均线(Triple Exponential Moving Average, TEMA)是一种高级移动平均线指标,由Patrick Mulloy开发。它通过三重指数平滑处理来减少传统移动平均线的滞后性,同时保持对价格变动的敏感度。TEMA的独特之处在于它使用了EMA的线性组合来实现更快的响应速度。
2. 因子计算逻辑
TEMA的计算公式如下:
E M A 1 = E M A ( C l o s e , n ) E M A 2 = E M A ( E M A 1 , n ) E M A 3 = E M A ( E M A 2 , n ) T E M A = 3 × E M A 1 − 3 × E M A 2 + E M A 3 T E M A f a c t o r = C l o s e − T E M A σ n ( C l o s e ) \begin{align*} EMA_1 &= EMA(Close, n) \\ EMA_2 &= EMA(EMA_1, n) \\ EMA_3 &= EMA(EMA_2, n) \\ TEMA &= 3 \times EMA_1 - 3 \times EMA_2 + EMA_3 \\ TEMA_{factor} &= \frac{Close - TEMA}{\sigma_n(Close)} \end{align*} EMA1EMA2EMA3TEMATEMAfactor=EMA(Close,n)=EMA(EMA1,n)=EMA(EMA2,n)=3×EMA1−3×EMA2+EMA3=σn(Close)Close−TEMA
其中:
- n为移动平均周期
- EMA为指数移动平均
- σ_n(Close)为n周期收盘价的滚动标准差
3. 因子应用场景
-
趋势跟踪:
- 价格上穿TEMA,做多信号
- 价格下穿TEMA,做空信号
-
趋势转折:
- TEMA拐点预示趋势变化
- TEMA斜率反映趋势强度
-
价格回归:
- TEMA作为价格回归目标
- 用于均值回归策略
-
市场状态:
- TEMA形态反映市场状态
- 用于判断趋势持续性
4. 因子优缺点
优点:
- 响应迅速:减少了传统EMA的滞后
- 平滑性好:三重平滑降低噪音
- 计算简单:相比T3更容易实现
- 灵敏度高:能及时捕捉趋势变化
缺点:
- 超前风险:可能过度反应价格变化
- 假信号:在震荡市场易生成虚假信号
- 参数敏感:周期选择影响效果
- 滞后存在:极端行情仍有一定滞后
5. 因子代码实现
def TEMA_factor(df, n=20):
"""
计算三重指数移动平均线(TEMA)因子
参数:
df (DataFrame): 输入数据
- code: 证券代码,如'600036.SH'
- date: 日期,格式为'YYYY-MM-DD'
- close: 收盘价
n (int): 移动平均周期,默认20
返回:
DataFrame: 包含原有列和TEMA因子值,理论取值范围(-∞,+∞),实际大多在[-3,3]之间
注意:
1. 返回数据包含所有输入列
2. 新增TEMA列为因子值
3. date列保持原有字符串格式'YYYY-MM-DD'
4. 数据将按code分组、date倒序排列
"""
import numpy as np
import pandas as pd
# 创建副本避免修改原始数据
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分组计算
def calculate_tema(group):
close = group['close'].values
# 计算第一次EMA
alpha = 2 / (n + 1)
ema1 = pd.Series(close).ewm(alpha=alpha, adjust=False).mean().values
# 计算第二次EMA
ema2 = pd.Series(ema1).ewm(alpha=alpha, adjust=False).mean().values
# 计算第三次EMA
ema3 = pd.Series(ema2).ewm(alpha=alpha, adjust=False).mean().values
# 计算TEMA
tema = 3 * ema1 - 3 * ema2 + ema3 # 所有输入都是numpy数组,运算结果也是numpy数组
# 计算n周期滚动标准差
rolling_std = pd.Series(close).rolling(window=n).std().values
# 计算因子值:使用滚动标准差标准化的价格偏离度
# 处理标准差为0的情况
group['TEMA'] = np.where(
rolling_std != 0,
(close - tema) / rolling_std,
0
)
return group
df_copy = df_copy.groupby('code', group_keys=False).apply(calculate_tema)
# 按照最终要求重新排序并重置索引
df_copy = df_copy.sort_values(['code', 'date'], ascending=[True, False]).reset_index(drop=True)
return df_copy
测试数据:
6. 因子取值范围及其含义
TEMA因子的取值范围理论上是(-∞,+∞),但实际上大多数值会落在[-3,3]区间内:
- 取值 > 2:表示价格显著高于TEMA(超过2个标准差),强烈超买信号
- 取值在(1,2]之间:表示价格高于TEMA一个标准差以上,偏多信号
- 取值在[-1,1]之间:表示价格在TEMA一个标准差范围内波动,震荡区间
- 取值在[-2,-1)之间:表示价格低于TEMA一个标准差以上,偏空信号
- 取值 < -2:表示价格显著低于TEMA(超过2个标准差),强烈超卖信号
7. 因子函数参数建议
- n (移动平均周期):
- 默认值:20
- 建议范围:[10, 30]
- 参数说明:决定移动平均的平滑程度
- 选择建议:
- 日线数据建议使用:
- 短期:10-15天
- 中期:20-25天
- 长期:25-30天
- 小时线数据建议使用8-16
- 分钟线数据建议使用5-10
- 高波动市场使用较短周期
- 低波动市场使用较长周期
- 日线数据建议使用: