自适应移动平均线AMA是由美国数量金融投资家佩里·J·考夫曼(Perry J. Kaufman)发明的。我们都知道,大多数类型的移动平均线仅是通过价格简单构造出来的,而自适应移动平均线AMA却非常不同,该指标不仅考虑了价格因素,还考虑了市场中价格的波动性,这也是它与传统均线之间最大的差别。
该指标的发明者佩里·J·考夫曼目前是全球最为著名的量化投资专家之一,著有众多畅销书籍,包括《精明交易者:系统交易指南》和《交易系统与方法》等。
移动平均线是一种最为常用的技术指标,大部分交易者在分析决策过程中都会用到。但在使用均线时,很多人都会遇到类似这样的困境:短期均线表现灵敏、反应快速,但常常发出错误信号;而长期均线表现稳定、错误率低,但又总是反应滞后。到底应该选择短期均线还是长期均线?均线参数究竟应该如何设置?这些问题总是让人左右为难。
迫不得已,我们只能重新审视这个问题,寻找症结所在:
情况一
市场趋势明显时:短期均线的表现更好。
情况二
市场趋势不明显时:长期均线的表现则会更好。
因为此时长期均线不敏感、反应慢,可以让我们避免短期均线频繁发出的错误信号。
步骤1:价格方向
价格方向被表示为整个时间段中的净价格变化。比如,使用n天的间隔(或n小时):
direction = price – price[n];
其中,direction是当前价格差或方向数值,price是当前价格(当日收盘价或小时收盘价),price[n]是n日前的收盘价(或n个周期前)。
步骤2:波动性
波动性是市场噪音的总数量,它可以用许多不同的方法定义,但是这个计算使用了所有“日到日”或“小时到小时”的价格变化的总和(每一个都作为一个正数),在同样的n个周期上。
如下表达:
volatility = @sum(@abs(price – price[1]), n);
其中,volatility是指波动性数值,@abs是绝对值函数,@sum(value, n)是n个周期中的数值之和函数。
步骤3:效率系数(ER)
以上两个成分被组合起来,以表达方向移动对噪音之比,称之为效率系数,ER:
Efficiency_Ratio = direction/volativity;
fastest = 2/(N+1) = 2/(2+1) = 0.6667;
slowest = 2/(N+1) = 2/(30+1) = 0.0645;
smooth = ER*(fastest - slowest) + slowest;
c = smooth*smooth;
使用数据为:
核心思路 AMA = AMA[1] + c*(price – AMA[1]);
def cal_ama(last_ama, cp_df, var_er = 14, fastest_N = 2, slowest_N = 30):
fastest = 2/(fastest_N+1)
slowest = 2/(slowest_N+1)
cp_df = cp_df[-var_er : ]
direction = cp_df.iloc[-1] - cp_df.iloc[0]
# print("direction ==>" + str(direction))
er_df = cp_df.diff()
er_df = er_df.apply(lambda x : abs(x))
volatility = er_df.sum()
# print("volatility ==>" + str(volatility))
efficiency_ratio = direction / volatility
# print("efficiency_ratio==>" + str(efficiency_ratio))
smooth = efficiency_ratio*(fastest - slowest) + slowest;
c = smooth* smooth
# print("c ==>" + str(c))
last_ama = last_ama + c*(cp_df.iloc[-1] - last_ama)
ama = last_ama
# print("ama==>" + str(ama))
return ama, efficiency_ratio
last_ama = 0
timeperiod = 14
pos = 0
for index, row in zz500_df.iterrows():
if pos < timeperiod:
last_ama = zz500_df[0:pos]['close'].mean()
# print("last_ama==>" + str(last_ama))
pos += 1
continue
cp_df = zz500_df[pos - timeperiod:pos]['close']
ama, efficiency_ratio = cal_ama(last_ama, cp_df)
zz500_df.loc[index,'er'] = efficiency_ratio
zz500_df.loc[index,'ama'] = ama
last_ama = ama
pos += 1
fig = plt.figure(figsize=(16,6))
ax1 = fig.add_subplot(1,1,1)
ax1.semilogy(zz500_df.index, zz500_df['close'], color='blue', label='close')
ax1.semilogy(zz500_df.index, zz500_df['ama'], color='yellow', label='close')
# ax2 = ax1.twinx()
# ax2.plot(zz500_df.index, zz500_df['er'], color='red', label='close')
plt.show()