mns-common 1.3.5.7__py3-none-any.whl → 1.3.5.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.

Potentially problematic release.


This version of mns-common might be problematic. Click here for more details.

@@ -0,0 +1,250 @@
1
+ import sys
2
+ import os
3
+
4
+ file_path = os.path.abspath(__file__)
5
+ end = file_path.index('mns') + 16
6
+ project_path = file_path[0:end]
7
+ sys.path.append(project_path)
8
+ import asyncio
9
+ from typing import Dict, List
10
+ import aiohttp
11
+ import pandas as pd
12
+ import datetime
13
+ import nest_asyncio
14
+ from loguru import logger
15
+
16
+
17
+ async def fetch_single_page(
18
+ session: aiohttp.ClientSession, url: str, params: Dict
19
+ ) -> Dict:
20
+ """异步获取单页数据"""
21
+ async with session.get(url, params=params, ssl=False) as response:
22
+ return await response.json()
23
+
24
+
25
+ async def fetch_all_pages_async(url: str, base_params: Dict) -> List[Dict]:
26
+ """异步获取所有页面数据"""
27
+ # 首先获取总数以计算页数
28
+ first_page_params = base_params.copy()
29
+ first_page_params["pn"] = "1"
30
+
31
+ async with aiohttp.ClientSession() as session:
32
+ first_page_data = await fetch_single_page(session, url, first_page_params)
33
+
34
+ # 检查是否成功获取数据
35
+ if first_page_data.get("rc") != 0 or not first_page_data.get("data"):
36
+ return [first_page_data] # 返回错误信息
37
+
38
+ total = first_page_data["data"]["total"]
39
+ page_size = int(base_params["pz"])
40
+ total_pages = (total + page_size - 1) // page_size
41
+
42
+ # 限制页数,避免过大请求
43
+ total_pages = min(total_pages, 100)
44
+
45
+ # 创建所有页面的任务
46
+ tasks = []
47
+ for page in range(1, total_pages + 1):
48
+ page_params = base_params.copy()
49
+ page_params["pn"] = str(page)
50
+ tasks.append(fetch_single_page(session, url, page_params))
51
+
52
+ # 并发执行所有任务
53
+ results = await asyncio.gather(*tasks)
54
+ return results
55
+
56
+
57
+ def process_data(page_results: List[Dict]) -> pd.DataFrame:
58
+ """处理获取到的数据,转换为DataFrame"""
59
+ all_data = []
60
+
61
+ # 保存每个页面的结果和页码
62
+ page_number = 1
63
+ items_per_page = 100 # 假设每页100条
64
+
65
+ for result in page_results:
66
+ if result.get("rc") == 0 and result.get("data") and result["data"].get("diff"):
67
+ page_data = result["data"]["diff"]
68
+
69
+ # 添加页面信息以便后续计算序号
70
+ for item in page_data:
71
+ item["page_number"] = page_number
72
+ item["page_index"] = page_data.index(item)
73
+
74
+ all_data.extend(page_data)
75
+ page_number += 1
76
+
77
+ if not all_data:
78
+ return pd.DataFrame()
79
+
80
+ df = pd.DataFrame(all_data)
81
+
82
+ # 删除临时列
83
+ df.drop(columns=["page_number", "page_index"], inplace=True, errors="ignore")
84
+
85
+ df = df.rename(columns={
86
+ "f2": "now_price",
87
+ "f3": "chg",
88
+ "f5": "volume",
89
+ "f6": "amount",
90
+ "f8": "exchange",
91
+ "f10": "quantity_ratio",
92
+ "f22": "up_speed",
93
+ "f11": "up_speed_05",
94
+ "f12": "symbol",
95
+ "f14": "name",
96
+ "f15": "high",
97
+ "f16": "low",
98
+ "f17": "open",
99
+ "f18": "yesterday_price",
100
+ "f20": "total_mv",
101
+ "f21": "flow_mv",
102
+ "f26": "list_date",
103
+ "f33": "wei_bi",
104
+ "f34": "outer_disk",
105
+ "f35": "inner_disk",
106
+ "f62": "today_main_net_inflow",
107
+ "f66": "super_large_order_net_inflow",
108
+ "f69": "super_large_order_net_inflow_ratio",
109
+ "f72": "large_order_net_inflow",
110
+ # "f78": "medium_order_net_inflow",
111
+ # "f84": "small_order_net_inflow",
112
+ "f100": "industry",
113
+ # "f103": "concept",
114
+ "f184": "today_main_net_inflow_ratio",
115
+ "f352": "average_price",
116
+ "f211": "buy_1_num",
117
+ "f212": "sell_1_num"
118
+ })
119
+
120
+ # 选择需要的列并确保所有需要的列都存在
121
+ desired_columns = [
122
+ 'symbol',
123
+ "now_price",
124
+ "chg",
125
+ "volume",
126
+ "amount",
127
+ "exchange",
128
+ "quantity_ratio",
129
+ "up_speed",
130
+ "up_speed_05",
131
+ "high",
132
+ "low",
133
+ "open",
134
+ "yesterday_price",
135
+ "total_mv",
136
+ "flow_mv",
137
+ "wei_bi",
138
+ "outer_disk",
139
+ "inner_disk",
140
+ "today_main_net_inflow",
141
+ "super_large_order_net_inflow",
142
+ "super_large_order_net_inflow_ratio",
143
+ "large_order_net_inflow",
144
+ "today_main_net_inflow_ratio",
145
+ "average_price",
146
+ "buy_1_num",
147
+ "sell_1_num",
148
+ ]
149
+
150
+ # 过滤出存在的列
151
+ available_columns = [col for col in desired_columns if col in df.columns]
152
+ df = df[available_columns]
153
+
154
+ # 转换数值类型
155
+ numeric_columns = [
156
+ "now_price",
157
+ "chg",
158
+ "volume",
159
+ "amount",
160
+ "exchange",
161
+ "quantity_ratio",
162
+ "up_speed",
163
+ "up_speed_05",
164
+ "high",
165
+ "low",
166
+ "open",
167
+ "yesterday_price",
168
+ "total_mv",
169
+ "flow_mv",
170
+ "wei_bi",
171
+ "outer_disk",
172
+ "inner_disk",
173
+ "today_main_net_inflow",
174
+ "super_large_order_net_inflow",
175
+ "super_large_order_net_inflow_ratio",
176
+ "large_order_net_inflow",
177
+ "today_main_net_inflow_ratio",
178
+ "average_price",
179
+ "buy_1_num",
180
+ "sell_1_num",
181
+ ]
182
+
183
+ for col in numeric_columns:
184
+ if col in df.columns:
185
+ df.loc[df[col] == '-', col] = 0
186
+ df[col] = pd.to_numeric(df[col], errors="coerce")
187
+
188
+ # 大单比例
189
+ df['large_order_net_inflow_ratio'] = round((df['large_order_net_inflow'] / df['amount']) * 100, 2)
190
+
191
+ # 外盘是内盘倍数
192
+ df['disk_ratio'] = round((df['outer_disk'] - df['inner_disk']) / df['inner_disk'], 2)
193
+ # 只有外盘没有内盘
194
+ df.loc[df["inner_disk"] == 0, ['disk_ratio']] = 1688
195
+ # 按涨跌幅降序排序
196
+ df.sort_values(by="chg", ascending=False, inplace=True)
197
+
198
+ return df
199
+
200
+
201
+ async def stock_zh_a_spot_em_async() -> pd.DataFrame:
202
+ fields = "f352,f2,f3,f5,f6,f8,f10,f11,f22,f12,f15,f16,f17,f18,f20,f21,f33,f34,f35,f62,f66,f69,f72,f184,f211,f212",
203
+ # 获取当前日期和时间
204
+ current_time = datetime.datetime.now()
205
+
206
+ # 将当前时间转换为时间戳(以毫秒为单位)
207
+ current_timestamp_ms = int(current_time.timestamp() * 1000)
208
+ """
209
+ 异步获取东方财富网-沪深京 A 股-实时行情
210
+ https://quote.eastmoney.com/center/gridlist.html#hs_a_board
211
+ :return: 实时行情
212
+ :rtype: pandas.DataFrame
213
+ """
214
+ url = "https://82.push2.eastmoney.com/api/qt/clist/get"
215
+ params = {
216
+ "pn": "1",
217
+ "pz": "100",
218
+ "po": "1",
219
+ "np": "1",
220
+ "ut": "bd1d9ddb04089700cf9c27f6f7426281",
221
+ "fltt": "2",
222
+ "invt": "2",
223
+ "fid": "f12",
224
+ "fs": "m:0 t:6,m:0 t:80,m:1 t:2,m:1 t:23,m:0 t:81 s:2048",
225
+ "fields": fields,
226
+ "_": current_timestamp_ms
227
+ }
228
+
229
+ results = await fetch_all_pages_async(url, params)
230
+ return process_data(results)
231
+
232
+
233
+ def stock_real_quotes() -> pd.DataFrame:
234
+ """
235
+ 东方财富网-沪深京 A 股-实时行情 (同步接口)
236
+ https://quote.eastmoney.com/center/gridlist.html#hs_a_board
237
+ :return: 实时行情
238
+ :rtype: pandas.DataFrame
239
+ """
240
+ try:
241
+ nest_asyncio.apply()
242
+ return asyncio.run(stock_zh_a_spot_em_async())
243
+ except Exception as e:
244
+ logger.error("同步实时行情出现异常:{}", e)
245
+
246
+
247
+ if __name__ == "__main__":
248
+ while True:
249
+ stock_zh_a_spot_em_df = stock_real_quotes()
250
+ logger.info(1)
@@ -33,6 +33,10 @@ def calculate_real_time_k_line_param(real_time_quotes_now):
33
33
  real_time_quotes_now['chg_from_open'] = round(
34
34
  (((real_time_quotes_now['now_price'] - real_time_quotes_now['open']) / real_time_quotes_now[
35
35
  'open']) * 100), 2)
