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

Is there a proper way to extend pandas-ta with Custom Indicator? #264

Closed
locupleto opened this issue Apr 5, 2021 · 46 comments
Closed

Is there a proper way to extend pandas-ta with Custom Indicator? #264

locupleto opened this issue Apr 5, 2021 · 46 comments
Labels
enhancement New feature or request info Informational question Further information is requested

Comments

@locupleto
Copy link
Contributor

locupleto commented Apr 5, 2021

Which version are you running? The lastest version is Github. Pip is for major releases.
0.2.62b0

Is your feature request related to a problem? Please describe.
I fail to figure out how to add my own custom indicators on top of all the great functions in the pandas-ta module

Describe the solution you'd like
I would love a short example showing the best way to add a simple custom indicator and use that together with pandas-ta without modifying the code within the pandas-ta module.

Describe alternatives you've considered
I considered subclassing AnalysisIndicators in core.py but I was unsure which methods I needed to override. Another way would be to post-process the dataframe myself completely outside the module and adding the cols of the custom indicator after running a pandas-ta strategy I guess. But that's a rather ugly way of doing it I think.

Additional context
Being able to extend the base functionality of Pandas TA and experiment with custom indicators is a common way TA platforms such as MultiCharts or TradeStation are used and it would make Pandas TA even better I believe.

Anyhow, great work guys!

@locupleto locupleto added the enhancement New feature or request label Apr 5, 2021
@twopirllc
Copy link
Owner

Hello @locupleto,

Apologies for the delay. I have been meaning to write a guide on this topic, so there is no better time than now. 🤣

I hope these steps are clear and easy to follow so any feedback on the process or wording would be greatly appreciated. 😎 In short, there are basically four steps to fully add an indicator to Pandas TA. For concrete examples, I recommend looking at @rengel8's RSX and @whubsch's MCG indicators. Essentially their indicator submission is some combination of steps outlined below.

Creating a Custom Indicator: The Big 4

This is a step by step guide to creating a Custom Indicator to provide both Standard and Pandas TA DataFrame Extensionable Indicators. So lets create a "hypothetical indicator" named ni(close, length=10, **kwargs) that belongs in the Trend Category. It's implementation is up to you, however at a minimum it should only rely on Pandas's dependencies (typically Pandas or NumPy calculations).

Step One: Adding the Indicator to it's Category

For ni(close, length=None, **kwargs) to be evaluated the Standard way, we need to do two things:

  1. Add the line from .ni import ni to pandas_ta/trend/__init__.py
  2. Create the file: pandas_ta/trend/ni.py.
    1. Copy a similar indicator as a template for the ni indicator specification and then modify it.

Now it should be callable the Standard way like a TA Lib indicator:

import pandas as pd
import pandas_ta as ta

df = # ohlcv data
nidf = ta.ni(df["close"]) #  = ta.ni(df["close"], 10)

Step Two: Adding the Indicator to the Pandas TA DataFrame

The next two steps are required to link ni(close, length=10, **kwargs) with Pandas TA DataFrame. This allows you to call it from the ta extension or from the ta.strategy() extension method.

  1. Add "ni" to the Category dict under the "trend" key in pandas_ta/__init__.py
  2. Add the ni method to pandas_ta/core.py.
    1. Copy a similar working core DataFrame method and update the required names.
@pd.api.extensions.register_dataframe_accessor("ta")
class AnalysisIndicators(BasePandasObject):

    # ...
    # Trend
    # ...

    def ni(self, length=None, offset=None, **kwargs):
        close = self._get_column(kwargs.pop("close", "close"))
        result = ni(close=close, length=length, offset=offset, **kwargs)
        return self._post_process(result, **kwargs)

That should be it!

Now you can run ni(close, length=10, **kwargs) either the Standard way above or as a DataFrame Extension:

import pandas as pd
import pandas_ta as ta

df = # ohlcv data
df.ta.ni(append=True)

Or via a Custom Strategy:

import pandas as pd
import pandas_ta as ta

df = # ohlcv data
# (1) Create the Strategy
MyStrategy = ta.Strategy(
    name="NI Trend",
    ta=[
        {"kind": "ohlc4"},
        {"kind": "ni", "length": 12},
    ]
)

