ezKit 1.9.9__py3-none-any.whl → 1.9.11__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.
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