36
+ # 最低和最高之间的差值
37
+ real_time_quotes_now['high_from_low_chg'] = round(
38
+ (((real_time_quotes_now['high'] - real_time_quotes_now['low']) / real_time_quotes_now[
39
+ 'low']) * 100), 2)
36
40
 
37
41
  if 'average_price' in real_time_quotes_now.columns:
38
42
  # 高于平均线的差值 越大表明极速拉伸
@@ -1,4 +1,4 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mns-common
3
- Version: 1.3.5.7
3
+ Version: 1.3.5.9
4
4
 
@@ -13,6 +13,7 @@ mns_common/api/em/east_money_etf_api.py,sha256=PtVBNArQ5sMjzBVCW-WBnAuqSp8qB4E1H
13
13
  mns_common/api/em/east_money_stock_api.py,sha256=NkV8jmdYOrOpQd00KsMBNoAkPZuWGtw0N1Rryg21RZ0,9892
14
14
  mns_common/api/em/east_money_stock_gdfx_free_top_10_api.py,sha256=jVy3fNdrkLq3ri7yUwXWt0ItB8LCHzt9CPz91Fj8sPA,9198
15
15
  mns_common/api/em/east_money_stock_hk_api.py,sha256=C75TfZzRnNVaz_ILEPHcxhgJqV7f4rFrlWjgMWLRu7c,14788
