How to find Average directional movement for stocks using Pandas?

陌路散爱 提交于 2021-01-29 15:31:20

问题


I have a dataframe of OHLCV data. I would like to know if anyone knows any tutorial or any way of finding ADX(Average directional movement ) using pandas?

import pandas as pd 
import yfinance as yf
import matplotlib.pyplot as plt
import datetime as dt 
import  numpy as nm 


start=dt.datetime.today()-dt.timedelta(59)
end=dt.datetime.today()

df=pd.DataFrame(yf.download("MSFT", start=start, end=end))

The average directional index, or ADX, is the primary technical indicator among the five indicators that make up a technical trading system developed by J. Welles Wilder, Jr. and is calculated using the other indicators that make up the trading system. The ADX is primarily used as an indicator of momentum, or trend strength, but the total ADX system is also used as a directional indicator.
Directional movement is calculated by comparing the difference between two consecutive lows with the difference between their respective highs.

For the excel calculation of ADX this is a really good video:

https://www.youtube.com/watch?v=LKDJQLrXedg&t=387s


回答1:


Math was taken from here.

def ADX(df):

    def getCDM(df):
        dmpos = df["High"][-1] - df["High"][-2]
        dmneg = df["Low"][-2] - df["Low"][-1]
        if dmpos > dmneg:
            return dmpos
        else:
            return dmneg 

    def getDMnTR(df):
        DMpos = []
        DMneg = []
        TRarr = []
        n = round(len(df)/14)
        idx = n
        while n <= (len(df)):
            dmpos = df["High"][n-1] - df["High"][n-2]
            dmneg = df["Low"][n-2] - df["Low"][n-1]
                
            DMpos.append(dmpos)
            DMneg.append(dmneg)
        
            a1 = df["High"][n-1] - df["High"][n-2]
            a2 = df["High"][n-1] - df["Close"][n-2]
            a3 = df["Low"][n-1] - df["Close"][n-2]
            TRarr.append(max(a1,a2,a3))

            n = idx + n
    
        return DMpos, DMneg, TRarr

    def getDI(df):
        DMpos, DMneg, TR = getDMnTR(df)
        CDM = getCDM(df)
        POSsmooth = (sum(DMpos) - sum(DMpos)/len(DMpos) + CDM)
        NEGsmooth = (sum(DMneg) - sum(DMneg)/len(DMneg) + CDM)
        
        DIpos = (POSsmooth / (sum(TR)/len(TR))) *100
        DIneg = (NEGsmooth / (sum(TR)/len(TR))) *100

        return DIpos, DIneg

    def getADX(df):
        DIpos, DIneg = getDI(df)

        dx = (abs(DIpos- DIneg) / abs(DIpos + DIneg)) * 100
        
       
        ADX = dx/14
        return ADX

    return(getADX(df))

print(ADX(df))



回答2:


I was playing with this a little bit and found something that can help you with the issue:

def ADX(data: pd.DataFrame, period: int):
    """
    Computes the ADX indicator.
    """
    
    df = data.copy()
    alpha = 1/period

    # TR
    df['H-L'] = df['High'] - df['Low']
    df['H-C'] = np.abs(df['High'] - df['Close'].shift(1))
    df['L-C'] = np.abs(df['Low'] - df['Close'].shift(1))
    df['TR'] = df[['H-L', 'H-C', 'L-C']].max(axis=1)
    del df['H-L'], df['H-C'], df['L-C']

    # ATR
    df['ATR'] = df['TR'].ewm(alpha=alpha, adjust=False).mean()

    # +-DX
    df['H-pH'] = df['High'] - df['High'].shift(1)
    df['pL-L'] = df['Low'].shift(1) - df['Low']
    df['+DX'] = np.where(
        (df['H-pH'] > df['pL-L']) & (df['H-pH']>0),
        df['H-pH'],
        0.0
    )
    df['-DX'] = np.where(
        (df['H-pH'] < df['pL-L']) & (df['pL-L']>0),
        df['pL-L'],
        0.0
    )
    del df['H-pH'], df['pL-L']

    # +- DMI
    df['S+DM'] = df['+DX'].ewm(alpha=alpha, adjust=False).mean()
    df['S-DM'] = df['-DX'].ewm(alpha=alpha, adjust=False).mean()
    df['+DMI'] = (df['S+DM']/df['ATR'])*100
    df['-DMI'] = (df['S-DM']/df['ATR'])*100
    del df['S+DM'], df['S-DM']

    # ADX
    df['DX'] = (np.abs(df['+DMI'] - df['-DMI'])/(df['+DMI'] + df['-DMI']))*100
    df['ADX'] = df['DX'].ewm(alpha=alpha, adjust=False).mean()
    del df['DX'], df['ATR'], df['TR'], df['-DX'], df['+DX'], df['+DMI'], df['-DMI']

    return df

At the beginning the values aren't correct (as always with the EWM approach) but after several computations it converges to the correct value.



来源:https://stackoverflow.com/questions/63020750/how-to-find-average-directional-movement-for-stocks-using-pandas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!