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.
- mns_scheduler/{company_info/announce → auto_da_ban}/__init__.py +1 -1
- mns_scheduler/auto_da_ban/auto_da_ban_service.py +89 -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 +59 -49
- mns_scheduler/company_info/em_stock_info/sync_em_stock_info_sync.py +94 -40
- 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 +11 -3
- 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 +34 -26
- mns_scheduler/irm/stock_question_id_service.py +169 -0
- mns_scheduler/self_choose/ths_self_choose_service.py +53 -25
- mns_scheduler/trade/auto_login/trader_auto_service.py +2 -1
- mns_scheduler/trade/task/trader_task_service.py +13 -2
- mns_scheduler/trade/tfp/stock_tfp_info_sync.py +1 -1
- mns_scheduler/zb/stock_zb_pool_sync.py +1 -1
- mns_scheduler/zt/zt_pool/em_zt_pool_sync_api.py +80 -104
- 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 +45 -37
- {mns_scheduler-1.4.3.2.dist-info → mns_scheduler-1.4.5.7.dist-info}/METADATA +1 -1
- {mns_scheduler-1.4.3.2.dist-info → mns_scheduler-1.4.5.7.dist-info}/RECORD +38 -31
- 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.2.dist-info → mns_scheduler-1.4.5.7.dist-info}/WHEEL +0 -0
- {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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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()
|
|
@@ -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("
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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-
|
|
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-
|
|
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')
|