Требуется средний истинный диапазон и экспоненциальная скользящая средняя для PandasDataSeries
Я застрял при расчете среднего истинного диапазона [ATR] серии. ATR - это, в основном, Exp Movin Avg из TrueRange[TR]
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)
В Пандах у нас нет встроенной функции 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
Приведенный выше код не выдает ошибку, но также не дает правильных значений. Я сравнил это с ручным вычислением значений ATR для тех же наборов данных в Excel, и значения были разными
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 ответа
Вам нужно использовать ewma. Смотрите здесь: Экспоненциальное скользящее среднее (EMA) - это тип скользящего среднего, который похож на простое скользящее среднее, за исключением того, что более поздним данным присваивается больший вес.
Подробнее: Экспоненциальная скользящая средняя (EMA) http://www.investopedia.com/terms/e/ema.asp
Я не думаю, что ваша формула Excel является правильным... Вот ручной способ расчета EMA в Python
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
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,...,N
а также a'[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