Coverage for source/indicators/macd_indicator_handler.py: 35%

17 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-08-01 20:51 +0000

1# indicators/macd_indicator_handler.py 

2 

3# global imports 

4import pandas as pd 

5 

6# local imports 

7from source.indicators import ExponentialMovingAverageIndicatorHandler, IndicatorHandlerBase 

8 

9class MovingAverageConvergenceDivergenceIndicatorHandler(IndicatorHandlerBase): 

10 """ 

11 Implements Moving Average Convergence Divergence (MACD) indicator. It shows the relationship 

12 between two moving averages of an asset's price. 

13 """ 

14 

15 def __init__(self, fast_period_window_size: int = 12, slow_period_window_size: int = 26, 

16 signal_period_window_size: int = 9) -> None: 

17 """ 

18 Class constructor. 

19 

20 Parameters: 

21 fast_period_window_size (int): Length of the fast EMA window. 

22 slow_period_window_size (int): Length of the slow EMA window. 

23 signal_period_window_size (int): Length of the signal line window. 

24 """ 

25 

26 self.__fast_period_window_size = fast_period_window_size 

27 self.__slow_period_window_size = slow_period_window_size 

28 self.__signal_period_window_size = signal_period_window_size 

29 

30 def calculate(self, data: pd.DataFrame) -> pd.DataFrame: 

31 """ 

32 Calculates Moving Average Convergence Divergence (MACD) indicator values for given data. 

33 

34 Parameters: 

35 data (pd.DataFrame): Data frame with input data. 

36 

37 Returns: 

38 (pd.DataFrame): Output data with calculated MACD values. 

39 """ 

40 

41 fast_ema = ExponentialMovingAverageIndicatorHandler(self.__fast_period_window_size).calculate(data) 

42 slow_ema = ExponentialMovingAverageIndicatorHandler(self.__slow_period_window_size).calculate(data) 

43 

44 macd_data_df = pd.DataFrame(index = data.index) 

45 macd_data_df['macd_line'] = fast_ema['ema'] - slow_ema['ema'] 

46 macd_data_df['macd_sig'] = macd_data_df['macd_line']. \ 

47 ewm(span = self.__signal_period_window_size, adjust = False).mean() 

48 macd_data_df['macd_hist'] = macd_data_df['macd_line'] - macd_data_df['macd_sig'] 

49 

50 return macd_data_df 

51 

52 def can_be_normalized(self) -> bool: 

53 """ 

54 Checks if the indicator can be normalized. 

55 

56 Returns: 

57 (bool): True if the indicator can be normalized, False otherwise. 

58 """ 

59 

60 return True