需要PandasDataSeries上的平均真实范围和指数移动平均函数

时间:2016-11-17 11:28:30

标签: python pandas technical-indicator

我在计算一系列的平均真实范围[ATR]时遇到困难。         ATR基本上是True Movge [TR]

的Exp Movin平均值
 TR is nothing but MAX of -
       Method 1: Current High less the current Low
       Method 2: Current High less the previous Close (absolute value)
       Method 3: Current Low less the previous Close (absolute value)

在Pandas,我们没有内置的EMA功能。相反,我们的EWMA是加权移动平均线。

如果有人帮助计算EMA也足够好

      def ATR(df,n):
          df['H-L']=abs(df['High']-df['Low'])
          df['H-PC']=abs(df['High']-df['Close'].shift(1))
          df['L-PC']=abs(df['Low']-df['Close'].shift(1))
          df['TR']=df[['H-L','H-PC','L-PC']].max(axis=1)
          df['ATR_' + str(n)] =pd.ewma(df['TR'], span = n, min_periods = n)
          return df

上面的代码没有给出错误但它也没有给出正确的值。我将它与在excel中相同数据集上手动计算ATR值进行比较,并且值不同

           ATR excel formula-
             Current ATR = [(Prior ATR x 13) + Current TR] / 14

             - Multiply the previous 14-day ATR by 13.
             - Add the most recent day's TR value.
             - Divide the total by 14

这是我用作样本的数据

           start='2016-1-1'
           end='2016-10-30'
           auro=web.DataReader('AUROPHARMA.NS','yahoo',start,end)

2 个答案:

答案 0 :(得分:1)

您确实需要使用ewma 请参阅此处:指数移动平均线(EMA)是一种类似于简单移动平均线的移动平均线,除了对最新数据给予更多权重。

了解详情:指数移动平均线(EMA)http://www.investopedia.com/terms/e/ema.asp#ixzz4ishZbOGx

我不认为你的excel公式是正确的...这是一种在python中计算ema的手动方式

def exponential_average(values, window):
    weights = np.exp(np.linspace(-1.,0.,window))
    weights /= weights.sum()

    a = np.convolve(values, weights) [:len(values)]
    a[:window]=a[window]
    return a

答案 1 :(得分:0)

scipy.signal.lfilter可以帮到你。

scipy.signal.lfilter(b, a, x, axis=-1,zi=None)

滤波器功能实现为直接II转置结构。这意味着过滤器实现:

a[0]*y[n] = b[0]*x[n] + b[1]*x[n-1] + ... + b[M]*x[n-M]
                      - a[1]*y[n-1] - ... - a[N]*y[n-N]

如果我们将上述公式标准化,我们得到以下公式:

y[n] = b'[0]*x[n] + b'[1]*x[n-1] + ... + b'[M]*x[n-M]
                  - a'[1]*y[n-1] + ... + a'[N]*y[n-N]

其中b'[i] = b[i]/a[0], i = 0,1,...,M; a'[j] = a[j]/a[0],j = 1,2,...,Na'[0] = 1

指数移动平均线公式:

y[n] = alpha*x[n] + (1-alpha)*y[n-1]

所以要应用scipy.signal.lfilter,通过上面的公式我们可以设置a和b如下:

a[0] = 1, a[1] = -(1-alpha)
b[0] = alpha

我的实施如下,希望它能为您提供帮助。

def ema(values, window_size):
    alpha = 2./ (window_size + 1)
    a = np.array([1, alpha - 1.])
    b = np.array([alpha])
    zi = sig.lfilter_zi(b, a)
    y, _ = sig.lfilter(b, a, values, zi=zi)
    return y