From af51b62d491674764736f7092469859b876bef6c Mon Sep 17 00:00:00 2001 From: "Bobby (aider)" Date: Thu, 13 Feb 2025 23:11:06 -0800 Subject: [PATCH] fix: Handle pandas-ta indicators with fillna and numpy conversion --- src/pages/backtesting/backtesting_page.py | 27 ++++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/pages/backtesting/backtesting_page.py b/src/pages/backtesting/backtesting_page.py index caad559..10ba0fa 100644 --- a/src/pages/backtesting/backtesting_page.py +++ b/src/pages/backtesting/backtesting_page.py @@ -18,24 +18,25 @@ class DynamicStrategy(Strategy): # Initialize all selected indicators for ind_name, ind_config in self.indicator_configs.items(): if ind_config['type'] == 'SMA': - self.indicators[ind_name] = self.I(lambda x: ta.sma(x, length=ind_config['params']['length']), self.data.Close) + self.indicators[ind_name] = self.I(lambda x: ta.sma(x, length=int(ind_config['params']['length'])).fillna(0).to_numpy(), self.data.Close) elif ind_config['type'] == 'EMA': - self.indicators[ind_name] = self.I(lambda x: ta.ema(x, length=ind_config['params']['length']), self.data.Close) + self.indicators[ind_name] = self.I(lambda x: ta.ema(x, length=int(ind_config['params']['length'])).fillna(0).to_numpy(), self.data.Close) elif ind_config['type'] == 'RSI': - self.indicators[ind_name] = self.I(lambda x: ta.rsi(x, length=ind_config['params']['length']), self.data.Close) + self.indicators[ind_name] = self.I(lambda x: ta.rsi(x, length=int(ind_config['params']['length'])).fillna(0).to_numpy(), self.data.Close) elif ind_config['type'] == 'MACD': - fast = ind_config['params']['fast'] - slow = ind_config['params']['slow'] - signal = ind_config['params']['signal'] - self.indicators[f"{ind_name}_macd"] = self.I(lambda x: ta.macd(x, fast=fast, slow=slow, signal=signal).iloc[:,0], self.data.Close) - self.indicators[f"{ind_name}_signal"] = self.I(lambda x: ta.macd(x, fast=fast, slow=slow, signal=signal).iloc[:,2], self.data.Close) + fast = int(ind_config['params']['fast']) + slow = int(ind_config['params']['slow']) + signal = int(ind_config['params']['signal']) + macd = self.I(lambda x: ta.macd(x, fast=fast, slow=slow, signal=signal), self.data.Close) + self.indicators[f"{ind_name}_macd"] = self.I(lambda x: x.iloc[:,0].fillna(0).to_numpy(), macd) + self.indicators[f"{ind_name}_signal"] = self.I(lambda x: x.iloc[:,2].fillna(0).to_numpy(), macd) elif ind_config['type'] == 'BB': - length = ind_config['params']['length'] - std = ind_config['params']['std'] + length = int(ind_config['params']['length']) + std = float(ind_config['params']['std']) bbands = self.I(lambda x: ta.bbands(x, length=length, std=std), self.data.Close) - self.indicators[f"{ind_name}_upper"] = self.I(lambda x: x.iloc[:,0], bbands) - self.indicators[f"{ind_name}_middle"] = self.I(lambda x: x.iloc[:,1], bbands) - self.indicators[f"{ind_name}_lower"] = self.I(lambda x: x.iloc[:,2], bbands) + self.indicators[f"{ind_name}_upper"] = self.I(lambda x: x.iloc[:,0].fillna(0).to_numpy(), bbands) + self.indicators[f"{ind_name}_middle"] = self.I(lambda x: x.iloc[:,1].fillna(0).to_numpy(), bbands) + self.indicators[f"{ind_name}_lower"] = self.I(lambda x: x.iloc[:,2].fillna(0).to_numpy(), bbands) def next(self): # Simple example strategy - should be customized based on user input