# (2) Run the Strategy
df.ta.strategy(MyStrategy, **kwargs)

TLDR

Add and edit the file pandas_ta/trend/ni.py. Then modify the three files: pandas_ta/trend/__init__.py, pandas_ta/__init__.py, and pandas_ta/core.py


Hope this helps! Please let me know (good/bad)! Future contributions are greatly appreciated! 😎

Kind Regards,
KJ

@twopirllc twopirllc added info Informational question Further information is requested labels Apr 6, 2021
@locupleto
Copy link
Contributor Author

Hello KJ!

Awesome! Absolutely no need to apologise for anything. Your answer was both swift and thorough. And I found your guide to be very easy to follow, showing step by step how to extend pandas-ta with new a indicator of your own in a way that enables you to then use it exactly as the built-in functions. Big thanks!

Seeing these discrete steps described got me thinking though. Wouldn't it be sweet if in the future pandas_ta could support a dynamic plugin-style extension of its base functionality as well. With that I mean in a way that eliminate the need to modify pandas-ta itself.

E.g. say that I have pandas_ta in my python venv and in my project folder I create a structure mimicking the pandas_ta folder structure for the functions I like to dynamically import like this:

my_extensions/
│
├── momentum/
│   ├── my_mom.py
│   └── my_grand_mom.py
.
.
└── trend/
       ├── my_trend.py
       ├── my_supertrend.py
       └── my_something_else_trend.py

If I then passed the path to my_extension folders to pandas-ta it would try to dynamically load all user functions found there in the same manner it does today in a more static way. The idea would be to use a combination of importlib and decorators in pandas_ta to achieve this optional dynamic loading of user functions much in the same way as you do statically today.

That way we could avoid having to re-insert custom user functions each time with update pandas_ta in the pyenv. Just a thought.

Again, thank you very much KJ!

@twopirllc
Copy link
Owner

Hello @locupleto,

Awesome! Absolutely no need to apologise for anything. Your answer was both swift and thorough. And I found your guide to be very easy to follow, showing step by step how to extend pandas-ta with new a indicator of your own in a way that enables you to then use it exactly as the built-in functions. Big thanks!

Great! I appreciate the feedback. You're welcome! Thank you.

Seeing these discrete steps described got me thinking though. Wouldn't it be sweet if in the future pandas_ta could support a dynamic plugin-style extension of its base functionality as well. With that I mean in a way that eliminate the need to modify pandas-ta itself.

If I then passed the path to my_extension folders to pandas-ta it would try to dynamically load all user functions found there in the same manner it does today in a more static way. The idea would be to use a combination of importlib and decorators in pandas_ta to achieve this optional dynamic loading of user functions much in the same way as you do statically today.

That way we could avoid having to re-insert custom user functions each time with update pandas_ta in the pyenv. Just a thought.

Again, thank you very much KJ!

Yeah. I have been mulling on the approach to easily implement that feature because I could use it also. You are welcome to contribute as I have not tackled this problem before. 😎 No worries if you can not. This approached sounds logical. 😎

Also I plan to build a Pandas TA YAML config as described in Issue #258 which hopefully paves the way.

Thank you for your swift response, feedback, and ideas. I appreciate it.

Kind Regards,
KJ

@locupleto
Copy link
Contributor Author

Well, neither have I, at least not with Python. But I will give it a try and let you know if I get anywhere. At least maybe I will learn something. :-)

Cheers!
Urban

@twopirllc
Copy link
Owner

@locupleto,

I look forward to seeing what you come up with. 😎 No worries if you don't.

Thanks,
KJ

@locupleto
Copy link
Contributor Author

locupleto commented Apr 11, 2021 via email

@00slark
Copy link

00slark commented Jun 12, 2021

hi, you need a helping hand on this topic?

@twopirllc
Copy link
Owner

Hello @jacobt77,

Sure thing. I am open to ideas and/or implementations. 😎

Thanks,
KJ

@utpal4job
Copy link

utpal4job commented Nov 3, 2023