16
+ mns_common/api/em/east_money_stock_quotes_sync_api.py,sha256=-me8o6n9XzE3gruKNXHlhvJiVByA6aoXBeORFCnqllc,7568
16
17
  mns_common/api/em/east_money_stock_us_api.py,sha256=6u0fSkIxZqPVrI1JChhwTrUWRTCDDSBNvU5cehPA1uM,11417
17
18
  mns_common/api/em/east_money_stock_v2_api.py,sha256=BxLZqIUecy71TkbMelAF8Bg3xEd3tR02r2Nj3NfF8Ts,16326
18
19
  mns_common/api/em/em_concept_index_api.py,sha256=PP87ES8a_y0o3SKLzBsPrc7DCPI3MBCD-4SmoUUirl0,8285
@@ -96,7 +97,7 @@ mns_common/component/k_line/clean/__init__.py,sha256=2U9DiKslxsWwLLEcZKjS8UiQPN1
96
97
  mns_common/component/k_line/clean/k_line_param.py,sha256=ErcOZdanTOkY2qDDJ9M9DJTMiE3q5sW9rYxDlJx0oEo,248
97
98
  mns_common/component/k_line/clean/sh_small_normal_zt_k_line_check_api.py,sha256=Xao8JPtvEqUwiEO1-l2YIwSIYCaCuuDUu34KY5mdncA,12593
