在Python中计算指数移动平均值

33

我有一组日期和每个日期的度量值。 我想为每个日期计算指数移动平均值。 有人知道如何做吗?

我是Python新手。 标准Python库似乎没有内置平均函数,这让我感到有些奇怪。 或许我没有找对地方。

因此,鉴于以下代码,我该如何计算日历日期智商点数的移动加权平均值?

from datetime import date
days = [date(2008,1,1), date(2008,1,2), date(2008,1,7)]
IQ = [110, 105, 90]

(可能有更好的方式来构建这个数据,任何建议都将不胜感激)

16个回答

2

我有点晚来到这里,但是没有一个给出的解决方案是我想要的。使用递归和在Investopedia中给出的确切公式是一个不错的小挑战。 不需要numpy或pandas。

prices = [{'i': 1, 'close': 24.5}, {'i': 2, 'close': 24.6}, {'i': 3, 'close': 24.8}, {'i': 4, 'close': 24.9},
          {'i': 5, 'close': 25.6}, {'i': 6, 'close': 25.0}, {'i': 7, 'close': 24.7}]


def rec_calculate_ema(n):
    k = 2 / (n + 1)
    price = prices[n]['close']
    if n == 1:
        return price
    res = (price * k) + (rec_calculate_ema(n - 1) * (1 - k))
    return res


print(rec_calculate_ema(3))

2
这是我基于http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages制作的一个简单示例。
请注意,与它们的电子表格不同,我不计算SMA,并且不等待在生成10个样本后再生成EMA。这意味着我的值略有不同,但如果你绘制图表,它会在10个样本之后完全跟随。在前10个样本期间,我计算的EMA适当地平滑。
def emaWeight(numSamples):
    return 2 / float(numSamples + 1)

def ema(close, prevEma, numSamples):
    return ((close-prevEma) * emaWeight(numSamples) ) + prevEma

samples = [
22.27, 22.19, 22.08, 22.17, 22.18, 22.13, 22.23, 22.43, 22.24, 22.29,
22.15, 22.39, 22.38, 22.61, 23.36, 24.05, 23.75, 23.83, 23.95, 23.63,
23.82, 23.87, 23.65, 23.19, 23.10, 23.33, 22.68, 23.10, 22.40, 22.17,
]
emaCap = 10
e=samples[0]
for s in range(len(samples)):
    numSamples = emaCap if s > emaCap else s
    e =  ema(samples[s], e, numSamples)
    print e

0

一个快速的方法(从这里复制粘贴)如下:

def ExpMovingAverage(values, window):
    """ Numpy implementation of EMA
    """
    weights = np.exp(np.linspace(-1., 0., window))
    weights /= weights.sum()
    a =  np.convolve(values, weights, mode='full')[:len(values)]
    a[:window] = a[window]
    return a

如果你使用 from scipy import signal 替换 np.convolve,速度会更快。代码如下:a = signal.convolve(values, weights, mode='full')[:len(values)] - user11186769
a[:window] = a[window -1] 因为越界了。 - PaSe

0
Papahaba的回答几乎是我所需要的(谢谢!),但我需要匹配初始条件。使用具有scipy.signal.lfilter的IIR滤波器肯定是最有效的。这是我的简化版:
给定一个NumPy向量x
import numpy as np
from scipy import signal

period = 12
b = np.array((1,), 'd')
a = np.array((period, 1-period), 'd')
zi = signal.lfilter_zi(b, a)
y, zi = signal.lfilter(b, a, x, zi=zi*x[0:1])

获取N点EMA(这里是12)并返回到向量y


0

我正在使用列表和衰减率作为输入。希望这个只有两行的小函数能对你有所帮助,考虑到在Python中深度递归不稳定。

def expma(aseries, ratio):
    return sum([ratio*aseries[-x-1]*((1-ratio)**x) for x in range(len(aseries))])

0
更简单地说,使用pandas。
def EMA(tw):
    for x in tw:
        data["EMA{}".format(x)] = data['close'].ewm(span=x, adjust=False).mean()
        EMA([10,50,100])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接