hello i have tried to create custom indicator like you said but error appears. below are the error message:

File "/root/simulation_test/src/app.py", line 14, in
import pandas_ta as ta
File "/root/myenv/lib/python3.11/site-packages/pandas_ta/init.py", line 1, in
from pandas_ta.core import *
File "/root/myenv/lib/python3.11/site-packages/pandas_ta/core.py", line 14, in
from pandas_ta import Category, Imports, version
ImportError: cannot import name 'Category' from partially initialized module 'pandas_ta' (most likely due to a circular import) (/root/myenv/lib/python3.11/site-packages/pandas_ta/init.py)

Please help me to solve the issue.

@locupleto
Copy link
Contributor Author

locupleto commented Nov 3, 2023 via email

@utpal4job
Copy link

Hello, thanks for you reply.

on "init.py" file i have added "ni" on below section

# Trend "trend": [ "adx", "ni", "amat", "aroon", "chop", "cksp", "decay", "decreasing", "dpo", "increasing", "long_run", "psar", "qstick", "short_run", "tsignals", "ttm_trend", "vhf", "vortex", "xsignals" ],

on "core.py" i have added the "ni" method like you said

def ni(self, length=None, offset=None, **kwargs): close = self._get_column(kwargs.pop("close", "close")) result = ni(close=close, length=length, offset=offset, **kwargs) return self._post_process(result, **kwargs)

error appears on "core.py" file. i have attached the screenshot also.
2023-11-03_17-33_core py

Pls help me.
Thanks.

@locupleto
Copy link
Contributor Author

locupleto commented Nov 3, 2023 via email

@utpal4job
Copy link

Hello, thanks for your reply. first of all i will not make anything on local environment.
I have sent you the screenshot from the server file, right now i am using more than 130 indicators from "pandas-ta" lib. I want to add more custom indicators on "panda-ta" lib which we have on the server.

I want to know using "Creating a Custom Indicator: The Big 4" steps can i create custom indicators on the server on "pandas-ta" lib because i want to use my custom indicators on different section like we are using "RSI/SMA/MACD/...". Pls let me know.

Regards.

@locupleto
Copy link
Contributor Author

Right, thank you for clarifying that you are working on your own fork of pandas_ta itself. I thought you were loading modules dynamically. Sorry for the confusion. I cloned the repo, started a clean venv end followed the instructions "The Big 4" and I had no issues as far as I can tell. Screenshots follows so you can compare with your setup:

the big 4

Screenshot 2023-11-03 at 16 11 03 Screenshot 2023-11-03 at 16 11 19 Screenshot 2023-11-03 at 16 11 34 Screenshot 2023-11-03 at 16 11 50

test

Screenshot 2023-11-03 at 16 28 15

@utpal4job
Copy link

utpal4job commented Nov 3, 2023

Hello, thanks for your detailed reply. I have made all the same steps what you have shown on the screenshot but still same error appears. i have attached the screenshot also.

I have made the same steps 10hrs ago and getting the same error but not able to solve the issue. pls help me to solve the issue. if you want i can send you the TV details and you can check it directly and it will take few mins to check.
2023-11-03_21-14_root@11- ~-simulation_test-src.

I have run on the terminal like you made it but same error appears. pls check the screenshot.
2023-11-03_21-22_root@11- ~-simulation_test-src

Regards.

@locupleto
Copy link
Contributor Author

Alright then, I take have a quick look. Just two basic questions

  • did you start up with a new clean venv or are there any other packages installed as well?
  • which version of pandas_ta have you cloned and is it modified in any way?

@utpal4job
Copy link

utpal4job commented Nov 3, 2023

  1. We have many packages installed.
  2. I have installed using pip3 install pandas_ta, i have attached the screenshot. I have not modified anything earlier, today i have modified to add custom indicator.
    2023-11-03_22-43_root@11- ~-simulation_test-src

Thanks,

@locupleto
Copy link
Contributor Author

locupleto commented Nov 3, 2023

Ok, thank you. That looks recent. I get this when installing into a clean venv :

