Skip to content

Commit a472ea4

Browse files
committed
SmootherFactory, SmoothedIndicator and SOBV
1 parent ed5e0e1 commit a472ea4

File tree

4 files changed

+71
-53
lines changed

4 files changed

+71
-53
lines changed

talipp/indicators/SOBV.py

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,16 @@
1-
from typing import List, Any
2-
3-
from talipp.indicator_util import has_valid_values
4-
from talipp.indicators.Indicator import Indicator, InputModifierType
51
from talipp.indicators.OBV import OBV
6-
from talipp.input import SamplingPeriodType
7-
from talipp.ohlcv import OHLCV
8-
9-
10-
class SOBV(Indicator):
11-
"""Smoothed On Balance Volume.
12-
13-
Input type: [OHLCV][talipp.ohlcv.OHLCV]
14-
15-
Output type: `float`
16-
17-
Args:
18-
period: Moving average period.
19-
input_values: List of input values.
20-
input_indicator: Input indicator.
21-
input_modifier: Input modifier.
22-
input_sampling: Input sampling type.
23-
"""
24-
25-
def __init__(self, period: int,
26-
input_values: List[OHLCV] = None,
27-
input_indicator: Indicator = None,
28-
input_modifier: InputModifierType = None,
29-
input_sampling: SamplingPeriodType = None):
30-
super().__init__(input_modifier=input_modifier,
31-
input_sampling=input_sampling)
32-
33-
self.period = period
34-
35-
self.obv = OBV()
36-
self.add_sub_indicator(self.obv)
37-
38-
self.initialize(input_values, input_indicator)
39-
40-
def _calculate_new_value(self) -> Any:
41-
if not has_valid_values(self.obv, self.period):
42-
return None
43-
44-
return sum(self.obv[-self.period:]) / float(self.period)
2+
from talipp.indicators.Smoother import SmootherFactory
3+
from talipp.ma import MAType
4+
5+
6+
"""Smoothed On Balance Volume.
7+
Input type: [OHLCV][talipp.ohlcv.OHLCV]
8+
Output type: `float`
9+
Args:
10+
period: Moving average period.
11+
input_values: List of input values.
12+
input_indicator: Input indicator.
13+
input_modifier: Input modifier.
14+
input_sampling: Input sampling type.
15+
"""
16+
SOBV = SmootherFactory.get_smoother(OBV, MAType.SMA)

talipp/indicators/Smoother.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
from typing import Any
2+
from talipp.indicators.Indicator import Indicator
3+
from talipp.ma import MAFactory, MAType
4+
5+
6+
class SmoothedIndicator(Indicator):
7+
def __init__(self, indicator_class, ma_type: MAType):
8+
super().__init__()
9+
10+
self.indicator_class = indicator_class
11+
self.ma_type = ma_type
12+
13+
def __call__(
14+
self,
15+
smoothing_period: int,
16+
input_values=None,
17+
input_indicator=None,
18+
*args: Any,
19+
**kwargs
20+
) -> Any:
21+
self.ma = MAFactory.get_ma(self.ma_type, smoothing_period)
22+
23+
self.internal_indicator = self.indicator_class(*args, **kwargs)
24+
self.add_sub_indicator(self.internal_indicator)
25+
26+
self.initialize(input_values, input_indicator)
27+
28+
return self
29+
30+
def _calculate_new_value(self) -> Any:
31+
self.ma.add(self.internal_indicator.output_values)
32+
return self.ma.output_values[-1]
33+
34+
35+
class SmootherFactory:
36+
"""Smoother factory."""
37+
38+
@staticmethod
39+
def get_smoother(indicator_class, ma_type: MAType = MAType.SMA):
40+
"""
41+
Return a smoother indicator
42+
43+
Args:
44+
indicator_class: indicator class
45+
smoothing_period: Smoothing period.
46+
ma_type: Moving average type.
47+
"""
48+
return SmoothedIndicator(indicator_class, ma_type)

test/TalippTest.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def assertIndicatorUpdate(self, indicator: Indicator, iterations_no: int = 20):
3131

3232
indicator.update(last_input_value)
3333

34-
self.assertEqual(last_indicator_value, indicator[-1])
34+
self.assertAlmostEqual(last_indicator_value, indicator[-1], places = 5)
3535

3636
def assertIndicatorDelete(self, indicator: Indicator, iterations_no: int = 20):
3737
last_indicator_value = indicator[-1]
@@ -48,13 +48,13 @@ def assertIndicatorDelete(self, indicator: Indicator, iterations_no: int = 20):
4848
indicator.remove()
4949

5050
# verify that adding and then removing X input values returns the original output value
51-
self.assertEqual(last_indicator_value, indicator[-1])
51+
self.assertAlmostEqual(last_indicator_value, indicator[-1], places = 5)
5252

5353
# delete the original last input value and add it back and check the original last output value is returned
5454
indicator.remove()
5555
indicator.add(last_input_value)
5656

57-
self.assertEqual(last_indicator_value, indicator[-1])
57+
self.assertAlmostEqual(last_indicator_value, indicator[-1], places = 5)
5858

5959
def assertIndicatorPurgeOldest(self, indicator: Indicator):
6060
# purge oldest 5 values

test/test_SOBV.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@ def setUp(self) -> None:
1010
self.input_values = list(TalippTest.OHLCV_TMPL)
1111

1212
def test_init(self):
13-
ind = SOBV(20, self.input_values)
13+
ind = SOBV(20, input_values=self.input_values)
1414

15-
print(ind)
16-
17-
self.assertAlmostEqual(ind[-3], 90.868499, places = 5)
18-
self.assertAlmostEqual(ind[-2], 139.166499, places = 5)
19-
self.assertAlmostEqual(ind[-1], 187.558499, places = 5)
15+
self.assertAlmostEqual(ind[-3], 90.868499, places=5)
16+
self.assertAlmostEqual(ind[-2], 139.166499, places=5)
17+
self.assertAlmostEqual(ind[-1], 187.558499, places=5)
2018

2119
def test_update(self):
2220
self.assertIndicatorUpdate(SOBV(20, self.input_values))
@@ -28,5 +26,5 @@ def test_purge_oldest(self):
2826
self.assertIndicatorPurgeOldest(SOBV(20, self.input_values))
2927

3028

31-
if __name__ == '__main__':
29+
if __name__ == "__main__":
3230
unittest.main()

0 commit comments

Comments
 (0)