mns-common 1.3.3.5__py3-none-any.whl → 1.5.7.2__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.
Files changed (76) hide show
  1. mns_common/api/akshare/__init__.py +0 -1
  2. mns_common/api/akshare/k_line_api.py +20 -82
  3. mns_common/api/akshare/stock_bid_ask_api.py +22 -97
  4. mns_common/api/akshare/stock_zb_pool.py +2 -0
  5. mns_common/api/akshare/stock_zt_pool_api.py +1 -1
  6. mns_common/api/em/gd/__init__.py +7 -0
  7. mns_common/api/em/{east_money_stock_gdfx_free_top_10_api.py → gd/east_money_stock_gdfx_free_top_10_api.py} +64 -9
  8. mns_common/api/em/real_time/__init__.py +7 -0
  9. mns_common/api/em/{east_money_debt_api.py → real_time/east_money_debt_api.py} +154 -69
  10. mns_common/api/em/{east_money_etf_api.py → real_time/east_money_etf_api.py} +149 -27
  11. mns_common/api/em/real_time/east_money_stock_a_api.py +301 -0
  12. mns_common/api/em/real_time/east_money_stock_a_v2_api.py +340 -0
  13. mns_common/api/em/real_time/east_money_stock_common_api.py +174 -0
  14. mns_common/api/em/real_time/east_money_stock_hk_api.py +288 -0
  15. mns_common/api/em/real_time/east_money_stock_hk_gtt_api.py +260 -0
  16. mns_common/api/em/real_time/east_money_stock_multi_thread_api_v3.py +154 -0
  17. mns_common/api/em/{east_money_stock_us_api.py → real_time/east_money_stock_us_api.py} +149 -72
  18. mns_common/api/em/real_time/real_time_quotes_repeat_api.py +195 -0
  19. mns_common/api/k_line/stock_k_line_data_api.py +11 -1
  20. mns_common/api/k_line/stock_minute_data_api.py +1 -0
  21. mns_common/api/kpl/common/kpl_common_api.py +35 -0
  22. mns_common/api/kpl/symbol/symbol_his_quotes_api.py +1 -1
  23. mns_common/api/proxies/__init__.py +7 -0
  24. mns_common/api/proxies/liu_guan_proxy_api.py +115 -0
  25. mns_common/api/ths/company/company_product_area_industry_index_query.py +46 -0
  26. mns_common/api/ths/company/ths_company_info_api.py +13 -9
  27. mns_common/api/ths/company/ths_company_info_web.py +159 -0
  28. mns_common/api/ths/concept/app/ths_concept_index_app.py +3 -1
  29. mns_common/api/ths/wen_cai/ths_wen_cai_api.py +10 -7
  30. mns_common/api/ths/zt/ths_stock_zt_pool_api.py +21 -4
  31. mns_common/api/ths/zt/ths_stock_zt_pool_v2_api.py +111 -40
  32. mns_common/api/xueqiu/__init__.py +7 -0
  33. mns_common/api/xueqiu/xue_qiu_k_line_api.py +83 -0
  34. mns_common/component/__init__.py +1 -1
  35. mns_common/component/classify/symbol_classify_api.py +7 -7
  36. mns_common/component/common_service_fun_api.py +66 -6
  37. mns_common/component/company/company_common_service_api.py +21 -1
  38. mns_common/component/company/company_common_service_new_api.py +4 -1
  39. mns_common/component/cookie/cookie_enum.py +15 -0
  40. mns_common/component/cookie/cookie_info_service.py +9 -4
  41. mns_common/component/data/data_init_api.py +13 -8
  42. mns_common/component/deal/deal_service_api.py +70 -8
  43. mns_common/component/deal/deal_service_v2_api.py +167 -0
  44. mns_common/component/em/__init__.py +7 -0
  45. mns_common/component/em/em_real_time_quotes_api.py +56 -0
  46. mns_common/component/em/em_stock_info_api.py +48 -0
  47. mns_common/component/exception/ExceptionMonitor.py +86 -0
  48. mns_common/component/exception/__init__.py +7 -0
  49. mns_common/component/k_line/common/k_line_common_service_api.py +4 -0
  50. mns_common/component/main_line/__init__.py +7 -0
  51. mns_common/component/main_line/main_line_zt_reason_service.py +237 -0
  52. mns_common/component/proxies/__init__.py +7 -0
  53. mns_common/component/proxies/proxy_common_api.py +252 -0
  54. mns_common/component/self_choose/__init__.py +13 -0
  55. mns_common/component/tfp/stock_tfp_api.py +82 -12
  56. mns_common/component/us/__init__.py +7 -0
  57. mns_common/component/us/us_stock_etf_info_api.py +125 -0
  58. mns_common/constant/__init__.py +1 -0
  59. mns_common/constant/db_name_constant.py +65 -34
  60. mns_common/constant/extra_income_db_name.py +154 -0
  61. mns_common/constant/strategy_classify.py +72 -0
  62. mns_common/db/MongodbUtil.py +2 -1
  63. mns_common/db/MongodbUtilLocal.py +1 -0
  64. mns_common/db/v2/MongodbUtilV2.py +0 -4
  65. mns_common-1.5.7.2.dist-info/METADATA +4 -0
  66. {mns_common-1.3.3.5.dist-info → mns_common-1.5.7.2.dist-info}/RECORD +70 -45
  67. {mns_common-1.3.3.5.dist-info → mns_common-1.5.7.2.dist-info}/WHEEL +1 -1
  68. mns_common/api/em/east_money_stock_api.py +0 -222
  69. mns_common/api/em/east_money_stock_hk_api.py +0 -318
  70. mns_common/api/em/east_money_stock_v2_api.py +0 -219
  71. mns_common/api/ths/concept/web/ths_company_info_web.py +0 -163
  72. mns_common/component/qmt/qmt_buy_service.py +0 -172
  73. mns_common-1.3.3.5.dist-info/METADATA +0 -4
  74. /mns_common/{component/qmt → api/em/concept}/__init__.py +0 -0
  75. /mns_common/api/em/{em_concept_index_api.py → concept/em_concept_index_api.py} +0 -0
  76. {mns_common-1.3.3.5.dist-info → mns_common-1.5.7.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,237 @@
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 mns_common.constant.db_name_constant as db_name_constant
9
+ from mns_common.db.MongodbUtil import MongodbUtil
10
+ import mns_common.api.ths.zt.ths_stock_zt_pool_api as ths_stock_zt_pool_api
11
+ from mns_common.utils.async_fun import async_fun
12
+ import mns_common.component.trade_date.trade_date_common_service_api as trade_date_common_service_api
13
+
14
+ mongodb_util = MongodbUtil('27017')
15
+ import mns_common.utils.data_frame_util as data_frame_util
16
+ import time
17
+ from loguru import logger
18
+ import pandas as pd
19
+ from datetime import datetime
20
+
21
+
22
+ # 添加主线和涨停分析临时数据
23
+ def merge_main_line_info(str_day, data_df):
24
+ # 保证数据完整性
25
+ if 'main_line' not in data_df.columns:
26
+ data_df['main_line'] = ''
27
+ else:
28
+ data_df.fillna({'main_line': ''}, inplace=True)
29
+
30
+ if 'sub_main_line' not in data_df.columns:
31
+ data_df['sub_main_line'] = ''
32
+ else:
33
+ data_df.fillna({'sub_main_line': ''}, inplace=True)
34
+
35
+ if 'zt_analysis' not in data_df.columns:
36
+ data_df['zt_analysis'] = ''
37
+
38
+ else:
39
+ data_df.fillna({'zt_analysis': ''}, inplace=True)
40
+
41
+ if 'zt_reason' not in data_df.columns:
42
+ data_df['zt_reason'] = ''
43
+ else:
44
+ data_df.fillna({'zt_reason': ''}, inplace=True)
45
+
46
+ if 'main_line_choose_source' not in data_df.columns:
47
+ data_df['main_line_choose_source'] = 'now_zt'
48
+ else:
49
+ data_df.fillna({'main_line_choose_source': 'now_zt'}, inplace=True)
50
+
51
+ if 'main_line_grade' not in data_df.columns:
52
+ data_df['main_line_grade'] = 1
53
+ else:
54
+ data_df.fillna({'main_line_grade': 1}, inplace=True)
55
+
56
+ query_zt_now = {'symbol': {"$in": list(data_df['symbol'])}, 'str_day': str_day}
57
+ # merge 主线 涨停详情
58
+ main_line_detail_df = mongodb_util.find_query_data(db_name_constant.MAIN_LINE_DETAIL, query_zt_now)
59
+ if data_frame_util.is_not_empty(main_line_detail_df):
60
+ symbol_mapping_zt_reason_now = dict(
61
+ zip(main_line_detail_df['symbol'], main_line_detail_df['zt_reason']))
62
+
63
+ symbol_mapping_zt_analysis_now = dict(
64
+ zip(main_line_detail_df['symbol'], main_line_detail_df['zt_analysis']))
65
+
66
+ symbol_mapping_main_line_now = dict(
67
+ zip(main_line_detail_df['symbol'], main_line_detail_df['main_line']))
68
+
69
+ symbol_mapping_sub_main_line_now = dict(
70
+ zip(main_line_detail_df['symbol'], main_line_detail_df['sub_main_line']))
71
+
72
+ symbol_mapping_main_line_choose_source = dict(
73
+ zip(main_line_detail_df['symbol'], main_line_detail_df['main_line_choose_source']))
74
+
75
+ symbol_mapping_main_line_grade = dict(
76
+ zip(main_line_detail_df['symbol'], main_line_detail_df['main_line_grade']))
77
+
78
+ data_df['main_line_grade'] = data_df['symbol'].map(
79
+ symbol_mapping_main_line_grade).fillna(
80
+ data_df['main_line_grade'])
81
+
82
+ data_df['main_line'] = data_df['symbol'].map(
83
+ symbol_mapping_main_line_now).fillna(
84
+ data_df['main_line'])
85
+
86
+ data_df['sub_main_line'] = data_df['symbol'].map(
87
+ symbol_mapping_sub_main_line_now).fillna(
88
+ data_df['sub_main_line'])
89
+ data_df['zt_reason'] = data_df['symbol'].map(
90
+ symbol_mapping_zt_reason_now).fillna(
91
+ data_df['zt_reason'])
92
+ data_df['zt_analysis'] = data_df['symbol'].map(
93
+ symbol_mapping_zt_analysis_now).fillna(
94
+ data_df['zt_analysis'])
95
+
96
+ data_df['main_line_choose_source'] = data_df['symbol'].map(
97
+ symbol_mapping_main_line_choose_source).fillna(
98
+ data_df['main_line_choose_source'])
99
+
100
+ return data_df
101
+
102
+
103
+ # merge涨停分析 原因
104
+ def merge_zt_reason_info(str_day, data_df):
105
+ if 'zt_analysis' not in data_df.columns:
106
+ data_df['zt_analysis'] = ''
107
+
108
+ else:
109
+ data_df.fillna({'zt_analysis': ''}, inplace=True)
110
+
111
+ if 'zt_reason' not in data_df.columns:
112
+ data_df['zt_reason'] = ''
113
+ else:
114
+ data_df.fillna({'zt_reason': ''}, inplace=True)
115
+
116
+ query_zt_now = {'symbol': {"$in": list(data_df['symbol'])}, 'str_day': str_day}
117
+ # merge 主线 涨停详情
118
+ zt_reason_analysis_df = mongodb_util.find_query_data(db_name_constant.ZT_REASON_ANALYSIS, query_zt_now)
119
+ if data_frame_util.is_not_empty(zt_reason_analysis_df):
120
+ symbol_mapping_zt_reason_now = dict(
121
+ zip(zt_reason_analysis_df['symbol'], zt_reason_analysis_df['zt_reason']))
122
+
123
+ symbol_mapping_zt_analysis_now = dict(
124
+ zip(zt_reason_analysis_df['symbol'], zt_reason_analysis_df['zt_analysis']))
125
+
126
+ data_df['zt_reason'] = data_df['symbol'].map(
127
+ symbol_mapping_zt_reason_now).fillna(
128
+ data_df['zt_reason'])
129
+ data_df['zt_analysis'] = data_df['symbol'].map(
130
+ symbol_mapping_zt_analysis_now).fillna(
131
+ data_df['zt_analysis'])
132
+
133
+ return data_df
134
+
135
+
136
+ def update_zt_reason_analysis(symbol, str_day, name, need_update):
137
+ try:
138
+ key_id = symbol + "_" + str_day
139
+ query_zt = {"_id": key_id}
140
+
141
+ # 已经存在的数据
142
+ zt_reason_analysis_exists_df = mongodb_util.find_query_data(db_name_constant.ZT_REASON_ANALYSIS,
143
+ query_zt)
144
+
145
+ if data_frame_util.is_not_empty(zt_reason_analysis_exists_df):
146
+ zt_analysis = list(zt_reason_analysis_exists_df['zt_analysis'])[0]
147
+ zt_reason = list(zt_reason_analysis_exists_df['zt_reason'])[0]
148
+ # 需要更新数据
149
+ if data_frame_util.is_string_empty(zt_analysis) or data_frame_util.is_string_empty(
150
+ zt_reason) or need_update:
151
+ try:
152
+ zt_result_dict = ths_stock_zt_pool_api.zt_analyse_reason(symbol)
153
+ zt_analysis = zt_result_dict['zt_analyse_detail']
154
+ zt_reason = zt_result_dict['zt_reason']
155
+ time.sleep(1)
156
+ except BaseException as e:
157
+ time.sleep(1)
158
+ zt_analysis = ''
159
+ zt_reason = ''
160
+
161
+ zt_reason_analysis_exists_df['zt_analysis'] = zt_analysis
162
+ zt_reason_analysis_exists_df['zt_reason'] = zt_reason
163
+ now_date = datetime.now()
164
+ str_now_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
165
+ zt_reason_analysis_exists_df['str_now_date'] = str_now_date
166
+ mongodb_util.save_mongo(zt_reason_analysis_exists_df, db_name_constant.ZT_REASON_ANALYSIS)
167
+ else:
168
+ # 不存在临时主线数据
169
+ try:
170
+ zt_result_dict = ths_stock_zt_pool_api.zt_analyse_reason(symbol)
171
+ zt_analysis = zt_result_dict['zt_analyse_detail']
172
+ zt_reason = zt_result_dict['zt_reason']
173
+ time.sleep(1)
174
+ except BaseException as e:
175
+ time.sleep(1)
176
+ zt_analysis = ''
177
+ zt_reason = ''
178
+ now_date = datetime.now()
179
+ str_now_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
180
+ reason_dict = {'_id': key_id,
181
+ 'symbol': symbol,
182
+ 'name': name,
183
+ 'zt_analysis': zt_analysis,
184
+ 'zt_reason': zt_reason,
185
+ 'str_day': str_day,
186
+ 'update_time': str_now_date,
187
+ }
188
+ reason_df = pd.DataFrame(reason_dict, index=[1])
189
+ mongodb_util.save_mongo(reason_df, db_name_constant.ZT_REASON_ANALYSIS)
190
+ except BaseException as e:
191
+ logger.error("添加涨停原因详情异常:{},{}", e, name)
192
+
193
+
194
+ @async_fun
195
+ def update_symbol_list_zt_reason_analysis(data_df, need_update):
196
+ for stock_one in data_df.itertuples():
197
+ str_day = stock_one.str_day
198
+ symbol = stock_one.symbol
199
+ name = stock_one.name
200
+ update_zt_reason_analysis(symbol, str_day, name, need_update)
201
+ time.sleep(1)
202
+
203
+
204
+ # 保存连板股票主线
205
+ @async_fun
206
+ def save_last_trade_day_main_line(str_day, stock_em_zt_pool_df_data):
207
+ last_trade_day = trade_date_common_service_api.get_last_trade_day(str_day)
208
+ stock_em_zt_pool_connected_df = stock_em_zt_pool_df_data.loc[
209
+ stock_em_zt_pool_df_data['connected_boards_numbers'] > 1]
210
+ if data_frame_util.is_empty(stock_em_zt_pool_connected_df):
211
+ return
212
+ else:
213
+ query = {'str_day': last_trade_day, 'symbol': {"$in": list(stock_em_zt_pool_connected_df['symbol'])}}
214
+ last_trade_day_main_line_detail_df = mongodb_util.find_query_data(db_name_constant.MAIN_LINE_DETAIL, query)
215
+ if data_frame_util.is_empty(last_trade_day_main_line_detail_df):
216
+ return
217
+ else:
218
+ last_trade_day_main_line_detail_df['_id'] = last_trade_day_main_line_detail_df['symbol'] + '_' + str_day
219
+ last_trade_day_main_line_detail_df['str_day'] = str_day
220
+ last_trade_day_main_line_detail_df['connected_boards_numbers'] = last_trade_day_main_line_detail_df[
221
+ 'connected_boards_numbers'] + 1
222
+ now_date = datetime.now()
223
+ str_now_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
224
+ last_trade_day_main_line_detail_df['update_time'] = str_now_date
225
+ today_exist_main_line_df = mongodb_util.find_query_data(db_name_constant.MAIN_LINE_DETAIL,
226
+ {'str_day': str_day, 'symbol': {"$in": list(
227
+ last_trade_day_main_line_detail_df['symbol'])}})
228
+ if data_frame_util.is_not_empty(today_exist_main_line_df):
229
+ today_new_main_line_df = last_trade_day_main_line_detail_df.loc[~
230
+ last_trade_day_main_line_detail_df['symbol'].isin(list(today_exist_main_line_df['symbol']))]
231
+ else:
232
+ today_new_main_line_df = last_trade_day_main_line_detail_df.copy()
233
+ mongodb_util.save_mongo(today_new_main_line_df, db_name_constant.MAIN_LINE_DETAIL)
234
+
235
+
236
+ if __name__ == '__main__':
237
+ update_zt_reason_analysis('600362', '2025-12-26', '江西铜业', True)
@@ -0,0 +1,7 @@
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)
@@ -0,0 +1,252 @@
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
+ import mns_common.api.proxies.liu_guan_proxy_api as liu_guan_proxy_api
10
+ import pandas as pd
11
+ import mns_common.utils.data_frame_util as data_frame_util
12
+ from mns_common.db.MongodbUtil import MongodbUtil
13
+ import mns_common.constant.db_name_constant as db_name_constant
14
+ import datetime
15
+ import time
16
+ from loguru import logger
17
+ from functools import lru_cache
18
+ import mns_common.api.em.real_time.east_money_stock_a_api as east_money_stock_a_api
19
+ import threading
20
+
21
+ mongodb_util = MongodbUtil('27017')
22
+
23
+ IP_POOL = 'ip_pool'
24
+ ONE_IP = 'one_ip'
25
+ query_one = {'ip_type': ONE_IP}
26
+ query_pool = {'ip_type': IP_POOL}
27
+
28
+
29
+ def query_liu_guan_proxy_ip():
30
+ ip_proxy_pool = mongodb_util.find_query_data(db_name_constant.IP_PROXY_POOL, query_one)
31
+ return ip_proxy_pool
32
+
33
+
34
+ def remove_one_proxy_ip():
35
+ mongodb_util.remove_data(query_one, db_name_constant.IP_PROXY_POOL)
36
+
37
+
38
+ def check_valid(ip_proxy_pool):
39
+ effect_time = list(ip_proxy_pool['effect_time'])[0]
40
+ now_date = datetime.datetime.now()
41
+ str_now_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
42
+ if effect_time > str_now_date:
43
+ return True
44
+ else:
45
+ remove_one_proxy_ip()
46
+ return False
47
+
48
+
49
+ @lru_cache(maxsize=None)
50
+ def get_account_cache():
51
+ query = {"type": "liu_guan_proxy"}
52
+ return mongodb_util.find_query_data(db_name_constant.STOCK_ACCOUNT_INFO, query)
53
+
54
+
55
+ def generate_proxy_ip_api(minutes):
56
+ try_numer = 3
57
+ while try_numer > 0:
58
+ try:
59
+ stock_account_info = get_account_cache()
60
+ order_id = list(stock_account_info['password'])[0]
61
+ secret = list(stock_account_info['account'])[0]
62
+ # 获取10分钟动态ip
63
+ liu_guan_ip = liu_guan_proxy_api.get_proxy_api(order_id, secret, str(60 * minutes))
64
+ try_numer = try_numer
65
+ logger.info("生成新的ip:{}", liu_guan_ip)
66
+ return liu_guan_ip
67
+ except BaseException as e:
68
+ logger.error("获取ip失败:{}", str(e))
69
+ time.sleep(1)
70
+ continue
71
+
72
+
73
+ def generate_proxy_ip(minutes):
74
+ ip_proxy_pool = query_liu_guan_proxy_ip()
75
+ if data_frame_util.is_not_empty(ip_proxy_pool):
76
+ return list(ip_proxy_pool['ip'])[0]
77
+ else:
78
+ remove_one_proxy_ip()
79
+ now_date = datetime.datetime.now()
80
+ # 加上分钟
81
+ time_to_add = datetime.timedelta(minutes=minutes)
82
+ new_date = now_date + time_to_add
83
+ str_now_date = new_date.strftime('%Y-%m-%d %H:%M:%S')
84
+ try:
85
+ ip_proxy = generate_proxy_ip_api(minutes)
86
+
87
+ result_dict = {"_id": ip_proxy,
88
+ 'ip_type': ONE_IP,
89
+ 'effect_time': str_now_date,
90
+ 'ip': ip_proxy}
91
+ result_df = pd.DataFrame(result_dict, index=[1])
92
+
93
+ mongodb_util.insert_mongo(result_df, db_name_constant.IP_PROXY_POOL)
94
+ except BaseException as e:
95
+ logger.error("获取ip失败:{}", str(e))
96
+
97
+ return ip_proxy
98
+
99
+
100
+ def get_proxy_ip(minutes):
101
+ ip_proxy_pool = query_liu_guan_proxy_ip()
102
+ if data_frame_util.is_empty(ip_proxy_pool):
103
+ return generate_proxy_ip(minutes)
104
+ else:
105
+ if check_valid(ip_proxy_pool):
106
+ return list(ip_proxy_pool['ip'])[0]
107
+ else:
108
+ return generate_proxy_ip(minutes)
109
+
110
+
111
+ #
112
+ # def check_proxy(proxy_ip):
113
+ # try:
114
+ # # 两秒超时
115
+ # test_df = call_with_timeout(get_em_real_time_data, proxy_ip, timeout=2)
116
+ # if data_frame_util.is_not_empty(test_df):
117
+ # logger.info("可用代理ip:{}", proxy_ip)
118
+ # return True
119
+ # else:
120
+ # return False
121
+ # except Exception as e:
122
+ # logger.error("代理ip不可用:{},{}", proxy_ip, e)
123
+ # return False
124
+
125
+
126
+ # 查询ip池子
127
+ def query_liu_guan_proxy_ip_pool():
128
+ ip_proxy_pool = mongodb_util.find_query_data(db_name_constant.IP_PROXY_POOL, query_pool)
129
+ return ip_proxy_pool
130
+
131
+
132
+ def remove_proxy_ip_pool():
133
+ mongodb_util.remove_data(query_pool, db_name_constant.IP_PROXY_POOL)
134
+
135
+
136
+ def generate_proxy_ip_pool_api(minutes, ip_num):
137
+ stock_account_info = get_account_cache()
138
+ order_id = list(stock_account_info['password'])[0]
139
+ secret = list(stock_account_info['account'])[0]
140
+ # 获取10分钟动态ip
141
+ ip_pool = liu_guan_proxy_api.get_proxy_pool_api(order_id, secret, str(60 * minutes), ip_num)
142
+ return ip_pool
143
+
144
+
145
+ def get_proxy_ip_pool(minutes, seconds, ip_num):
146
+ ip_proxy_pool = query_liu_guan_proxy_ip_pool()
147
+ if data_frame_util.is_empty(ip_proxy_pool):
148
+ return generate_proxy_ip_pool(minutes, seconds, ip_num)
149
+ else:
150
+ if check_valid(ip_proxy_pool):
151
+ ip_pool = list(ip_proxy_pool['ip_pool'])[0]
152
+ effect_time = list(ip_proxy_pool['effect_time'])[0]
153
+ result = {'ip_pool': ip_pool,
154
+ 'effect_time': effect_time}
155
+ return result
156
+ else:
157
+ # 已经失效 移除ip pool
158
+ remove_proxy_ip_pool()
159
+ # 重新生成
160
+ return generate_proxy_ip_pool(minutes, seconds, ip_num)
161
+
162
+
163
+ # seconds 有效秒数,minutes 需要减1
164
+ def generate_proxy_ip_pool(minutes, seconds, ip_num):
165
+ ip_proxy_pool = query_liu_guan_proxy_ip_pool()
166
+ if data_frame_util.is_not_empty(ip_proxy_pool):
167
+ ip_pool = list(ip_proxy_pool['ip_pool'])[0]
168
+ effect_time = list(ip_proxy_pool['effect_time'])[0]
169
+
170
+
171
+ else:
172
+ remove_proxy_ip_pool()
173
+ now_date = datetime.datetime.now()
174
+ # 加上分钟 少10秒
175
+ time_to_add = datetime.timedelta(minutes=minutes - 1, seconds=seconds)
176
+ new_date = now_date + time_to_add
177
+ effect_time = new_date.strftime('%Y-%m-%d %H:%M:%S')
178
+ ip_pool = generate_proxy_ip_pool_api(minutes, ip_num)
179
+ result_dict = {
180
+ "_id": [IP_POOL],
181
+ 'ip_type': [IP_POOL],
182
+ 'effect_time': [effect_time],
183
+ 'ip_pool': [ip_pool] # 每个字段都包装成列表
184
+ }
185
+ result_df = pd.DataFrame(result_dict)
186
+
187
+ mongodb_util.insert_mongo(result_df, db_name_constant.IP_PROXY_POOL)
188
+ result = {'ip_pool': ip_pool,
189
+ 'effect_time': effect_time}
190
+ return result
191
+
192
+
193
+ def get_em_real_time_data(proxy_ip):
194
+ proxies = {
195
+ "http": proxy_ip,
196
+ "https": proxy_ip
197
+ }
198
+ return east_money_stock_a_api.get_stock_page_data(1, proxies, 20, 10)
199
+
200
+
201
+ # 定义一个带超时的函数调用
202
+ def call_with_timeout(func, *args, timeout=2, **kwargs):
203
+ # 用于存储函数执行结果
204
+ result = None
205
+ exception = None
206
+
207
+ # 定义一个线程目标函数
208
+ def target():
209
+ nonlocal result, exception
210
+ try:
211
+ result = func(*args, **kwargs)
212
+ except Exception as e:
213
+ exception = e
214
+
215
+ # 创建线程并启动
216
+ thread = threading.Thread(target=target)
217
+ thread.start()
218
+
219
+ # 等待线程完成,最多等待 timeout 秒
220
+ thread.join(timeout)
221
+
222
+ # 如果线程仍然存活,说明函数超时了
223
+ if thread.is_alive():
224
+ raise TimeoutError(f"Function exceeded timeout of {timeout} seconds")
225
+
226
+ # 如果函数抛出了异常,重新抛出
227
+ if exception is not None:
228
+ raise exception
229
+ return result
230
+
231
+
232
+ @lru_cache(maxsize=None)
233
+ def query_province_and_city_info():
234
+ return mongodb_util.find_all_data(db_name_constant.IP_PROXY_CITY_PROVINCE)
235
+
236
+
237
+ def import_province_and_city():
238
+ # 设置文件夹路径
239
+ folder_path = r'E:\province-and-city.xlsx'
240
+ df = pd.read_excel(folder_path)
241
+ df['_id'] = df['cid']
242
+
243
+ mongodb_util.save_mongo(df, db_name_constant.IP_PROXY_CITY_PROVINCE)
244
+ return df
245
+
246
+
247
+ if __name__ == "__main__":
248
+ stock_account_info_test = get_account_cache()
249
+ order_id_test = list(stock_account_info_test['password'])[0]
250
+ secret_test = list(stock_account_info_test['account'])[0]
251
+ # 获取10分钟动态ip
252
+ ip = liu_guan_proxy_api.get_proxy_api(order_id_test, secret_test, str(60 * 1))
@@ -5,3 +5,16 @@ file_path = os.path.abspath(__file__)
5
5
  end = file_path.index('mns') + 16