numpy==1.26.1
pandas==2.1.2
pandas-ta==0.3.14b0
python-dateutil==2.8.2
pytz==2023.3.post1
six==1.16.0
tzdata==2023.3

It will probably not be what you want to hear but I would try on a brand new venv with only pandas_ta in it and when you have that up and running including your custom indicator, add the other requirements from your current env and go from there. I had a very similar issue recently trying to add the gradio library to one of my bigger projects which I solved in that manner. It's annoying I know but It is very hard to debug these types of errors and starting over is usually the fastest way to resolve them. Sorry I couldn't be of more help.

And just to clarify, I presume you have

  1. made a git clone (or fork) on your server of the pandas_ta project
  2. done uninstall of any previous upstream pandas_ta lib in your venv
    pip uninstall pandas_ta
  3. made the source code changes in your local pandas_ta repo
  4. installed pandas_ta from your local repo not the upstream one
    pip install -e .

Otherwise try that

BR
Urban

@utpal4job
Copy link

Hello, thanks for your reply. tomorrow i will try in fresh server what you said and let you know for sure.

Thanks again.

Regards.

@utpal4job
Copy link

Hello, to let you know i have installed the "pandas_ta" lib on the fresh server but after adding the "ni" indicator same error appears like yesterday. i am going to be mad not with that issue.

Thanks.

@locupleto
Copy link
Contributor Author

Hi, dang that's disappointing. When you say on a fresh server, what exactly did you do, a complete new vm? I reckon that to test it out the same way I showed you in my recent reply, it would suffice to

  1. clone a fresh pandas-ta repository somewhere on the server/vm
  2. make the 4 steps as I did to extend that forked source code project with the ni-module
  3. cd to that directory on the server, create a fresh empty python venv there
  4. activate that venv
  5. install your modded pandas_ta by
    pip install -e .
  6. Test the ni indicator

Is that what you did? (I'm asking just to understand how different our setups are).

@utpal4job
Copy link

Hi, i have not made like you said. I am trying to make like you said and let you know.

Thanks.

@utpal4job
Copy link

Hello, i have tried in the same way like you said but same error appears. check the screenshot.
2023-11-04_22-08_root@111- ~-test-pandas-ta
2023-11-04_22-08_root@111- ~-test-pandas-ta(2)

Regards.

@locupleto
Copy link
Contributor Author

locupleto commented Nov 4, 2023

Not what we wanted. There's definitely a problem with a circular import then, two or more modules depend on each other to function. I can't see that anyone else has reported that yet though for pandas_ta which is a bit strange. Also we're both on Python 3.11.6...

You can try two ways forward if you want.

A) You can modify your copy of core.py by changing the global imports of Category to local imports. This isn't a great practice in general for library maintainability, but it can serve as a quick fix.

So let's try modifying your core.py like this:
Screenshot 2023-11-04 at 19 15 10

then
Screenshot 2023-11-04 at 19 17 10

and
Screenshot 2023-11-04 at 19 17 34

Now, after these changes my repo still works. But of course this is no guarantee that it will on your end.

B) another alternative is to create a new venv with an older version of Python 3 and repeat what you just tried. E.g.
python3.9 -m venv myenv39

@utpal4job
Copy link

Hello, ok i will check later and let you know.

Regards.

@utpal4job
Copy link

Hello, i have removed "from pandas_ta import Category, Imports, version" row from core.py file but "circular import" issue appears on different section. I am not getting one thing when i am installing fresh "pandas_ta" library then "circular import" issue not appearing but whenever edited anything then "circular import" issue appeared.

One another thing i have noticed, i have removed everything what i have edited and uploaded the files like it's fresh installed still "circular import" issue appears. some thing i am doing wrong for sure.

if possible can you please check what i am doing wrong, if you want i will send server details.

Regards.

@utpal4job
Copy link

Hello, ok, i will make the 3 edits and check again.

Thanks.

@locupleto
Copy link
Contributor Author

It is very hard for me to help you with your specific problems on your specific environment since I am unable to re-produce your issues in my own environment. Details regarding your machine and OS wouldn't necessarily help either unless I was able to 100% mimic it.

