pandas-ta icon indicating copy to clipboard operation
pandas-ta copied to clipboard

How To Test TMO Indicator

Open azimgiant opened this issue 1 year ago • 7 comments

I want to first give a big thanks to @luisbarrancos and @twopirllc for working on the indicator. I have been trying to backtest it but am having trouble. I keep getting an error when inputting the first part of the code:

from numpy import broadcast_to, isnan, nan, nansum, newaxis, pad, sign, zeros
from numpy.lib.stride_tricks import sliding_window_view
from pandas import DataFrame, Series

from pandas_ta._typing import DictLike, Int
from pandas_ta.ma import ma
from pandas_ta.utils import (
    v_bool,
    v_mamode,
    v_offset,
    v_pos_default,
    v_series
)

I get this error when running it:

ModuleNotFoundError: No module named 'pandas_ta._typing'

Do I need to run the code on another platform I am currently using Jupyter?

azimgiant avatar Jan 23 '24 18:01 azimgiant

Hello @azimgiant

I am curious why your testing code begins like the beginning of an indicator code?

The tmo indicator is only available on the development branch. So if you do not have that installed, you will need to do so first.

Second you don't necesarily need Jupyter for testing, but you can if you want.

# your imports here

df = # your ohlcv date retrieval here
df.ta.tmo(append=True) # Apply tmo

# Continue your backtesting here

Kind Regards KJ

twopirllc avatar Jan 23 '24 20:01 twopirllc

I tried installing the development branch first but received this error:

 pip install -U git+https://github.com/twopirllc/pandas-ta.git@development

ERROR: Error [WinError 2] The system cannot find the file specified while executing command git version
ERROR: Cannot find command 'git' - do you have 'git' installed and in your PATH?

So, I decided to copy to the raw code thinking it would work like that. As you can see, I am a complete beginner lol. Do you know the right code to install the development branch or why it isn't installing?

azimgiant avatar Jan 23 '24 20:01 azimgiant

@azimgiant

It says you do not have git on your Windows machine. Install that first.

twopirllc avatar Jan 29 '24 19:01 twopirllc

@twopirllc

So I was able to download git but when trying to run the backtest the values for the tmo show up as NaN. I don't think I am pulling the tmo correctly from the development branch. Here is the code maybe you can help as to why the values show up as NaN.

import pandas as pd
from backtesting import Backtest, Strategy
from backtesting.lib import crossover
import yfinance as yf
yf.pdr_override()
import numpy as np
import talib
import pandas_ta as ta

df = pd.read_csv("SPY_3m.csv", index_col='Datetime', parse_dates=True)
df=df[df.Volume!=0]
df.ta.tmo(append=True)

class TMO(Strategy):
    tmo_length = 14
    calc_length = 5
    smooth_length = 3
    zero = 0
    sma_window2 = 29
    def init(self):
        self.tmo = self.I(ta.tmo, close=self.data.Close, open=self.data.Open,
                      tmo_length=self.tmo_length, calc_length=self.calc_length, smooth_length=self.smooth_length)
        self.sma2 = self.I(talib.SMA, self.data.Close, self.sma_window2)
        self.Buy_position_open = False
        self.Sell_position_open = False
    def next(self):
        if crossover(self.tmo, self.zero):
            self.buy(size=0.5)
            self.Buy_position_open = True
        if crossover(self.sma2, self.data.Close) and self.Buy_position_open:
            self.position.close()
            self.Buy_position_open = False     
        if crossover(self.zero, self.tmo):
            self.sell(size=0.5)
            self.Sell_position_open = True 
        if crossover(self.data.Close, self.sma2) and self.Sell_position_open:
            self.position.close()
            self.Sell_position_open = False

bt = Backtest(df, TMO, cash=900_000, exclusive_orders=True)
stats = bt.run()
stats

I get this error popping up: RuntimeError: Indicator "tmo(C,O,14,5,3)" errored with exception: tmo() missing 1 required positional argument: 'open_'

When I change the column using this: df = df.rename(columns={'Open': 'open_'}) # Rename 'Open' column to 'open_' I get error saying pandas dataframe only takes the "Open" and not "open_"

azimgiant avatar Feb 08 '24 17:02 azimgiant

@azimgiant

So you were able to install the development version via git?

To avoid confusion with Python's keyword open, I used open_ instead. So the parameter keyword is open_= and not open=.

Should be this if calling with named parameters:

self.tmo = self.I(ta.tmo, close=self.data.Close, open_=self.data.Open,
                      tmo_length=self.tmo_length, calc_length=self.calc_length, smooth_length=self.smooth_length)

Don't forget to also use: help(ta.tmo). When in doubt, check the source.

KJ

twopirllc avatar Feb 08 '24 19:02 twopirllc

@twopirllc

I was able to install the development version. Watched a Youtube video on how to install git and it worked. I'm not sure what's causing the problem here. This hasn't happened for other indicators maybe because this isn't on the main library. When I changed my code to what you suggested this is the error I receive:

ValueError: Indicators must return (optionally a tuple of) numpy.arrays of same length as data (data shape: (32380,); indicator "tmo(C,O,14,5,3)"shape: , returned value: None)

I saw someone run into a similar issue on Stack Overflow and I used there solution this is the updated code:

self.tmo = self.I(ta.tmo, close=pd.Series(self.data.Close), open_=pd.Series(self.data.Open), tmo_length=self.tmo_length, calc_length=self.calc_length, smooth_length=self.smooth_length)

I get no error when using the above code however after running the stats all the results show up as NaN:

Start 2022-11-07 09:30:00 End 2023-11-03 15:57:00 Duration 361 days 06:27:00 Exposure Time [%] 0.0 Equity Final [$] 900000.0 Equity Peak [$] 900000.0 Return [%] 0.0 Buy & Hold Return [%] 16.517008 Return (Ann.) [%] 0.0 Volatility (Ann.) [%] 0.0 Sharpe Ratio NaN Sortino Ratio NaN Calmar Ratio NaN Max. Drawdown [%] -0.0 Avg. Drawdown [%] NaN Max. Drawdown Duration NaN Avg. Drawdown Duration NaN

Trades 0

Win Rate [%] NaN Best Trade [%] NaN Worst Trade [%] NaN Avg. Trade [%] NaN Max. Trade Duration NaN Avg. Trade Duration NaN Profit Factor NaN Expectancy [%] NaN SQN NaN _strategy TMO _equity_curve ... _trades Empty DataFrame dtype: object

azimgiant avatar Feb 08 '24 20:02 azimgiant

@azimgiant

Since your a beginner and Pandas is used everywhere, I recommend becoming more familiar with this popular tool starting here.

In short, help(ta.tmo) says that it returns a DataFrame with four columns: main, smooth, main momentum, smooth momentum. Your crossover condition is trying to compare 4 values with 0:

    if crossover(self.tmo, self.zero):

and Pandas does not know how to do that, so you have to isolate the column you need. I am assuming the first column: main.

Additionally, I do not know what crossover() takes for it's arguments, two values, two Series, or a value and a Series/array or a Series/array and a value?

If you need the first column (a Series):

    if crossover(self.tmo.iloc[:,0], self.zero):

Or the first column and last value for (a Value):

    if crossover(self.tmo.iloc[-1,0], self.zero):

Lastly I do not know the backtesting package, so any particular details or issues you should bring to their attention.

Hope this helps!

twopirllc avatar Feb 09 '24 19:02 twopirllc

Hello @azimgiant,

I assume by no response that the solution provided was sufficient. Thus I will be closing this issue in a few days.

Kind Regards, KJ

twopirllc avatar Feb 17 '24 20:02 twopirllc