mns-scheduler 1.4.3.5__py3-none-any.whl → 1.4.6.4__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 +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/clean_em_us_hk_stock_info.py +30 -0
- mns_scheduler/company_info/em_stock_info/sync_em_stock_info_sync.py +100 -39
- 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/k_line/clean/k_line_info_clean_task.py +1 -0
- mns_scheduler/kpl/theme/__init__.py +7 -0
- mns_scheduler/kpl/theme/kpl_theme_sync_service.py +231 -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 +45 -130
- mns_scheduler/zt/zt_pool/ths_zt_pool_sync_api.py +1 -1
- mns_scheduler/zt/zt_pool/update_null_zt_reason_api.py +49 -31
- mns_scheduler/zz_task/compensation/compensate_task.py +1 -1
- mns_scheduler/zz_task/compensation/compensate_task_one_day.py +6 -6
- mns_scheduler/zz_task/data_sync_task.py +58 -37
- {mns_scheduler-1.4.3.5.dist-info → mns_scheduler-1.4.6.4.dist-info}/METADATA +1 -1
- {mns_scheduler-1.4.3.5.dist-info → mns_scheduler-1.4.6.4.dist-info}/RECORD +43 -33
- 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.5.dist-info → mns_scheduler-1.4.6.4.dist-info}/WHEEL +0 -0
- {mns_scheduler-1.4.3.5.dist-info → mns_scheduler-1.4.6.4.dist-info}/top_level.txt +0 -0
|
@@ -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
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
file_path = os.path.abspath(__file__)
|
|
5
|
+
end = file_path.index('mns') + 17
|
|
6
|
+
project_path = file_path[0:end]
|
|
7
|
+
sys.path.append(project_path)
|
|
8
|
+
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
import pandas as pd
|
|
11
|
+
from loguru import logger
|
|
12
|
+
|
|
13
|
+
import mns_common.component.common_service_fun_api as common_service_fun_api
|
|
14
|
+
import mns_common.component.concept.ths_concept_common_service_api as ths_concept_common_service_api
|
|
15
|
+
from mns_common.db.MongodbUtil import MongodbUtil
|
|
16
|
+
import mns_common.api.kpl.symbol.kpl_real_time_quotes_api as kpl_real_time_quotes_api
|
|
17
|
+
import mns_common.utils.data_frame_util as data_frame_util
|
|
18
|
+
import mns_common.component.k_line.common.k_line_common_service_api as k_line_common_service_api
|
|
19
|
+
import mns_common.constant.db_name_constant as db_name_constant
|
|
20
|
+
from mns_scheduler.company_info.common.company_common_query_service import get_company_info
|
|
21
|
+
import mns_scheduler.company_info.sync.company_info_set_service as company_info_set_service
|
|
22
|
+
import mns_scheduler.company_info.constant.company_constant_data as company_constant_data
|
|
23
|
+
|
|
24
|
+
mongodb_util = MongodbUtil('27017')
|
|
25
|
+
# 分页大小
|
|
26
|
+
MAX_PAGE_NUMBER = 500
|
|
27
|
+
import threading
|
|
28
|
+
|
|
29
|
+
# 定义一个全局锁,用于保护 result 变量的访问
|
|
30
|
+
result_lock = threading.Lock()
|
|
31
|
+
# 初始化 result 变量为一个空的 Pandas DataFrame
|
|
32
|
+
result = []
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# 同步公司基本信息
|
|
36
|
+
|
|
37
|
+
def sync_company_base_info(symbol_list):
|
|
38
|
+
global result
|
|
39
|
+
result = []
|
|
40
|
+
|
|
41
|
+
east_money_stock_info = get_company_info()
|
|
42
|
+
|
|
43
|
+
east_money_stock_info = common_service_fun_api.total_mv_classification(east_money_stock_info)
|
|
44
|
+
east_money_stock_info = common_service_fun_api.classify_symbol(east_money_stock_info)
|
|
45
|
+
# 将日期数值转换为日期时间格式
|
|
46
|
+
east_money_stock_info['list_date_01'] = pd.to_datetime(east_money_stock_info['list_date'], format='%Y%m%d')
|
|
47
|
+
# 开盘啦实时数据
|
|
48
|
+
kpl_real_time_quotes = kpl_real_time_quotes_api.get_kpl_real_time_quotes()
|
|
49
|
+
if len(symbol_list) > 0:
|
|
50
|
+
east_money_stock_info = east_money_stock_info.loc[east_money_stock_info['symbol'].isin(symbol_list)]
|
|
51
|
+
count = east_money_stock_info.shape[0]
|
|
52
|
+
page_number = round(count / MAX_PAGE_NUMBER, 0) + 1
|
|
53
|
+
page_number = int(page_number)
|
|
54
|
+
threads = []
|
|
55
|
+
# 创建多个线程来获取数据
|
|
56
|
+
for page in range(page_number): # 0到100页
|
|
57
|
+
end_count = (page + 1) * MAX_PAGE_NUMBER
|
|
58
|
+
begin_count = page * MAX_PAGE_NUMBER
|
|
59
|
+
page_df = east_money_stock_info.iloc[begin_count:end_count]
|
|
60
|
+
thread = threading.Thread(target=single_thread_sync_company_info,
|
|
61
|
+
args=(page_df, kpl_real_time_quotes))
|
|
62
|
+
threads.append(thread)
|
|
63
|
+
thread.start()
|
|
64
|
+
|
|
65
|
+
# 等待所有线程完成
|
|
66
|
+
for thread in threads:
|
|
67
|
+
thread.join()
|
|
68
|
+
|
|
69
|
+
fail_df = east_money_stock_info.loc[east_money_stock_info['symbol'].isin(result)]
|
|
70
|
+
single_thread_sync_company_info(fail_df, kpl_real_time_quotes)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def single_thread_sync_company_info(east_money_stock_info,
|
|
74
|
+
kpl_real_time_quotes):
|
|
75
|
+
global result
|
|
76
|
+
fail_list = []
|
|
77
|
+
for company_one in east_money_stock_info.itertuples():
|
|
78
|
+
try:
|
|
79
|
+
|
|
80
|
+
company_one_df = east_money_stock_info.loc[east_money_stock_info['symbol'] == company_one.symbol]
|
|
81
|
+
|
|
82
|
+
company_one_df = company_one_df.rename(columns={
|
|
83
|
+
"industry": "em_industry",
|
|
84
|
+
"concept": "em_concept"
|
|
85
|
+
})
|
|
86
|
+
now_date = datetime.now()
|
|
87
|
+
str_day = now_date.strftime('%Y-%m-%d')
|
|
88
|
+
str_now_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
|
|
89
|
+
|
|
90
|
+
# 计算日期差值 距离现在上市时间
|
|
91
|
+
company_one_df['diff_days'] = (now_date - company_one.list_date_01).days
|
|
92
|
+
company_one_df = company_one_df[[
|
|
93
|
+
'symbol',
|
|
94
|
+
'name',
|
|
95
|
+
'em_industry',
|
|
96
|
+
'em_concept',
|
|
97
|
+
'hk_stock_code',
|
|
98
|
+
'hk_stock_name',
|
|
99
|
+
'amount',
|
|
100
|
+
'now_price',
|
|
101
|
+
'total_share',
|
|
102
|
+
'flow_share',
|
|
103
|
+
'total_mv',
|
|
104
|
+
'flow_mv',
|
|
105
|
+
'area',
|
|
106
|
+
'list_date',
|
|
107
|
+
'diff_days',
|
|
108
|
+
'pe_ttm',
|
|
109
|
+
'pb',
|
|
110
|
+
'ROE',
|
|
111
|
+
'flow_mv_sp',
|
|
112
|
+
'total_mv_sp',
|
|
113
|
+
'flow_mv_level',
|
|
114
|
+
'classification',
|
|
115
|
+
]]
|
|
116
|
+
|
|
117
|
+
company_one_df['sync_date'] = str_now_date
|
|
118
|
+
|
|
119
|
+
# 行业信息
|
|
120
|
+
company_industry_info_df = mongodb_util.find_query_data(db_name_constant.COMPANY_INDUSTRY_INFO,
|
|
121
|
+
{"symbol": company_one.symbol})
|
|
122
|
+
|
|
123
|
+
if data_frame_util.is_empty(company_industry_info_df):
|
|
124
|
+
company_one_df['business_nature'] = '数据异常'
|
|
125
|
+
company_one_df['holder_controller_name'] = '数据异常'
|
|
126
|
+
company_one_df['holder_controller_rate'] = 0
|
|
127
|
+
company_one_df['final_controller_name'] = '数据异常'
|
|
128
|
+
company_one_df['final_controller_rate'] = 0
|
|
129
|
+
company_one_df['actual_controller_name'] = '数据异常'
|
|
130
|
+
company_one_df['actual_controller_rate'] = 0
|
|
131
|
+
company_one_df['base_business'] = ''
|
|
132
|
+
company_one_df['intro'] = ''
|
|
133
|
+
company_one_df['address'] = ''
|
|
134
|
+
company_one_df['market_id'] = ''
|
|
135
|
+
company_one_df['main_business_list'] = [[] for _ in range(len(company_one_df))]
|
|
136
|
+
company_one_df['most_profitable_business'] = ''
|
|
137
|
+
company_one_df['most_profitable_business_rate'] = '0'
|
|
138
|
+
company_one_df['most_profitable_business_profit'] = 0
|
|
139
|
+
company_one_df['first_industry_code'] = '0'
|
|
140
|
+
company_one_df['second_industry_code'] = '0'
|
|
141
|
+
company_one_df['third_industry_code'] = '0'
|
|
142
|
+
company_one_df['first_sw_industry'] = '数据异常'
|
|
143
|
+
company_one_df['second_sw_industry'] = '数据异常'
|
|
144
|
+
company_one_df['third_sw_industry'] = '数据异常'
|
|
145
|
+
company_one_df['industry'] = '数据异常'
|
|
146
|
+
else:
|
|
147
|
+
|
|
148
|
+
del company_industry_info_df['_id']
|
|
149
|
+
del company_industry_info_df['name']
|
|
150
|
+
# 申万二级行业 作业行业
|
|
151
|
+
company_industry_info_df['industry'] = company_industry_info_df['second_sw_industry']
|
|
152
|
+
|
|
153
|
+
company_industry_info_df = company_industry_info_df.set_index(['symbol'], drop=True)
|
|
154
|
+
company_one_df = company_one_df.set_index(['symbol'], drop=False)
|
|
155
|
+
company_one_df = pd.merge(company_one_df, company_industry_info_df, how='outer',
|
|
156
|
+
left_index=True, right_index=True)
|
|
157
|
+
|
|
158
|
+
# 设置流通比例和外资持股
|
|
159
|
+
company_one_df = company_info_set_service.set_calculate_circulation_ratio(company_one.symbol, str_day,
|
|
160
|
+
company_one_df)
|
|
161
|
+
|
|
162
|
+
# 获取同花顺最新概念
|
|
163
|
+
company_one_df = ths_concept_common_service_api.set_ths_concept(company_one.symbol, company_one_df)
|
|
164
|
+
# 修改行业
|
|
165
|
+
fix_symbol_industry_df = company_constant_data.get_fix_symbol_industry()
|
|
166
|
+
if company_one.symbol in list(fix_symbol_industry_df['symbol']):
|
|
167
|
+
# fix sw_industry
|
|
168
|
+
company_one_df = company_constant_data.fix_symbol_industry(company_one_df,
|
|
169
|
+
company_one.symbol)
|
|
170
|
+
|
|
171
|
+
# 交易天数
|
|
172
|
+
deal_days = k_line_common_service_api.get_deal_days(str_day, company_one.symbol)
|
|
173
|
+
company_one_df['deal_days'] = deal_days
|
|
174
|
+
|
|
175
|
+
# 设置财务年报信息
|
|
176
|
+
company_one_df = company_info_set_service.set_recent_year_income(company_one.symbol, company_one_df)
|
|
177
|
+
# 设置开盘信息
|
|
178
|
+
company_one_df['kpl_plate_list_info'] = '-'
|
|
179
|
+
company_one_df['kpl_plate_name'] = '-'
|
|
180
|
+
company_one_df['kpl_most_relative_name'] = '-'
|
|
181
|
+
company_one_df = company_info_set_service.set_kpl_plate_info(company_one_df, company_one,
|
|
182
|
+
kpl_real_time_quotes)
|
|
183
|
+
# 设置可转债 信息
|
|
184
|
+
company_one_df['kzz_debt_list'] = [[] for _ in range(len(company_one_df))]
|
|
185
|
+
company_one_df = company_info_set_service.set_kzz_debt(company_one_df, company_one.symbol)
|
|
186
|
+
|
|
187
|
+
company_one_df['_id'] = company_one_df['symbol']
|
|
188
|
+
|
|
189
|
+
company_one_df = company_constant_data.filed_sort(company_one_df)
|
|
190
|
+
mongodb_util.save_mongo(company_one_df.copy(), db_name_constant.COMPANY_INFO_TEMP)
|
|
191
|
+
logger.info("同步公司信息完成:{}", company_one.symbol + '-' + company_one.name)
|
|
192
|
+
except BaseException as e:
|
|
193
|
+
fail_list.append(company_one.symbol)
|
|
194
|
+
logger.error("同步公司信息发生异常:{},{}", company_one.symbol, e)
|
|
195
|
+
with result_lock:
|
|
196
|
+
# 使用锁来保护 result 变量的访问,将每页的数据添加到结果中
|
|
197
|
+
result = fail_list
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
if __name__ == '__main__':
|
|
201
|
+
|
|
202
|
+
sync_company_base_info(['688795'])
|
|
203
|
+
# sync_company_base_info([])
|
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import sys
|
|
2
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
|
+
import sys
|
|
10
|
+
import os
|
|
3
11
|
|
|
4
12
|
file_path = os.path.abspath(__file__)
|
|
5
13
|
end = file_path.index('mns') + 17
|
|
6
14
|
project_path = file_path[0:end]
|
|
7
15
|
sys.path.append(project_path)
|
|
8
|
-
import mns_common.component.company.company_common_service_new_api as company_common_service_new_api
|
|
9
16
|
import mns_common.api.ths.company.ths_company_announce_api as ths_company_announce_api
|
|
10
17
|
from loguru import logger
|
|
11
18
|
from mns_common.db.MongodbUtil import MongodbUtil
|
|
12
19
|
import mns_common.constant.db_name_constant as db_name_constant
|
|
20
|
+
from mns_scheduler.company_info.common.company_common_query_service import get_company_info
|
|
21
|
+
import mns_common.component.common_service_fun_api as common_service_fun_api
|
|
13
22
|
|
|
14
23
|
mongodb_util = MongodbUtil('27017')
|
|
15
24
|
|
|
@@ -17,7 +26,7 @@ mongodb_util = MongodbUtil('27017')
|
|
|
17
26
|
# 同步最新公告
|
|
18
27
|
# eq-f1001 业绩预告 eq-f1002 重大事项 eq-f1003 股份变动公告
|
|
19
28
|
|
|
20
|
-
def
|
|
29
|
+
def sync_company_announce_task(symbol_list):
|
|
21
30
|
page_size = 100
|
|
22
31
|
announce_type_list = ['all', 'eq-f1003', 'eq-f1001', 'eq-f1002']
|
|
23
32
|
for announce_type_one in announce_type_list:
|
|
@@ -25,21 +34,25 @@ def sync_company_announce(symbol_list):
|
|
|
25
34
|
get_company_announce(announce_type_one, page_size, symbol_list)
|
|
26
35
|
except BaseException as e:
|
|
27
36
|
logger.error("更新公告出现异常:{}", e)
|
|
28
|
-
logger.info("同步到公告信息完成")
|
|
29
37
|
|
|
30
38
|
|
|
31
39
|
def get_company_announce(announce_type, page_size, symbol_list):
|
|
32
|
-
|
|
33
|
-
de_list_company = company_common_service_new_api.get_de_list_company()
|
|
34
|
-
company_all_df = company_all_df.loc[~(company_all_df['symbol'].isin(de_list_company))]
|
|
40
|
+
all_company_info_df = get_company_info()
|
|
35
41
|
|
|
36
|
-
if symbol_list
|
|
37
|
-
|
|
42
|
+
if len(symbol_list) > 0:
|
|
43
|
+
all_company_info_df = all_company_info_df.loc[(all_company_info_df['symbol'].isin(symbol_list))]
|
|
44
|
+
all_company_info_df = common_service_fun_api.classify_symbol(all_company_info_df)
|
|
38
45
|
|
|
39
|
-
for stock_one in
|
|
46
|
+
for stock_one in all_company_info_df.itertuples():
|
|
40
47
|
try:
|
|
41
48
|
symbol = stock_one.symbol
|
|
42
|
-
|
|
49
|
+
classification = stock_one.classification
|
|
50
|
+
if classification in ['H', 'K']:
|
|
51
|
+
market_id = '17'
|
|
52
|
+
elif classification in ['S', 'C']:
|
|
53
|
+
market_id = '33'
|
|
54
|
+
elif classification in ['X']:
|
|
55
|
+
market_id = '151'
|
|
43
56
|
# 公告应该不多 只更新一页的数据 页码设置100已经是最大
|
|
44
57
|
page_number = 1
|
|
45
58
|
try:
|
|
@@ -55,11 +68,10 @@ def get_company_announce(announce_type, page_size, symbol_list):
|
|
|
55
68
|
ths_company_announce_result['_id'] = ths_company_announce_result['guid'] + '_' + \
|
|
56
69
|
ths_company_announce_result['seq'] + "_" + announce_type
|
|
57
70
|
mongodb_util.save_mongo(ths_company_announce_result, db_name_constant.COMPANY_ANNOUNCE_INFO)
|
|
58
|
-
|
|
59
|
-
|
|
71
|
+
time.sleep(1)
|
|
60
72
|
except BaseException as e:
|
|
61
73
|
logger.error("更新公告出现异常:{}", e)
|
|
62
74
|
|
|
63
75
|
|
|
64
76
|
if __name__ == '__main__':
|
|
65
|
-
|
|
77
|
+
sync_company_announce_task([])
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
file_path = os.path.abspath(__file__)
|
|
5
|
+
end = file_path.index('mns') + 17
|
|
6
|
+
project_path = file_path[0:end]
|
|
7
|
+
sys.path.append(project_path)
|
|
8
|
+
import mns_common.api.ths.company.ths_company_info_web as ths_company_info_web
|
|
9
|
+
from mns_common.db.MongodbUtil import MongodbUtil
|
|
10
|
+
import mns_common.utils.data_frame_util as data_frame_util
|
|
11
|
+
import mns_common.constant.db_name_constant as db_name_constant
|
|
12
|
+
from loguru import logger
|
|
13
|
+
from mns_scheduler.company_info.common.company_common_query_service import get_company_info
|
|
14
|
+
import time
|
|
15
|
+
from datetime import datetime
|
|
16
|
+
|
|
17
|
+
mongodb_util = MongodbUtil('27017')
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def sync_company_base_info_task(symbol_list):
|
|
21
|
+
all_company_info_df = get_company_info()
|
|
22
|
+
if len(symbol_list) > 0:
|
|
23
|
+
all_company_info_df = all_company_info_df.loc[all_company_info_df['symbol'].isin(symbol_list)]
|
|
24
|
+
fail_list = []
|
|
25
|
+
for stock_one in all_company_info_df.itertuples():
|
|
26
|
+
try:
|
|
27
|
+
sync_one_symbol_base_info(stock_one.symbol)
|
|
28
|
+
time.sleep(0.5)
|
|
29
|
+
except BaseException as e:
|
|
30
|
+
time.sleep(3)
|
|
31
|
+
logger.error("同步公司基础信息发生异常:{},{}", stock_one.symbol, e)
|
|
32
|
+
fail_list.append(stock_one.symbol)
|
|
33
|
+
sync_number = 1
|
|
34
|
+
while len(fail_list) > 0 and sync_number < 10:
|
|
35
|
+
for symbol in fail_list:
|
|
36
|
+
try:
|
|
37
|
+
sync_one_symbol_base_info(symbol)
|
|
38
|
+
time.sleep(5)
|
|
39
|
+
except BaseException as e:
|
|
40
|
+
time.sleep(10)
|
|
41
|
+
logger.error("同步公司基础信息发生异常:{},{}", symbol, e)
|
|
42
|
+
sync_number = sync_number + 1
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def sync_one_symbol_base_info(symbol):
|
|
46
|
+
company_remark_info = ths_company_info_web.get_company_info(symbol)
|
|
47
|
+
company_remark_info['_id'] = symbol
|
|
48
|
+
company_remark_info['symbol'] = symbol
|
|
49
|
+
company_remark_info['remark'] = ''
|
|
50
|
+
|
|
51
|
+
now_date = datetime.now()
|
|
52
|
+
sync_str_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
|
|
53
|
+
|
|
54
|
+
company_remark_info['sync_str_date'] = sync_str_date
|
|
55
|
+
|
|
56
|
+
exist_company_remark_df = mongodb_util.find_query_data(db_name_constant.COMPANY_BASE_INFO,
|
|
57
|
+
query={"symbol": symbol})
|
|
58
|
+
if data_frame_util.is_not_empty(exist_company_remark_df):
|
|
59
|
+
company_remark_info['remark'] = list(exist_company_remark_df['remark'])[0]
|
|
60
|
+
mongodb_util.save_mongo(company_remark_info, db_name_constant.COMPANY_BASE_INFO)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
if __name__ == '__main__':
|
|
64
|
+
sync_company_base_info_task([])
|
|
@@ -5,7 +5,7 @@ file_path = os.path.abspath(__file__)
|
|
|
5
5
|
end = file_path.index('mns') + 17
|
|
6
6
|
project_path = file_path[0:end]
|
|
7
7
|
sys.path.append(project_path)
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
import mns_common.component.common_service_fun_api as common_service_fun_api
|
|
10
10
|
import mns_common.api.ths.company.company_product_area_industry_index_query as company_product_area_industry_index_query
|
|
11
11
|
from loguru import logger
|
|
@@ -14,38 +14,40 @@ import mns_common.constant.db_name_constant as db_name_constant
|
|
|
14
14
|
import mns_common.utils.data_frame_util as data_frame_util
|
|
15
15
|
import pandas as pd
|
|
16
16
|
from datetime import datetime
|
|
17
|
+
from mns_scheduler.company_info.common.company_common_query_service import get_company_info
|
|
17
18
|
|
|
18
19
|
mongodb_util = MongodbUtil('27017')
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
def
|
|
22
|
+
def sync_company_business_task(symbol_list):
|
|
22
23
|
now_date = datetime.now()
|
|
23
24
|
now_year = now_date.year
|
|
24
25
|
now_month = now_date.month
|
|
25
26
|
|
|
26
27
|
if now_month in [1, 2, 3, 4]:
|
|
27
28
|
period_time_year = str(now_year - 1) + "-12-31"
|
|
28
|
-
sync_company_product_area_industry(
|
|
29
|
+
sync_company_product_area_industry(symbol_list, period_time_year)
|
|
29
30
|
|
|
30
31
|
if now_month in [4, 5, 6]:
|
|
31
32
|
period_time_one = str(now_year) + "-03-31"
|
|
32
|
-
sync_company_product_area_industry(
|
|
33
|
+
sync_company_product_area_industry(symbol_list, period_time_one)
|
|
33
34
|
|
|
34
35
|
elif now_month in [7, 8, 9]:
|
|
35
36
|
period_time_two = str(now_year) + "-06-30"
|
|
36
|
-
sync_company_product_area_industry(
|
|
37
|
+
sync_company_product_area_industry(symbol_list, period_time_two)
|
|
37
38
|
|
|
38
39
|
elif now_month in [10, 11, 12]:
|
|
39
40
|
period_time_three = str(now_year) + "-09-30"
|
|
40
|
-
sync_company_product_area_industry(
|
|
41
|
+
sync_company_product_area_industry(symbol_list, period_time_three)
|
|
42
|
+
|
|
41
43
|
|
|
44
|
+
def sync_company_product_area_industry(symbol_list, date):
|
|
45
|
+
all_company_info_df = get_company_info()
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
real_time_quotes_all_stocks = real_time_quotes_all_stocks.loc[real_time_quotes_all_stocks['symbol'] == symbol]
|
|
48
|
-
for stock_one in real_time_quotes_all_stocks.itertuples():
|
|
47
|
+
all_company_info_df = common_service_fun_api.classify_symbol(all_company_info_df)
|
|
48
|
+
if len(symbol_list) > 0:
|
|
49
|
+
all_company_info_df = all_company_info_df.loc[all_company_info_df['symbol'].isin(symbol_list)]
|
|
50
|
+
for stock_one in all_company_info_df.itertuples():
|
|
49
51
|
try:
|
|
50
52
|
symbol = stock_one.symbol
|
|
51
53
|
|
|
@@ -57,6 +59,22 @@ def sync_company_product_area_industry(symbol, date):
|
|
|
57
59
|
elif classification in ['X']:
|
|
58
60
|
market = '151'
|
|
59
61
|
|
|
62
|
+
query_exist = {'symbol': symbol, 'time': date}
|
|
63
|
+
exist_company_business_info_df = mongodb_util.find_query_data(db_name_constant.COMPANY_BUSINESS_INFO,
|
|
64
|
+
query_exist)
|
|
65
|
+
if data_frame_util.is_empty(exist_company_business_info_df):
|
|
66
|
+
exist_all = False
|
|
67
|
+
else:
|
|
68
|
+
exist_all = (
|
|
69
|
+
(exist_company_business_info_df.loc[
|
|
70
|
+
exist_company_business_info_df['analysis_type'] == 'area'].shape[0] > 0)
|
|
71
|
+
and (exist_company_business_info_df.loc[
|
|
72
|
+
exist_company_business_info_df['analysis_type'] == 'industry'].shape[0] > 0)
|
|
73
|
+
and (exist_company_business_info_df.loc[
|
|
74
|
+
exist_company_business_info_df['analysis_type'] == 'product'].shape[
|
|
75
|
+
0] > 0))
|
|
76
|
+
if exist_all:
|
|
77
|
+
continue
|
|
60
78
|
company_product_area_industry_list = company_product_area_industry_index_query.company_product_area_industry(
|
|
61
79
|
symbol, market, date)
|
|
62
80
|
for company_one in company_product_area_industry_list:
|
|
@@ -74,10 +92,8 @@ def sync_company_product_area_industry(symbol, date):
|
|
|
74
92
|
handle_industry_area_product(time_operate_index_item_df, symbol)
|
|
75
93
|
except BaseException as e:
|
|
76
94
|
logger.error("同步经营数据异常:{},{}", symbol, e)
|
|
77
|
-
|
|
78
|
-
logger.info("同步经营数据完成:{}", stock_one.symbol)
|
|
79
95
|
except BaseException as e:
|
|
80
|
-
logger.error("
|
|
96
|
+
logger.error("同步经营数据异常:{},{}", stock_one.symbol, e)
|
|
81
97
|
|
|
82
98
|
|
|
83
99
|
def handle_industry_area_product(time_operate_index_item_df, symbol):
|
|
@@ -149,7 +165,7 @@ def handle_industry_area_product(time_operate_index_item_df, symbol):
|
|
|
149
165
|
|
|
150
166
|
|
|
151
167
|
if __name__ == '__main__':
|
|
152
|
-
sync_company_product_area_industry('300211', '
|
|
168
|
+
sync_company_product_area_industry('300211', '2024-12-31')
|
|
153
169
|
# sync_company_product_area_industry('002323')
|
|
154
170
|
# sync_company_product_area_industry('300901')
|
|
155
171
|
# sync_company_product_area_industry('603225')
|
|
@@ -158,4 +174,4 @@ if __name__ == '__main__':
|
|
|
158
174
|
# sync_company_product_area_industry('000508')
|
|
159
175
|
# sync_company_product_area_industry('810011')
|
|
160
176
|
|
|
161
|
-
sync_company_product_area_industry(
|
|
177
|
+
sync_company_product_area_industry([], None)
|