Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pandas 2.1.0 and mfi indicator #731

Closed
zakcali opened this issue Oct 14, 2023 · 5 comments
Closed

Pandas 2.1.0 and mfi indicator #731

zakcali opened this issue Oct 14, 2023 · 5 comments
Labels
bug Something isn't working good first issue Good for newcomers help wanted Extra attention is needed

Comments

@zakcali
Copy link

zakcali commented Oct 14, 2023

Which version are you running? The lastest version is on Github. Pip is for major releases.
pandas-ta 0.3.14b
python 3.12
pandas 2.1.0
Do you have TA Lib also installed in your environment?
No

Have you tried the development version? Did it resolve the issue?
no, because is not compatible with python 3.12

Describe the bug
[A clear and concise description of what the bug is.](futurewarning: setting an item of incompatible dtype is deprecated and will raise in a future error of pandas)

To Reproduce

df["MFI"] = ta.mfi(high=df["High"], low=df["Low"], close=df["Close"], volume=df["Volume"], length=14, talib=False)

Expected behavior
pandas 2.0.3 doesn't give that warning

Screenshots
Reason is updated pandas behaviour

Additional context
I find a function from: https://gist.github.com/quantra-go-algo/d3ced509e55ceb15eb0a6bd283e6853f#file-ti_mfi-py
and fine tuned with chatgpt to execute faster than original code and pandas-ta:
I couldn't correct the pandas-ta bug, so I embedded below code to my python program

def mfi(high, low, close, volume, n):
    typical_price = (high + low + close) / 3
    money_flow = typical_price * volume
    mf_sign = np.where(typical_price > typical_price.shift(1), 1, -1)
    signed_mf = money_flow * mf_sign

    # Calculate gain and loss using vectorized operations
    positive_mf = np.where(signed_mf > 0, signed_mf, 0)
    negative_mf = np.where(signed_mf < 0, -signed_mf, 0)

    mf_avg_gain = pd.Series(positive_mf).rolling(n, min_periods=1).sum()
    mf_avg_loss = pd.Series(negative_mf).rolling(n, min_periods=1).sum()

    return (100 - 100 / (1 + mf_avg_gain / mf_avg_loss)).to_numpy()

Thanks for using Pandas TA!

@zakcali zakcali added the bug Something isn't working label Oct 14, 2023
@twopirllc twopirllc removed their assignment Oct 14, 2023
@twopirllc twopirllc added help wanted Extra attention is needed good first issue Good for newcomers labels Oct 14, 2023
@twopirllc
Copy link
Owner

Hello @zakcali,

I couldn't correct the pandas-ta bug, so I embedded below code to my python program

Nice! Glad you find a work around and shared the code. 😎

Like many indicators, including mfi, are in need of an update. So this really helps! Thanks 😎

Kind Regards,
KJ

@zakcali
Copy link
Author

zakcali commented Oct 17, 2023

this one runs faster, by using numpy arrays instead of pandas.series on my 376 items xu100 market. Please ensure that you are not sending an empty array.

Calculate money flow index

def calculate_mfi(high, low, close, volume, period):
    typical_price = (high + low + close) / 3
    money_flow = typical_price * volume
    mf_sign = np.where(typical_price > np.roll(typical_price, shift=1), 1, -1)
    signed_mf = money_flow * mf_sign

    # Calculate gain and loss using vectorized operations
    positive_mf = np.maximum(signed_mf, 0)
    negative_mf = np.maximum(-signed_mf, 0)

    mf_avg_gain = np.convolve(positive_mf, np.ones(period), mode='full')[:len(positive_mf)] / period
    mf_avg_loss = np.convolve(negative_mf, np.ones(period), mode='full')[:len(negative_mf)] / period

    epsilon = 1e-10  # Small epsilon value to avoid division by zero
    mfi = 100 - 100 / (1 + mf_avg_gain / (mf_avg_loss + epsilon))
    return mfi

df = pd.read_csv(file_name)
if len(df.index) == 0: # faster than if df.empty:
    df_is_empty = True
else:
    df_is_empty = False

if df_is_empty: 
    df["MFI"] = np.nan
else:
    df["MFI"] = calculate_mfi(high=df["High"].values, low=df["Low"].values, close=df["Close"].values, volume=df["Volume"].values, period=MFI_PERIOD)

@twopirllc
Copy link
Owner

Hello @zakcali

Thanks for submitting a faster version. It is now available on the development branch.

KJ

@carissssa
Copy link

@twopirllc any idea when this will be in main release? i cannot use dev branches and this is blocking pandas upgrade

@twopirllc
Copy link
Owner

Hello @carissssa,

A new main release will occur after outstanding PRs are completed and some other bugs and maintenance issues have been taken care of. When, however, is unknowable at this time. 😕

i cannot use dev branches and this is blocking pandas upgrade

What is preventing the use of the dev branch?

Kind Regards,
KJ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants