mns-common 1.5.1.6__py3-none-any.whl → 1.5.1.8__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.

@@ -1,306 +0,0 @@
1
- import sys
2
- import os
3
-
4
- import sys
5
- import os
6
-
7
- file_path = os.path.abspath(__file__)
8
- end = file_path.index('mns') + 14
9
- project_path = file_path[0:end]
10
- sys.path.append(project_path)
11
- from concurrent.futures import ThreadPoolExecutor
12
- import pandas as pd
13
- from loguru import logger
14
- import json
15
- import requests
16
- import time
17
- import akshare as ak
18
- import numpy as np
19
-
20
- # 最大返回条数
21
- max_number = 600
22
- # 最小返回条数
23
- min_number = 500
24
- # 分页条数
25
- page_number = 100
26
-
27
-
28
- # fields_02 = "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17,f18,f19,f20,f21,f22,f23,f24,f25,f26,f27,f28,f29,f30,f31,f32,f33,f34,f35,f36,f37,f38,f39,f40,f41,f42,f43,f44,f45,f46,f47,f48,f49,f50,f51,f52,f53,f54,f55,f56,f57,f58,f59,f60,f61,f62,f63,f64,f65,f66,f67,f68,f69,f70,f71,f72,f73,f74,f75,f76,f77,f78,f79,f80,f81,f82,f83,f84,f85,f86,f87,f88,f89,f90,f91,f92,f93,f94,f95,f96,f97,f98,f99,f100,f101,f102,f103,f104,f105,f106,f107,f108" \
29
- # ",f109,f110,f111,f112,f113,f114,f115,f116,f117,f118,f119,f120,f121,f122,f123,f124,f125,f126,f127,f128,f129,f130,f131,f132,f133,f134,f135,f136,f137,f138,f139,f140,f141,f142,f143,f144,f145,f146,f147,f148,f149,f150,f151,f152,f153,f154,f155,f156,f157,f158,f159,f160,f161,f162,f163,f164,f165,f166,f167,f168,f169,f170,f171,f172,f173,f174,f175,f176,f177,f178,f179,f180,f181,f182,f183,f184,f185,f186,f187,f188,f189,f190,f191,f192,f193,f194,f195,f196,f197,f198,f199,f200" \
30
- # ",f209,f210,f211,f212,f213,f214,f215,f216,f217,f218,f219,f220,f221,f222,f223,f224,f225,f226,f227,f228,f229,f230,f231,f232,f233,f234,f235,f236,f237,f238,f239,f240,f241,f242,f243,f244,f245,f246,f247,f248,f249,f250,f251,f252,f253,f254,f255,f256,f257,f258,f259,f260,f261,f262,f263,f264,f265,f266,f267,f268,f269,f270,f271,f272,f273,f274,f275,f276,f277,f278,f279,f280,f281,f282,f283,f284,f285,f286,f287,f288,f289,f290,f291,f292,f293,f294,f295,f296,f297,f298,f299,f300" \
31
- # ",f309,f310,f312,f313,f314,f315,f316,f317,f318,f319,f320,f321,f322,f323,f324,f325,f326,f327,f328,f329,f330,f331,f332,f333,f334,f335,f336,f337,f338,f339,f340,f341,f342,f343,f344,f345,f346,f347,f348,f349,f350,f351,f352,f353,f354,f355,f356,f357,f358,f359,f360,f361,f362,f363,f364,f365,f366,f367,f368,f369,f370,f371,f372,f373,f374,f375,f376,f377,f378,f379,f380,f381,f382,f383,f384,f385,f386,f387,f388,f389,f390,f391,f392,f393,f394,f395,f396,f397,f398,f399,f401"
32
- #
33
-
34
- #
35
- # url = https://push2.eastmoney.com/api/qt/clist/get?cb=jQuery34103608466964799838_1718163189869&pn=1&np=1&ut
36
- # =8a086bfc3570bdde64a6a1c585cccb35&fltt=1&invt=1&fs=m:0+e:11,m:1+e:11,m:1+e:11+s:4194304,
37
- # m:0+e:11+s:8388608&dpt=zqsc.zpg&fields=f1,f2,f3,f4,f5,f6,f8,f10,f12,f13,f14,f18,f22,f152,
38
- # f237&wbp2u=|0|0|0|wap&fid=f3&po=1&pz=2000&_=1718163189870
39
- def get_debt_page_data(fields, pn, proxies) -> pd.DataFrame:
40
- current_timestamp = str(int(round(time.time() * 1000, 0)))
41
- url = "https://push2.eastmoney.com/api/qt/clist/get"
42
-
43
- params = {
44
- "cb": "jQuery34103608466964799838_" + current_timestamp,
45
- "pn": str(pn),
46
- "np": 3,
47
- "ut": "8a086bfc3570bdde64a6a1c585cccb35",
48
- "fltt": 1,
49
- "invt": 1,
50
- "fs": "m:0+e:11,m:1+e:11,m:1+e:11+s:4194304,m:0+e:11+s:8388608",
51
- "dpt": "zqsc.zpg",
52
- "fields": fields,
53
- "wbp2u": "|0|0|0|wap",
54
- "fid": "f12",
55
- "po": 1,
56
- "pz": 2000,
57
- "_": current_timestamp
58
- }
59
- try:
60
- if proxies is None:
61
- r = requests.get(url, params)
62
- else:
63
- r = requests.get(url, params, proxies=proxies)
64
- data_text = r.text
65
-
66
- if pn == 1:
67
- try:
68
- begin_index_total = data_text.index('"total":')
69
-
70
- end_index_total = data_text.index('"diff"')
71
- global max_number
72
- max_number = int(data_text[begin_index_total + 8:end_index_total - 1])
73
- except Exception as e:
74
- logger.error(f"获取第{pn}页可转债列表异常: {e}")
75
- return pd.DataFrame()
76
-
77
- begin_index = data_text.index('[')
78
- end_index = data_text.index(']')
79
- data_json = data_text[begin_index:end_index + 1]
80
- data_json = json.loads(data_json)
81
- if data_json is None:
82
- return pd.DataFrame()
83
- else:
84
- return pd.DataFrame(data_json)
85
- except Exception as e:
86
- logger.error("获取可转债列表,实时行情异常:{}", e)
87
- return pd.DataFrame()
88
-
89
-
90
- def all_debt_ticker_data(fields, proxies) -> pd.DataFrame:
91
- """
92
- 使用多线程获取所有债券数据
93
- """
94
- # 计算总页数,假设总共有1000条数据,每页200条
95
-
96
- per_page = page_number
97
- total_pages = (max_number + per_page - 1) // per_page # 向上取整
98
-
99
- # 创建线程池
100
- with ThreadPoolExecutor(max_workers=3) as executor:
101
- # 提交任务,获取每页数据
102
- futures = [executor.submit(get_debt_page_data, fields, pn, proxies)
103
- for pn in range(1, total_pages + 1)]
104
-
105
- # 收集结果
106
- results = []
107
- for future in futures:
108
- result = future.result()
109
- if not result.empty:
110
- results.append(result)
111
-
112
- # 合并所有页面的数据
113
- if results:
114
- return pd.concat(results, ignore_index=True)
115
- else:
116
- return pd.DataFrame()
117
-
118
-
119
- def get_debt_real_time_quotes(proxies):
120
- fields = ("f352,f2,f3,f5,f6,f8,f10,f11,f22,f12,f14,f15,f16,f17,f18,f20,f21,f26,f33,f34,f35,f62,f66,f69,f72,f184,"
121
- "f211,f212,f232,f233,f234")
122
- # 获取第一页数据
123
- page_one_df = get_debt_page_data(fields, 1, proxies)
124
- # 数据接口正常返回5600以上的数量
125
- if page_one_df.shape[0] > min_number:
126
- page_one_df = rename_real_time_quotes_df(page_one_df)
127
- page_one_df.drop_duplicates('symbol', keep='last', inplace=True)
128
- return page_one_df
129
- else:
130
- page_df = all_debt_ticker_data(fields, proxies)
131
- page_df = rename_real_time_quotes_df(page_df)
132
- page_df.drop_duplicates('symbol', keep='last', inplace=True)
133
- return page_df
134
-
135
-
136
- def rename_real_time_quotes_df(temp_df):
137
- temp_df = temp_df.rename(columns={
138
- "f2": "now_price",
139
- "f3": "chg",
140
- "f5": "volume",
141
- "f6": "amount",
142
- "f8": "exchange",
143
- "f10": "quantity_ratio",
144
- "f22": "up_speed",
145
- "f11": "up_speed_05",
146
- "f12": "symbol",
147
- "f14": "name",
148
- "f15": "high",
149
- "f16": "low",
150
- "f17": "open",
151
- "f18": "yesterday_price",
152
- "f20": "total_mv",
153
- "f21": "flow_mv",
154
- "f26": "list_date",
155
- "f33": "wei_bi",
156
- "f34": "outer_disk",
157
- "f35": "inner_disk",
158
- "f62": "today_main_net_inflow",
159
- "f66": "super_large_order_net_inflow",
160
- "f69": "super_large_order_net_inflow_ratio",
161
- "f72": "large_order_net_inflow",
162
- # "f78": "medium_order_net_inflow",
163
- # "f84": "small_order_net_inflow",
164
- # "f103": "concept",
165
- "f184": "today_main_net_inflow_ratio",
166
- "f352": "average_price",
167
- "f211": "buy_1_num",
168
- "f212": "sell_1_num",
169
- "f232": "stock_symbol",
170
- "f234": "stock_name",
171
- "f233": "market"
172
- })
173
- temp_df.loc[temp_df['buy_1_num'] == '-', 'buy_1_num'] = 0
174
- temp_df.loc[temp_df['sell_1_num'] == '-', 'sell_1_num'] = 0
175
- temp_df.loc[temp_df['up_speed_05'] == '-', 'up_speed_05'] = 0
176
- temp_df.loc[temp_df['up_speed'] == '-', 'up_speed'] = 0
177
- temp_df.loc[temp_df['average_price'] == '-', 'average_price'] = 0
178
- temp_df.loc[temp_df['wei_bi'] == '-', 'wei_bi'] = 0
179
- temp_df.loc[temp_df['yesterday_price'] == '-', 'yesterday_price'] = 0
180
- temp_df.loc[temp_df['now_price'] == '-', 'now_price'] = 0
181
- temp_df.loc[temp_df['chg'] == '-', 'chg'] = 0
182
- temp_df.loc[temp_df['volume'] == '-', 'volume'] = 0
183
- temp_df.loc[temp_df['amount'] == '-', 'amount'] = 0
184
- temp_df.loc[temp_df['exchange'] == '-', 'exchange'] = 0
185
- temp_df.loc[temp_df['quantity_ratio'] == '-', 'quantity_ratio'] = 0
186
- temp_df.loc[temp_df['high'] == '-', 'high'] = 0
187
- temp_df.loc[temp_df['low'] == '-', 'low'] = 0
188
- temp_df.loc[temp_df['open'] == '-', 'open'] = 0
189
- temp_df.loc[temp_df['total_mv'] == '-', 'total_mv'] = 0
190
- temp_df.loc[temp_df['flow_mv'] == '-', 'flow_mv'] = 0
191
- temp_df.loc[temp_df['inner_disk'] == '-', 'inner_disk'] = 0
192
- temp_df.loc[temp_df['outer_disk'] == '-', 'outer_disk'] = 0
193
- temp_df.loc[temp_df['today_main_net_inflow_ratio'] == '-', 'today_main_net_inflow_ratio'] = 0
194
- temp_df.loc[temp_df['today_main_net_inflow'] == '-', 'today_main_net_inflow'] = 0
195
- temp_df.loc[temp_df['super_large_order_net_inflow'] == '-', 'super_large_order_net_inflow'] = 0
196
- temp_df.loc[temp_df['super_large_order_net_inflow_ratio'] == '-', 'super_large_order_net_inflow_ratio'] = 0
197
- temp_df.loc[temp_df['large_order_net_inflow'] == '-', 'large_order_net_inflow'] = 0
198
- temp_df["list_date"] = pd.to_numeric(temp_df["list_date"], errors="coerce")
199
- temp_df["wei_bi"] = pd.to_numeric(temp_df["wei_bi"], errors="coerce")
200
- temp_df["average_price"] = pd.to_numeric(temp_df["average_price"], errors="coerce")
201
- temp_df["yesterday_price"] = pd.to_numeric(temp_df["yesterday_price"], errors="coerce")
202
- temp_df["now_price"] = pd.to_numeric(temp_df["now_price"], errors="coerce")
203
- temp_df["chg"] = pd.to_numeric(temp_df["chg"], errors="coerce")
204
- temp_df["volume"] = pd.to_numeric(temp_df["volume"], errors="coerce")
205
- temp_df["amount"] = pd.to_numeric(temp_df["amount"], errors="coerce")
206
- temp_df["exchange"] = pd.to_numeric(temp_df["exchange"], errors="coerce")
207
- temp_df["quantity_ratio"] = pd.to_numeric(temp_df["quantity_ratio"], errors="coerce")
208
- temp_df["high"] = pd.to_numeric(temp_df["high"], errors="coerce")
209
- temp_df["low"] = pd.to_numeric(temp_df["low"], errors="coerce")
210
- temp_df["open"] = pd.to_numeric(temp_df["open"], errors="coerce")
211
- temp_df["total_mv"] = pd.to_numeric(temp_df["total_mv"], errors="coerce")
212
- temp_df["flow_mv"] = pd.to_numeric(temp_df["flow_mv"], errors="coerce")
213
- temp_df["outer_disk"] = pd.to_numeric(temp_df["outer_disk"], errors="coerce")
214
- temp_df["inner_disk"] = pd.to_numeric(temp_df["inner_disk"], errors="coerce")
215
- temp_df["today_main_net_inflow"] = pd.to_numeric(temp_df["today_main_net_inflow"], errors="coerce")
216
- temp_df["super_large_order_net_inflow"] = pd.to_numeric(temp_df["super_large_order_net_inflow"],
217
- errors="coerce")
218
- temp_df["super_large_order_net_inflow_ratio"] = pd.to_numeric(temp_df["super_large_order_net_inflow_ratio"],
219
- errors="coerce")
220
- temp_df["large_order_net_inflow"] = pd.to_numeric(temp_df["large_order_net_inflow"],
221
- errors="coerce")
222
- # 大单比例
223
- temp_df['large_order_net_inflow_ratio'] = round((temp_df['large_order_net_inflow'] / temp_df['amount']) * 100, 2)
224
-
225
- # 外盘是内盘倍数
226
- temp_df['disk_ratio'] = round((temp_df['outer_disk'] - temp_df['inner_disk']) / temp_df['inner_disk'], 2)
227
- # 只有外盘没有内盘
228
- temp_df.loc[temp_df["inner_disk"] == 0, ['disk_ratio']] = 1688
229
-
230
- temp_df['now_price'] = round(temp_df['now_price'] / 1000, 3)
231
- temp_df['chg'] = round(temp_df['chg'] / 100, 2)
232
- temp_df['exchange'] = round(temp_df['exchange'] / 100, 2)
233
- temp_df['quantity_ratio'] = round(temp_df['quantity_ratio'] / 100, 2)
234
-
235
- temp_df['up_speed'] = round(temp_df['up_speed'] / 100, 2)
236
- temp_df['up_speed_05'] = round(temp_df['up_speed_05'] / 100, 2)
237
-
238
- temp_df['high'] = round(temp_df['high'] / 1000, 2)
239
- temp_df['low'] = round(temp_df['low'] / 1000, 2)
240
-
241
- temp_df['open'] = round(temp_df['open'] / 1000, 2)
242
- temp_df['yesterday_price'] = round(temp_df['yesterday_price'] / 1000, 2)
243
- temp_df['wei_bi'] = round(temp_df['wei_bi'] / 100, 2)
244
- temp_df['super_large_order_net_inflow_ratio'] = round(temp_df['super_large_order_net_inflow_ratio'] / 100, 2)
245
- temp_df['today_main_net_inflow_ratio'] = round(temp_df['today_main_net_inflow_ratio'] / 100, 2)
246
- temp_df['average_price'] = round(temp_df['average_price'] / 1000, 2)
247
-
248
- temp_df.loc[:, 'reference_main_inflow'] = round(
249
- (temp_df['flow_mv'] * (1 / 1000)), 2)
250
-
251
- temp_df.loc[:, 'main_inflow_multiple'] = round(
252
- (temp_df['today_main_net_inflow'] / temp_df['reference_main_inflow']), 2)
253
-
254
- temp_df.loc[:, 'super_main_inflow_multiple'] = round(
255
- (temp_df['super_large_order_net_inflow'] / temp_df['reference_main_inflow']), 2)
256
- temp_df['large_inflow_multiple'] = round(
257
- (temp_df['large_order_net_inflow'] / temp_df['reference_main_inflow']), 2)
258
-
259
- # 债权是10
260
- temp_df['disk_diff_amount'] = round(
261
- (temp_df['outer_disk'] - temp_df['inner_disk']) * temp_df[
262
- "average_price"] * 10,
263
- 2)
264
-
265
- temp_df['disk_diff_amount_exchange'] = round(
266
- (temp_df['disk_diff_amount'] / temp_df['reference_main_inflow']), 2)
267
- temp_df.loc[:, 'sum_main_inflow_disk'] = temp_df['main_inflow_multiple'] + \
268
- temp_df['disk_diff_amount_exchange']
269
- temp_df.replace([np.inf, -np.inf], 0, inplace=True)
270
- temp_df = temp_df.fillna(0)
271
- return temp_df
272
-
273
-
274
- # 可转债信息
275
- def get_kzz_bond_info():
276
- try:
277
- bond_zh_cov_info_ths_df = ak.bond_zh_cov_info_ths()
278
- bond_zh_cov_info_ths_df = bond_zh_cov_info_ths_df.rename(columns={
279
- "债券代码": "symbol",
280
- "债券简称": "name",
281
- "申购日期": "apply_date",
282
- "申购代码": "apply_code",
283
- "原股东配售码": "config_code",
284
- "每股获配额": "per_share_limit",
285
- "计划发行量": "planned_circulation",
286
- "实际发行量": "actual_circulation",
287
- "中签公布日": "winning_date",
288
- "中签号": "winning_number",
289
- "上市日期": "list_date",
290
- "正股代码": "stock_code",
291
- "正股简称": "stock_name",
292
- "转股价格": "conversion_price",
293
- "到期时间": "due_date",
294
- "中签率": "lot_winning_rate"
295
- })
296
- return bond_zh_cov_info_ths_df
297
- except BaseException as e:
298
- logger.error("获取可转债信息异常:{}", e)
299
-
300
-
301
- if __name__ == '__main__':
302
- info_df = get_kzz_bond_info()
303
- print(info_df)
304
- while True:
305
- df = get_debt_real_time_quotes(None)
306
- logger.info(df)
@@ -1,374 +0,0 @@
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
-
9
- from concurrent.futures import ThreadPoolExecutor
10
- import pandas as pd
11
- from loguru import logger
12
- import requests
13
- import time
14
- import numpy as np
15
-
16
- # 最大返回条数
17
- max_number = 1200
18
- # 最小返回条数
19
- min_number = 1000
20
- # 分页条数
21
- page_number = 100
22
-
23
-
24
- def get_fund_etf_page_df(pn, proxies) -> pd.DataFrame:
25
- """
26
- 东方财富-ETF 实时行情
27
- https://quote.eastmoney.com/center/gridlist.html#fund_etf
28
- :return: ETF 实时行情
29
- :rtype: pandas.DataFrame
30
- """
31
- current_timestamp = str(int(round(time.time() * 1000, 0)))
32
- url = "https://88.push2.eastmoney.com/api/qt/clist/get"
33
- params = {
34
- "pn": str(pn),
35
- "pz": "5000",
36
- "po": "1",
37
- "np": "3",
38
- "ut": "bd1d9ddb04089700cf9c27f6f7426281",
39
- "fltt": "2",
40
- "invt": "2",
41
- "wbp2u": "|0|0|0|web",
42
- "fid": "f12",
43
- "fs": "b:MK0021,b:MK0022,b:MK0023,b:MK0024",
44
- "fields": (
45
- "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,"
46
- "f12,f13,f14,f15,f16,f17,f18,f20,f21,"
47
- "f23,f24,f25,f26,f22,f11,f30,f31,f32,f33,"
48
- "f34,f35,f38,f62,f63,f64,f65,f66,f69,"
49
- "f72,f75,f78,f81,f84,f87,f115,f124,f128,"
50
- "f136,f152,f184,f297,f402,f441"
51
- ),
52
- "_": str(current_timestamp),
53
- }
54
- try:
55
- if proxies is None:
56
- r = requests.get(url, params)
57
- else:
58
- r = requests.get(url, params, proxies=proxies)
59
- data_json = r.json()
60
- if pn == 1:
61
- try:
62
- global max_number
63
- max_number = int(data_json['data']['total'])
64
- except Exception as e:
65
- logger.error(f"获取第{pn}页ETF列表异常: {e}")
66
- return pd.DataFrame()
67
-
68
- temp_df = pd.DataFrame(data_json["data"]["diff"])
69
- temp_df.rename(
70
- columns={
71
- "f26": "上市时间",
72
- "f12": "代码",
73
- "f14": "名称",
74
- "f2": "最新价",
75
- "f4": "涨跌额",
76
- "f3": "涨跌幅",
77
- "f5": "成交量",
78
- "f6": "成交额",
79
- "f7": "振幅",
80
- "f17": "开盘价",
81
- "f15": "最高价",
82
- "f16": "最低价",
83
- "f18": "昨收",
84
- "f8": "换手率",
85
- "f10": "量比",
86
- "f30": "现手",
87
- "f31": "买一",
88
- "f32": "卖一",
89
- "f33": "委比",
90
- "f34": "外盘",
91
- "f35": "内盘",
92
- "f62": "主力净流入-净额",
93
- "f184": "主力净流入-净占比",
94
- "f66": "超大单净流入-净额",
95
- "f69": "超大单净流入-净占比",
96
- "f72": "大单净流入-净额",
97
- "f75": "大单净流入-净占比",
98
- "f78": "中单净流入-净额",
99
- "f81": "中单净流入-净占比",
100
- "f84": "小单净流入-净额",
101
- "f87": "小单净流入-净占比",
102
- "f38": "最新份额",
103
- "f21": "流通市值",
104
- "f20": "总市值",
105
- "f402": "基金折价率",
106
- "f441": "IOPV实时估值",
107
- "f297": "数据日期",
108
- "f124": "更新时间",
109
- "f13": "market"
110
- },
111
- inplace=True,
112
- )
113
- temp_df = temp_df[
114
- [
115
- "代码",
116
- "名称",
117
- "最新价",
118
- "IOPV实时估值",
119
- "基金折价率",
120
- "涨跌额",
121
- "涨跌幅",
122
- "成交量",
123
- "成交额",
124
- "开盘价",
125
- "最高价",
126
- "最低价",
127
- "昨收",
128
- "振幅",
129
- "换手率",
130
- "量比",
131
- "委比",
132
- "外盘",
133
- "内盘",
134
- "主力净流入-净额",
135
- "主力净流入-净占比",
136
- "超大单净流入-净额",
137
- "超大单净流入-净占比",
138
- "大单净流入-净额",
139
- "大单净流入-净占比",
140
- "中单净流入-净额",
141
- "中单净流入-净占比",
142
- "小单净流入-净额",
143
- "小单净流入-净占比",
144
- "现手",
145
- "买一",
146
- "卖一",
147
- "最新份额",
148
- "流通市值",
149
- "总市值",
150
- "数据日期",
151
- "更新时间",
152
- "market",
153
- "上市时间"
154
- ]
155
- ]
156
- temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
157
- temp_df["涨跌额"] = pd.to_numeric(temp_df["涨跌额"], errors="coerce")
158
- temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce")
159
- temp_df["成交量"] = pd.to_numeric(temp_df["成交量"], errors="coerce")
160
- temp_df["成交额"] = pd.to_numeric(temp_df["成交额"], errors="coerce")
161
- temp_df["开盘价"] = pd.to_numeric(temp_df["开盘价"], errors="coerce")
162
- temp_df["最高价"] = pd.to_numeric(temp_df["最高价"], errors="coerce")
163
- temp_df["最低价"] = pd.to_numeric(temp_df["最低价"], errors="coerce")
164
- temp_df["昨收"] = pd.to_numeric(temp_df["昨收"], errors="coerce")
165
- temp_df["换手率"] = pd.to_numeric(temp_df["换手率"], errors="coerce")
166
- temp_df["量比"] = pd.to_numeric(temp_df["量比"], errors="coerce")
167
- temp_df["委比"] = pd.to_numeric(temp_df["委比"], errors="coerce")
168
- temp_df["外盘"] = pd.to_numeric(temp_df["外盘"], errors="coerce")
169
- temp_df["内盘"] = pd.to_numeric(temp_df["内盘"], errors="coerce")
170
- temp_df["流通市值"] = pd.to_numeric(temp_df["流通市值"], errors="coerce")
171
- temp_df["总市值"] = pd.to_numeric(temp_df["总市值"], errors="coerce")
172
- temp_df["振幅"] = pd.to_numeric(temp_df["振幅"], errors="coerce")
173
- temp_df["现手"] = pd.to_numeric(temp_df["现手"], errors="coerce")
174
- temp_df["买一"] = pd.to_numeric(temp_df["买一"], errors="coerce")
175
- temp_df["卖一"] = pd.to_numeric(temp_df["卖一"], errors="coerce")
176
- temp_df["最新份额"] = pd.to_numeric(temp_df["最新份额"], errors="coerce")
177
- temp_df["IOPV实时估值"] = pd.to_numeric(temp_df["IOPV实时估值"], errors="coerce")
178
- temp_df["基金折价率"] = pd.to_numeric(temp_df["基金折价率"], errors="coerce")
179
- temp_df["主力净流入-净额"] = pd.to_numeric(
180
- temp_df["主力净流入-净额"], errors="coerce"
181
- )
182
- temp_df["主力净流入-净占比"] = pd.to_numeric(
183
- temp_df["主力净流入-净占比"], errors="coerce"
184
- )
185
- temp_df["超大单净流入-净额"] = pd.to_numeric(
186
- temp_df["超大单净流入-净额"], errors="coerce"
187
- )
188
- temp_df["超大单净流入-净占比"] = pd.to_numeric(
189
- temp_df["超大单净流入-净占比"], errors="coerce"
190
- )
191
- temp_df["大单净流入-净额"] = pd.to_numeric(
192
- temp_df["大单净流入-净额"], errors="coerce"
193
- )
194
- temp_df["大单净流入-净占比"] = pd.to_numeric(
195
- temp_df["大单净流入-净占比"], errors="coerce"
196
- )
197
- temp_df["中单净流入-净额"] = pd.to_numeric(
198
- temp_df["中单净流入-净额"], errors="coerce"
199
- )
200
- temp_df["中单净流入-净占比"] = pd.to_numeric(
201
- temp_df["中单净流入-净占比"], errors="coerce"
202
- )
203
- temp_df["小单净流入-净额"] = pd.to_numeric(
204
- temp_df["小单净流入-净额"], errors="coerce"
205
- )
206
- temp_df["小单净流入-净占比"] = pd.to_numeric(
207
- temp_df["小单净流入-净占比"], errors="coerce"
208
- )
209
- temp_df["数据日期"] = pd.to_datetime(
210
- temp_df["数据日期"], format="%Y%m%d", errors="coerce"
211
- )
212
- temp_df["更新时间"] = (
213
- pd.to_datetime(temp_df["更新时间"], unit="s", errors="coerce")
214
- .dt.tz_localize("UTC")
215
- .dt.tz_convert("Asia/Shanghai")
216
- )
217
-
218
- return temp_df
219
- except Exception as e:
220
- logger.error("获取ETF列表,实时行情异常:{}", e)
221
- return pd.DataFrame()
222
-
223
-
224
- def thread_pool_executor(proxies):
225
- """
226
- 使用多线程获取所有ETF数据
227
- """
228
- # 计算总页数,假设总共有1000条数据,每页200条
229
-
230
- per_page = page_number
231
- total_pages = (max_number + per_page - 1) // per_page # 向上取整
232
-
233
- # 创建线程池
234
- with ThreadPoolExecutor(max_workers=3) as executor:
235
- # 提交任务,获取每页数据
236
- futures = [executor.submit(get_fund_etf_page_df, pn, proxies)
237
- for pn in range(1, total_pages + 1)]
238
-
239
- # 收集结果
240
- results = []
241
- for future in futures:
242
- result = future.result()
243
- if not result.empty:
244
- results.append(result)
245
-
246
- # 合并所有页面的数据
247
- if results:
248
- return pd.concat(results, ignore_index=True)
249
- else:
250
- return pd.DataFrame()
251
-
252
-
253
- def rename_etf(fund_etf_spot_em_df):
254
- fund_etf_spot_em_df = fund_etf_spot_em_df.rename(columns={
255
- "上市时间": "list_date",
256
- "最新价": "now_price",
257
- "涨跌幅": "chg",
258
- "基金折价率": "fund_discount_rate",
259
- "振幅": "pct_chg",
260
- "涨跌额": "range",
261
- "成交额": "amount",
262
- "成交量": "volume",
263
- "换手率": "exchange",
264
- "量比": "quantity_ratio",
265
- "代码": "symbol",
266
- "名称": "name",
267
- "最高价": "high",
268
- "最低价": "low",
269
- "开盘价": "open",
270
- "昨收": "yesterday_price",
271
- "总市值": "total_mv",
272
- "流通市值": "flow_mv",
273
- "委比": "wei_bi",
274
- "外盘": "outer_disk",
275
- "内盘": "inner_disk",
276
- "主力净流入-净额": "today_main_net_inflow",
277
- "超大单净流入-净额": "super_large_order_net_inflow",
278
- "超大单净流入-净占比": "super_large_order_net_inflow_ratio",
279
- "大单净流入-净额": "large_order_net_inflow",
280
- # "f78": "medium_order_net_inflow",
281
- # "f84": "small_order_net_inflow",
282
- # "f103": "concept",
283
- "主力净流入-净占比": "today_main_net_inflow_ratio",
284
- "买一": "buy_1_num",
285
- "卖一": "sell_1_num",
286
- "最新份额": "latest_share",
287
- "数据日期": "data_time",
288
- "更新时间": "update_time"
289
- })
290
-
291
- fund_etf_spot_em_df = fund_etf_spot_em_df[[
292
- "now_price",
293
- "chg",
294
- "fund_discount_rate",
295
- "pct_chg",
296
- "range",
297
- "amount",
298
- "volume",
299
- "exchange",
300
- "quantity_ratio",
301
- "symbol",
302
- "name",
303
- "high",
304
- "low",
305
- "open",
306
- "yesterday_price",
307
- "total_mv",
308
- "flow_mv",
309
- "wei_bi",
310
- "outer_disk",
311
- "inner_disk",
312
- "today_main_net_inflow",
313
- "super_large_order_net_inflow",
314
- "super_large_order_net_inflow_ratio",
315
- "large_order_net_inflow",
316
- "today_main_net_inflow_ratio",
317
- "buy_1_num",
318
- "sell_1_num",
319
- "latest_share",
320
- "data_time",
321
- "update_time",
322
- "market",
323
- 'list_date'
324
- ]]
325
-
326
- fund_etf_spot_em_df['disk_ratio'] = round(
327
- (fund_etf_spot_em_df['outer_disk'] - fund_etf_spot_em_df['inner_disk']) / fund_etf_spot_em_df['inner_disk'], 2)
328
-
329
- fund_etf_spot_em_df.loc[:, 'reference_main_inflow'] = round(
330
- (fund_etf_spot_em_df['flow_mv'] * (1 / 1000)), 2)
331
-
332
- fund_etf_spot_em_df.loc[:, 'main_inflow_multiple'] = round(
333
- (fund_etf_spot_em_df['today_main_net_inflow'] / fund_etf_spot_em_df['reference_main_inflow']), 2)
334
-
335
- fund_etf_spot_em_df.loc[:, 'super_main_inflow_multiple'] = round(
336
- (fund_etf_spot_em_df['super_large_order_net_inflow'] / fund_etf_spot_em_df['reference_main_inflow']), 2)
337
- fund_etf_spot_em_df['large_inflow_multiple'] = round(
338
- (fund_etf_spot_em_df['large_order_net_inflow'] / fund_etf_spot_em_df['reference_main_inflow']), 2)
339
-
340
- fund_etf_spot_em_df['disk_diff_amount'] = round(
341
- (fund_etf_spot_em_df['outer_disk'] - fund_etf_spot_em_df['inner_disk']) * fund_etf_spot_em_df[
342
- "now_price"] * 100,
343
- 2)
344
-
345
- fund_etf_spot_em_df['disk_diff_amount_exchange'] = round(
346
- (fund_etf_spot_em_df['disk_diff_amount'] / fund_etf_spot_em_df['reference_main_inflow']), 2)
347
- fund_etf_spot_em_df.loc[:, 'sum_main_inflow_disk'] = fund_etf_spot_em_df['main_inflow_multiple'] + \
348
- fund_etf_spot_em_df['disk_diff_amount_exchange']
349
- fund_etf_spot_em_df = fund_etf_spot_em_df.fillna(0)
350
-
351
- fund_etf_spot_em_df.replace([np.inf, -np.inf], 0, inplace=True)
352
- return fund_etf_spot_em_df
353
-
354
-
355
- def get_etf_real_time_quotes(proxies):
356
- # 获取第一页数据
357
- page_one_df = get_fund_etf_page_df(1, proxies)
358
- # 数据接口正常返回5600以上的数量
359
- if page_one_df.shape[0] > min_number:
360
- page_one_df = rename_etf(page_one_df)
361
- page_one_df.drop_duplicates('symbol', keep='last', inplace=True)
362
- return page_one_df
363
- else:
364
- page_df = thread_pool_executor(proxies)
365
- page_df = rename_etf(page_df)
366
- page_df.drop_duplicates('symbol', keep='last', inplace=True)
367
- return page_df
368
-
369
-
370
- if __name__ == '__main__':
371
- fund_etf_df = get_etf_real_time_quotes(None)
372
- fund_etf_df = fund_etf_df.sort_values(by=['amount'], ascending=False)
373
- fund_etf_df = fund_etf_df.fillna(0)
374
- print(fund_etf_df)