6
6
  project_path = file_path[0:end]
7
7
  sys.path.append(project_path)
8
+
9
+ import requests
10
+
11
+
12
+ def get_qq_hang_qing():
13
+ url = 'https://proxy.finance.qq.com/cgi/cgi-bin/rank/hs/getBoardRankList?_appver=11.17.0&board_code=aStock&sort_type=turnover&direct=down&offset=1&count=1'
14
+ return requests.get(url)
15
+
16
+
17
+ if __name__ == '__main__':
18
+ while True:
19
+ r = get_qq_hang_qing()
20
+ print(r.status_code)
@@ -5,7 +5,6 @@ file_path = os.path.abspath(__file__)
5
5
  end = file_path.index('mns') + 16
6
6
  project_path = file_path[0:end]
7
7
  sys.path.append(project_path)
8
- import akshare as ak
9
8
  import mns_common.utils.date_handle_util as date_handle_util
10
9
  from loguru import logger
11
10
  import mns_common.utils.data_frame_util as data_frame_util
@@ -15,20 +14,87 @@ import mns_common.constant.db_name_constant as db_name_constant
15
14
 
16
15
  mongodb_util = MongodbUtil('27017')
17
16
 
17
+ """
18
+ Date: 2024/4/29 15:00
19
+ Desc: 东方财富网-数据中心-特色数据-停复牌信息
20
+ https://data.eastmoney.com/tfpxx/
21
+ """
22
+
23
+ import pandas as pd
24
+ import requests
25
+
26
+
27
+ def stock_tfp_em(date: str = "20240426") -> pd.DataFrame:
28
+ """
29
+ 东方财富网-数据中心-特色数据-停复牌信息
30
+ https://data.eastmoney.com/tfpxx/
31
+ :param date: specific date as "2020-03-19"
32
+ :type date: str
33
+ :return: 停复牌信息表
34
+ :rtype: pandas.DataFrame
35
+ """
36
+ url = "https://datacenter-web.eastmoney.com/api/data/v1/get"
37
+ params = {
38
+ "sortColumns": "SUSPEND_START_DATE",
39
+ "sortTypes": "-1",
40
+ "pageSize": "500",
41
+ "pageNumber": "1",
42
+ "reportName": "RPT_CUSTOM_SUSPEND_DATA_INTERFACE",
43
+ "columns": "ALL",
44
+ "source": "WEB",
45
+ "client": "WEB",
46
+ "filter": f"""(MARKET="全部")(DATETIME='{"-".join([date[:4], date[4:6], date[6:]])}')""",
47
+ }
48
+ r = requests.get(url, params=params)
49
+ data_json = r.json()
50
+ total_page = data_json["result"]["pages"]
51
+ big_df = pd.DataFrame()
52
+ for page in range(1, total_page + 1):
53
+ params.update({"pageNumber": page})
54
+ r = requests.get(url, params=params)
55
+ data_json = r.json()
56
+ temp_df = pd.DataFrame(data_json["result"]["data"])
57
+ big_df = pd.concat(objs=[big_df, temp_df], ignore_index=True)
58
+
59
+ big_df.reset_index(inplace=True)
60
+
61
+ big_df["SUSPEND_START_TIME"] = pd.to_datetime(big_df["SUSPEND_START_TIME"], errors="coerce").dt.date
62
+ big_df["SUSPEND_END_TIME"] = pd.to_datetime(
63
+ big_df["SUSPEND_END_TIME"], errors="coerce"
64
+ ).dt.date
65
+
66
+ big_df["SUSPEND_START_DATE"] = pd.to_datetime(
67
+ big_df["SUSPEND_START_DATE"], errors="coerce"
68
+ ).dt.date
69
+ big_df["PREDICT_RESUME_DATE"] = pd.to_datetime(
70
+ big_df["PREDICT_RESUME_DATE"], errors="coerce"
71
+ ).dt.date
72
+
73
+ big_df = big_df[['index', 'SECURITY_CODE', 'SECURITY_NAME_ABBR', 'SUSPEND_START_TIME',
74
+ 'SUSPEND_END_TIME', 'SUSPEND_EXPIRE', 'SUSPEND_REASON', 'TRADE_MARKET',
75
+ 'SUSPEND_START_DATE',
76
+ 'PREDICT_RESUME_DATE'
77
+ ]]
78
+
79
+ return big_df
80
+
18
81
 
