Luca Palese
Luca Palese

Reputation: 11

adaptive ATR with dominant cycle period

I created a function that computes an adaptive ATR with the period coming from estimations using fft on a certain window. the highpass and supersmoother functions come from Jhon Ehlers work; they select data with cycles periods between 10 and 48 observations.

def dominant_cycle(close):   
    close = highpass_filter(close)
    close = close[-int(np.floor(len(close) / 2)):]  
    close = super_smoother(close)
    close = close / np.std(close)
    
    ft = np.fft.fft(close)
    FFT = pd.DataFrame()
    FFT['amp'] = np.sqrt(ft.real**2 + ft.imag**2) / (len(close) / 2)
    plt.plot(FFT['amp'])
    FFT['freq'] = np.fft.fftfreq(ft.size, d=1)

    
    max_ = FFT.iloc[FFT['amp'].idxmax()]  
    max_freq = max_['freq']
    print(max_)
    
    # Check if max_freq is zero to avoid division by zero
    if max_freq == 0:
        return 48  
    
    cycle = np.floor(0.5 / max_freq)
    
    if cycle < 10:
        return 10
    elif cycle > 48:
        return 48 
    else: 
        return cycle

def adaptive_atr(data, window=100):
    high = np.array(data['High'])
    low = np.array(data['Low'])
    close = np.array(data['Close'])
    period=np.zeros_like(close)
    atr = np.zeros_like(close)
    center=np.zeros_like(close)
    center[:window]=close[:window]
    atr[window-1] = np.mean(np.maximum.reduce([high[:window] - low[:window],
                                          np.abs(high[:window] - np.roll(close, 1)[:window]),
                                          np.abs(low[:window] - np.roll(close, 1)[:window])]))
    
    for i in range(window, len(data)):
        period[i] = dominant_cycle(close[i - window + 1:i])
        # Calculate true ranges
        tr1 = high[i] - low[i]
        tr2 = np.abs(high[i] - np.roll(close, 1)[i])
        tr3 = np.abs(low[i] - np.roll(close, 1)[i])
        tr = max(tr1, tr2, tr3)
        
        atr[i] = (atr[i - 1] * (period[i] - 1) + tr) / period[i]
        center[i]=(center[i - 1] * (period[i] - 1) + close[i]) / period[i]
    
    return atr,center,period

What do you think? how can I improve? should I compute the fft of the autocorrelation vector? should I use the Goertzel alg? Thank you :)

Upvotes: 1

Views: 50

Answers (0)

Related Questions