Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
What is the Quantopain's EMA, MACD or RSI Formula for the fixed 34-day window length?

There are some posts discussed the EMA, MACD and RSI discrepancy between Quantopian and external data sources like Yahoo and Google see here. Quantopain help document TA-Lib methods explains they use the a fixed window length of 34 days every time for the calculation of the functions that has a "memory", like EMA, MACD, RSI. But no detailed formula provided.

There are many ways to calculate the "memory" functions using truncated time-series data (that is, the fixed window length), and each will have different result. Sometime the difference might be significant, especially for the short window-length or EMA period. In order to eliminate the confusion on the EMA, MACD and RSI value discrepancies, could Quantiopain disclose the algorithm or formula used for the fixed 34-day window length? At least for the EMA, since lots of other memory functions are based on it. I don't think that is a business secrete -:).

1 response

Below is my EMA formula for the fixed window length version:

Let k = the length of window, v = 2/(1+period)

In theory: EMA (n) = v.( P(n) + (1-v).EMA(n-1) = .... = w[P(n)+(1-v).P(n-1)+(1-v)^2.P(n-2)+ ... + (1-v)^(k-1).P(n-k+1) + (1-v)^(k).P(n-k) + ...... )
If we drop the data points that are older than k days, then we have

           *EMA (n)  ~= v ( P(n)+(1-v).P(n-1)+(1-v)^2.P(n-2)+ ... + (1-v)^(k-1).P(n-k+1) )*

The implementation code is given below:

import numpy as np

def EMAFIX (prices, period = 14, window_length = 34):  
    """  
    Exponential Moving Average (EMA) using fixed window length  
    """  
    num_prices = len(prices)  
    if ( ( num_prices < period) or ( num_prices < window_length ) or  ( window_length < period) ) :  
        print ("not enough data values")  
        raise SystemExit

    w = 2 / float(period + 1)  
    emas = np.zeros(num_prices)

    weight = w * np.power( (1-w), range(0, window_length))  
    weight = weight / weight.sum()  
    emas =  np.convolve(prices, weight, 'full')[0:num_prices]  
    emas[0:window_length] = EMA(prices[0:window_length], period)  # adjust the initial values

    return emas  

The test results show that when Window_length:Period >= 2:1, the EMA and EMAFIX are very close each other. When Window_length:Period is about 3:1, the EMA and EMAFIX are almost identical.