pythonpandasdataframeaverage

How to find Average directional movement for stocks using Pandas?


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


Solution

  • 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))