I would suggest the following:

  • Did you make all three edits I suggested to get rid of the global import of Category? If not do that.
  • If that fixed that issue but you now get new similar issues somewhere else in the code, just fix those in the same way. You should be able to fix all circular references that relatively easy. Just repeat the pattern I showed you.

It is comforting at least that the straight import of the standard pantas_ta works. The installation from PyPI compiles the package and its dependencies in a way that may avoid some of the pitfalls of direct module execution, like circular imports. So that may be why you only experience problems when working with the library in edit mode.

Best regards

@utpal4job
Copy link

Hello, i have made what you said, when removed Category then same error appears for Imports that's why i have removed all 3 imports and made all 3 import like you said for "Category/Imports/version. below error appears right now.

`>>> import pandas as pd

import pandas_ta as ta
Traceback (most recent call last):
File "", line 1, in
File "/root/test/pandas-ta/pandas_ta/init.py", line 1, in
from pandas_ta.core import *
File "/root/test/pandas-ta/pandas_ta/core.py", line 15, in
from pandas_ta.candles.cdl_pattern import ALL_PATTERNS
File "/root/test/pandas-ta/pandas_ta/candles/init.py", line 2, in
from .cdl_doji import cdl_doji
File "/root/test/pandas-ta/pandas_ta/candles/cdl_doji.py", line 2, in
from pandas_ta.overlap import sma
File "/root/test/pandas-ta/pandas_ta/overlap/init.py", line 2, in
from .alma import alma
File "/root/test/pandas-ta/pandas_ta/overlap/alma.py", line 5, in
from pandas_ta.utils import get_offset, verify_series
File "/root/test/pandas-ta/pandas_ta/utils/init.py", line 2, in
from ._candles import *
File "/root/test/pandas-ta/pandas_ta/utils/_candles.py", line 4, in
from ._core import non_zero_range
File "/root/test/pandas-ta/pandas_ta/utils/_core.py", line 9, in
from pandas_ta import Imports
ImportError: cannot import name 'Imports' from partially initialized module 'pandas_ta' (most likely due to a circular import) (/root/test/pandas-ta/pandas_ta/init.py)
`

Thanks.

@locupleto
Copy link
Contributor Author

Yes, well - as I said, just continue to fix any following problems like I showed you. Read the error and act accordingly. In this case

  • cut out "from pandas_ta.candles.cdl_pattern import ALL_PATTERNS" at line 15 of core.py.
  • search for all occurrences of ALL_PATTERNS in core.py and add that import there instead making it local.
  • try again, repeat until no such errors are reported.

If you want to avoid this hassel you could always resort to the way I explained to you in my first reply, that is use the official pandas_ta and add your own indicator to it by loading them dynamically at run-time.

Sorry, but there's nothing more I can do for you at this point.
Good luck!

@utpal4job
Copy link

Hello, It's ok.

Thanks again...

@twopirllc
Copy link
Owner

Hello @utpal4job,

Thanks @locupleto for trying helping to resolve @utpal4job 's issue with adding a new indicator.

So @utpal4job, after restarting with a fresh virtual environment as @locupleto has suggested, have you tried doing only Step One listed below (before attempting Step Two to add it to core.py)? If the minimum implementation of Step One is not working, then don't count on Step Two to work.

Step One: Adding the Indicator to it's Category

For ni(close, length=None, **kwargs) to be evaluated the Standard way, we need to do two things:

  1. Add the line from .ni import ni to pandas_ta/trend/__init__.py
  2. Create the file: pandas_ta/trend/ni.py.
    1. Copy a similar indicator as a template for the ni indicator specification and then modify it.

Now it should be callable the Standard way like a TA Lib indicator:

import pandas as pd
import pandas_ta as ta

df = # ohlcv data
nidf = ta.ni(df["close"]) #  = ta.ni(df["close"], 10)

Also can you share some more of custom indicator, perhaps there is some import that is

Additionally, I highly recommend using the development version instead of 0.3.14b0. It has some speed improvements with numpy/numba, cleaner code, and better documentation.

Kind Regards,
KJ

@utpal4job
Copy link

Hello @twopirllc / @locupleto . I will check the step1 and let you know.