98
99
  mns_common/component/k_line/common/__init__.py,sha256=2U9DiKslxsWwLLEcZKjS8UiQPN1QgALvnK3HiJNIZE0,163
99
- mns_common/component/k_line/common/k_line_common_service_api.py,sha256=BxN7aqCueGKaJzWiJSSJZKQbG06KCJrAS8v35E0pCRg,4770
100
+ mns_common/component/k_line/common/k_line_common_service_api.py,sha256=UODqzK3eApC776vDdxTDnp3Q7er2EIQtz4sDmKasXwo,4992
100
101
  mns_common/component/k_line/patterns/__init__.py,sha256=2U9DiKslxsWwLLEcZKjS8UiQPN1QgALvnK3HiJNIZE0,163
101
102
  mns_common/component/k_line/patterns/k_line_patterns_service_api.py,sha256=C5mg49OhACILto657H513sg1-lOmYlgCXl7y_Gw88ro,1809
102
103
  mns_common/component/k_line/patterns/pattern_Enum.py,sha256=bl8cH1H3BWdj_deVO124oSGYMPUtDQWvqqWk_5rf5rQ,509
@@ -140,7 +141,7 @@ mns_common/utils/date_handle_util.py,sha256=XS-MyA8_7k35LOCFAYOHgVcVkMft_Kc4Wa9U
140
141
  mns_common/utils/db_util.py,sha256=hSmfNAN4vEeEaUva6_cicZEhb2jSnib-Gvk2reke1vc,2590
141
142
  mns_common/utils/file_util.py,sha256=egWu6PenGPRp_ixrNTHKarT4dAnOT6FETR82EHUZJnQ,1042
142
143
  mns_common/utils/ip_util.py,sha256=UTcYfz_uytB__6nlBf7T-izuI7hi4XdB6ET0sJgEel4,969
143
- mns_common-1.3.5.7.dist-info/METADATA,sha256=SKwYaZR1_q2gnIK1hIDfVGnSdkWIy8JDqxjDxmHdSJo,61
144
- mns_common-1.3.5.7.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
145
- mns_common-1.3.5.7.dist-info/top_level.txt,sha256=ZC58kAR-8Hvc6U2xhYNBNLAh3mb6sZazbdj5nZpvEkQ,11
146
- mns_common-1.3.5.7.dist-info/RECORD,,
144
+ mns_common-1.3.5.9.dist-info/METADATA,sha256=o2Pf9nqAOl0fJPRJ06oQtKyo_ETBMs7orHmkhPC9i1U,61
145
+ mns_common-1.3.5.9.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
146
+ mns_common-1.3.5.9.dist-info/top_level.txt,sha256=ZC58kAR-8Hvc6U2xhYNBNLAh3mb6sZazbdj5nZpvEkQ,11
147
+ mns_common-1.3.5.9.dist-info/RECORD,,