ezKit 1.9.9__py3-none-any.whl → 1.9.11__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
ezKit/stock.py CHANGED
@@ -94,16 +94,17 @@ def kdj_vector(
94
94
  # 有采用 ewm 使用 com=2 的, 但是如果使用 com=2 在默认值的情况下KDJ值是正确的.
95
95
  # 但是非默认值, 比如调整参数, 尝试慢速 KDJ 时就不对了, 最终采用 alpha = 1/m 的情况, 对比同花顺数据, 是正确的.
96
96
 
97
- # 判断参数是否正确
98
- match True:
99
- case True if not utils.isTrue(df, DataFrame):
100
- logger.error("argument error: df")
101
- return None
102
- case True if not any([utils.isTrue(kdj_options, tuple), all(utils.isTrue(item, int) for item in kdj_options)]):
103
- logger.error("argument error: kdj_options")
104
- return None
105
- case _:
106
- pass
97
+ # 检查参数
98
+ if isinstance(df, DataFrame) and df.empty:
99
+ logger.error("argument error: df")
100
+ return None
101
+
102
+ if not utils.check_arguments([(kdj_options, tuple, "kdj_options")]):
103
+ return None
104
+
105
+ if not all(utils.isTrue(item, int) for item in kdj_options):
106
+ logger.error("argument error: kdj_options")
107
+ return None
107
108
 
108
109
  try:
109
110
  low_list = df['low'].rolling(kdj_options[0]).min()
@@ -128,25 +129,23 @@ def data_vector(
128
129
  ) -> DataFrame | None:
129
130
  """数据运算"""
130
131
 
131
- # 判断参数是否正确
132
- match True:
133
- case True if not utils.isTrue(df, DataFrame):
134
- logger.error("argument error: df")
135
- return None
136
- case True if not any([utils.isTrue(macd_options, tuple), all(utils.isTrue(item, int) for item in macd_options)]):
137
- logger.error("argument error: macd_options")
138
- return None
139
- case True if not any([utils.isTrue(kdj_options, tuple), all(utils.isTrue(item, int) for item in kdj_options)]):
140
- logger.error("argument error: kdj_options")
141
- return None
142
- case _:
143
- pass
132
+ # 检查参数
133
+ if isinstance(df, DataFrame) and df.empty:
134
+ logger.error("argument error: df")
135
+ return None
144
136
 
145
- try:
137
+ if not utils.check_arguments([(macd_options, tuple, "macd_options"), (kdj_options, tuple, "kdj_options")]):
138
+ return None
146
139
 
147
- # 数据为空
148
- if isinstance(df, DataFrame) and df.empty:
149
- return None
140
+ if not all(utils.isTrue(item, int) for item in macd_options):
141
+ logger.error("argument error: macd_options")
142
+ return None
143
+
144
+ if not all(utils.isTrue(item, int) for item in kdj_options):
145
+ logger.error("argument error: kdj_options")
146
+ return None
147
+
148
+ try:
150
149
 
151
150
  # ------------------------------------------------------------------------------------------
152
151
 
@@ -174,7 +173,13 @@ def data_vector(
174
173
  # ------------------------------------------------------------------------------------------
175
174
 
176
175
  # 计算 MACD: 默认参数 12 26 9
177
- macd_dif, macd_dea, macd_bar = ta.MACD(df['close'].values, fastperiod=macd_options[0], slowperiod=macd_options[1], signalperiod=macd_options[2]) # type: ignore
176
+ macd_dif, macd_dea, macd_bar = ta.MACD( # type: ignore
177
+ df['close'].values,
178
+ fastperiod=macd_options[0],
179
+ slowperiod=macd_options[1],
180
+ signalperiod=macd_options[2]
181
+ )
182
+
178
183
  macd_dif[np.isnan(macd_dif)], macd_dea[np.isnan(macd_dea)], macd_bar[np.isnan(macd_bar)] = 0, 0, 0
179
184
 
180
185
  # https://www.bilibili.com/read/cv10185856
@@ -182,15 +187,26 @@ def data_vector(
182
187
  df['MACD_DIF'] = macd_dif
183
188
  df['MACD_DEA'] = macd_dea
184
189
 
185
- # MACD 金叉死叉: 0 无, 1 金叉, 2 死叉
190
+ # 初始化 MACD_X 列(0 无, 1 金叉, 2 死叉)
186
191
  df['MACD_X'] = 0
192
+
193
+ # 计算 MACD 条件
187
194
  macd_position = df['MACD_DIF'] > df['MACD_DEA']
188
- df.loc[macd_position[(macd_position is True) & (macd_position.shift() is False)].index, 'MACD_X'] = 1 # type: ignore
189
- df.loc[macd_position[(macd_position is False) & (macd_position.shift() is True)].index, 'MACD_X'] = 2 # type: ignore
195
+
196
+ # 设置 MACD_X = 1: False 变为 True 的位置
197
+ df.loc[macd_position & ~macd_position.shift(fill_value=False), 'MACD_X'] = 1
198
+
199
+ # 设置 MACD_X = 2: 从 True 变为 False 的位置
200
+ df.loc[~macd_position & macd_position.shift(fill_value=False), 'MACD_X'] = 2
201
+
202
+ # 将浮点数限制为小数点后两位
203
+ df['MACD'] = df['MACD'].round(2)
204
+ df['MACD_DIF'] = df['MACD_DIF'].round(2)
205
+ df['MACD_DEA'] = df['MACD_DEA'].round(2)
190
206
 
191
207
  # ------------------------------------------------------------------------------------------
192
208
 
193
- # 计算 KDJ: : 默认参数 9 3 3
209
+ # # 计算 KDJ: : 默认参数 9 3 3
194
210
  kdj_data = kdj_vector(df, kdj_options)
195
211
 
196
212
  if kdj_data is not None:
@@ -200,11 +216,22 @@ def data_vector(
200
216
  df['D'] = kdj_data['D'].values
201
217
  df['J'] = kdj_data['J'].values
202
218
 
203
- # KDJ 金叉死叉: 0 无, 1 金叉, 2 死叉
219
+ # 初始化 KDJ_X 列(0 无, 1 金叉, 2 死叉)
204
220
  df['KDJ_X'] = 0
221
+
222
+ # 计算 MACD 条件
205
223
  kdj_position = df['J'] > df['D']
206
- df.loc[kdj_position[(kdj_position is True) & (kdj_position.shift() is False)].index, 'KDJ_X'] = 1 # type: ignore
207
- df.loc[kdj_position[(kdj_position is False) & (kdj_position.shift() is True)].index, 'KDJ_X'] = 2 # type: ignore
224
+
225
+ # 设置 KDJ_X = 1: False 变为 True 的位置
226
+ df.loc[kdj_position & ~kdj_position.shift(fill_value=False), 'KDJ_X'] = 1
227
+
228
+ # 设置 KDJ_X = 2: 从 True 变为 False 的位置
229
+ df.loc[~kdj_position & kdj_position.shift(fill_value=False), 'KDJ_X'] = 2
230
+
231
+ # 将浮点数限制为小数点后两位
232
+ df['K'] = df['K'].round(2)
233
+ df['D'] = df['D'].round(2)
234
+ df['J'] = df['J'].round(2)
208
235
 
209
236
  # ------------------------------------------------------------------------------------------
210
237
 
@@ -261,12 +288,10 @@ def get_stock_data_from_akshare(
261
288
  "收盘": "close",
262
289
  "最高": "high",
263
290
  "最低": "low",
264
- "成交量": "volume",
265
- "成交额": "turnover"
291
+ "成交量": "volume"
266
292
  })
267
- df = df.round({'turnover': 4})
268
293
  logger.success(f"{info} [成功]")
269
- return df[['date', 'open', 'close', 'high', 'low', 'volume', 'turnover']].copy()
294
+ return df[['date', 'open', 'close', 'high', 'low', 'volume']].copy()
270
295
  except Exception as e:
271
296
  logger.error(f"{info} [失败]")
272
297
  logger.exception(e)
ezKit/utils.py CHANGED
@@ -30,15 +30,10 @@ NoneType = type(None)
30
30
  # --------------------------------------------------------------------------------------------------
31
31
 
32
32
 
33
- def isTrue(
34
- object_data: Any,
35
- object_type: Any = None,
36
- true_list: list | tuple | set | str | None = None,
37
- false_list: list | tuple | set | str | None = None
38
- ) -> bool:
39
- """检查对象类型以及对象数据是否为 True"""
33
+ def isTrue(target: object, typeClass: Any) -> bool:
34
+ """检查对象是否为真"""
40
35
 
41
- # 常见类型:
36
+ # 常见布尔类型:
42
37
  #
43
38
  # Boolean bool False
44
39
  # Numbers int/float 0/0.0
@@ -60,44 +55,33 @@ def isTrue(
60
55
  # all() 用于检查一个可迭代对象(如列表、元组、集合等)中的 所有 元素是否为 真值 (truthy), 所有元素为真, 返回 True
61
56
  # any() 用于检查一个可迭代对象(如列表、元组、集合等)中的 某个 元素是否为 真值 (truthy), 某个元素为真, 返回 True
62
57
  # 与 all() 作用相反的 not any(), 可以用来检查所有元素是否为 假值 (falsy), any() 中所有元素为假, not any() 返回 True
58
+ #
59
+ # return target not in [False, None, 0, 0.0, '', (), [], {}, {*()}, {*[]}, {*{}}]
63
60
 
64
61
  try:
62
+ return isinstance(target, typeClass) and bool(target)
63
+ except Exception as e:
64
+ logger.exception(e)
65
+ return False
65
66
 
66
- if isinstance(object_data, object_type):
67
-
68
- if all(
69
- [
70
- true_list is not None,
71
- false_list is None,
72
- isinstance(true_list, (list, tuple, set, str))
73
- ]
74
- ):
75
- return object_data in true_list
76
-
77
- if all(
78
- [
79
- true_list is None,
80
- false_list is not None,
81
- isinstance(false_list, (list, tuple, set, str))
82
- ]
83
- ):
84
- return object_data not in false_list
85
-
86
- if all(
87
- [
88
- true_list is not None,
89
- false_list is not None,
90
- isinstance(true_list, (list, tuple, set, str)),
91
- isinstance(false_list, (list, tuple, set, str))
92
- ]
93
- ):
94
- return (object_data in true_list) and (object_data not in false_list)
95
-
96
- # return object_data not in [False, None, 0, 0.0, '', (), [], {}, {*()}, {*[]}, {*{}}]
97
- return bool(object_data)
98
67
 
99
- return False
68
+ # --------------------------------------------------------------------------------------------------
69
+
70
+
71
+ def check_arguments(data: list) -> bool:
72
+ """检查函数参数"""
73
+
74
+ # data 示例: [(name, str, "name"), (age, int, "age")]
100
75
 
76
+ try:
77
+ if not isTrue(data, list):
78
+ logger.error("argument error: data")
79
+ return False
80
+ for arg, arg_type, arg_name in data:
81
+ if not isTrue(arg, arg_type):
82
+ logger.error(f"argument error: {arg_name}")
83
+ return False
84
+ return True
101
85
  except Exception as e:
102
86
  logger.exception(e)
103
87
  return False
@@ -116,13 +100,9 @@ def os_environ(
116
100
  # Python 没有全局变量, 多个文件无法调用同一个变量.
117
101
  # 为了解决这个问题, 将变量设置为系统变量, 从而实现多个文件调用同一个变量.
118
102
 
119
- # 判断参数是否正确
120
- match True:
121
- case True if not isTrue(name, str):
122
- logger.error("argument error: name")
123
- return None
124
- case _:
125
- pass
103
+ # 检查参数是否正确
104
+ if not check_arguments([(name, str, "name")]):
105
+ return None
126
106
 
127
107
  try:
128
108
 
@@ -165,29 +145,24 @@ def mam_of_numbers(
165
145
  # numbers 数字列表 (仅支持 list 和 tuple, 不支 set)
166
146
  # dest_type 目标类型 (将数字列表中的数字转换成统一的类型)
167
147
 
168
- # 判断参数是否正确
169
- match True:
170
- case True if not isTrue(numbers, (list, tuple)):
171
- logger.error("argument error: numbers")
172
- return None
173
- case True if not any([isTrue(dest_type, str), dest_type is None]):
174
- logger.error("argument error: dest_type")
175
- return None
176
- case _:
177
- pass
148
+ # 检查参数是否正确
149
+ if not check_arguments([(numbers, (list, tuple), "numbers")]):
150
+ return None
151
+
152
+ if not any([isTrue(dest_type, str), dest_type is None]):
153
+ logger.error("argument error: dest_type")
154
+ return None
178
155
 
179
156
  try:
180
157
 
181
158
  _numbers = deepcopy(numbers)
182
159
 
183
160
  # 转换数据类型
184
- match True:
185
- case True if dest_type == "float":
186
- _numbers = [float(i) for i in numbers]
187
- case True if dest_type == "int":
188
- _numbers = [int(i) for i in numbers]
189
- case _:
190
- pass
161
+ if dest_type == "float":
162
+ _numbers = [float(i) for i in numbers]
163
+
164
+ if dest_type == "int":
165
+ _numbers = [int(i) for i in numbers]
191
166
 
192
167
  # 提取数据
193
168
  _num_max = max(_numbers)
@@ -248,6 +223,9 @@ def division(
248
223
  divisor: int | float
249
224
  ) -> float | None:
250
225
  """Division"""
226
+ # 检查参数是否正确
227
+ if not check_arguments([(dividend, (int, float), "dividend"), (divisor, (int, float), "divisor")]):
228
+ return None
251
229
  try:
252
230
  return dividend / divisor
253
231
  except Exception as e:
@@ -262,14 +240,15 @@ def check_file_type(
262
240
  file_object: str,
263
241
  file_type: str
264
242
  ) -> bool:
265
- """
266
- check file type
243
+ """检查文件类型"""
267
244
 
268
- 检查文件类型
245
+ # file_object 文件对象
246
+ # file_type 文件类型
247
+
248
+ # 检查参数是否正确
249
+ if not check_arguments([(file_object, str, "file"), (file_type, str, "file_type")]):
250
+ return False
269
251
 
270
- file_object 文件对象
271
- file_type 文件类型
272
- """
273
252
  try:
274
253
 
275
254
  _file_path = Path(file_object)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ezKit
3
- Version: 1.9.9
3
+ Version: 1.9.11
4
4
  Summary: Easy Kit
5
5
  Author: septvean
6
6
  Author-email: septvean@gmail.com
@@ -9,12 +9,12 @@ ezKit/mongo.py,sha256=dOm_1wXEPp_e8Ml5Qq78M7FDNrQUAZaThzVIiiLJJwk,2393
9
9
  ezKit/qywx.py,sha256=X_H4fzP-iEqeDEbumr7D1bXi6dxczaxfO8iyutzy02s,7171
10
10
  ezKit/redis.py,sha256=g2_V4jvq0djRc20jLZkgeAeF_bYrq-Rbl_kHcCUPZcA,1965
11
11
  ezKit/sendemail.py,sha256=tRXCsJm_RfTJ9xEWe_lTQ5kOs2JxHGPXvq0oWA7prq0,7263
12
- ezKit/stock.py,sha256=cbL0ZXCur4G290wFN5ynmLmMjgDRNSvVQgsE_0jSQKU,11802
12
+ ezKit/stock.py,sha256=J-fM2XH2q7G6-Q30N8clqLIv7sSn87_fN1qjLOiTrFk,12088
13
13
  ezKit/token.py,sha256=HKREyZj_T2S8-aFoFIrBXTaCKExQq4zE66OHXhGHqQg,1750
14
- ezKit/utils.py,sha256=H-VaWzH1TkpJe_lpPBW2yaP6R7NElDbHRTsByRj_t9w,43234
14
+ ezKit/utils.py,sha256=TDsL3PRkQy6NdZgphkgwacbWvHqEmq4LOkfNzmxV4DY,42682
15
15
  ezKit/xftp.py,sha256=XyIdr_2rxRVLqPofG6fIYWhAMVsFwTyp46dg5P9FLW4,7774
16
- ezKit-1.9.9.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
17
- ezKit-1.9.9.dist-info/METADATA,sha256=i9NRcyP11nSCxo9bCngbdreKObAoIebkPJz5Sh1EiR0,190
18
- ezKit-1.9.9.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
19
- ezKit-1.9.9.dist-info/top_level.txt,sha256=aYLB_1WODsqNTsTFWcKP-BN0KCTKcV-HZJ4zlHkCFw8,6
20
- ezKit-1.9.9.dist-info/RECORD,,
16
+ ezKit-1.9.11.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
17
+ ezKit-1.9.11.dist-info/METADATA,sha256=O05DZpUqxTH6u_llpwm7s7FCxb1EgTqMwX_xjYx3fcw,191
18
+ ezKit-1.9.11.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
19
+ ezKit-1.9.11.dist-info/top_level.txt,sha256=aYLB_1WODsqNTsTFWcKP-BN0KCTKcV-HZJ4zlHkCFw8,6
20
+ ezKit-1.9.11.dist-info/RECORD,,
File without changes