Thanks.

@utpal4job
Copy link

Hello, i have made the step1 like you said but error appears. pls check it below.
`>>> import pandas as pd

import pandas_ta as ta
df= pd.read_csv("/root/test2/myenv/lib/python3.11/site-packages/pandas_ta/trend/SPY_D.csv")
df.set_index(pd.DatetimeIndex(df["date"]), inplace=True)
df.ta.ni(append=True)
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'AnalysisIndicators' object has no attribute 'ni'. Did you mean: 'nvi'?
nidf = ta.ni(df["close"])
Traceback (most recent call last):
File "", line 1, in
File "/root/test2/myenv/lib/python3.11/site-packages/pandas_ta/trend/ni.py", line 26, in ni
# Name and Categorize it
^^
UnboundLocalError: cannot access local variable 'ni' where it is not associated with a value
`

Thanks.

@utpal4job
Copy link

utpal4job commented Nov 6, 2023

Hello, here is the "ni.py" file code:

# -*- coding: utf-8 -*-
from pandas_ta.utils import get_drift, get_offset, is_percent, verify_series

def ni(close, length=None, offset=None, **kwargs):
    """NI Doc here"""
    # Validate Arguments
    length = int(length) if length and length > 0 else 1
    close = verify_series(close, length)
    offset = get_offset(offset)

    if close is None:
        return

    ni = ni(close, length)
    # Offset
    if offset != 0:
        ni = ni.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        ni.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        ni.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    ni.name = f"NI_{length}"
    ni.category = "trend"

    return ni

Thanks.

@twopirllc
Copy link
Owner

Hello @utpal4job,

i have made the step1 like you said

Unfortunately you did not follow the instructions or perhaps the instructions were not clear. 🤷🏼‍♂️

Lets stick this version of ni.py before modifying it.

# -*- coding: utf-8 -*-
from pandas_ta.overlap import sma
from pandas_ta.utils import get_offset, verify_series

# - Standard definition of your custom indicator function (including docs)-

def ni(close, length=None, centered=False, offset=None, **kwargs):
    """
    Example indicator ni
    """
    # Validate Arguments
    length = int(length) if length and length > 0 else 20
    close = verify_series(close, length)
    offset = get_offset(offset)

    if close is None: return

    # Calculate Result
    t = int(0.5 * length) + 1
    ma = sma(close, length)

    ni = close - ma.shift(t)
    if centered:
        ni = (close.shift(t) - ma).shift(-t)

    # Offset
    if offset != 0:
        ni = ni.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        ni.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        ni.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    ni.name = f"ni_{length}"
    ni.category = "trend"

    return ni

ni.__doc__ = \
"""Example indicator (NI)

Is an indicator provided solely as an example

Sources:
    https://github.com/twopirllc/pandas-ta/issues/264

Calculation:
    Default Inputs:
        length=20, centered=False
    SMA = Simple Moving Average
    t = int(0.5 * length) + 1

    ni = close.shift(t) - SMA(close, length)
    if centered:
        ni = ni.shift(-t)

Args:
    close (pd.Series): Series of 'close's
    length (int): It's period. Default: 20
    centered (bool): Shift the ni back by int(0.5 * length) + 1. Default: False
    offset (int): How many periods to offset the result. Default: 0

Kwargs:
    fillna (value, optional): pd.DataFrame.fillna(value)
    fill_method (value, optional): Type of fill method

Returns:
    pd.Series: New feature generated.
"""

However, you did not follow the instructions when testing ni() code. You were supposed to run the code listed in Step One:

import pandas as pd
import pandas_ta as ta

df = # ohlcv data
nidf = ta.ni(df["close"]) #  = ta.ni(df["close"], 10)

But instead you ran it as a DataFrame Extension which is the testing phase of Step Two.

import pandas as pd
import pandas_ta as ta

df = # ohlcv data
df.set_index(pd.DatetimeIndex(df["date"]), inplace=True) # including this fine
df.ta.ni(append=True) 

As a reminder, first you must be able to get Step One working before integrating it into the DataFrame in core.py in Step Two. In other words, Step Two will not work unless Step One is working.

