mns-scheduler 1.4.3.2__py3-none-any.whl → 1.4.5.7__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 (41) hide show
  1. mns_scheduler/{company_info/announce → auto_da_ban}/__init__.py +1 -1
  2. mns_scheduler/auto_da_ban/auto_da_ban_service.py +89 -0
  3. mns_scheduler/company_info/clean/company_info_clean_api.py +37 -16
  4. mns_scheduler/company_info/{base → common}/__init__.py +1 -1
  5. mns_scheduler/company_info/common/company_common_query_service.py +45 -0
  6. mns_scheduler/company_info/constant/company_constant_data.py +59 -49
  7. mns_scheduler/company_info/em_stock_info/sync_em_stock_info_sync.py +94 -40
  8. mns_scheduler/company_info/{remark → sync}/__init__.py +1 -1
  9. mns_scheduler/company_info/sync/company_info_set_service.py +208 -0
  10. mns_scheduler/company_info/sync/sync_company_info_task.py +203 -0
  11. mns_scheduler/company_info/task/__init__.py +7 -0
  12. mns_scheduler/company_info/{announce/company_announce_sync_service.py → task/company_announce_info_task.py} +25 -13
  13. mns_scheduler/company_info/task/company_base_info_task.py +64 -0
  14. mns_scheduler/company_info/{base/sync_company_product_area_industry.py → task/company_business_info_task.py} +33 -17
  15. mns_scheduler/company_info/task/company_hold_info_task.py +66 -0
  16. mns_scheduler/company_info/task/company_industry_info_task.py +167 -0
  17. mns_scheduler/company_info/task/company_total_task.py +69 -0
  18. mns_scheduler/concept/ths/common/ths_concept_sync_common_api.py +3 -3
  19. mns_scheduler/concept/ths/update_concept_info/sync_one_symbol_all_concepts_api.py +1 -1
  20. mns_scheduler/db/script/sync/remote_data_sync_to_local.py +11 -3
  21. mns_scheduler/irm/api/sh_stock_sns_sse_info_api.py +7 -57
  22. mns_scheduler/irm/api/sz_stock_sns_sse_info_api.py +14 -25
  23. mns_scheduler/irm/stock_irm_cninfo_service.py +34 -26
  24. mns_scheduler/irm/stock_question_id_service.py +169 -0
  25. mns_scheduler/self_choose/ths_self_choose_service.py +53 -25
  26. mns_scheduler/trade/auto_login/trader_auto_service.py +2 -1
  27. mns_scheduler/trade/task/trader_task_service.py +13 -2
  28. mns_scheduler/trade/tfp/stock_tfp_info_sync.py +1 -1
  29. mns_scheduler/zb/stock_zb_pool_sync.py +1 -1
  30. mns_scheduler/zt/zt_pool/em_zt_pool_sync_api.py +80 -104
  31. mns_scheduler/zt/zt_pool/ths_zt_pool_sync_api.py +1 -1
  32. mns_scheduler/zt/zt_pool/update_null_zt_reason_api.py +4 -1
  33. mns_scheduler/zz_task/compensation/compensate_task_one_day.py +1 -1
  34. mns_scheduler/zz_task/data_sync_task.py +45 -37
  35. {mns_scheduler-1.4.3.2.dist-info → mns_scheduler-1.4.5.7.dist-info}/METADATA +1 -1
  36. {mns_scheduler-1.4.3.2.dist-info → mns_scheduler-1.4.5.7.dist-info}/RECORD +38 -31
  37. mns_scheduler/company_info/base/sync_company_base_info_api.py +0 -531
  38. mns_scheduler/company_info/base/sync_company_hold_info_api.py +0 -37
  39. mns_scheduler/company_info/remark/company_remark_info_sync.py +0 -46
  40. {mns_scheduler-1.4.3.2.dist-info → mns_scheduler-1.4.5.7.dist-info}/WHEEL +0 -0
  41. {mns_scheduler-1.4.3.2.dist-info → mns_scheduler-1.4.5.7.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,169 @@
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
+ """
10
+ """
11
+
12
+ from functools import lru_cache
13
+ import pandas as pd
14
+ import requests
15
+ from bs4 import BeautifulSoup
16
+ from mns_common.db.MongodbUtil import MongodbUtil
17
+ import mns_common.constant.db_name_constant as db_name_constant
18
+ import mns_common.component.common_service_fun_api as common_service_fun_api
19
+ import mns_common.component.em.em_stock_info_api as em_stock_info_api
20
+ import mns_common.component.company.company_common_service_api as company_common_service_api
21
+ from loguru import logger
22
+ import mns_common.utils.data_frame_util as data_frame_util
23
+ from datetime import datetime, timedelta
24
+
25
+ mongodb_util = MongodbUtil('27017')
26
+ from tqdm import tqdm
27
+
28
+
29
+ # 同步所有映射表
30
+ @lru_cache()
31
+ def sync_stock_uid() -> pd.DataFrame:
32
+ """
33
+ 上证e互动-代码ID映射
34
+ https://sns.sseinfo.com/list/company.do
35
+ :return: 代码ID映射
36
+ :rtype: str
37
+ """
38
+ url = "https://sns.sseinfo.com/allcompany.do"
39
+ data = {
40
+ "code": "0",
41
+ "order": "2",
42
+ "areaId": "0",
43
+ "page": "1",
44
+ }
45
+ uid_list = list()
46
+ code_list = list()
47
+ for page in tqdm(range(1, 74), leave=False):
48
+ data.update({"page": page})
49
+ r = requests.post(url, data=data)
50
+ data_json = r.json()
51
+ soup = BeautifulSoup(data_json["content"], "lxml")
52
+ soup.find_all("a", attrs={"rel": "tag"})
53
+ uid_list.extend(
54
+ [item["uid"] for item in soup.find_all("a", attrs={"rel": "tag"})]
55
+ )
56
+ code_list.extend(
57
+ [
58
+ item.find("img")["src"].split("?")[0].split("/")[-1].split(".")[0]
59
+ for item in soup.find_all("a", attrs={"rel": "tag"})
60
+ ]
61
+ )
62
+ code_uid_df = pd.DataFrame()
63
+ code_uid_df['symbol'] = code_list
64
+ code_uid_df['uid'] = uid_list
65
+ code_uid_df['_id'] = uid_list
66
+ return code_uid_df
67
+
68
+
69
+ # 获取上海问答id
70
+ @lru_cache()
71
+ def get_sh_stock_all_uid() -> pd.DataFrame:
72
+ return mongodb_util.find_all_data(db_name_constant.SH_INFO_UID)
73
+
74
+
75
+ # 获取深圳问答id
76
+ @lru_cache()
77
+ def get_sz_stock_all_uid() -> pd.DataFrame:
78
+ return mongodb_util.find_all_data(db_name_constant.SZ_INFO_UID)
79
+
80
+
81
+ # 获取深圳互动回答单个ID
82
+ def get_one_sz_symbol_org_id(symbol):
83
+ sz_info_uid_df = get_sz_stock_all_uid()
84
+ sz_info_uid_one_df = sz_info_uid_df.loc[sz_info_uid_df['symbol'] == symbol]
85
+ if data_frame_util.is_not_empty(sz_info_uid_one_df):
86
+ return list(sz_info_uid_one_df['uid'])[0]
87
+ else:
88
+ try:
89
+ return fetch_sz_org_id(symbol)
90
+ except BaseException as e:
91
+ logger.error("获取组织代码异常:{},{}", symbol, e)
92
+ return '0'
93
+
94
+
95
+ # 获取上海互动回答单个ID
96
+ def get_one_sh_symbol_org_id(symbol):
97
+ sh_info_uid_df = get_sh_stock_all_uid()
98
+ sh_info_uid_one_df = sh_info_uid_df.loc[sh_info_uid_df['symbol'] == symbol]
99
+ if data_frame_util.is_not_empty(sh_info_uid_one_df):
100
+ return list(sh_info_uid_one_df['uid'])[0]
101
+ else:
102
+ return '0'
103
+
104
+
105
+ # 深圳股票-互动易-组织代码 单个获取
106
+ def fetch_sz_org_id(symbol: str = "000001") -> str:
107
+ """
108
+ 股票-互动易-组织代码
109
+ https://irm.cninfo.com.cn/
110
+ :return: 组织代码
111
+ :rtype: str
112
+ """
113
+ url = "https://irm.cninfo.com.cn/newircs/index/queryKeyboardInfo"
114
+ params = {"_t": "1691144074"}
115
+ data = {"keyWord": symbol}
116
+ r = requests.post(url, params=params, data=data)
117
+ data_json = r.json()
118
+ org_id = data_json["data"][0]["secid"]
119
+ return org_id
120
+
121
+
122
+ # 同步上证互动uid
123
+ def sync_sh_stock_uid():
124
+ code_uid_df = sync_stock_uid()
125
+ mongodb_util.save_mongo(code_uid_df, db_name_constant.SH_INFO_UID)
126
+
127
+
128
+ # 同步深圳互动uid
129
+ def sync_sz_stock_uid(symbol_list):
130
+ real_time_quotes_all_stocks = em_stock_info_api.get_a_stock_info()
131
+ de_list_company_symbols = company_common_service_api.get_de_list_company()
132
+ real_time_quotes_all_stocks = real_time_quotes_all_stocks.loc[
133
+ ~(real_time_quotes_all_stocks['symbol'].isin(de_list_company_symbols))]
134
+ real_time_quotes_all_stocks = common_service_fun_api.classify_symbol(real_time_quotes_all_stocks)
135
+
136
+ real_time_quotes_all_stocks = real_time_quotes_all_stocks.loc[
137
+ real_time_quotes_all_stocks['classification'].isin(['S', 'C'])]
138
+ if len(symbol_list) != 0:
139
+ real_time_quotes_all_stocks = real_time_quotes_all_stocks.loc[
140
+ real_time_quotes_all_stocks['symbol'].isin(symbol_list)]
141
+ else:
142
+ # 获取当前时间
143
+ now_date = datetime.now()
144
+ # 计算前7天的时间(timedelta 用于表示时间间隔)
145
+ seven_days_ago = now_date - timedelta(days=30)
146
+ str_day_number = int(seven_days_ago.strftime('%Y%m%d'))
147
+ real_time_quotes_all_stocks = real_time_quotes_all_stocks.loc[
148
+ (real_time_quotes_all_stocks['list_date'] >= str_day_number) | (
149
+ real_time_quotes_all_stocks['list_date'] == 19890604)]
150
+ for stock_one in real_time_quotes_all_stocks.itertuples():
151
+ try:
152
+ symbol = stock_one.symbol
153
+ uid = fetch_sz_org_id(symbol)
154
+ result_dict = {'_id': symbol, 'symbol': symbol, 'uid': uid}
155
+ result_dict_df = pd.DataFrame(result_dict, index=[1])
156
+ mongodb_util.save_mongo(result_dict_df, db_name_constant.SZ_INFO_UID)
157
+ logger.info("同步SZ互动ID:{}", stock_one.symbol)
158
+ except Exception as e:
159
+ logger.error("同步SZ互动ID异常:{},{}", stock_one.symbol, e)
160
+
161
+
162
+ if __name__ == '__main__':
163
+ sz_symbol_org_id = get_one_sz_symbol_org_id('300085')
164
+ sh_symbol_org_id = get_one_sh_symbol_org_id('600000')
165
+ print(sz_symbol_org_id)
166
+ print(sh_symbol_org_id)
167
+ sync_sz_stock_uid([])
168
+ # sync_sz_stock_uid([])
169
+ # sync_sh_stock_uid([])
@@ -17,6 +17,7 @@ import mns_common.component.trade_date.trade_date_common_service_api as trade_da
17
17
 
18
18
  mongodb_util = MongodbUtil('27017')
19
19
 
20
+
20
21
  # 固定的选择
21
22
  # fixed_optional_list = ['USDCNH', 'XAUUSD',
22
23
  # '881279',
@@ -37,17 +38,16 @@ mongodb_util = MongodbUtil('27017')
37
38
  # ]
38
39
 
39
40
  # 固定的选择
40
- fixed_optional_list = ['899050', '881157']
41
-
41
+ # fixed_optional_list = ['899050', '881157']
42
42
 
43
- def add_fixed_optional():
44
- ths_cookie = cookie_info_service.get_ths_cookie()
45
- for symbol in fixed_optional_list:
46
- ths_self_choose_api.add_stock_to_account(symbol, ths_cookie)
43
+ #
44
+ # def add_fixed_optional():
45
+ # ths_cookie = cookie_info_service.get_ths_cookie()
46
+ # for symbol in fixed_optional_list:
47
+ # ths_self_choose_api.add_stock_to_account(symbol, ths_cookie)
47
48
 
48
-
49
- def delete_all_self_choose_stocks():
50
- ths_cookie = cookie_info_service.get_ths_cookie()
49
+ # 删除所有自选股票
50
+ def delete_all_self_choose_stocks(ths_cookie):
51
51
  all_self_choose_stock_list = ths_self_choose_api.get_all_self_choose_stock_list(ths_cookie)
52
52
  for stock_one in all_self_choose_stock_list.itertuples():
53
53
  symbol = stock_one.code
@@ -55,8 +55,7 @@ def delete_all_self_choose_stocks():
55
55
 
56
56
 
57
57
  # 添加固定自选股票
58
- def add_self_choose_symbol():
59
- ths_cookie = cookie_info_service.get_ths_cookie()
58
+ def add_self_choose_symbol(ths_cookie):
60
59
  # 固定自选
61
60
  self_choose_symbol_df = mongodb_util.find_all_data(db_name_constant.SELF_CHOOSE_STOCK)
62
61
  if data_frame_util.is_not_empty(self_choose_symbol_df):
@@ -66,8 +65,7 @@ def add_self_choose_symbol():
66
65
 
67
66
 
68
67
  # 添加今日选择股票
69
- def add_today_choose_symbol():
70
- ths_cookie = cookie_info_service.get_ths_cookie()
68
+ def add_today_choose_symbol(ths_cookie):
71
69
  now_date = datetime.now()
72
70
  str_day = now_date.strftime('%Y-%m-%d')
73
71
  last_trade_day = trade_date_common_service_api.get_last_trade_day(str_day)
@@ -81,8 +79,7 @@ def add_today_choose_symbol():
81
79
 
82
80
 
83
81
  # 添加同花顺概念
84
- def add_self_choose_concept():
85
- ths_cookie = cookie_info_service.get_ths_cookie()
82
+ def add_self_choose_concept(ths_cookie):
86
83
  query_plate = {'self_type': {
87
84
  "$in": [self_choose_constant.SELF_CHOOSE_THS_CONCEPT,
88
85
  self_choose_constant.SELF_CHOOSE_THS_INDUSTRY]}}
@@ -95,7 +92,7 @@ def add_self_choose_concept():
95
92
 
96
93
 
97
94
  # 添加最近交易股票
98
- def add_trade_stocks():
95
+ def add_trade_stocks(ths_cookie):
99
96
  now_date = datetime.now()
100
97
  str_day = now_date.strftime('%Y-%m-%d')
101
98
  last_trade_day = trade_date_common_service_api.get_last_trade_day(str_day)
@@ -109,15 +106,13 @@ def add_trade_stocks():
109
106
  trade_stocks_df = mongodb_util.find_query_data(db_name_constant.BUY_STOCK_NAME, query)
110
107
  if data_frame_util.is_not_empty(trade_stocks_df):
111
108
  stock_list = stock_list.union(set(trade_stocks_df['symbol']))
112
- ths_cookie = cookie_info_service.get_ths_cookie()
113
109
  if len(stock_list) > 0:
114
110
  for symbol in stock_list:
115
111
  ths_self_choose_api.add_stock_to_account(symbol, ths_cookie)
116
112
 
117
113
 
118
114
  # 添加连板到自选
119
- def add_continue_boards_zt_stocks():
120
- ths_cookie = cookie_info_service.get_ths_cookie()
115
+ def add_continue_boards_zt_stocks(ths_cookie):
121
116
  now_date = datetime.now()
122
117
  str_day = now_date.strftime('%Y-%m-%d')
123
118
  if trade_date_common_service_api.is_trade_day(str_day):
@@ -138,19 +133,52 @@ def add_continue_boards_zt_stocks():
138
133
  ths_self_choose_api.add_stock_to_account(stock_one.symbol, ths_cookie)
139
134
 
140
135
 
136
+ # 添加主线龙头
137
+ def add_main_line_leader(ths_cookie):
138
+ main_line_leader_df = mongodb_util.find_query_data('main_line_leader', {})
139
+ if data_frame_util.is_not_empty(main_line_leader_df):
140
+ main_line_leader_df = count_main_line_number(main_line_leader_df)
141
+
142
+ main_line_leader_df = main_line_leader_df.sort_values(
143
+ by=['main_line_number', 'main_line_leader_grade'],
144
+ ascending=[False, False,]
145
+ )
146
+ for stock_one in main_line_leader_df.itertuples():
147
+ ths_self_choose_api.add_stock_to_account(stock_one.symbol, ths_cookie)
148
+
149
+
150
+ # 统计主线的数量
151
+ def count_main_line_number(main_line_detail_df):
152
+ # 统计主线的数量
153
+ main_line_detail_df['main_line_number'] = main_line_detail_df.groupby('main_line')['main_line'].transform(
154
+ 'count')
155
+ # 相同主线数量 数量加1
156
+ main_line_detail_df['main_line_number'] = (
157
+ main_line_detail_df.groupby('main_line_number')['main_line']
158
+ .transform('rank', method='dense') - 1
159
+ ) * 0.1 + main_line_detail_df['main_line_number']
160
+
161
+ return main_line_detail_df
162
+
163
+
141
164
  # 自选股操作 删除当天自选股 增加新的连板股票 添加固定选择自选
142
165
  def self_choose_stock_handle():
143
- delete_all_self_choose_stocks()
166
+ ths_cookie = cookie_info_service.get_ths_cookie()
167
+
168
+ delete_all_self_choose_stocks(ths_cookie)
144
169
  # 固定自选板块
145
- add_fixed_optional()
170
+ # add_fixed_optional()
146
171
  # 添加同花顺概念
147
- add_self_choose_concept()
172
+ add_self_choose_concept(ths_cookie)
173
+ # 添加主线龙头
174
+ add_main_line_leader(ths_cookie)
148
175
  # 连板股票
149
- add_continue_boards_zt_stocks()
176
+ add_continue_boards_zt_stocks(ths_cookie)
177
+
150
178
  # 自己买入的股票
151
- add_trade_stocks()
179
+ add_trade_stocks(ths_cookie)
152
180
  # 添加自选股票
153
- add_self_choose_symbol()
181
+ add_self_choose_symbol(ths_cookie)
154
182
 
155
183
 
156
184
  if __name__ == '__main__':
@@ -10,6 +10,7 @@ from mns_common.component.deal.terminal_enum import TerminalEnum
10
10
  import time
11
11
  from loguru import logger
12
12
 
13
+
13
14
  # qmt 自动登录
14
15
  def qmt_auto_login():
15
16
  deal_service_api.auto_login(TerminalEnum.QMT.terminal_code)
@@ -29,4 +30,4 @@ def auto_login():
29
30
 
30
31
 
31
32
  if __name__ == '__main__':
32
- auto_login()
33
+ qmt_auto_login()
@@ -17,11 +17,22 @@ TRADER_SERVER_PATH = 'H:\\mns_trader_server.bat'
17
17
  TRADER_SERVER_NAME = "mns_trader_server"
18
18
 
19
19
 
20
+ # 打开qmt
21
+ def open_qmt_terminal():
22
+ logger.info('打开 [交易web服务端]')
23
+ if bool(1 - is_open_trader_server()):
24
+ cmd_util.open_bat_file(TRADER_SERVER_PATH)
25
+ else:
26
+ logger.info('交易服务端已经运行')
27
+ logger.info('自动登陆qmt')
28
+ trader_auto_service.qmt_auto_login()
29
+
30
+
20
31
  # 打开交易客户端
21
32
  def open_trader_terminal():
22
33
  # 打开 [交易web服务端]
23
34
  logger.info('打开 [交易web服务端]')
24
- if bool(1- is_open_trader_server()):
35
+ if bool(1 - is_open_trader_server()):
25
36
  cmd_util.open_bat_file(TRADER_SERVER_PATH)
26
37
  time.sleep(10)
27
38
  logger.info('自动登陆ths和qmt')
@@ -62,4 +73,4 @@ def kill_server():
62
73
 
63
74
  if __name__ == '__main__':
64
75
  # kill_server()
65
- open_trader_terminal()
76
+ open_qmt_terminal()
@@ -52,5 +52,5 @@ def sync_stock_tfp(str_day):
52
52
 
53
53
 
54
54
  if __name__ == '__main__':
55
- df = sync_stock_tfp('2025-07-30')
55
+ df = sync_stock_tfp('2025-12-25')
56
56
  print(df)
@@ -27,4 +27,4 @@ def sync_stock_zb_pool(str_now_day):
27
27
 
28
28
 
29
29
  if __name__ == '__main__':
30
- sync_stock_zb_pool('2025-04-18')
30
+ sync_stock_zb_pool('2025-12-11')
@@ -18,10 +18,11 @@ import mns_common.api.ths.zt.ths_stock_zt_pool_v2_api as ths_stock_zt_pool_v2_ap
18
18
  import mns_common.component.zt.zt_common_service_api as zt_common_service_api
19
19
  import mns_common.component.em.em_real_time_quotes_api as em_real_time_quotes_api
20
20
  from datetime import datetime
21
- import mns_common.api.ths.zt.ths_stock_zt_pool_api as ths_stock_zt_pool_api
22
21
  import mns_common.constant.db_name_constant as db_name_constant
23
22
  import mns_common.component.deal.deal_service_api as deal_service_api
24
23
  import mns_common.component.company.company_common_service_new_api as company_common_service_new_api
24
+ import mns_common.component.main_line.main_line_zt_reason_service as main_line_zt_reason_service
25
+ from mns_common.utils.async_fun import async_fun
25
26
 
26
27
  '''
27
28
  东方财富涨停池
@@ -63,10 +64,12 @@ def save_zt_info(str_day):
63
64
  # 同花顺问财涨停池
64
65
  ths_zt_pool_df_data = ths_stock_zt_pool_v2_api.get_ths_stock_zt_reason_with_cache(str_day)
65
66
  except BaseException as e:
66
- logger.error("同步ths涨停数据异常")
67
+ logger.error("使用问财同步ths涨停数据异常:{}", e)
67
68
  ths_zt_pool_df_data = pd.DataFrame()
68
69
 
69
70
  stock_em_zt_pool_df_data = handle_ths_em_diff_data(ths_zt_pool_df_data, stock_em_zt_pool_df_data)
71
+ # 更新涨停分析和原因数据
72
+ update_zt_reason_analysis(stock_em_zt_pool_df_data, str_day)
70
73
 
71
74
  stock_em_zt_pool_df_data = common_service_fun_api.total_mv_classification(stock_em_zt_pool_df_data.copy())
72
75
 
@@ -76,12 +79,18 @@ def save_zt_info(str_day):
76
79
 
77
80
  stock_em_zt_pool_df_data = company_common_service_api.amendment_industry(stock_em_zt_pool_df_data.copy())
78
81
 
79
- # 主线标记 复盘用
80
- stock_em_zt_pool_df_data['main_line'] = '无'
81
- stock_em_zt_pool_df_data['sub_main_line'] = '无'
82
-
83
82
  # 上个交易交易日涨停股票
84
83
  last_trade_day_zt_df = zt_common_service_api.get_last_trade_day_zt(str_day)
84
+ # 设置连板
85
+ stock_em_zt_pool_df_data = set_connected_boards_numbers(stock_em_zt_pool_df_data.copy(),
86
+ last_trade_day_zt_df.copy())
87
+
88
+ # 添加主线信息
89
+ stock_em_zt_pool_df_data = main_line_zt_reason_service.merge_main_line_info(str_day,
90
+ stock_em_zt_pool_df_data.copy())
91
+ # 添加涨停原因和分析信息
92
+ stock_em_zt_pool_df_data = main_line_zt_reason_service.merge_zt_reason_info(str_day,
93
+ stock_em_zt_pool_df_data.copy())
85
94
 
86
95
  stock_em_zt_pool_df_data['first_closure_time'] = stock_em_zt_pool_df_data['first_closure_time'].str.strip()
87
96
  stock_em_zt_pool_df_data['list_date'] = stock_em_zt_pool_df_data['list_date'].apply(
@@ -104,105 +113,47 @@ def save_zt_info(str_day):
104
113
  stock_em_zt_pool_df_data = stock_em_zt_pool_df_data.sort_values(by=['first_closure_time'])
105
114
 
106
115
  # 重置索引,并将排序结果保存到新的"index"列中
107
-
108
116
  stock_em_zt_pool_df_data['str_day'] = str_day
109
117
  stock_em_zt_pool_df_data['_id'] = stock_em_zt_pool_df_data['symbol'] + "_" + str_day
110
118
  stock_em_zt_pool_df_data.drop_duplicates('symbol', keep='last', inplace=True)
111
119
 
112
120
  query_today_zt = {'str_day': str_day}
113
-
114
- stock_today_zt_pool_df = mongodb_util.find_query_data(db_name_constant.STOCK_ZT_POOL, query_today_zt)
115
-
116
- if data_frame_util.is_empty(stock_today_zt_pool_df):
117
-
121
+ stock_exist_zt_pool_df = mongodb_util.find_query_data(db_name_constant.STOCK_ZT_POOL, query_today_zt)
122
+ if data_frame_util.is_empty(stock_exist_zt_pool_df):
118
123
  today_new_zt_pool_df = stock_em_zt_pool_df_data.copy()
119
124
  else:
120
125
  today_new_zt_pool_df = stock_em_zt_pool_df_data.loc[
121
- ~stock_em_zt_pool_df_data['symbol'].isin(stock_today_zt_pool_df['symbol'])]
122
-
123
- try:
124
-
125
- today_main_line_df = mongodb_util.find_query_data(db_name_constant.MAIN_LINE_DETAIL, {'str_day': str_day})
126
-
127
- for stock_one in today_new_zt_pool_df.itertuples():
128
- try:
129
-
130
- # 设置连板数目
131
- stock_em_zt_pool_df_data = set_connected_boards_numbers(stock_em_zt_pool_df_data.copy(),
132
- stock_one.symbol,
133
- last_trade_day_zt_df.copy())
134
-
135
- # 涨停分析
136
- zt_result_dict = ths_stock_zt_pool_api.zt_analyse_reason(stock_one.symbol)
137
- zt_analysis = zt_result_dict['zt_analyse_detail']
138
- zt_reason = zt_result_dict['zt_reason']
139
-
140
- stock_em_zt_pool_df_data.loc[
141
- stock_em_zt_pool_df_data['symbol'] == stock_one.symbol, 'zt_reason'] = zt_reason
142
-
143
- stock_em_zt_pool_df_data.loc[
144
- stock_em_zt_pool_df_data['symbol'] == stock_one.symbol, 'zt_analysis'] = zt_analysis
145
-
146
- today_main_line_one_df = today_main_line_df.loc[today_main_line_df['symbol'] == stock_one.symbol]
147
- if data_frame_util.is_not_empty(today_main_line_one_df):
148
- stock_em_zt_pool_df_data.loc[
149
- stock_em_zt_pool_df_data['symbol'] == stock_one.symbol, 'main_line'] = \
150
- list(today_main_line_one_df['main_line'])[0]
151
-
152
- stock_em_zt_pool_df_data.loc[
153
- stock_em_zt_pool_df_data['symbol'] == stock_one.symbol, 'sub_main_line'] = \
154
- list(today_main_line_one_df['sub_main_line'])[0]
155
-
156
- query_exist = {'symbol': stock_one.symbol, 'str_day': str_day}
157
- if mongodb_util.exist_data_query(db_name_constant.STOCK_ZT_POOL, query_exist):
158
- continue
159
- else:
160
-
161
- stock_em_zt_pool_df_data_one = stock_em_zt_pool_df_data.loc[
162
- stock_em_zt_pool_df_data['symbol'] == stock_one.symbol]
163
- stock_em_zt_pool_df_data_one = stock_em_zt_pool_df_data_one[ZT_FIELD]
164
-
165
- chg = round(float(list(stock_em_zt_pool_df_data_one['chg'])[0]), 2)
166
- stock_em_zt_pool_df_data_one['chg'] = chg
126
+ ~stock_em_zt_pool_df_data['symbol'].isin(stock_exist_zt_pool_df['symbol'])]
167
127
 
168
- mongodb_util.save_mongo(stock_em_zt_pool_df_data_one, db_name_constant.STOCK_ZT_POOL)
128
+ mongodb_util.save_mongo(today_new_zt_pool_df, db_name_constant.STOCK_ZT_POOL)
129
+ stock_em_zt_pool_df_data = pd.concat([stock_exist_zt_pool_df, today_new_zt_pool_df])
130
+ # 保存连板股票主线
131
+ save_last_trade_day_main_line(str_day, stock_em_zt_pool_df_data)
169
132
 
170
- except BaseException as e:
171
- stock_em_zt_pool_df_data['zt_reason'] = '0'
172
- logger.error("同步涨停信息出现异常:{},{}", stock_one.symbol, e)
173
- except BaseException as e:
174
- stock_em_zt_pool_df_data['zt_reason'] = '0'
175
- logger.error("出现异常:{}", e)
176
-
177
- stock_em_zt_pool_df_data = pd.concat([stock_today_zt_pool_df, today_new_zt_pool_df])
133
+ stock_em_zt_pool_df_data.fillna('', inplace=True)
178
134
  stock_em_zt_pool_df_data = stock_em_zt_pool_df_data[ZT_FIELD]
179
135
  return stock_em_zt_pool_df_data
180
136
 
181
137
 
182
138
  # 设置连板数目
183
- def set_connected_boards_numbers(stock_em_zt_pool_df_data, symbol, last_trade_day_zt_df):
139
+ def set_connected_boards_numbers(stock_em_zt_pool_df_data, last_trade_day_zt_df):
140
+ if data_frame_util.is_empty(stock_em_zt_pool_df_data):
141
+ return stock_em_zt_pool_df_data
142
+ if data_frame_util.is_empty(last_trade_day_zt_df):
143
+ return stock_em_zt_pool_df_data
184
144
  # 连板股票
185
145
  connected_boards_df_copy = last_trade_day_zt_df.loc[
186
146
  last_trade_day_zt_df['symbol'].isin(stock_em_zt_pool_df_data['symbol'])]
187
147
 
188
148
  connected_boards_df = connected_boards_df_copy.copy()
149
+ #
189
150
  connected_boards_df['connected_boards_numbers'] = connected_boards_df['connected_boards_numbers'] + 1
190
151
 
191
- # 连板股票
192
- connected_boards_df_one = connected_boards_df.loc[connected_boards_df['symbol'] == symbol]
193
-
194
- if data_frame_util.is_not_empty(connected_boards_df_one):
195
- stock_em_zt_pool_df_data.loc[stock_em_zt_pool_df_data['symbol'] == symbol, 'connected_boards_numbers'] = \
196
- list(connected_boards_df_one['connected_boards_numbers'])[0]
197
-
198
- if 'main_line' in connected_boards_df_one.columns:
199
- stock_em_zt_pool_df_data.loc[stock_em_zt_pool_df_data['symbol'] == symbol, 'main_line'] = \
200
- list(connected_boards_df_one['main_line'])[0]
201
-
202
- if 'sub_main_line' in connected_boards_df_one.columns:
203
- stock_em_zt_pool_df_data.loc[stock_em_zt_pool_df_data['symbol'] == symbol, 'sub_main_line'] = \
204
- list(connected_boards_df_one['sub_main_line'])[0]
205
-
152
+ symbol_mapping_connected_boards_numbers = dict(
153
+ zip(connected_boards_df['symbol'], connected_boards_df['connected_boards_numbers']))
154
+ # 使用map进行替换,不匹配的保持原值
155
+ stock_em_zt_pool_df_data['connected_boards_numbers'] = stock_em_zt_pool_df_data['symbol'].map(
156
+ symbol_mapping_connected_boards_numbers).fillna(1)
206
157
  return stock_em_zt_pool_df_data
207
158
 
208
159
 
@@ -389,25 +340,50 @@ def query_company_info_with_share():
389
340
  return company_info_df
390
341
 
391
342
 
343
+ # 异步更新涨停分析和数据
344
+ @async_fun
345
+ def update_zt_reason_analysis(stock_em_zt_pool_df_data, str_day):
346
+ if data_frame_util.is_empty(stock_em_zt_pool_df_data):
347
+ return
348
+ now_date = datetime.now()
349
+ now_str_day = now_date.strftime('%Y-%m-%d')
350
+ if now_str_day != str_day:
351
+ return
352
+
353
+ stock_em_zt_pool_df_data['str_day'] = str_day
354
+ main_line_zt_reason_service.update_symbol_list_zt_reason_analysis(stock_em_zt_pool_df_data, True)
355
+
356
+
357
+ # 保存连板股票主线
358
+ @async_fun
359
+ def save_last_trade_day_main_line(str_day, stock_em_zt_pool_df_data):
360
+ last_trade_day = trade_date_common_service_api.get_last_trade_day(str_day)
361
+ stock_em_zt_pool_connected_df = stock_em_zt_pool_df_data.loc[
362
+ stock_em_zt_pool_df_data['connected_boards_numbers'] > 1]
363
+ if data_frame_util.is_empty(stock_em_zt_pool_connected_df):
364
+ return
365
+ else:
366
+ query = {'str_day': last_trade_day, 'symbol': {"$in": list(stock_em_zt_pool_connected_df['symbol'])}}
367
+ last_trade_day_main_line_detail_df = mongodb_util.find_query_data(db_name_constant.MAIN_LINE_DETAIL, query)
368
+ if data_frame_util.is_empty(last_trade_day_main_line_detail_df):
369
+ return
370
+ else:
371
+ last_trade_day_main_line_detail_df['_id'] = last_trade_day_main_line_detail_df['symbol'] + '_' + str_day
372
+ last_trade_day_main_line_detail_df['str_day'] = str_day
373
+ last_trade_day_main_line_detail_df['connected_boards_numbers'] = last_trade_day_main_line_detail_df[
374
+ 'connected_boards_numbers'] + 1
375
+ now_date = datetime.now()
376
+ str_now_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
377
+ last_trade_day_main_line_detail_df['update_time'] = str_now_date
378
+ today_exist_main_line_df = mongodb_util.find_query_data(db_name_constant.MAIN_LINE_DETAIL,
379
+ {'str_day': str_day})
380
+ if data_frame_util.is_not_empty(today_exist_main_line_df):
381
+ today_new_main_line_df = last_trade_day_main_line_detail_df.loc[
382
+ last_trade_day_main_line_detail_df['symbol'].isin(list(today_exist_main_line_df['symbol']))]
383
+ else:
384
+ today_new_main_line_df = last_trade_day_main_line_detail_df.copy()
385
+ mongodb_util.save_mongo(today_new_main_line_df, db_name_constant.MAIN_LINE_DETAIL)
386
+
387
+
392
388
  if __name__ == '__main__':
393
- save_zt_info('2025-11-17')
394
- # from datetime import datetime
395
- #
396
- # if __name__ == '__main__':
397
- #
398
- # sync_date = date_handle_util.add_date_day('20240110', 0)
399
- #
400
- # now_date = datetime.now()
401
- #
402
- # str_now_day = sync_date.strftime('%Y-%m-%d')
403
- #
404
- # while now_date > sync_date:
405
- # try:
406
- # save_zt_info(str_now_day)
407
- # sync_date = date_handle_util.add_date_day(date_handle_util.no_slash_date(str_now_day), 1)
408
- # print(str_now_day)
409
- # str_now_day = sync_date.strftime('%Y-%m-%d')
410
- #
411
- # except BaseException as e:
412
- # sync_date = date_handle_util.add_date_day(date_handle_util.no_slash_date(str_now_day), 1)
413
- # str_now_day = sync_date.strftime('%Y-%m-%d')
389
+ save_zt_info('2025-12-26')
@@ -188,6 +188,6 @@ if __name__ == '__main__':
188
188
  # trade_date = '2024-08-01'
189
189
  # zt_df = ths_zt_pool(trade_date, None)
190
190
  # save_ths_zt_pool(zt_df, trade_date)
191
- trade_date = '2025-09-05'
191
+ trade_date = '2025-11-04'
192
192
  ths_zt_pool_df_test = ths_zt_pool(trade_date, None)
193
193
  save_ths_zt_pool(ths_zt_pool_df_test, trade_date)
@@ -11,6 +11,7 @@ mongodb_util = MongodbUtil('27017')
11
11
  import mns_common.api.ths.zt.ths_stock_zt_pool_api as ths_stock_zt_pool_api
12
12
  import mns_common.utils.data_frame_util as data_frame_util
13
13
  from loguru import logger
14
+ import time
14
15
 
15
16
 
16
17
  def update_null_zt_reason(str_day):
@@ -38,6 +39,8 @@ def update_null_zt_reason(str_day):
38
39
  stock_zt_pool_df_null_zt_reason['symbol'] == stock_zt_one.symbol]
39
40
  # 涨停分析
40
41
  zt_result_dict = ths_stock_zt_pool_api.zt_analyse_reason(stock_zt_one.symbol)
42
+ time.sleep(5)
43
+
41
44
  zt_analysis = zt_result_dict['zt_analyse_detail']
42
45
  zt_reason = zt_result_dict['zt_reason']
43
46
 
@@ -55,4 +58,4 @@ def update_null_zt_reason(str_day):
55
58
 
56
59
 
57
60
  if __name__ == '__main__':
58
- update_null_zt_reason('2025-11-14')
61
+ update_null_zt_reason('2025-12-08')
@@ -134,7 +134,7 @@ def col_data_move():
134
134
 
135
135
  if __name__ == '__main__':
136
136
  # todo 修改日期
137
- str_day = '2025-11-13'
137
+ str_day = '2025-11-20'
138
138
  # col_data_move()
139
139
  sync_daily_data_info()
140
140
  sync_stock_zt_pool()