akshare-one 0.3.7__py3-none-any.whl → 0.3.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- akshare_one/__init__.py +214 -214
- akshare_one/eastmoney/client.py +80 -80
- akshare_one/eastmoney/utils.py +102 -102
- akshare_one/indicators.py +395 -395
- akshare_one/modules/cache.py +30 -27
- akshare_one/modules/financial/base.py +27 -27
- akshare_one/modules/financial/eastmoney_direct.py +183 -183
- akshare_one/modules/financial/factory.py +46 -46
- akshare_one/modules/financial/sina.py +292 -292
- akshare_one/modules/historical/base.py +47 -47
- akshare_one/modules/historical/eastmoney.py +236 -236
- akshare_one/modules/historical/eastmoney_direct.py +79 -78
- akshare_one/modules/historical/factory.py +48 -48
- akshare_one/modules/historical/sina.py +250 -250
- akshare_one/modules/indicators/base.py +158 -158
- akshare_one/modules/indicators/factory.py +33 -33
- akshare_one/modules/indicators/simple.py +9 -8
- akshare_one/modules/indicators/talib.py +263 -263
- akshare_one/modules/info/base.py +25 -25
- akshare_one/modules/info/eastmoney.py +51 -51
- akshare_one/modules/info/factory.py +44 -44
- akshare_one/modules/insider/base.py +28 -28
- akshare_one/modules/insider/factory.py +44 -44
- akshare_one/modules/insider/xueqiu.py +110 -110
- akshare_one/modules/news/base.py +22 -22
- akshare_one/modules/news/eastmoney.py +43 -43
- akshare_one/modules/news/factory.py +44 -44
- akshare_one/modules/realtime/base.py +27 -27
- akshare_one/modules/realtime/eastmoney.py +53 -53
- akshare_one/modules/realtime/eastmoney_direct.py +36 -36
- akshare_one/modules/realtime/factory.py +71 -48
- akshare_one/modules/realtime/xueqiu.py +57 -57
- akshare_one/modules/utils.py +10 -10
- akshare_one/py.typed +0 -0
- {akshare_one-0.3.7.dist-info → akshare_one-0.3.9.dist-info}/METADATA +72 -74
- akshare_one-0.3.9.dist-info/RECORD +38 -0
- akshare_one-0.3.9.dist-info/WHEEL +4 -0
- akshare_one-0.3.7.dist-info/RECORD +0 -39
- akshare_one-0.3.7.dist-info/WHEEL +0 -5
- akshare_one-0.3.7.dist-info/licenses/LICENSE +0 -21
- akshare_one-0.3.7.dist-info/top_level.txt +0 -1
@@ -1,158 +1,158 @@
|
|
1
|
-
from abc import ABC, abstractmethod
|
2
|
-
import pandas as pd
|
3
|
-
|
4
|
-
|
5
|
-
class BaseIndicatorCalculator(ABC):
|
6
|
-
"""Base class for indicator calculators"""
|
7
|
-
|
8
|
-
@abstractmethod
|
9
|
-
def calculate_sma(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
10
|
-
pass
|
11
|
-
|
12
|
-
@abstractmethod
|
13
|
-
def calculate_ema(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
14
|
-
pass
|
15
|
-
|
16
|
-
@abstractmethod
|
17
|
-
def calculate_rsi(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
18
|
-
pass
|
19
|
-
|
20
|
-
@abstractmethod
|
21
|
-
def calculate_macd(
|
22
|
-
self, df: pd.DataFrame, fast: int, slow: int, signal: int
|
23
|
-
) -> pd.DataFrame:
|
24
|
-
pass
|
25
|
-
|
26
|
-
@abstractmethod
|
27
|
-
def calculate_bollinger_bands(
|
28
|
-
self, df: pd.DataFrame, window: int, std: int
|
29
|
-
) -> pd.DataFrame:
|
30
|
-
pass
|
31
|
-
|
32
|
-
@abstractmethod
|
33
|
-
def calculate_stoch(
|
34
|
-
self, df: pd.DataFrame, window: int, smooth_d: int, smooth_k: int
|
35
|
-
) -> pd.DataFrame:
|
36
|
-
pass
|
37
|
-
|
38
|
-
@abstractmethod
|
39
|
-
def calculate_atr(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
40
|
-
pass
|
41
|
-
|
42
|
-
@abstractmethod
|
43
|
-
def calculate_cci(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
44
|
-
pass
|
45
|
-
|
46
|
-
@abstractmethod
|
47
|
-
def calculate_adx(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
48
|
-
pass
|
49
|
-
|
50
|
-
@abstractmethod
|
51
|
-
def calculate_willr(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
52
|
-
pass
|
53
|
-
|
54
|
-
@abstractmethod
|
55
|
-
def calculate_ad(self, df: pd.DataFrame) -> pd.DataFrame:
|
56
|
-
pass
|
57
|
-
|
58
|
-
@abstractmethod
|
59
|
-
def calculate_adosc(
|
60
|
-
self, df: pd.DataFrame, fast_period: int, slow_period: int
|
61
|
-
) -> pd.DataFrame:
|
62
|
-
pass
|
63
|
-
|
64
|
-
@abstractmethod
|
65
|
-
def calculate_obv(self, df: pd.DataFrame) -> pd.DataFrame:
|
66
|
-
pass
|
67
|
-
|
68
|
-
@abstractmethod
|
69
|
-
def calculate_mom(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
70
|
-
pass
|
71
|
-
|
72
|
-
@abstractmethod
|
73
|
-
def calculate_sar(
|
74
|
-
self, df: pd.DataFrame, acceleration: float, maximum: float
|
75
|
-
) -> pd.DataFrame:
|
76
|
-
pass
|
77
|
-
|
78
|
-
@abstractmethod
|
79
|
-
def calculate_tsf(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
80
|
-
pass
|
81
|
-
|
82
|
-
@abstractmethod
|
83
|
-
def calculate_apo(
|
84
|
-
self, df: pd.DataFrame, fast_period: int, slow_period: int, ma_type: int
|
85
|
-
) -> pd.DataFrame:
|
86
|
-
pass
|
87
|
-
|
88
|
-
@abstractmethod
|
89
|
-
def calculate_aroon(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
90
|
-
pass
|
91
|
-
|
92
|
-
@abstractmethod
|
93
|
-
def calculate_aroonosc(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
94
|
-
pass
|
95
|
-
|
96
|
-
@abstractmethod
|
97
|
-
def calculate_bop(self, df: pd.DataFrame) -> pd.DataFrame:
|
98
|
-
pass
|
99
|
-
|
100
|
-
@abstractmethod
|
101
|
-
def calculate_cmo(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
102
|
-
pass
|
103
|
-
|
104
|
-
@abstractmethod
|
105
|
-
def calculate_dx(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
106
|
-
pass
|
107
|
-
|
108
|
-
@abstractmethod
|
109
|
-
def calculate_mfi(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
110
|
-
pass
|
111
|
-
|
112
|
-
@abstractmethod
|
113
|
-
def calculate_minus_di(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
114
|
-
pass
|
115
|
-
|
116
|
-
@abstractmethod
|
117
|
-
def calculate_minus_dm(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
118
|
-
pass
|
119
|
-
|
120
|
-
@abstractmethod
|
121
|
-
def calculate_plus_di(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
122
|
-
pass
|
123
|
-
|
124
|
-
@abstractmethod
|
125
|
-
def calculate_plus_dm(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
126
|
-
pass
|
127
|
-
|
128
|
-
@abstractmethod
|
129
|
-
def calculate_ppo(
|
130
|
-
self, df: pd.DataFrame, fast_period: int, slow_period: int, ma_type: int
|
131
|
-
) -> pd.DataFrame:
|
132
|
-
pass
|
133
|
-
|
134
|
-
@abstractmethod
|
135
|
-
def calculate_roc(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
136
|
-
pass
|
137
|
-
|
138
|
-
@abstractmethod
|
139
|
-
def calculate_rocp(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
140
|
-
pass
|
141
|
-
|
142
|
-
@abstractmethod
|
143
|
-
def calculate_rocr(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
144
|
-
pass
|
145
|
-
|
146
|
-
@abstractmethod
|
147
|
-
def calculate_rocr100(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
148
|
-
pass
|
149
|
-
|
150
|
-
@abstractmethod
|
151
|
-
def calculate_trix(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
152
|
-
pass
|
153
|
-
|
154
|
-
@abstractmethod
|
155
|
-
def calculate_ultosc(
|
156
|
-
self, df: pd.DataFrame, window1: int, window2: int, window3: int
|
157
|
-
) -> pd.DataFrame:
|
158
|
-
pass
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
import pandas as pd
|
3
|
+
|
4
|
+
|
5
|
+
class BaseIndicatorCalculator(ABC):
|
6
|
+
"""Base class for indicator calculators"""
|
7
|
+
|
8
|
+
@abstractmethod
|
9
|
+
def calculate_sma(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
10
|
+
pass
|
11
|
+
|
12
|
+
@abstractmethod
|
13
|
+
def calculate_ema(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
14
|
+
pass
|
15
|
+
|
16
|
+
@abstractmethod
|
17
|
+
def calculate_rsi(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
18
|
+
pass
|
19
|
+
|
20
|
+
@abstractmethod
|
21
|
+
def calculate_macd(
|
22
|
+
self, df: pd.DataFrame, fast: int, slow: int, signal: int
|
23
|
+
) -> pd.DataFrame:
|
24
|
+
pass
|
25
|
+
|
26
|
+
@abstractmethod
|
27
|
+
def calculate_bollinger_bands(
|
28
|
+
self, df: pd.DataFrame, window: int, std: int
|
29
|
+
) -> pd.DataFrame:
|
30
|
+
pass
|
31
|
+
|
32
|
+
@abstractmethod
|
33
|
+
def calculate_stoch(
|
34
|
+
self, df: pd.DataFrame, window: int, smooth_d: int, smooth_k: int
|
35
|
+
) -> pd.DataFrame:
|
36
|
+
pass
|
37
|
+
|
38
|
+
@abstractmethod
|
39
|
+
def calculate_atr(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
40
|
+
pass
|
41
|
+
|
42
|
+
@abstractmethod
|
43
|
+
def calculate_cci(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
44
|
+
pass
|
45
|
+
|
46
|
+
@abstractmethod
|
47
|
+
def calculate_adx(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
48
|
+
pass
|
49
|
+
|
50
|
+
@abstractmethod
|
51
|
+
def calculate_willr(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
52
|
+
pass
|
53
|
+
|
54
|
+
@abstractmethod
|
55
|
+
def calculate_ad(self, df: pd.DataFrame) -> pd.DataFrame:
|
56
|
+
pass
|
57
|
+
|
58
|
+
@abstractmethod
|
59
|
+
def calculate_adosc(
|
60
|
+
self, df: pd.DataFrame, fast_period: int, slow_period: int
|
61
|
+
) -> pd.DataFrame:
|
62
|
+
pass
|
63
|
+
|
64
|
+
@abstractmethod
|
65
|
+
def calculate_obv(self, df: pd.DataFrame) -> pd.DataFrame:
|
66
|
+
pass
|
67
|
+
|
68
|
+
@abstractmethod
|
69
|
+
def calculate_mom(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
70
|
+
pass
|
71
|
+
|
72
|
+
@abstractmethod
|
73
|
+
def calculate_sar(
|
74
|
+
self, df: pd.DataFrame, acceleration: float, maximum: float
|
75
|
+
) -> pd.DataFrame:
|
76
|
+
pass
|
77
|
+
|
78
|
+
@abstractmethod
|
79
|
+
def calculate_tsf(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
80
|
+
pass
|
81
|
+
|
82
|
+
@abstractmethod
|
83
|
+
def calculate_apo(
|
84
|
+
self, df: pd.DataFrame, fast_period: int, slow_period: int, ma_type: int
|
85
|
+
) -> pd.DataFrame:
|
86
|
+
pass
|
87
|
+
|
88
|
+
@abstractmethod
|
89
|
+
def calculate_aroon(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
90
|
+
pass
|
91
|
+
|
92
|
+
@abstractmethod
|
93
|
+
def calculate_aroonosc(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
94
|
+
pass
|
95
|
+
|
96
|
+
@abstractmethod
|
97
|
+
def calculate_bop(self, df: pd.DataFrame) -> pd.DataFrame:
|
98
|
+
pass
|
99
|
+
|
100
|
+
@abstractmethod
|
101
|
+
def calculate_cmo(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
102
|
+
pass
|
103
|
+
|
104
|
+
@abstractmethod
|
105
|
+
def calculate_dx(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
106
|
+
pass
|
107
|
+
|
108
|
+
@abstractmethod
|
109
|
+
def calculate_mfi(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
110
|
+
pass
|
111
|
+
|
112
|
+
@abstractmethod
|
113
|
+
def calculate_minus_di(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
114
|
+
pass
|
115
|
+
|
116
|
+
@abstractmethod
|
117
|
+
def calculate_minus_dm(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
118
|
+
pass
|
119
|
+
|
120
|
+
@abstractmethod
|
121
|
+
def calculate_plus_di(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
122
|
+
pass
|
123
|
+
|
124
|
+
@abstractmethod
|
125
|
+
def calculate_plus_dm(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
126
|
+
pass
|
127
|
+
|
128
|
+
@abstractmethod
|
129
|
+
def calculate_ppo(
|
130
|
+
self, df: pd.DataFrame, fast_period: int, slow_period: int, ma_type: int
|
131
|
+
) -> pd.DataFrame:
|
132
|
+
pass
|
133
|
+
|
134
|
+
@abstractmethod
|
135
|
+
def calculate_roc(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
136
|
+
pass
|
137
|
+
|
138
|
+
@abstractmethod
|
139
|
+
def calculate_rocp(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
140
|
+
pass
|
141
|
+
|
142
|
+
@abstractmethod
|
143
|
+
def calculate_rocr(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
144
|
+
pass
|
145
|
+
|
146
|
+
@abstractmethod
|
147
|
+
def calculate_rocr100(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
148
|
+
pass
|
149
|
+
|
150
|
+
@abstractmethod
|
151
|
+
def calculate_trix(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
152
|
+
pass
|
153
|
+
|
154
|
+
@abstractmethod
|
155
|
+
def calculate_ultosc(
|
156
|
+
self, df: pd.DataFrame, window1: int, window2: int, window3: int
|
157
|
+
) -> pd.DataFrame:
|
158
|
+
pass
|
@@ -1,33 +1,33 @@
|
|
1
|
-
from .base import BaseIndicatorCalculator
|
2
|
-
from .simple import SimpleIndicatorCalculator
|
3
|
-
|
4
|
-
_calculators = {
|
5
|
-
"simple": SimpleIndicatorCalculator,
|
6
|
-
}
|
7
|
-
TALIB_AVAILABLE = False
|
8
|
-
try:
|
9
|
-
from .talib import TalibIndicatorCalculator
|
10
|
-
|
11
|
-
_calculators["talib"] = TalibIndicatorCalculator
|
12
|
-
TALIB_AVAILABLE = True
|
13
|
-
except ImportError:
|
14
|
-
# talib is optional
|
15
|
-
pass
|
16
|
-
|
17
|
-
|
18
|
-
class IndicatorFactory:
|
19
|
-
"""Factory for indicator calculators"""
|
20
|
-
|
21
|
-
@classmethod
|
22
|
-
def get_calculator(cls, calculator_type: str = "talib") -> BaseIndicatorCalculator:
|
23
|
-
"""Get indicator calculator instance
|
24
|
-
|
25
|
-
If talib is not installed, it will fall back to the simple implementation.
|
26
|
-
"""
|
27
|
-
if calculator_type == "talib" and not TALIB_AVAILABLE:
|
28
|
-
calculator_type = "simple"
|
29
|
-
|
30
|
-
calculator_class = _calculators.get(calculator_type)
|
31
|
-
if not calculator_class:
|
32
|
-
raise ValueError(f"Unsupported calculator type: {calculator_type}")
|
33
|
-
return calculator_class()
|
1
|
+
from .base import BaseIndicatorCalculator
|
2
|
+
from .simple import SimpleIndicatorCalculator
|
3
|
+
|
4
|
+
_calculators = {
|
5
|
+
"simple": SimpleIndicatorCalculator,
|
6
|
+
}
|
7
|
+
TALIB_AVAILABLE = False
|
8
|
+
try:
|
9
|
+
from .talib import TalibIndicatorCalculator
|
10
|
+
|
11
|
+
_calculators["talib"] = TalibIndicatorCalculator # type: ignore
|
12
|
+
TALIB_AVAILABLE = True
|
13
|
+
except ImportError:
|
14
|
+
# talib is optional
|
15
|
+
pass
|
16
|
+
|
17
|
+
|
18
|
+
class IndicatorFactory:
|
19
|
+
"""Factory for indicator calculators"""
|
20
|
+
|
21
|
+
@classmethod
|
22
|
+
def get_calculator(cls, calculator_type: str = "talib") -> BaseIndicatorCalculator:
|
23
|
+
"""Get indicator calculator instance
|
24
|
+
|
25
|
+
If talib is not installed, it will fall back to the simple implementation.
|
26
|
+
"""
|
27
|
+
if calculator_type == "talib" and not TALIB_AVAILABLE:
|
28
|
+
calculator_type = "simple"
|
29
|
+
|
30
|
+
calculator_class = _calculators.get(calculator_type)
|
31
|
+
if not calculator_class:
|
32
|
+
raise ValueError(f"Unsupported calculator type: {calculator_type}")
|
33
|
+
return calculator_class()
|
@@ -220,13 +220,14 @@ class SimpleIndicatorCalculator(BaseIndicatorCalculator):
|
|
220
220
|
def calculate_tsf(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
221
221
|
close = df["close"]
|
222
222
|
|
223
|
-
def linear_reg_forecast(y):
|
223
|
+
def linear_reg_forecast(y: np.ndarray) -> float:
|
224
224
|
x = np.arange(1, len(y) + 1)
|
225
225
|
b_num = len(x) * np.sum(x * y) - np.sum(x) * np.sum(y)
|
226
226
|
b_den = len(x) * np.sum(x * x) - np.sum(x) ** 2
|
227
227
|
b = b_num / b_den if b_den != 0 else 0
|
228
228
|
a = np.mean(y) - b * np.mean(x)
|
229
|
-
|
229
|
+
result = a + b * len(y)
|
230
|
+
return float(result)
|
230
231
|
|
231
232
|
tsf = close.rolling(window=window, min_periods=window).apply(
|
232
233
|
linear_reg_forecast, raw=True
|
@@ -267,8 +268,8 @@ class SimpleIndicatorCalculator(BaseIndicatorCalculator):
|
|
267
268
|
|
268
269
|
def calculate_cmo(self, df: pd.DataFrame, window: int) -> pd.DataFrame:
|
269
270
|
close_diff = df["close"].diff(1)
|
270
|
-
sum_up = close_diff.where(close_diff > 0, 0).rolling(window=window).sum()
|
271
|
-
sum_down = -close_diff.where(close_diff < 0, 0).rolling(window=window).sum()
|
271
|
+
sum_up = close_diff.where(close_diff > 0, 0).rolling(window=window).sum() # type: ignore
|
272
|
+
sum_down = -close_diff.where(close_diff < 0, 0).rolling(window=window).sum() # type: ignore
|
272
273
|
cmo = 100 * (sum_up - sum_down) / (sum_up + sum_down).replace(0, np.nan)
|
273
274
|
cmo = cmo.fillna(0)
|
274
275
|
return cmo.to_frame("cmo")
|
@@ -284,8 +285,8 @@ class SimpleIndicatorCalculator(BaseIndicatorCalculator):
|
|
284
285
|
typical_price = (df["high"] + df["low"] + df["close"]) / 3
|
285
286
|
money_flow = typical_price * df["volume"]
|
286
287
|
price_diff = typical_price.diff()
|
287
|
-
positive_mf = money_flow.where(price_diff > 0, 0)
|
288
|
-
negative_mf = money_flow.where(price_diff < 0, 0)
|
288
|
+
positive_mf = money_flow.where(price_diff > 0, 0) # type: ignore
|
289
|
+
negative_mf = money_flow.where(price_diff < 0, 0) # type: ignore
|
289
290
|
positive_mf_sum = positive_mf.rolling(window=window).sum()
|
290
291
|
negative_mf_sum = negative_mf.rolling(window=window).sum()
|
291
292
|
money_ratio = positive_mf_sum / negative_mf_sum.replace(0, np.nan)
|
@@ -304,7 +305,7 @@ class SimpleIndicatorCalculator(BaseIndicatorCalculator):
|
|
304
305
|
low = df["low"]
|
305
306
|
up_move = high.diff()
|
306
307
|
down_move = -low.diff()
|
307
|
-
minus_dm = down_move.where((down_move > up_move) & (down_move > 0), 0)
|
308
|
+
minus_dm = down_move.where((down_move > up_move) & (down_move > 0), 0) # type: ignore
|
308
309
|
smoothed_minus_dm = self._wilder_smooth(minus_dm, window)
|
309
310
|
return smoothed_minus_dm.to_frame("minus_dm")
|
310
311
|
|
@@ -319,7 +320,7 @@ class SimpleIndicatorCalculator(BaseIndicatorCalculator):
|
|
319
320
|
low = df["low"]
|
320
321
|
up_move = high.diff()
|
321
322
|
down_move = -low.diff()
|
322
|
-
plus_dm = up_move.where((up_move > down_move) & (up_move > 0), 0)
|
323
|
+
plus_dm = up_move.where((up_move > down_move) & (up_move > 0), 0) # type: ignore
|
323
324
|
smoothed_plus_dm = self._wilder_smooth(plus_dm, window)
|
324
325
|
return smoothed_plus_dm.to_frame("plus_dm")
|
325
326
|
|