Once you are able to get Step One working by itself, then it should be easier to resolve your Step Two issue(s).

KJ

@utpal4job
Copy link

Hello, thanks for your reply.

Just checked step1 is working fine. pls let me know what i will do on step2.

Thanks,

@twopirllc
Copy link
Owner

@utpal4job

Just checked step1 is working fine.

Great! Could you please share a screenshot?

pls let me know what i will do on step2

  • Also include a screenshot after completing Step Two below.

Step Two: Adding the Indicator to the Pandas TA DataFrame

The next two steps are required to link ni(close, length=10, **kwargs) with Pandas TA DataFrame. This allows you to call it from the ta extension or from the ta.strategy() extension method.

  1. Add "ni" to the Category dict under the "trend" key in pandas_ta/__init__.py
  2. Add the ni method to pandas_ta/core.py.
    1. Copy a similar working core DataFrame method and update the required names.
@pd.api.extensions.register_dataframe_accessor("ta")
class AnalysisIndicators(BasePandasObject):

    # ...
    # Trend
    # ...

    def ni(self, length=None, offset=None, **kwargs):
        close = self._get_column(kwargs.pop("close", "close"))
        result = ni(close=close, length=length, offset=offset, **kwargs)
        return self._post_process(result, **kwargs)

That should be it!

Now you can run ni(close, length=10, **kwargs) either the Standard way above or as a DataFrame Extension:

import pandas as pd
import pandas_ta as ta

df = # ohlcv data
df.ta.ni(append=True)

@utpal4job
Copy link

Hello, thanks for your reply. Yes both steps are working fine.

Step1:
step1

Step2:
step2

Now i will check both steps in my working server.

Thanks again.

@utpal4job
Copy link

Hello, i have checked on my working server and both steps are working fine.

Thank you @twopirllc and @locupleto

@locupleto
Copy link
Contributor Author

locupleto commented Nov 8, 2023 via email

@utpal4job
Copy link

Hello, i have created another custom indicator and step1 working fine but step2 not working fine. pls check the screenshot.
step1-2

Thanks.

@twopirllc
Copy link
Owner

@utpal4job

Glad you were able to get the example indicator ni working as expected! 😎

Can you share details about your indicator volume_value()? More specifically, can you share what you are importing in volume_value.py? Perhaps some import in it is causing your circular import issue?

In general, circular imports are an issue on your end and very hard for us to solve on our end unless you share more details. 🤷🏼‍♂️

Kind Regards

@utpal4job
Copy link

utpal4job commented Nov 16, 2023

Hello, sorry for late reply.

i have attached volume_values.py file code

def volume_values(volume, length=None, centered=False, offset=None, **kwargs):
    """
    Example indicator volume_values
    """
    # Validate Arguments
    length = int(length) if length and length > 0 else 20
    volume = verify_series(volume, length)
    offset = get_offset(offset)

    if volume is None:
        return

    # Calculate Result
    t = int(0.5 * length) + 1
    ma = sma(volume, length)

    # volume_values = volume - ma.shift(t)
    volume_values = volume
    if centered:
        volume_values = (volume.shift(t) - ma).shift(-t)

    # Offset
    if offset != 0:
        volume_values = volume_values.shift(offset)

    # Handle fills
    if "fillna" in kwargs:
        volume_values.fillna(kwargs["fillna"], inplace=True)
    if "fill_method" in kwargs:
        volume_values.fillna(method=kwargs["fill_method"], inplace=True)

    # Name and Categorize it
    volume_values.name = f"volume_values_{length}"
    volume_values.category = "trend"

    return volume_values

Thanks.

@twopirllc
Copy link
Owner

@utpal4job

Weird. 🤔 It is hard to triage without being on the machine. 🤷🏼‍♂️
If you figure it out, let us know so others can resolve similar circular dependency issues.

Again, I highly recommend using the development version instead of 0.3.14b0. It has some speed improvements with numpy/numba, cleaner code, and better documentation.

Kind Regards
KJ

@utpal4job
Copy link

Hello, thanks for your reply. I will let you know if i am able to solve the issue.
Regards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request info Informational question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants