base_trailing_indicator.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import logging
  2. from abc import ABC, abstractmethod
  3. from decimal import Decimal
  4. import numpy as np
  5. from util.ring_buffer import RingBuffer
  6. class BaseTrailingIndicator(ABC):
  7. def __init__(self, sampling_length: int = 30, processing_length: int = 15):
  8. self._sampling_buffer = RingBuffer(sampling_length)
  9. self._processing_buffer = RingBuffer(processing_length)
  10. self._samples_length = 0
  11. def add_sample(self, value: float):
  12. self._sampling_buffer.add_value(value)
  13. indicator_value = self._indicator_calculation()
  14. self._processing_buffer.add_value(indicator_value)
  15. @abstractmethod
  16. def _indicator_calculation(self) -> float:
  17. raise NotImplementedError
  18. def _processing_calculation(self) -> float:
  19. """
  20. Processing of the processing buffer to return final value.
  21. Default behavior is buffer average
  22. """
  23. return np.mean(self._processing_buffer.get_as_numpy_array())
  24. @property
  25. def current_value(self) -> Decimal:
  26. return Decimal(self._processing_calculation())
  27. @property
  28. def is_sampling_buffer_full(self) -> bool:
  29. return self._sampling_buffer.is_full
  30. @property
  31. def is_processing_buffer_full(self) -> bool:
  32. return self._processing_buffer.is_full
  33. @property
  34. def is_sampling_buffer_changed(self) -> bool:
  35. buffer_len = len(self._sampling_buffer.get_as_numpy_array())
  36. is_changed = self._samples_length != buffer_len
  37. self._samples_length = buffer_len
  38. return is_changed
  39. @property
  40. def sampling_length(self) -> int:
  41. return self._sampling_buffer.length
  42. @sampling_length.setter
  43. def sampling_length(self, value):
  44. self._sampling_buffer.length = value
  45. @property
  46. def processing_length(self) -> int:
  47. return self._processing_buffer.length
  48. @processing_length.setter
  49. def processing_length(self, value):
  50. self._processing_buffer.length = value