|
@@ -12,11 +12,8 @@ from src.config.config import Config
|
|
|
from src.clients.hyperliquid_client import HyperliquidClient
|
|
|
from src.notifications.notification_manager import NotificationManager
|
|
|
|
|
|
-try:
|
|
|
- import talib
|
|
|
-except ImportError:
|
|
|
- logging.error("talib is required for RSI calculations. Install with: pip install talib")
|
|
|
- raise
|
|
|
+# Using pandas/numpy for RSI calculation instead of TA-Lib to avoid installation issues
|
|
|
+import pandas as pd
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
@@ -52,6 +49,68 @@ class RsiMonitor:
|
|
|
|
|
|
logger.info(f"🔧 RSI Monitor initialized: {self.timeframe} timeframe, RSI({self.rsi_period}), SMA({self.rsi_sma_period})")
|
|
|
|
|
|
+ def _calculate_rsi(self, prices: np.ndarray, period: int) -> np.ndarray:
|
|
|
+ """
|
|
|
+ Calculate RSI using pandas/numpy implementation.
|
|
|
+
|
|
|
+ Args:
|
|
|
+ prices: Array of price values
|
|
|
+ period: RSI calculation period
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ Array of RSI values
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ # Convert to pandas Series for easier calculation
|
|
|
+ prices_series = pd.Series(prices)
|
|
|
+
|
|
|
+ # Calculate price changes
|
|
|
+ delta = prices_series.diff()
|
|
|
+
|
|
|
+ # Separate gains and losses
|
|
|
+ gains = delta.where(delta > 0, 0)
|
|
|
+ losses = -delta.where(delta < 0, 0)
|
|
|
+
|
|
|
+ # Calculate rolling averages of gains and losses
|
|
|
+ avg_gains = gains.rolling(window=period, min_periods=period).mean()
|
|
|
+ avg_losses = losses.rolling(window=period, min_periods=period).mean()
|
|
|
+
|
|
|
+ # Calculate RS (Relative Strength)
|
|
|
+ rs = avg_gains / avg_losses
|
|
|
+
|
|
|
+ # Calculate RSI
|
|
|
+ rsi = 100 - (100 / (1 + rs))
|
|
|
+
|
|
|
+ return rsi.values
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"❌ Error calculating RSI: {e}")
|
|
|
+ return np.full(len(prices), np.nan)
|
|
|
+
|
|
|
+ def _calculate_sma(self, values: np.ndarray, period: int) -> np.ndarray:
|
|
|
+ """
|
|
|
+ Calculate Simple Moving Average using pandas.
|
|
|
+
|
|
|
+ Args:
|
|
|
+ values: Array of values
|
|
|
+ period: SMA calculation period
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ Array of SMA values
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ # Convert to pandas Series
|
|
|
+ values_series = pd.Series(values)
|
|
|
+
|
|
|
+ # Calculate rolling mean
|
|
|
+ sma = values_series.rolling(window=period, min_periods=period).mean()
|
|
|
+
|
|
|
+ return sma.values
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"❌ Error calculating SMA: {e}")
|
|
|
+ return np.full(len(values), np.nan)
|
|
|
+
|
|
|
async def has_new_candle(self, symbol: str) -> bool:
|
|
|
"""
|
|
|
Check if there's a new candle for the given symbol and timeframe.
|
|
@@ -122,11 +181,11 @@ class RsiMonitor:
|
|
|
# Extract close prices
|
|
|
close_prices = np.array([float(candle[4]) for candle in candles]) # candle[4] is close price
|
|
|
|
|
|
- # Calculate RSI using talib
|
|
|
- rsi_values = talib.RSI(close_prices, timeperiod=self.rsi_period)
|
|
|
+ # Calculate RSI using pandas/numpy implementation
|
|
|
+ rsi_values = self._calculate_rsi(close_prices, self.rsi_period)
|
|
|
|
|
|
# Calculate RSI SMA (Simple Moving Average of RSI)
|
|
|
- rsi_sma_values = talib.SMA(rsi_values, timeperiod=self.rsi_sma_period)
|
|
|
+ rsi_sma_values = self._calculate_sma(rsi_values, self.rsi_sma_period)
|
|
|
|
|
|
# Get the latest values (skip NaN values)
|
|
|
valid_indices = ~(np.isnan(rsi_values) | np.isnan(rsi_sma_values))
|