mns-scheduler 1.4.3.3__py3-none-any.whl → 1.4.4.5__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-scheduler might be problematic. Click here for more details.
- mns_scheduler/{company_info/announce → auto_da_ban}/__init__.py +1 -1
- mns_scheduler/auto_da_ban/auto_da_ban_service.py +87 -0
- mns_scheduler/company_info/clean/company_info_clean_api.py +37 -16
- mns_scheduler/company_info/{base → common}/__init__.py +1 -1
- mns_scheduler/company_info/common/company_common_query_service.py +45 -0
- mns_scheduler/company_info/constant/company_constant_data.py +60 -49
- mns_scheduler/company_info/em_stock_info/sync_em_stock_info_sync.py +1 -0
- mns_scheduler/company_info/{remark → sync}/__init__.py +1 -1
- mns_scheduler/company_info/sync/company_info_set_service.py +208 -0
- mns_scheduler/company_info/sync/sync_company_info_task.py +203 -0
- mns_scheduler/company_info/task/__init__.py +7 -0
- mns_scheduler/company_info/{announce/company_announce_sync_service.py → task/company_announce_info_task.py} +25 -13
- mns_scheduler/company_info/task/company_base_info_task.py +64 -0
- mns_scheduler/company_info/{base/sync_company_product_area_industry.py → task/company_business_info_task.py} +33 -17
- mns_scheduler/company_info/task/company_hold_info_task.py +66 -0
- mns_scheduler/company_info/task/company_industry_info_task.py +167 -0
- mns_scheduler/company_info/task/company_total_task.py +69 -0
- mns_scheduler/concept/ths/common/ths_concept_sync_common_api.py +3 -3
- mns_scheduler/concept/ths/update_concept_info/sync_one_symbol_all_concepts_api.py +1 -1
- mns_scheduler/db/script/sync/remote_data_sync_to_local.py +7 -2
- mns_scheduler/irm/api/sh_stock_sns_sse_info_api.py +7 -57
- mns_scheduler/irm/api/sz_stock_sns_sse_info_api.py +14 -25
- mns_scheduler/irm/stock_irm_cninfo_service.py +32 -26
- mns_scheduler/irm/stock_question_id_service.py +159 -0
- mns_scheduler/trade/auto_login/trader_auto_service.py +2 -1
- mns_scheduler/trade/task/trader_task_service.py +13 -2
- mns_scheduler/zb/stock_zb_pool_sync.py +1 -1
- mns_scheduler/zt/zt_pool/em_zt_pool_sync_api.py +217 -126
- mns_scheduler/zt/zt_pool/ths_zt_pool_sync_api.py +1 -1
- mns_scheduler/zt/zt_pool/update_null_zt_reason_api.py +4 -1
- mns_scheduler/zz_task/compensation/compensate_task_one_day.py +1 -1
- mns_scheduler/zz_task/data_sync_task.py +30 -36
- {mns_scheduler-1.4.3.3.dist-info → mns_scheduler-1.4.4.5.dist-info}/METADATA +1 -1
- {mns_scheduler-1.4.3.3.dist-info → mns_scheduler-1.4.4.5.dist-info}/RECORD +36 -29
- mns_scheduler/company_info/base/sync_company_base_info_api.py +0 -531
- mns_scheduler/company_info/base/sync_company_hold_info_api.py +0 -37
- mns_scheduler/company_info/remark/company_remark_info_sync.py +0 -46
- {mns_scheduler-1.4.3.3.dist-info → mns_scheduler-1.4.4.5.dist-info}/WHEEL +0 -0
- {mns_scheduler-1.4.3.3.dist-info → mns_scheduler-1.4.4.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,159 @@
|
|
|
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
|
+
|
|
24
|
+
mongodb_util = MongodbUtil('27017')
|
|
25
|
+
from tqdm import tqdm
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# 同步所有映射表
|
|
29
|
+
@lru_cache()
|
|
30
|
+
def sync_stock_uid() -> pd.DataFrame:
|
|
31
|
+
"""
|
|
32
|
+
上证e互动-代码ID映射
|
|
33
|
+
https://sns.sseinfo.com/list/company.do
|
|
34
|
+
:return: 代码ID映射
|
|
35
|
+
:rtype: str
|
|
36
|
+
"""
|
|
37
|
+
url = "https://sns.sseinfo.com/allcompany.do"
|
|
38
|
+
data = {
|
|
39
|
+
"code": "0",
|
|
40
|
+
"order": "2",
|
|
41
|
+
"areaId": "0",
|
|
42
|
+
"page": "1",
|
|
43
|
+
}
|
|
44
|
+
uid_list = list()
|
|
45
|
+
code_list = list()
|
|
46
|
+
for page in tqdm(range(1, 74), leave=False):
|
|
47
|
+
data.update({"page": page})
|
|
48
|
+
r = requests.post(url, data=data)
|
|
49
|
+
data_json = r.json()
|
|
50
|
+
soup = BeautifulSoup(data_json["content"], "lxml")
|
|
51
|
+
soup.find_all("a", attrs={"rel": "tag"})
|
|
52
|
+
uid_list.extend(
|
|
53
|
+
[item["uid"] for item in soup.find_all("a", attrs={"rel": "tag"})]
|
|
54
|
+
)
|
|
55
|
+
code_list.extend(
|
|
56
|
+
[
|
|
57
|
+
item.find("img")["src"].split("?")[0].split("/")[-1].split(".")[0]
|
|
58
|
+
for item in soup.find_all("a", attrs={"rel": "tag"})
|
|
59
|
+
]
|
|
60
|
+
)
|
|
61
|
+
code_uid_df = pd.DataFrame()
|
|
62
|
+
code_uid_df['symbol'] = code_list
|
|
63
|
+
code_uid_df['uid'] = uid_list
|
|
64
|
+
code_uid_df['_id'] = uid_list
|
|
65
|
+
return code_uid_df
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# 获取上海问答id
|
|
69
|
+
@lru_cache()
|
|
70
|
+
def get_sh_stock_all_uid() -> pd.DataFrame:
|
|
71
|
+
return mongodb_util.find_all_data(db_name_constant.SH_INFO_UID)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# 获取深圳问答id
|
|
75
|
+
@lru_cache()
|
|
76
|
+
def get_sz_stock_all_uid() -> pd.DataFrame:
|
|
77
|
+
return mongodb_util.find_all_data(db_name_constant.SZ_INFO_UID)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# 获取深圳互动回答单个ID
|
|
81
|
+
def get_one_sz_symbol_org_id(symbol):
|
|
82
|
+
sz_info_uid_df = get_sz_stock_all_uid()
|
|
83
|
+
sz_info_uid_one_df = sz_info_uid_df.loc[sz_info_uid_df['symbol'] == symbol]
|
|
84
|
+
if data_frame_util.is_not_empty(sz_info_uid_one_df):
|
|
85
|
+
return list(sz_info_uid_one_df['uid'])[0]
|
|
86
|
+
else:
|
|
87
|
+
try:
|
|
88
|
+
return fetch_sz_org_id(symbol)
|
|
89
|
+
except BaseException as e:
|
|
90
|
+
logger.error("获取组织代码异常:{},{}", symbol, e)
|
|
91
|
+
return '0'
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# 获取上海互动回答单个ID
|
|
95
|
+
def get_one_sh_symbol_org_id(symbol):
|
|
96
|
+
sh_info_uid_df = get_sh_stock_all_uid()
|
|
97
|
+
sh_info_uid_one_df = sh_info_uid_df.loc[sh_info_uid_df['symbol'] == symbol]
|
|
98
|
+
if data_frame_util.is_not_empty(sh_info_uid_one_df):
|
|
99
|
+
return list(sh_info_uid_one_df['uid'])[0]
|
|
100
|
+
else:
|
|
101
|
+
return '0'
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# 深圳股票-互动易-组织代码 单个获取
|
|
105
|
+
def fetch_sz_org_id(symbol: str = "000001") -> str:
|
|
106
|
+
"""
|
|
107
|
+
股票-互动易-组织代码
|
|
108
|
+
https://irm.cninfo.com.cn/
|
|
109
|
+
:return: 组织代码
|
|
110
|
+
:rtype: str
|
|
111
|
+
"""
|
|
112
|
+
url = "https://irm.cninfo.com.cn/newircs/index/queryKeyboardInfo"
|
|
113
|
+
params = {"_t": "1691144074"}
|
|
114
|
+
data = {"keyWord": symbol}
|
|
115
|
+
r = requests.post(url, params=params, data=data)
|
|
116
|
+
data_json = r.json()
|
|
117
|
+
org_id = data_json["data"][0]["secid"]
|
|
118
|
+
return org_id
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
# 同步上证互动uid
|
|
122
|
+
def sync_sh_stock_uid():
|
|
123
|
+
code_uid_df = sync_stock_uid()
|
|
124
|
+
mongodb_util.save_mongo(code_uid_df, db_name_constant.SH_INFO_UID)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# 同步深圳互动uid
|
|
128
|
+
def sync_sz_stock_uid(symbol_list):
|
|
129
|
+
real_time_quotes_all_stocks = em_stock_info_api.get_a_stock_info()
|
|
130
|
+
de_list_company_symbols = company_common_service_api.get_de_list_company()
|
|
131
|
+
real_time_quotes_all_stocks = real_time_quotes_all_stocks.loc[
|
|
132
|
+
~(real_time_quotes_all_stocks['symbol'].isin(de_list_company_symbols))]
|
|
133
|
+
real_time_quotes_all_stocks = common_service_fun_api.classify_symbol(real_time_quotes_all_stocks)
|
|
134
|
+
|
|
135
|
+
real_time_quotes_all_stocks = real_time_quotes_all_stocks.loc[
|
|
136
|
+
real_time_quotes_all_stocks['classification'].isin(['S', 'C'])]
|
|
137
|
+
if len(symbol_list) != 0:
|
|
138
|
+
real_time_quotes_all_stocks = real_time_quotes_all_stocks.loc[
|
|
139
|
+
real_time_quotes_all_stocks['symbol'].isin(symbol_list)]
|
|
140
|
+
|
|
141
|
+
for stock_one in real_time_quotes_all_stocks.itertuples():
|
|
142
|
+
try:
|
|
143
|
+
symbol = stock_one.symbol
|
|
144
|
+
uid = fetch_sz_org_id(symbol)
|
|
145
|
+
result_dict = {'_id': symbol, 'symbol': symbol, 'uid': uid}
|
|
146
|
+
result_dict_df = pd.DataFrame(result_dict, index=[1])
|
|
147
|
+
mongodb_util.save_mongo(result_dict_df, db_name_constant.SZ_INFO_UID)
|
|
148
|
+
logger.info("同步SZ互动ID:{}", stock_one.symbol)
|
|
149
|
+
except Exception as e:
|
|
150
|
+
logger.error("同步SZ互动ID异常:{},{}", stock_one.symbol, e)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
if __name__ == '__main__':
|
|
154
|
+
sz_symbol_org_id = get_one_sz_symbol_org_id('300085')
|
|
155
|
+
sh_symbol_org_id = get_one_sh_symbol_org_id('600000')
|
|
156
|
+
print(sz_symbol_org_id)
|
|
157
|
+
print(sh_symbol_org_id)
|
|
158
|
+
# sync_sz_stock_uid([])
|
|
159
|
+
# sync_sh_stock_uid([])
|
|
@@ -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
|
-
|
|
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
|
-
|
|
76
|
+
open_qmt_terminal()
|
|
@@ -66,7 +66,7 @@ def save_zt_info(str_day):
|
|
|
66
66
|
# 同花顺问财涨停池
|
|
67
67
|
ths_zt_pool_df_data = ths_stock_zt_pool_v2_api.get_ths_stock_zt_reason_with_cache(str_day)
|
|
68
68
|
except BaseException as e:
|
|
69
|
-
logger.error("使用问财同步ths
|
|
69
|
+
logger.error("使用问财同步ths涨停数据异常:{}", e)
|
|
70
70
|
ths_zt_pool_df_data = pd.DataFrame()
|
|
71
71
|
|
|
72
72
|
stock_em_zt_pool_df_data = handle_ths_em_diff_data(ths_zt_pool_df_data, stock_em_zt_pool_df_data)
|
|
@@ -80,11 +80,20 @@ def save_zt_info(str_day):
|
|
|
80
80
|
stock_em_zt_pool_df_data = company_common_service_api.amendment_industry(stock_em_zt_pool_df_data.copy())
|
|
81
81
|
|
|
82
82
|
# 主线标记 复盘用
|
|
83
|
-
stock_em_zt_pool_df_data['main_line'] = '
|
|
84
|
-
stock_em_zt_pool_df_data['sub_main_line'] = '
|
|
83
|
+
stock_em_zt_pool_df_data['main_line'] = ''
|
|
84
|
+
stock_em_zt_pool_df_data['sub_main_line'] = ''
|
|
85
|
+
stock_em_zt_pool_df_data['zt_reason'] = ''
|
|
86
|
+
stock_em_zt_pool_df_data['zt_analysis'] = ''
|
|
85
87
|
|
|
86
88
|
# 上个交易交易日涨停股票
|
|
87
89
|
last_trade_day_zt_df = zt_common_service_api.get_last_trade_day_zt(str_day)
|
|
90
|
+
# 设置连板
|
|
91
|
+
stock_em_zt_pool_df_data = set_connected_boards_numbers(stock_em_zt_pool_df_data.copy(),
|
|
92
|
+
last_trade_day_zt_df.copy())
|
|
93
|
+
# 同步今日主线数据
|
|
94
|
+
stock_em_zt_pool_df_data = sync_main_line_data(stock_em_zt_pool_df_data.copy(), str_day)
|
|
95
|
+
# 保存今日主线数据
|
|
96
|
+
stock_em_zt_pool_df_data = save_today_main_line(stock_em_zt_pool_df_data, str_day)
|
|
88
97
|
|
|
89
98
|
stock_em_zt_pool_df_data['first_closure_time'] = stock_em_zt_pool_df_data['first_closure_time'].str.strip()
|
|
90
99
|
stock_em_zt_pool_df_data['list_date'] = stock_em_zt_pool_df_data['list_date'].apply(
|
|
@@ -107,129 +116,44 @@ def save_zt_info(str_day):
|
|
|
107
116
|
stock_em_zt_pool_df_data = stock_em_zt_pool_df_data.sort_values(by=['first_closure_time'])
|
|
108
117
|
|
|
109
118
|
# 重置索引,并将排序结果保存到新的"index"列中
|
|
110
|
-
|
|
111
119
|
stock_em_zt_pool_df_data['str_day'] = str_day
|
|
112
120
|
stock_em_zt_pool_df_data['_id'] = stock_em_zt_pool_df_data['symbol'] + "_" + str_day
|
|
113
121
|
stock_em_zt_pool_df_data.drop_duplicates('symbol', keep='last', inplace=True)
|
|
114
122
|
|
|
115
123
|
query_today_zt = {'str_day': str_day}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if data_frame_util.is_empty(stock_today_zt_pool_df):
|
|
120
|
-
|
|
124
|
+
stock_exist_zt_pool_df = mongodb_util.find_query_data(db_name_constant.STOCK_ZT_POOL, query_today_zt)
|
|
125
|
+
if data_frame_util.is_empty(stock_exist_zt_pool_df):
|
|
121
126
|
today_new_zt_pool_df = stock_em_zt_pool_df_data.copy()
|
|
122
127
|
else:
|
|
123
128
|
today_new_zt_pool_df = stock_em_zt_pool_df_data.loc[
|
|
124
|
-
~stock_em_zt_pool_df_data['symbol'].isin(
|
|
125
|
-
|
|
126
|
-
try:
|
|
127
|
-
|
|
128
|
-
today_main_line_df = mongodb_util.find_query_data(db_name_constant.MAIN_LINE_DETAIL, {'str_day': str_day})
|
|
129
|
-
|
|
130
|
-
for stock_one in today_new_zt_pool_df.itertuples():
|
|
131
|
-
try:
|
|
132
|
-
zt_reason = ''
|
|
133
|
-
zt_analyse_detail = ''
|
|
134
|
-
|
|
135
|
-
# 设置连板数目
|
|
136
|
-
stock_em_zt_pool_df_data = set_connected_boards_numbers(stock_em_zt_pool_df_data.copy(),
|
|
137
|
-
stock_one.symbol,
|
|
138
|
-
last_trade_day_zt_df.copy())
|
|
139
|
-
|
|
140
|
-
reason_tag = False
|
|
141
|
-
# 网页获取
|
|
142
|
-
try:
|
|
143
|
-
ths_cookie = cookie_info_service.get_ths_cookie()
|
|
144
|
-
# 问财获取涨停分析
|
|
145
|
-
zt_analyse_detail = ths_company_info_api.get_company_hot_info(stock_one.symbol, ths_cookie)
|
|
146
|
-
|
|
147
|
-
zt_reason = zt_analyse_detail.split("\n")[0]
|
|
148
|
-
reason_tag = True
|
|
149
|
-
time.sleep(2)
|
|
150
|
-
except BaseException as e:
|
|
151
|
-
time.sleep(2)
|
|
152
|
-
logger.error("网页获取涨停详情异常:{},{}", stock_one.symbol, e)
|
|
153
|
-
|
|
154
|
-
# 问财获取
|
|
155
|
-
if bool(1 - reason_tag):
|
|
156
|
-
try:
|
|
157
|
-
# 问财获取涨停分析
|
|
158
|
-
zt_result_dict = ths_stock_zt_pool_api.zt_analyse_reason(stock_one.symbol)
|
|
159
|
-
zt_analyse_detail = zt_result_dict['zt_analyse_detail']
|
|
160
|
-
zt_reason = zt_result_dict['zt_reason']
|
|
161
|
-
time.sleep(2)
|
|
162
|
-
except BaseException as e:
|
|
163
|
-
time.sleep(2)
|
|
164
|
-
logger.error("问财获取涨停详情异常:{},{}", stock_one.symbol, e)
|
|
165
|
-
|
|
166
|
-
stock_em_zt_pool_df_data.loc[
|
|
167
|
-
stock_em_zt_pool_df_data['symbol'] == stock_one.symbol, 'zt_reason'] = zt_reason
|
|
168
|
-
|
|
169
|
-
stock_em_zt_pool_df_data.loc[
|
|
170
|
-
stock_em_zt_pool_df_data['symbol'] == stock_one.symbol, 'zt_analysis'] = zt_analyse_detail
|
|
171
|
-
|
|
172
|
-
if data_frame_util.is_not_empty(today_main_line_df):
|
|
173
|
-
today_main_line_one_df = today_main_line_df.loc[today_main_line_df['symbol'] == stock_one.symbol]
|
|
174
|
-
if data_frame_util.is_not_empty(today_main_line_one_df):
|
|
175
|
-
stock_em_zt_pool_df_data.loc[
|
|
176
|
-
stock_em_zt_pool_df_data['symbol'] == stock_one.symbol, 'main_line'] = \
|
|
177
|
-
list(today_main_line_one_df['main_line'])[0]
|
|
178
|
-
|
|
179
|
-
stock_em_zt_pool_df_data.loc[
|
|
180
|
-
stock_em_zt_pool_df_data['symbol'] == stock_one.symbol, 'sub_main_line'] = \
|
|
181
|
-
list(today_main_line_one_df['sub_main_line'])[0]
|
|
182
|
-
|
|
183
|
-
query_exist = {'symbol': stock_one.symbol, 'str_day': str_day}
|
|
184
|
-
if mongodb_util.exist_data_query(db_name_constant.STOCK_ZT_POOL, query_exist):
|
|
185
|
-
continue
|
|
186
|
-
else:
|
|
187
|
-
|
|
188
|
-
stock_em_zt_pool_df_data_one = stock_em_zt_pool_df_data.loc[
|
|
189
|
-
stock_em_zt_pool_df_data['symbol'] == stock_one.symbol]
|
|
190
|
-
stock_em_zt_pool_df_data_one = stock_em_zt_pool_df_data_one[ZT_FIELD]
|
|
191
|
-
|
|
192
|
-
chg = round(float(list(stock_em_zt_pool_df_data_one['chg'])[0]), 2)
|
|
193
|
-
stock_em_zt_pool_df_data_one['chg'] = chg
|
|
194
|
-
|
|
195
|
-
mongodb_util.save_mongo(stock_em_zt_pool_df_data_one, db_name_constant.STOCK_ZT_POOL)
|
|
196
|
-
|
|
197
|
-
except BaseException as e:
|
|
129
|
+
~stock_em_zt_pool_df_data['symbol'].isin(stock_exist_zt_pool_df['symbol'])]
|
|
198
130
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
logger.error("出现异常:{}", e)
|
|
203
|
-
|
|
204
|
-
stock_em_zt_pool_df_data = pd.concat([stock_today_zt_pool_df, today_new_zt_pool_df])
|
|
131
|
+
mongodb_util.save_mongo(today_new_zt_pool_df, db_name_constant.STOCK_ZT_POOL)
|
|
132
|
+
stock_em_zt_pool_df_data = pd.concat([stock_exist_zt_pool_df, today_new_zt_pool_df])
|
|
133
|
+
stock_em_zt_pool_df_data.fillna('', inplace=True)
|
|
205
134
|
stock_em_zt_pool_df_data = stock_em_zt_pool_df_data[ZT_FIELD]
|
|
206
135
|
return stock_em_zt_pool_df_data
|
|
207
136
|
|
|
208
137
|
|
|
209
138
|
# 设置连板数目
|
|
210
|
-
def set_connected_boards_numbers(stock_em_zt_pool_df_data,
|
|
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
|
|
211
144
|
# 连板股票
|
|
212
145
|
connected_boards_df_copy = last_trade_day_zt_df.loc[
|
|
213
146
|
last_trade_day_zt_df['symbol'].isin(stock_em_zt_pool_df_data['symbol'])]
|
|
214
147
|
|
|
215
148
|
connected_boards_df = connected_boards_df_copy.copy()
|
|
149
|
+
#
|
|
216
150
|
connected_boards_df['connected_boards_numbers'] = connected_boards_df['connected_boards_numbers'] + 1
|
|
217
151
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
list(connected_boards_df_one['connected_boards_numbers'])[0]
|
|
224
|
-
|
|
225
|
-
if 'main_line' in connected_boards_df_one.columns:
|
|
226
|
-
stock_em_zt_pool_df_data.loc[stock_em_zt_pool_df_data['symbol'] == symbol, 'main_line'] = \
|
|
227
|
-
list(connected_boards_df_one['main_line'])[0]
|
|
228
|
-
|
|
229
|
-
if 'sub_main_line' in connected_boards_df_one.columns:
|
|
230
|
-
stock_em_zt_pool_df_data.loc[stock_em_zt_pool_df_data['symbol'] == symbol, 'sub_main_line'] = \
|
|
231
|
-
list(connected_boards_df_one['sub_main_line'])[0]
|
|
232
|
-
|
|
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)
|
|
233
157
|
return stock_em_zt_pool_df_data
|
|
234
158
|
|
|
235
159
|
|
|
@@ -416,25 +340,192 @@ def query_company_info_with_share():
|
|
|
416
340
|
return company_info_df
|
|
417
341
|
|
|
418
342
|
|
|
343
|
+
def sync_main_line_data(stock_em_zt_pool_df_data, str_day):
|
|
344
|
+
# 主线标记 复盘用
|
|
345
|
+
stock_em_zt_pool_df_data['main_line'] = ''
|
|
346
|
+
stock_em_zt_pool_df_data['sub_main_line'] = ''
|
|
347
|
+
stock_em_zt_pool_df_data['zt_reason'] = ''
|
|
348
|
+
stock_em_zt_pool_df_data['zt_analysis'] = ''
|
|
349
|
+
|
|
350
|
+
last_trade_day = trade_date_common_service_api.get_last_trade_day(str_day)
|
|
351
|
+
|
|
352
|
+
last_trade_day_main_line_df = mongodb_util.find_query_data(db_name_constant.MAIN_LINE_DETAIL,
|
|
353
|
+
{'str_day': last_trade_day, 'symbol': {
|
|
354
|
+
"$in": list(stock_em_zt_pool_df_data['symbol'])}})
|
|
355
|
+
if data_frame_util.is_not_empty(last_trade_day_main_line_df):
|
|
356
|
+
symbol_mapping_main_line = dict(
|
|
357
|
+
zip(last_trade_day_main_line_df['symbol'], last_trade_day_main_line_df['main_line']))
|
|
358
|
+
|
|
359
|
+
symbol_mapping_sub_main_line = dict(
|
|
360
|
+
zip(last_trade_day_main_line_df['symbol'], last_trade_day_main_line_df['sub_main_line']))
|
|
361
|
+
|
|
362
|
+
stock_em_zt_pool_df_data['main_line'] = (stock_em_zt_pool_df_data['symbol']
|
|
363
|
+
.map(symbol_mapping_main_line).fillna(
|
|
364
|
+
stock_em_zt_pool_df_data['main_line']))
|
|
365
|
+
|
|
366
|
+
stock_em_zt_pool_df_data['sub_main_line'] = stock_em_zt_pool_df_data['symbol'].map(
|
|
367
|
+
symbol_mapping_sub_main_line).fillna(
|
|
368
|
+
stock_em_zt_pool_df_data['sub_main_line'])
|
|
369
|
+
|
|
370
|
+
today_zt_reason_analysis = mongodb_util.find_query_data(db_name_constant.MAIN_REASON_ANALYSIS,
|
|
371
|
+
{'str_day': str_day, 'symbol': {
|
|
372
|
+
"$in": list(stock_em_zt_pool_df_data['symbol'])}})
|
|
373
|
+
if data_frame_util.is_not_empty(today_zt_reason_analysis):
|
|
374
|
+
# 创建一个映射字典
|
|
375
|
+
symbol_mapping_zt_reason = dict(zip(today_zt_reason_analysis['symbol'], today_zt_reason_analysis['zt_reason']))
|
|
376
|
+
|
|
377
|
+
symbol_mapping_zt_analysis = dict(
|
|
378
|
+
zip(today_zt_reason_analysis['symbol'], today_zt_reason_analysis['zt_analysis']))
|
|
379
|
+
|
|
380
|
+
symbol_mapping_main_line = dict(zip(today_zt_reason_analysis['symbol'], today_zt_reason_analysis['main_line']))
|
|
381
|
+
|
|
382
|
+
symbol_mapping_sub_main_line = dict(
|
|
383
|
+
zip(today_zt_reason_analysis['symbol'], today_zt_reason_analysis['sub_main_line']))
|
|
384
|
+
|
|
385
|
+
# 使用map进行替换,不匹配的保持原值
|
|
386
|
+
stock_em_zt_pool_df_data['zt_reason'] = stock_em_zt_pool_df_data['symbol'].map(symbol_mapping_zt_reason).fillna(
|
|
387
|
+
stock_em_zt_pool_df_data['zt_reason'])
|
|
388
|
+
|
|
389
|
+
stock_em_zt_pool_df_data['zt_analysis'] = stock_em_zt_pool_df_data['symbol'].map(
|
|
390
|
+
symbol_mapping_zt_analysis).fillna(
|
|
391
|
+
stock_em_zt_pool_df_data['zt_analysis'])
|
|
392
|
+
|
|
393
|
+
stock_em_zt_pool_df_data['main_line'] = stock_em_zt_pool_df_data['symbol'].map(symbol_mapping_main_line).fillna(
|
|
394
|
+
stock_em_zt_pool_df_data['main_line'])
|
|
395
|
+
|
|
396
|
+
stock_em_zt_pool_df_data['sub_main_line'] = stock_em_zt_pool_df_data['symbol'].map(
|
|
397
|
+
symbol_mapping_sub_main_line).fillna(
|
|
398
|
+
stock_em_zt_pool_df_data['sub_main_line'])
|
|
399
|
+
|
|
400
|
+
return stock_em_zt_pool_df_data
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def save_today_main_line(stock_em_zt_pool_df_data, str_day):
|
|
404
|
+
for stock_one in stock_em_zt_pool_df_data.itertuples():
|
|
405
|
+
try:
|
|
406
|
+
zt_reason = stock_one.zt_reason
|
|
407
|
+
zt_analyse_detail = stock_one.zt_analysis
|
|
408
|
+
reason_tag = False
|
|
409
|
+
if data_frame_util.is_string_empty(zt_reason) or data_frame_util.is_string_empty(zt_analyse_detail):
|
|
410
|
+
|
|
411
|
+
# 问财获取
|
|
412
|
+
if bool(1 - reason_tag):
|
|
413
|
+
try:
|
|
414
|
+
# 问财获取涨停分析
|
|
415
|
+
zt_result_dict = ths_stock_zt_pool_api.zt_analyse_reason(stock_one.symbol)
|
|
416
|
+
zt_analyse_detail = zt_result_dict['zt_analyse_detail']
|
|
417
|
+
zt_reason = zt_result_dict['zt_reason']
|
|
418
|
+
time.sleep(2)
|
|
419
|
+
reason_tag = True
|
|
420
|
+
except BaseException as e:
|
|
421
|
+
time.sleep(2)
|
|
422
|
+
logger.error("问财获取涨停详情异常:{},{}", stock_one.symbol, e)
|
|
423
|
+
|
|
424
|
+
if bool(1 - reason_tag):
|
|
425
|
+
# 网页获取
|
|
426
|
+
try:
|
|
427
|
+
ths_cookie = cookie_info_service.get_ths_cookie()
|
|
428
|
+
# 问财获取涨停分析
|
|
429
|
+
zt_analyse_detail = ths_company_info_api.get_company_hot_info(stock_one.symbol, ths_cookie)
|
|
430
|
+
zt_reason = zt_analyse_detail.split("\n")[0]
|
|
431
|
+
|
|
432
|
+
time.sleep(2)
|
|
433
|
+
except BaseException as e:
|
|
434
|
+
time.sleep(2)
|
|
435
|
+
logger.error("网页获取涨停详情异常:{},{}", stock_one.symbol, e)
|
|
436
|
+
|
|
437
|
+
stock_em_zt_pool_df_data.loc[
|
|
438
|
+
stock_em_zt_pool_df_data['symbol'] == stock_one.symbol, 'zt_reason'] = zt_reason
|
|
439
|
+
|
|
440
|
+
stock_em_zt_pool_df_data.loc[
|
|
441
|
+
stock_em_zt_pool_df_data['symbol'] == stock_one.symbol, 'zt_analysis'] = zt_analyse_detail
|
|
442
|
+
|
|
443
|
+
main_line = stock_one.main_line
|
|
444
|
+
sub_main_line = stock_one.sub_main_line
|
|
445
|
+
connected_boards_numbers = stock_one.connected_boards_numbers
|
|
446
|
+
|
|
447
|
+
if data_frame_util.is_string_empty(zt_reason):
|
|
448
|
+
continue
|
|
449
|
+
|
|
450
|
+
if data_frame_util.is_string_empty(zt_analyse_detail):
|
|
451
|
+
continue
|
|
452
|
+
|
|
453
|
+
key_id = stock_one.symbol + "_" + str_day
|
|
454
|
+
# 更新临时表
|
|
455
|
+
query_zt = {"_id": key_id}
|
|
456
|
+
if mongodb_util.exist_data_query(db_name_constant.MAIN_REASON_ANALYSIS, query_zt):
|
|
457
|
+
|
|
458
|
+
if data_frame_util.is_string_not_empty(zt_reason):
|
|
459
|
+
new_values_reason = {"$set": {
|
|
460
|
+
'zt_reason': zt_reason}}
|
|
461
|
+
|
|
462
|
+
mongodb_util.update_many(query_zt, new_values_reason, db_name_constant.MAIN_REASON_ANALYSIS)
|
|
463
|
+
|
|
464
|
+
if data_frame_util.is_string_not_empty(zt_analyse_detail):
|
|
465
|
+
new_values_zt_analysis = {"$set": {
|
|
466
|
+
'zt_analysis': zt_analyse_detail}}
|
|
467
|
+
|
|
468
|
+
mongodb_util.update_many(query_zt, new_values_zt_analysis, db_name_constant.MAIN_REASON_ANALYSIS)
|
|
469
|
+
else:
|
|
470
|
+
main_dict = {'_id': key_id,
|
|
471
|
+
'symbol': stock_one.symbol,
|
|
472
|
+
'name': stock_one.name,
|
|
473
|
+
'zt_analysis': zt_analyse_detail,
|
|
474
|
+
'zt_reason': zt_reason,
|
|
475
|
+
'main_line': main_line,
|
|
476
|
+
'sub_main_line': sub_main_line,
|
|
477
|
+
'str_day': str_day,
|
|
478
|
+
'update_time': str_now_date,
|
|
479
|
+
'connected_boards_numbers': connected_boards_numbers
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
main_line_df = pd.DataFrame(main_dict, index=[1])
|
|
483
|
+
mongodb_util.insert_mongo(main_line_df, db_name_constant.MAIN_REASON_ANALYSIS)
|
|
484
|
+
|
|
485
|
+
if data_frame_util.is_string_empty(main_line):
|
|
486
|
+
continue
|
|
487
|
+
|
|
488
|
+
if data_frame_util.is_string_empty(sub_main_line):
|
|
489
|
+
continue
|
|
490
|
+
|
|
491
|
+
# 去除开头和结尾空格
|
|
492
|
+
if data_frame_util.is_string_not_empty(main_line):
|
|
493
|
+
main_line = main_line.strip()
|
|
494
|
+
if data_frame_util.is_string_not_empty(sub_main_line):
|
|
495
|
+
sub_main_line = sub_main_line.strip()
|
|
496
|
+
now_date = datetime.now()
|
|
497
|
+
str_now_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
|
|
498
|
+
hour = now_date.hour
|
|
499
|
+
|
|
500
|
+
main_dict = {'_id': key_id,
|
|
501
|
+
'symbol': stock_one.symbol,
|
|
502
|
+
'name': stock_one.name,
|
|
503
|
+
'zt_analysis': zt_analyse_detail,
|
|
504
|
+
'zt_reason': zt_reason,
|
|
505
|
+
'main_line': main_line,
|
|
506
|
+
'sub_main_line': sub_main_line,
|
|
507
|
+
'str_day': str_day,
|
|
508
|
+
'update_time': str_now_date,
|
|
509
|
+
'connected_boards_numbers': connected_boards_numbers
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
main_line_df = pd.DataFrame(main_dict, index=[1])
|
|
513
|
+
|
|
514
|
+
# 更新主线表
|
|
515
|
+
is_no_update_main_line = trade_date_common_service_api.is_trade_day(str_day) and 8 < hour < 15
|
|
516
|
+
if is_no_update_main_line:
|
|
517
|
+
continue
|
|
518
|
+
|
|
519
|
+
if mongodb_util.exist_data_query(db_name_constant.MAIN_LINE_DETAIL, query_zt):
|
|
520
|
+
continue
|
|
521
|
+
else:
|
|
522
|
+
mongodb_util.insert_mongo(main_line_df, db_name_constant.MAIN_LINE_DETAIL)
|
|
523
|
+
|
|
524
|
+
except BaseException as e:
|
|
525
|
+
logger.error("同步涨停信息出现异常:{},{}", stock_one.symbol, e)
|
|
526
|
+
|
|
527
|
+
return stock_em_zt_pool_df_data
|
|
528
|
+
|
|
529
|
+
|
|
419
530
|
if __name__ == '__main__':
|
|
420
|
-
save_zt_info('2025-
|
|
421
|
-
# from datetime import datetime
|
|
422
|
-
#
|
|
423
|
-
# if __name__ == '__main__':
|
|
424
|
-
#
|
|
425
|
-
# sync_date = date_handle_util.add_date_day('20240110', 0)
|
|
426
|
-
#
|
|
427
|
-
# now_date = datetime.now()
|
|
428
|
-
#
|
|
429
|
-
# str_now_day = sync_date.strftime('%Y-%m-%d')
|
|
430
|
-
#
|
|
431
|
-
# while now_date > sync_date:
|
|
432
|
-
# try:
|
|
433
|
-
# save_zt_info(str_now_day)
|
|
434
|
-
# sync_date = date_handle_util.add_date_day(date_handle_util.no_slash_date(str_now_day), 1)
|
|
435
|
-
# print(str_now_day)
|
|
436
|
-
# str_now_day = sync_date.strftime('%Y-%m-%d')
|
|
437
|
-
#
|
|
438
|
-
# except BaseException as e:
|
|
439
|
-
# sync_date = date_handle_util.add_date_day(date_handle_util.no_slash_date(str_now_day), 1)
|
|
440
|
-
# str_now_day = sync_date.strftime('%Y-%m-%d')
|
|
531
|
+
save_zt_info('2025-12-03')
|
|
@@ -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-
|
|
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-
|
|
61
|
+
update_null_zt_reason('2025-12-08')
|