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,87 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
file_path = os.path.abspath(__file__)
|
|
6
|
+
end = file_path.index('mns') + 16
|
|
7
|
+
project_path = file_path[0:end]
|
|
8
|
+
sys.path.append(project_path)
|
|
9
|
+
|
|
10
|
+
from mns_common.db.MongodbUtil import MongodbUtil
|
|
11
|
+
import mns_common.constant.db_name_constant as db_name_constant
|
|
12
|
+
import mns_common.utils.data_frame_util as data_frame_util
|
|
13
|
+
import mns_common.component.deal.deal_service_api as deal_service_api
|
|
14
|
+
from loguru import logger
|
|
15
|
+
from mns_common.utils.async_fun import async_fun
|
|
16
|
+
import mns_common.component.common_service_fun_api as common_service_fun_api
|
|
17
|
+
import mns_common.utils.date_handle_util as date_handle_util
|
|
18
|
+
mongodb_util = MongodbUtil('27017')
|
|
19
|
+
from datetime import datetime
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def auto_da_ban_task():
|
|
23
|
+
logger.info("打板任务启动")
|
|
24
|
+
while True:
|
|
25
|
+
try:
|
|
26
|
+
now_date = datetime.now()
|
|
27
|
+
now_str_day = now_date.strftime('%Y-%m-%d')
|
|
28
|
+
if bool(1 - date_handle_util.is_trade_date(now_str_day)):
|
|
29
|
+
logger.info("非交易日不执行:{}", now_str_day)
|
|
30
|
+
break
|
|
31
|
+
else:
|
|
32
|
+
# 执行打板任务
|
|
33
|
+
auto_da_ban()
|
|
34
|
+
except BaseException as e:
|
|
35
|
+
logger.error("自动打板定时任务异常:{}", e)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def auto_da_ban():
|
|
39
|
+
now_date = datetime.now()
|
|
40
|
+
now_str_day = now_date.strftime('%Y-%m-%d')
|
|
41
|
+
over_night_da_ban_list = query_over_night_da_ban_list(now_str_day)
|
|
42
|
+
if data_frame_util.is_empty(over_night_da_ban_list):
|
|
43
|
+
return None
|
|
44
|
+
for stock_one in over_night_da_ban_list.itertuples():
|
|
45
|
+
try:
|
|
46
|
+
symbol = stock_one.symbol
|
|
47
|
+
buy_price = stock_one.zt_price
|
|
48
|
+
buy_volume = stock_one.buy_volume
|
|
49
|
+
xia_dan_to_ths(symbol, buy_price, buy_volume, now_str_day)
|
|
50
|
+
time.sleep(0.5)
|
|
51
|
+
except BaseException as e:
|
|
52
|
+
logger.error("自动打板出现异常:{},{}", symbol, e)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def xia_dan_to_ths(symbol, buy_price, buy_volume, str_day):
|
|
56
|
+
symbol = common_service_fun_api.add_after_prefix_one(symbol)
|
|
57
|
+
|
|
58
|
+
buy_result = deal_service_api.trade_buy(symbol, buy_price, buy_volume, 'qmt')
|
|
59
|
+
|
|
60
|
+
# 异步更新信息
|
|
61
|
+
handle_async_msg(buy_result, str_day, symbol)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@async_fun
|
|
65
|
+
def handle_async_msg(buy_result, str_day, symbol):
|
|
66
|
+
if "message" in buy_result:
|
|
67
|
+
result_msg = buy_result['message']
|
|
68
|
+
if result_msg == 'success':
|
|
69
|
+
auto_da_ban_flag = True
|
|
70
|
+
else:
|
|
71
|
+
auto_da_ban_flag = False
|
|
72
|
+
elif "entrust_no" in buy_result:
|
|
73
|
+
auto_da_ban_flag = True
|
|
74
|
+
if auto_da_ban_flag:
|
|
75
|
+
query = {"str_day": str_day, "symbol": symbol}
|
|
76
|
+
new_values = {"$set": {"valid": False}}
|
|
77
|
+
mongodb_util.update_many(query, new_values, db_name_constant.OVER_NIGHT_DA_BAN)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def query_over_night_da_ban_list(str_day):
|
|
81
|
+
query = {"str_day": str_day, "valid": True}
|
|
82
|
+
return mongodb_util.find_query_data(db_name_constant.OVER_NIGHT_DA_BAN, query)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if __name__ == '__main__':
|
|
86
|
+
while True:
|
|
87
|
+
auto_da_ban()
|
|
@@ -12,25 +12,28 @@ from loguru import logger
|
|
|
12
12
|
import mns_scheduler.company_info.constant.company_constant_data as company_constant_data
|
|
13
13
|
import mns_common.constant.db_name_constant as db_name_constant
|
|
14
14
|
import mns_scheduler.concept.ths.detaill.ths_concept_detail_api as ths_concept_detail_api
|
|
15
|
-
import mns_scheduler.company_info.
|
|
15
|
+
import mns_scheduler.company_info.common.company_common_query_service as company_common_query_service
|
|
16
|
+
import mns_scheduler.company_info.sync.sync_company_info_task as sync_company_info_task
|
|
16
17
|
import mns_common.utils.data_frame_util as data_frame_util
|
|
17
|
-
|
|
18
|
-
mongodb_util = MongodbUtil('27017')
|
|
19
18
|
import mns_common.component.common_service_fun_api as common_service_fun_api
|
|
20
19
|
import mns_common.component.company.company_common_service_api as company_common_service_api
|
|
21
20
|
|
|
21
|
+
mongodb_util = MongodbUtil('27017')
|
|
22
|
+
|
|
22
23
|
|
|
23
24
|
# 修改行业信息
|
|
24
|
-
def clean_company_info(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
def clean_company_info(symbol_list):
|
|
26
|
+
create_company_info_index()
|
|
27
|
+
|
|
28
|
+
if len(symbol_list) > 0:
|
|
29
|
+
query = {"symbol": {"$in": symbol_list}}
|
|
30
|
+
company_info_temp_df = mongodb_util.find_query_data(db_name_constant.COMPANY_INFO_TEMP, query)
|
|
28
31
|
else:
|
|
29
|
-
|
|
32
|
+
company_info_temp_df = mongodb_util.find_query_data(db_name_constant.COMPANY_INFO_TEMP, {})
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
company_info_temp_df = company_constant_data.fix_second_industry(company_info_temp_df)
|
|
32
35
|
|
|
33
|
-
company_info =
|
|
36
|
+
company_info = company_info_temp_df.set_index(['second_sw_industry'], drop=False)
|
|
34
37
|
|
|
35
38
|
# 修改行业名称
|
|
36
39
|
del company_info['industry']
|
|
@@ -69,7 +72,7 @@ def clean_company_info(symbol):
|
|
|
69
72
|
sub_stock = ths_concept_detail_api.get_ths_concept_detail('885598', None)
|
|
70
73
|
sub_stock_symbol_list = list(sub_stock['symbol'])
|
|
71
74
|
except BaseException as e:
|
|
72
|
-
logger.error("出现异常:{},
|
|
75
|
+
logger.error("出现异常:{},", e)
|
|
73
76
|
query = {'concept_code': 885598}
|
|
74
77
|
ths_stock_concept_detail = mongodb_util.find_query_data(db_name_constant.THS_STOCK_CONCEPT_DETAIL, query)
|
|
75
78
|
sub_stock_symbol_list = list(ths_stock_concept_detail['symbol'])
|
|
@@ -83,6 +86,9 @@ def clean_company_info(symbol):
|
|
|
83
86
|
if data_frame_util.is_not_empty(ths_stock_industry_detail_df):
|
|
84
87
|
ths_stock_industry_detail_df = ths_stock_industry_detail_df[
|
|
85
88
|
['symbol', 'ths_industry_name', 'ths_industry_code']]
|
|
89
|
+
|
|
90
|
+
ths_stock_industry_detail_df = ths_stock_industry_detail_df.loc[
|
|
91
|
+
ths_stock_industry_detail_df['symbol'].isin(list(company_info['symbol']))]
|
|
86
92
|
ths_stock_industry_detail_df = ths_stock_industry_detail_df.set_index(['symbol'], drop=True)
|
|
87
93
|
company_info = company_info.set_index(['_id'], drop=False)
|
|
88
94
|
company_info = pd.merge(company_info, ths_stock_industry_detail_df, how='outer',
|
|
@@ -93,11 +99,13 @@ def clean_company_info(symbol):
|
|
|
93
99
|
else:
|
|
94
100
|
company_info['ths_industry_code'] = '0'
|
|
95
101
|
company_info['ths_industry_name'] = '异常'
|
|
102
|
+
company_info.dropna(subset=['symbol'], axis=0, inplace=True)
|
|
103
|
+
company_info.dropna(subset=['_id'], axis=0, inplace=True)
|
|
96
104
|
mongodb_util.save_mongo(company_info, db_name_constant.COMPANY_INFO)
|
|
97
105
|
# 保存历史数据
|
|
98
106
|
save_company_info_his(company_info)
|
|
99
107
|
except BaseException as e:
|
|
100
|
-
logger.error("出现异常:{}
|
|
108
|
+
logger.error("出现异常:{}", e)
|
|
101
109
|
|
|
102
110
|
return company_info
|
|
103
111
|
|
|
@@ -117,17 +125,30 @@ def save_company_info_his(company_info_df):
|
|
|
117
125
|
|
|
118
126
|
# 更新新上市公司信息
|
|
119
127
|
def new_company_info_update():
|
|
120
|
-
east_money_stock_info =
|
|
128
|
+
east_money_stock_info = company_common_query_service.get_company_info()
|
|
121
129
|
new_stock = common_service_fun_api.get_new_stock(east_money_stock_info.copy())
|
|
122
130
|
for company_one in new_stock.itertuples():
|
|
123
131
|
try:
|
|
124
|
-
|
|
125
|
-
clean_company_info(company_one.symbol)
|
|
132
|
+
sync_company_info_task.sync_company_base_info([company_one.symbol])
|
|
133
|
+
clean_company_info([company_one.symbol])
|
|
126
134
|
|
|
127
135
|
except BaseException as e:
|
|
128
136
|
logger.error("出现异常:{}", e)
|
|
129
137
|
company_common_service_api.company_info_industry_cache_clear
|
|
130
138
|
|
|
131
139
|
|
|
140
|
+
def create_company_info_index():
|
|
141
|
+
mongodb_util.create_index('company_info',
|
|
142
|
+
[("classification", 1)])
|
|
143
|
+
mongodb_util.create_index('company_info',
|
|
144
|
+
[("industry", 1)])
|
|
145
|
+
mongodb_util.create_index('company_info',
|
|
146
|
+
[("flow_mv", 1)])
|
|
147
|
+
mongodb_util.create_index('company_info',
|
|
148
|
+
[("list_date", 1)])
|
|
149
|
+
mongodb_util.create_index('company_info',
|
|
150
|
+
[("symbol", 1)])
|
|
151
|
+
|
|
152
|
+
|
|
132
153
|
if __name__ == '__main__':
|
|
133
|
-
clean_company_info(
|
|
154
|
+
clean_company_info(["688795"])
|
|
@@ -0,0 +1,45 @@
|
|
|
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.component.em.em_stock_info_api as em_stock_info_api
|
|
9
|
+
import mns_common.component.company.company_common_service_api as company_common_service_api
|
|
10
|
+
import mns_common.component.common_service_fun_api as common_service_fun_api
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_company_info():
|
|
14
|
+
em_company_info_df = em_stock_info_api.get_a_stock_info()
|
|
15
|
+
em_company_info_df = em_company_info_df[['symbol',
|
|
16
|
+
'name',
|
|
17
|
+
"now_price",
|
|
18
|
+
'total_mv',
|
|
19
|
+
'flow_mv',
|
|
20
|
+
'pe_ttm',
|
|
21
|
+
'sz_sh',
|
|
22
|
+
'area',
|
|
23
|
+
'pb',
|
|
24
|
+
'list_date',
|
|
25
|
+
'ROE',
|
|
26
|
+
'total_share',
|
|
27
|
+
'flow_share',
|
|
28
|
+
'industry',
|
|
29
|
+
'amount',
|
|
30
|
+
"hk_stock_code",
|
|
31
|
+
"hk_stock_name",
|
|
32
|
+
'concept']]
|
|
33
|
+
|
|
34
|
+
em_company_info_df = em_company_info_df.sort_values(by=['list_date'], ascending=False)
|
|
35
|
+
|
|
36
|
+
de_listed_stock_list = company_common_service_api.get_de_list_company()
|
|
37
|
+
em_company_info_df = em_company_info_df.loc[~(
|
|
38
|
+
em_company_info_df['symbol'].isin(de_listed_stock_list))]
|
|
39
|
+
em_company_info_df = common_service_fun_api.exclude_ts_symbol(em_company_info_df)
|
|
40
|
+
|
|
41
|
+
return em_company_info_df
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if __name__ == '__main__':
|
|
45
|
+
get_company_info()
|
|
@@ -14,49 +14,60 @@ mongodb_util = MongodbUtil('27017')
|
|
|
14
14
|
|
|
15
15
|
# 修改行业分类的股票
|
|
16
16
|
def get_fix_symbol_industry():
|
|
17
|
-
return pd.DataFrame([
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
17
|
+
return pd.DataFrame([
|
|
18
|
+
['688480', '赛恩斯', '760103', '环境治理'],
|
|
19
|
+
['000032', '深桑达A', '730204', '通信网络设备及器件'],
|
|
20
|
+
['688480', '赛恩斯', '640704', '自动化设备'],
|
|
21
|
+
['603260', '合盛硅业', '220316', '有机硅'],
|
|
22
|
+
['300559', '佳发教育', '461102', '培训教育'],
|
|
23
|
+
|
|
24
|
+
['600338', '西藏珠峰', '240303', '铅锌'],
|
|
25
|
+
|
|
26
|
+
['688507', '索辰科技', '710402', '横向通用软件'],
|
|
27
|
+
['301387', '光大同创', '270504', '消费电子零部件及组装'],
|
|
28
|
+
['300295', '三六五网', '430301', '物业管理'],
|
|
29
|
+
['300947', '德必集团', '430301', '物业管理'],
|
|
30
|
+
['300483', '首华燃气', '410301', '燃气Ⅲ'],
|
|
31
|
+
['300215', '电科院', '410110', '电能综合服务'],
|
|
32
|
+
# 持有上海微电子装备有限公司10%的股份 国产光刻机 主要炒作在芯片概念 不在房地产
|
|
33
|
+
|
|
34
|
+
['300836', '佰奥智能', '640701', '机器人'],
|
|
35
|
+
['300293', '蓝英装备', '640701', '机器人'],
|
|
36
|
+
['301112', '信邦智能', '640704', '其他自动化设备'],
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
['000670', '盈方微', '270401', '其他电子'],
|
|
41
|
+
|
|
42
|
+
['300803', '指南针', '490101', '证券'],
|
|
43
|
+
['300085', '银之杰', '490101', '证券'],
|
|
44
|
+
['300380', '安硕信息', '490101', '证券'],
|
|
45
|
+
['600446', '金证股份', '490101', '证券'],
|
|
46
|
+
['688318', '财富趋势', '490101', '证券'],
|
|
47
|
+
['600570', '恒生电子', '490101', '证券'],
|
|
48
|
+
['837592', '华信永道', '490101', '证券'],
|
|
49
|
+
['830799', '艾融软件', '490101', '证券'],
|
|
50
|
+
['300033', '同花顺', '490101', '证券'],
|
|
51
|
+
['300399', '天利科技', '490201', '保险'],
|
|
52
|
+
|
|
53
|
+
['002131', '利欧股份', '720501', '营销代理'],
|
|
54
|
+
|
|
55
|
+
['300042', '朗科科技', '270108', '半导体设备'],
|
|
56
|
+
# EDA软件
|
|
57
|
+
['301269', '华大九天', '270108', '半导体设备'],
|
|
58
|
+
['688206', '概伦电子', '270108', '半导体设备'],
|
|
59
|
+
['301095', '广立微', '270108', '半导体设备'],
|
|
60
|
+
['600895', '张江高科', '270108', '半导体设备'],
|
|
61
|
+
|
|
62
|
+
['688630', '芯碁微装', '270108', '半导体设备'],
|
|
63
|
+
['001309', '德明利', '270104', '数字芯片设计'],
|
|
64
|
+
['688795', '摩尔线程', '270104', '数字芯片设计'],
|
|
65
|
+
|
|
66
|
+
],
|
|
67
|
+
columns=['symbol',
|
|
68
|
+
'name',
|
|
69
|
+
'new_industry_code', # 三级行业代码
|
|
70
|
+
'new_industry'])
|
|
60
71
|
|
|
61
72
|
|
|
62
73
|
# 修改二级行业分类的股票
|
|
@@ -401,12 +412,12 @@ def find_sw_third_industry(new_third_industry_code):
|
|
|
401
412
|
# 修改行业信息
|
|
402
413
|
def fix_industry_data(new_third_industry_code, company_info):
|
|
403
414
|
sw_industry = find_sw_third_industry(new_third_industry_code)
|
|
404
|
-
company_info['first_sw_industry'] = sw_industry
|
|
405
|
-
company_info['first_industry_code'] = sw_industry
|
|
406
|
-
company_info['second_sw_industry'] = sw_industry
|
|
407
|
-
company_info['second_industry_code'] = sw_industry
|
|
408
|
-
company_info['third_sw_industry'] = sw_industry
|
|
409
|
-
company_info['third_industry_code'] = sw_industry
|
|
415
|
+
company_info['first_sw_industry'] = list(sw_industry['first_sw_industry'])[0]
|
|
416
|
+
company_info['first_industry_code'] = list(sw_industry['industry_code'])[0]
|
|
417
|
+
company_info['second_sw_industry'] = list(sw_industry['second_sw_industry'])[0]
|
|
418
|
+
company_info['second_industry_code'] = list(sw_industry['second_industry_code'])[0]
|
|
419
|
+
company_info['third_sw_industry'] = list(sw_industry['third_sw_industry'])[0]
|
|
420
|
+
company_info['third_industry_code'] = list(sw_industry['industry_code'])[0]
|
|
410
421
|
return company_info
|
|
411
422
|
|
|
412
423
|
|
|
@@ -37,6 +37,7 @@ def sync_all_em_stock_info():
|
|
|
37
37
|
logger.error("同步东方财富A股信息异常:{}", e)
|
|
38
38
|
try:
|
|
39
39
|
em_etf_info = east_money_etf_api.get_etf_real_time_quotes(30, 6)
|
|
40
|
+
em_etf_info['_id'] = em_etf_info['symbol']
|
|
40
41
|
em_etf_info['sync_time'] = str_now_date
|
|
41
42
|
mongodb_util.save_mongo(em_etf_info, extra_income_db_name.EM_ETF_INFO)
|
|
42
43
|
except BaseException as e:
|
|
@@ -0,0 +1,208 @@
|
|
|
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.component.common_service_fun_api as common_service_fun_api
|
|
9
|
+
from mns_common.db.MongodbUtil import MongodbUtil
|
|
10
|
+
import mns_common.utils.data_frame_util as data_frame_util
|
|
11
|
+
import mns_common.api.kpl.constant.kpl_constant as kpl_constant
|
|
12
|
+
import mns_common.constant.db_name_constant as db_name_constant
|
|
13
|
+
from functools import lru_cache
|
|
14
|
+
from loguru import logger
|
|
15
|
+
|
|
16
|
+
mongodb_util = MongodbUtil('27017')
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def set_kpl_plate_info(company_one_df, company_one, kpl_real_time_quotes):
|
|
20
|
+
try:
|
|
21
|
+
if data_frame_util.is_not_empty(kpl_real_time_quotes):
|
|
22
|
+
kpl_real_time_quotes_one = kpl_real_time_quotes.loc[
|
|
23
|
+
kpl_real_time_quotes['symbol'] == company_one.symbol]
|
|
24
|
+
|
|
25
|
+
if data_frame_util.is_not_empty(kpl_real_time_quotes_one):
|
|
26
|
+
company_one_df['kpl_plate_name'] = list(kpl_real_time_quotes_one['plate_name_list'])[0]
|
|
27
|
+
company_one_df['kpl_most_relative_name'] = \
|
|
28
|
+
list(kpl_real_time_quotes_one['most_relative_name'])[
|
|
29
|
+
0]
|
|
30
|
+
company_one_df = set_kpl_data(kpl_real_time_quotes_one, company_one_df, company_one)
|
|
31
|
+
|
|
32
|
+
if bool(1 - ("kpl_plate_name" in company_one_df.columns)) or bool(
|
|
33
|
+
1 - ("kpl_most_relative_name" in company_one_df.columns)):
|
|
34
|
+
company_one_df['kpl_plate_name'] = ""
|
|
35
|
+
company_one_df['kpl_most_relative_name'] = ""
|
|
36
|
+
except BaseException as e:
|
|
37
|
+
logger.warning("设置开盘啦数据异常:{},{}", company_one.symbol, e)
|
|
38
|
+
return company_one_df
|
|
39
|
+
|
|
40
|
+
def set_kpl_data(kpl_real_time_quotes_one, company_one_df, company_one):
|
|
41
|
+
if data_frame_util.is_not_empty(kpl_real_time_quotes_one):
|
|
42
|
+
company_one_df['kpl_plate_name'] = list(kpl_real_time_quotes_one['plate_name_list'])[0]
|
|
43
|
+
company_one_df['kpl_most_relative_name'] = list(kpl_real_time_quotes_one['most_relative_name'])[
|
|
44
|
+
0]
|
|
45
|
+
symbol = company_one.symbol
|
|
46
|
+
|
|
47
|
+
query = {'symbol': symbol, "index_class": kpl_constant.FIRST_INDEX}
|
|
48
|
+
kpl_best_choose_index_detail = mongodb_util.find_query_data('kpl_best_choose_index_detail', query)
|
|
49
|
+
if data_frame_util.is_not_empty(kpl_best_choose_index_detail):
|
|
50
|
+
kpl_best_choose_index_detail = kpl_best_choose_index_detail[[
|
|
51
|
+
"plate_code",
|
|
52
|
+
"plate_name",
|
|
53
|
+
"first_plate_code",
|
|
54
|
+
"first_plate_name",
|
|
55
|
+
"index_class"
|
|
56
|
+
]]
|
|
57
|
+
|
|
58
|
+
# 去除空格
|
|
59
|
+
kpl_best_choose_index_detail['plate_name'] = kpl_best_choose_index_detail['plate_name'].str.replace(' ', '')
|
|
60
|
+
# 去除空格
|
|
61
|
+
kpl_best_choose_index_detail['first_plate_name'] = kpl_best_choose_index_detail[
|
|
62
|
+
'first_plate_name'].str.replace(' ', '')
|
|
63
|
+
|
|
64
|
+
company_one_df.loc[:, 'kpl_plate_list_info'] = kpl_best_choose_index_detail.to_string(index=False)
|
|
65
|
+
return company_one_df
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# 获取可转债信息
|
|
69
|
+
@lru_cache(maxsize=None)
|
|
70
|
+
def get_kzz_debt_info():
|
|
71
|
+
query = {}
|
|
72
|
+
kzz_debt_info_df = mongodb_util.find_query_data(db_name_constant.KZZ_DEBT_INFO, query)
|
|
73
|
+
kzz_debt_info_df = kzz_debt_info_df[[
|
|
74
|
+
'symbol',
|
|
75
|
+
'name',
|
|
76
|
+
'stock_code',
|
|
77
|
+
'apply_date',
|
|
78
|
+
'list_date',
|
|
79
|
+
'due_date'
|
|
80
|
+
]]
|
|
81
|
+
return kzz_debt_info_df
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def set_kzz_debt(company_one_df, symbol):
|
|
85
|
+
kzz_debt_info_df_all = get_kzz_debt_info()
|
|
86
|
+
kzz_debt_info_df = kzz_debt_info_df_all.loc[kzz_debt_info_df_all['stock_code'] == symbol]
|
|
87
|
+
|
|
88
|
+
if data_frame_util.is_not_empty(kzz_debt_info_df):
|
|
89
|
+
kzz_debt_info_df_list = kzz_debt_info_df.to_dict(orient='records')
|
|
90
|
+
company_one_df['kzz_debt_list'] = [kzz_debt_info_df_list]
|
|
91
|
+
return company_one_df
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# 获取最近年报收入
|
|
95
|
+
def set_recent_year_income(symbol, company_one_df):
|
|
96
|
+
query = {'symbol': symbol, "REPORT_TYPE": "年报"}
|
|
97
|
+
em_stock_profit = mongodb_util.descend_query(query, db_name_constant.EM_STOCK_PROFIT, 'REPORT_DATE', 1)
|
|
98
|
+
if data_frame_util.is_not_empty(em_stock_profit):
|
|
99
|
+
company_one_df['operate_profit'] = list(em_stock_profit['OPERATE_PROFIT'])[0]
|
|
100
|
+
company_one_df['operate_date_name'] = list(em_stock_profit['REPORT_DATE_NAME'])[0]
|
|
101
|
+
total_operate_income = list(em_stock_profit['TOTAL_OPERATE_INCOME'])[0]
|
|
102
|
+
# 金融机构大多收入计入在这个字段中
|
|
103
|
+
if total_operate_income == 0:
|
|
104
|
+
total_operate_income = list(em_stock_profit['OPERATE_INCOME'])[0]
|
|
105
|
+
|
|
106
|
+
company_one_df['total_operate_income'] = total_operate_income
|
|
107
|
+
else:
|
|
108
|
+
company_one_df['operate_profit'] = 0
|
|
109
|
+
company_one_df['total_operate_income'] = 0
|
|
110
|
+
company_one_df['operate_date_name'] = '暂无年报'
|
|
111
|
+
company_one_df['operate_profit'] = round(
|
|
112
|
+
company_one_df['operate_profit'] / common_service_fun_api.HUNDRED_MILLION, 2)
|
|
113
|
+
company_one_df['total_operate_income'] = round(
|
|
114
|
+
company_one_df['total_operate_income'] / common_service_fun_api.HUNDRED_MILLION, 2)
|
|
115
|
+
return company_one_df
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# 计算真实流通比例
|
|
119
|
+
def set_calculate_circulation_ratio(symbol, now_str_day, company_one_df):
|
|
120
|
+
query = {"symbol": symbol}
|
|
121
|
+
stock_gdfx_free_top_1 = mongodb_util.descend_query(query, 'stock_gdfx_free_top_10', "period", 1)
|
|
122
|
+
if stock_gdfx_free_top_1.shape[0] == 0:
|
|
123
|
+
mv_circulation_ratio = 1
|
|
124
|
+
qfii_number = 0
|
|
125
|
+
qfii_type = 'A股'
|
|
126
|
+
share_holder_sync_day = now_str_day
|
|
127
|
+
else:
|
|
128
|
+
period_time = list(stock_gdfx_free_top_1['period'])[0]
|
|
129
|
+
|
|
130
|
+
query_free = {'symbol': symbol, 'period': period_time}
|
|
131
|
+
stock_gdfx_free_top_10 = mongodb_util.find_query_data('stock_gdfx_free_top_10', query_free)
|
|
132
|
+
|
|
133
|
+
stock_gdfx_free_top_10['shares_number_str'] = stock_gdfx_free_top_10['shares_number'].astype(str)
|
|
134
|
+
|
|
135
|
+
stock_gdfx_free_top_10['id_key'] = stock_gdfx_free_top_10['symbol'] + '_' + stock_gdfx_free_top_10[
|
|
136
|
+
'period'] + '_' + stock_gdfx_free_top_10.shares_number_str
|
|
137
|
+
|
|
138
|
+
stock_gdfx_free_top_10.drop_duplicates('id_key', keep='last', inplace=True)
|
|
139
|
+
|
|
140
|
+
# 排除香港结算公司 大于5%减持不用发公告 香港中央结算 HKSCC
|
|
141
|
+
stock_gdfx_free_top_10['is_hk'] = stock_gdfx_free_top_10['shareholder_name'].apply(
|
|
142
|
+
lambda shareholder_name: "HK" if shareholder_name.startswith('香港中央结算') or shareholder_name.startswith(
|
|
143
|
+
'HKSCC') else "A")
|
|
144
|
+
|
|
145
|
+
# 持股大于5% 减持需要发公告
|
|
146
|
+
# 排除香港结算公司不发公共 小于5%减持不用发公告
|
|
147
|
+
# 香港中央结算 HKSCC
|
|
148
|
+
stock_free_top_greater_than_5 = stock_gdfx_free_top_10.loc[
|
|
149
|
+
(stock_gdfx_free_top_10['circulation_ratio'] >= 5) & (stock_gdfx_free_top_10['is_hk'] == 'A')]
|
|
150
|
+
|
|
151
|
+
stock_free_qfii = stock_gdfx_free_top_10.loc[stock_gdfx_free_top_10['shareholder_nature'] == 'QFII']
|
|
152
|
+
|
|
153
|
+
share_holder_sync_day = list(stock_gdfx_free_top_10['create_day'])[0]
|
|
154
|
+
|
|
155
|
+
# qfii 数量
|
|
156
|
+
qfii_number = stock_free_qfii.shape[0]
|
|
157
|
+
# qfii 类型
|
|
158
|
+
qfii_type = set_qfii_type(qfii_number, stock_free_qfii.copy())
|
|
159
|
+
|
|
160
|
+
circulation_ratio = sum(stock_free_top_greater_than_5['circulation_ratio'])
|
|
161
|
+
mv_circulation_ratio = round((100 - circulation_ratio) / 100, 2)
|
|
162
|
+
# 防止错误数据
|
|
163
|
+
if mv_circulation_ratio < 0:
|
|
164
|
+
mv_circulation_ratio = 1
|
|
165
|
+
|
|
166
|
+
company_one_df['mv_circulation_ratio'] = mv_circulation_ratio
|
|
167
|
+
company_one_df['qfii_type'] = qfii_type
|
|
168
|
+
company_one_df['qfii_number'] = qfii_number
|
|
169
|
+
company_one_df['share_holder_sync_day'] = share_holder_sync_day
|
|
170
|
+
|
|
171
|
+
return company_one_df
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
# 设置QFII持股
|
|
175
|
+
def set_qfii_type(qfii_number, stock_free_qfii):
|
|
176
|
+
if qfii_number > 0:
|
|
177
|
+
stock_free_qfii['new_change'] = stock_free_qfii['change']
|
|
178
|
+
stock_free_qfii.loc[stock_free_qfii['change_ratio'] == 0, 'new_change'] = 0
|
|
179
|
+
stock_free_qfii.loc[stock_free_qfii['change'] == '新进', 'new_change'] = \
|
|
180
|
+
stock_free_qfii['shares_number']
|
|
181
|
+
stock_free_qfii['new_change'] = stock_free_qfii['new_change'].astype(float)
|
|
182
|
+
|
|
183
|
+
stock_free_qfii_new_in = stock_free_qfii.loc[stock_free_qfii['change'] == '新进']
|
|
184
|
+
if data_frame_util.is_not_empty(stock_free_qfii_new_in):
|
|
185
|
+
qfii_type = 1
|
|
186
|
+
return qfii_type
|
|
187
|
+
|
|
188
|
+
stock_free_qfii_add = stock_free_qfii.loc[
|
|
189
|
+
(~stock_free_qfii['change'].isin(['不变', '新进'])) & (stock_free_qfii['new_change'] > 0)]
|
|
190
|
+
|
|
191
|
+
if data_frame_util.is_not_empty(stock_free_qfii_add):
|
|
192
|
+
qfii_type = 2
|
|
193
|
+
return qfii_type
|
|
194
|
+
|
|
195
|
+
stock_free_qfii_not_change = stock_free_qfii.loc[stock_free_qfii['change'] == '不变']
|
|
196
|
+
|
|
197
|
+
if data_frame_util.is_not_empty(stock_free_qfii_not_change):
|
|
198
|
+
qfii_type = 3
|
|
199
|
+
return qfii_type
|
|
200
|
+
|
|
201
|
+
stock_free_qfii_reduce = stock_free_qfii.loc[
|
|
202
|
+
(~stock_free_qfii['change'].isin(['不变', '新进'])) & (stock_free_qfii['new_change'] < 0)]
|
|
203
|
+
|
|
204
|
+
if data_frame_util.is_not_empty(stock_free_qfii_reduce):
|
|
205
|
+
qfii_type = 4
|
|
206
|
+
return qfii_type
|
|
207
|
+
else:
|
|
208
|
+
return 0
|