Applying a function to a Pandas Dataframe

I have this code with me. And I need to pass a pandas data frame in it as a parameter. It returns errors.

The Logic for the Technical Analysis Indicator is this

def williams_ad(data, high_col="High", low_col="Low", close_col="Close"):
    data['williams_ad'] = 0.
    
    for index,row in data.iterrows():
        if index > 0:
            prev_value = data.at[index-1, 'williams_ad']
            prev_close = data.at[index-1, close_col]
            if row[close_col] > prev_close:
                ad = row[close_col] - min(prev_close, row[low_col])
            elif row[close_col] < prev_close:
                ad = row[close_col] - max(prev_close, row[high_col])
            else:
                ad = 0.
                                                                                                        
            data.set_value(index, 'williams_ad', (ad+prev_value))
        
    return data

Documentation for the above code.

William's Accumulation/Distribution
Source: https://www.metastock.com/customer/resources/taaz/?p=125
Params: 
    data: pandas DataFrame
    high_col: the name of the HIGH values column
    low_col: the name of the LOW values column
    close_col: the name of the CLOSE values column
    
Returns:
    copy of 'data' DataFrame with 'williams_ad' column added

What is the right way to use this

williams_ad()

I tried several ways. But unable to debug.

import pandas as pd
import yfinance as yF
import datetime
df = yF.download(tickers = "SPY",  # list of tickers
            period = "5y",         # time period
            interval = "1d",       # trading interval
            prepost = False,       # download pre/post market hours data?
            repair = True)         # repair obvious price errors e.g. 100x?

Now I tried to pass df as an argument in place of data.

williams_ad(df)

I get a type error:

TypeError: '>' not supported between instances of 'Timestamp' and 'int'

The default index is Date Timestamp in my pandas data frame. In the first if condition, it is checking if index > 0.
This is returning an error. How to overcome this issue?

Comment request dtypes:

Open           float64
High           float64
Low            float64
Close          float64
Adj Close      float64
Volume           int64
williams_ad    float64

  • Your code does not seem to be efficient, so it would be better to explain the logic and get new code than to fix the error.

    – 

  • Looks like you need to uniformize timestamps and datetimes across different columns, please share df.dtypes

    – 

  • Shared df.dtypes above

    – 

  • @PandaKim We are collecting OHLC data from Financial Markets and adding a new column containing a Technical Analysis Indicator to it.

    – 

  • 1

    Your error is that you cannot perform the operation because index of your df is Timestamp and you put the index and 0 of the > operator in the function. However, I do not think that finding and fixing this error is the right solution. It seems to be an inefficient approach and does not seem to be code that needs to be fixed.

    – 




The code below works well.

import pandas as pd
import yfinance as yF
import datetime


df1 = yF.download(tickers = "SPY",  # list of tickers
            period = "5y",         # time period
            interval = "1d",       # trading interval
            prepost = False,       # download pre/post market hours data?
            repair = True)         # repair obvious price errors e.g. 100x?

df1['Close_Yesterday'] = df1['Close'].shift(1)
df1['min_Lt_Ct-1'] = df1[['Low','Close_Yesterday']].min(axis=1)
df1['max_Ht_Ct-1'] = df1[['High','Close_Yesterday']].min(axis=1)


df1['X_Today_PRICE_INCREASING'] = df1['Close'] - df1['min_Lt_Ct-1']
df1['X_Today_PRICE_DECREASING'] = df1['Close'] - df1['max_Ht_Ct-1']

df1["X Today"] = df1.apply(lambda x: x.X_Today_PRICE_DECREASING if (x.X_Today_PRICE_DECREASING < 0) else x.X_Today_PRICE_INCREASING, axis = 1)


df1['ADWM'] = df1['X Today'].cumsum()

df1.head()

It is implemented according to the formula of Williams Accumulation and Distribution.

Leave a Comment