19
82
  def get_stock_tfp_by_day(str_day):
20
- stock_tfp_em_df = ak.stock_tfp_em(date_handle_util.no_slash_date(str_day))
83
+ stock_tfp_em_df = stock_tfp_em(date_handle_util.no_slash_date(str_day))
21
84
  stock_tfp_em_df = stock_tfp_em_df.rename(
22
- columns={'序号': 'index',
23
- '代码': 'symbol',
24
- '名称': 'name',
25
- '停牌时间': 'sus_begin_time',
26
- '停牌截止时间': 'sus_end_time',
27
- '停牌截止时间': 'sus_end_time',
28
- '停牌期限': 'sus_period',
29
- '停牌原因': 'sus_reason',
30
- '所属市场': 'market',
31
- '预计复牌时间': 'resume_time'
85
+ columns={'index': 'index',
86
+ 'SECURITY_CODE': 'symbol',
87
+ 'SECURITY_NAME_ABBR': 'name',
88
+ 'SUSPEND_START_TIME': 'sus_begin_time',
89
+ 'SUSPEND_END_TIME': 'sus_end_time',
90
+
91
+ 'SUSPEND_START_DATE': 'sus_begin_date',
92
+ 'PREDICT_RESUME_DATE': 'resume_time',
93
+
94
+ 'SUSPEND_EXPIRE': 'sus_period',
95
+ 'SUSPEND_REASON': 'sus_reason',
96
+ 'TRADE_MARKET': 'market',
97
+
32
98
  })
33
99
  return stock_tfp_em_df
34
100
 
@@ -60,3 +126,7 @@ def get_stock_tfp_symbol_from_db(str_day):
60
126
  except BaseException as e:
61
127
  logger.error("获取停牌信息异常:{}", e)
62
128
  return ['666666']
129
+
130
+
131
+ if __name__ == '__main__':
132
+ get_stock_tfp_symbol_list_by_day('2025-06-21')
@@ -0,0 +1,7 @@
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)