mns-scheduler 1.1.8.4__py3-none-any.whl → 1.4.3.2__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/__init__.py +1 -3
- mns_scheduler/company_info/announce/company_announce_sync_service.py +65 -0
- mns_scheduler/company_info/base/__init__.py +1 -1
- mns_scheduler/company_info/base/sync_company_base_info_api.py +171 -79
- mns_scheduler/company_info/base/sync_company_hold_info_api.py +3 -6
- mns_scheduler/company_info/base/sync_company_product_area_industry.py +161 -0
- mns_scheduler/company_info/clean/__init__.py +1 -1
- mns_scheduler/company_info/clean/company_info_clean_api.py +29 -9
- mns_scheduler/company_info/constant/__init__.py +1 -1
- mns_scheduler/company_info/constant/company_constant_data.py +285 -184
- mns_scheduler/company_info/de_list_stock/__init__.py +1 -1
- mns_scheduler/company_info/de_list_stock/de_list_stock_service.py +1 -1
- mns_scheduler/company_info/em_stock_info/__init__.py +7 -0
- mns_scheduler/company_info/em_stock_info/sync_em_stock_info_sync.py +80 -0
- mns_scheduler/company_info/remark/__init__.py +1 -1
- mns_scheduler/company_info/remark/company_remark_info_sync.py +3 -3
- mns_scheduler/concept/clean/kpl_concept_clean_api.py +1 -1
- mns_scheduler/concept/clean/ths_concept_clean_api.py +20 -4
- mns_scheduler/concept/ths/common/ths_concept_sync_common_api.py +21 -16
- mns_scheduler/concept/ths/common/ths_concept_update_common_api.py +4 -1
- mns_scheduler/concept/ths/detaill/ths_concept_detail_api.py +7 -7
- mns_scheduler/concept/ths/sync_new_index/sync_ths_concept_new_index_api.py +9 -4
- mns_scheduler/concept/ths/update_concept_info/sync_one_symbol_all_concepts_api.py +3 -3
- mns_scheduler/db/col_move_service.py +3 -3
- mns_scheduler/db/script/__init__.py +1 -1
- mns_scheduler/db/script/col_move_script.py +1 -1
- mns_scheduler/db/script/db_move/__init__.py +7 -0
- mns_scheduler/db/script/db_move/col_move_one_service.py +34 -0
- mns_scheduler/db/script/sync/__init__.py +1 -1
- mns_scheduler/db/script/sync/remote_data_sync_to_local.py +57 -4
- mns_scheduler/db/script/sync/sync_hui_ce_test_data.py +80 -0
- mns_scheduler/db/script/sync/sync_hui_ce_test_data_01.py +69 -0
- mns_scheduler/db/script/update/__init__.py +7 -0
- mns_scheduler/db/script/update/update_col_field.py +36 -0
- mns_scheduler/finance/__init__.py +1 -1
- mns_scheduler/finance/{em_financial_asset_liability_sync_service_api.py → em/em_financial_asset_liability_sync_service_api.py} +2 -2
- mns_scheduler/finance/{em_financial_profit_sync_service_api.py → em/em_financial_profit_sync_service_api.py} +27 -26
- mns_scheduler/finance/{finance_common_api.py → em/finance_common_api.py} +3 -3
- mns_scheduler/finance/{sync_financial_report_service_api.py → sync_financial_report_service_task.py} +80 -27
- mns_scheduler/finance/xue_qiu/down_load_xueqiu_report_api.py +77 -0
- mns_scheduler/finance/xue_qiu/sync_xue_qiu_fiance_data.py +161 -0
- mns_scheduler/hk/__init__.py +1 -1
- mns_scheduler/hk/hk_company_info_sync_service_api.py +4 -4
- mns_scheduler/hk/hk_industry_info_sync_service_api.py +3 -5
- mns_scheduler/industry/__init__.py +7 -0
- mns_scheduler/industry/ths/__init__.py +7 -0
- mns_scheduler/industry/ths/ths_industry_index_service.py +58 -0
- mns_scheduler/industry/ths/ths_industry_sync_service.py +68 -0
- mns_scheduler/irm/__init__.py +1 -1
- mns_scheduler/irm/api/__init__.py +1 -1
- mns_scheduler/irm/api/sh_stock_sns_sse_info_api.py +1 -1
- mns_scheduler/irm/api/sz_stock_sns_sse_info_api.py +1 -1
- mns_scheduler/irm/stock_irm_cninfo_service.py +12 -8
- mns_scheduler/k_line/clean/daily/__init__.py +1 -1
- mns_scheduler/k_line/clean/daily/daily_k_line_clean_common_service.py +52 -6
- mns_scheduler/k_line/clean/daily/daily_k_line_service.py +7 -2
- mns_scheduler/k_line/clean/k_line_info_clean_impl.py +3 -2
- mns_scheduler/k_line/clean/k_line_info_clean_task.py +42 -15
- mns_scheduler/k_line/clean/week_month/__init__.py +1 -1
- mns_scheduler/k_line/clean/week_month/normal_week_month_k_line_service.py +124 -26
- mns_scheduler/k_line/clean/week_month/sub_new_week_month_k_line_service.py +2 -2
- mns_scheduler/k_line/common/__init__.py +7 -0
- mns_scheduler/k_line/common/k_line_common_api.py +188 -0
- mns_scheduler/k_line/hot_stocks/__init__.py +1 -1
- mns_scheduler/k_line/hot_stocks/recent_hot_stocks_clean_service.py +1 -1
- mns_scheduler/k_line/{sync → month_week_daily}/bfq_k_line_sync.py +14 -29
- mns_scheduler/k_line/{sync → month_week_daily}/daily_week_month_line_sync.py +11 -12
- mns_scheduler/k_line/sync_status/__init__.py +7 -0
- mns_scheduler/k_line/sync_status/k_line_sync_status_check.py +54 -0
- mns_scheduler/k_line/test/__init__.py +1 -1
- mns_scheduler/k_line/test/k_line_info_clean_his_data.py +14 -3
- mns_scheduler/k_line/year_quarter/__init__.py +7 -0
- mns_scheduler/k_line/year_quarter/year_quarter_line_sync.py +76 -0
- mns_scheduler/kpl/selection/symbol/sync_best_choose_symbol.py +1 -2
- mns_scheduler/kpl/selection/symbol/sync_kpl_concept_symbol_choose_reason_api.py +108 -0
- mns_scheduler/kpl/selection/total/sync_kpl_best_total_sync_api.py +5 -0
- mns_scheduler/lhb/__init__.py +1 -1
- mns_scheduler/lhb/stock_lhb_sync_service.py +1 -1
- mns_scheduler/open/__init__.py +1 -1
- mns_scheduler/open/sync_one_day_open_data_to_db_service.py +2 -3
- mns_scheduler/risk/__init__.py +1 -1
- mns_scheduler/risk/compliance/undisclosed_annual_report_api.py +8 -2
- mns_scheduler/risk/financial/annual_report_audit_check_api.py +13 -3
- mns_scheduler/risk/financial/net_assets_check_api.py +21 -18
- mns_scheduler/risk/financial/profit_income_check_api.py +7 -2
- mns_scheduler/risk/financial_report_risk_check_api.py +1 -1
- mns_scheduler/risk/major_violations/register_and_investigate_stock_sync_api.py +1 -1
- mns_scheduler/risk/self/wei_pan_stock_api.py +1 -1
- mns_scheduler/risk/test/__init__.py +1 -1
- mns_scheduler/risk/test/fix_blask_list.py +4 -6
- mns_scheduler/risk/transactions/transactions_check_api.py +22 -4
- mns_scheduler/self_choose/__init__.py +1 -1
- mns_scheduler/self_choose/ths_self_choose_service.py +60 -32
- mns_scheduler/trade/auto_login/trader_auto_service.py +6 -4
- mns_scheduler/trade/auto_sell_service_api.py +4 -4
- mns_scheduler/trade/balance/__init__.py +7 -0
- mns_scheduler/trade/balance/ths_account_balance_service.py +7 -0
- mns_scheduler/trade/sync_position_api.py +39 -6
- mns_scheduler/trade/task/trader_task_service.py +26 -9
- mns_scheduler/trade/tfp/__init__.py +7 -0
- mns_scheduler/trade/tfp/stock_tfp_info_sync.py +56 -0
- mns_scheduler/zb/stock_zb_pool_sync.py +1 -16
- mns_scheduler/zt/high_chg/sync_high_chg_pool_service.py +2 -2
- mns_scheduler/zt/high_chg/sync_high_chg_real_time_quotes_service.py +1 -1
- mns_scheduler/zt/script/__init__.py +1 -1
- mns_scheduler/zt/script/fix_error_deal_day.py +41 -0
- mns_scheduler/zt/script/kcx_high_chg_open_his_data_handle.py +2 -2
- mns_scheduler/zt/script/sync_high_chg_pool_his_data.py +2 -2
- mns_scheduler/zt/script/sync_now_higt_chg_zt.py +8 -7
- mns_scheduler/zt/zt_pool/em_zt_pool_sync_api.py +256 -55
- mns_scheduler/zt/zt_pool/ths_zt_pool_sync_api.py +33 -90
- mns_scheduler/zt/zt_pool/update_null_zt_reason_api.py +24 -13
- mns_scheduler/zz_task/compensation/__init__.py +0 -0
- mns_scheduler/zz_task/compensation/compensate_task.py +161 -0
- mns_scheduler/zz_task/compensation/compensate_task_one_day.py +142 -0
- mns_scheduler/zz_task/data_sync_task.py +177 -91
- {mns_scheduler-1.1.8.4.dist-info → mns_scheduler-1.4.3.2.dist-info}/METADATA +1 -1
- mns_scheduler-1.4.3.2.dist-info/RECORD +169 -0
- {mns_scheduler-1.1.8.4.dist-info → mns_scheduler-1.4.3.2.dist-info}/WHEEL +1 -1
- mns_scheduler/2014-2015-test/2014_2015_chg_statistics.py +0 -87
- mns_scheduler/big_deal/ths_big_deal_sync.py +0 -98
- mns_scheduler/db/real_time_task_check.py +0 -84
- mns_scheduler/debt/kzz_bond_info_sync.py +0 -33
- mns_scheduler-1.1.8.4.dist-info/RECORD +0 -142
- /mns_scheduler/{big_deal → company_info/announce}/__init__.py +0 -0
- /mns_scheduler/{2014-2015-test → finance/em}/__init__.py +0 -0
- /mns_scheduler/{debt → finance/xue_qiu}/__init__.py +0 -0
- /mns_scheduler/k_line/{sync → month_week_daily}/__init__.py +0 -0
- {mns_scheduler-1.1.8.4.dist-info → mns_scheduler-1.4.3.2.dist-info}/top_level.txt +0 -0
mns_scheduler/__init__.py
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
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.component.company.company_common_service_new_api as company_common_service_new_api
|
|
9
|
+
import mns_common.api.ths.company.ths_company_announce_api as ths_company_announce_api
|
|
10
|
+
from loguru import logger
|
|
11
|
+
from mns_common.db.MongodbUtil import MongodbUtil
|
|
12
|
+
import mns_common.constant.db_name_constant as db_name_constant
|
|
13
|
+
|
|
14
|
+
mongodb_util = MongodbUtil('27017')
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# 同步最新公告
|
|
18
|
+
# eq-f1001 业绩预告 eq-f1002 重大事项 eq-f1003 股份变动公告
|
|
19
|
+
|
|
20
|
+
def sync_company_announce(symbol_list):
|
|
21
|
+
page_size = 100
|
|
22
|
+
announce_type_list = ['all', 'eq-f1003', 'eq-f1001', 'eq-f1002']
|
|
23
|
+
for announce_type_one in announce_type_list:
|
|
24
|
+
try:
|
|
25
|
+
get_company_announce(announce_type_one, page_size, symbol_list)
|
|
26
|
+
except BaseException as e:
|
|
27
|
+
logger.error("更新公告出现异常:{}", e)
|
|
28
|
+
logger.info("同步到公告信息完成")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_company_announce(announce_type, page_size, symbol_list):
|
|
32
|
+
company_all_df = company_common_service_new_api.get_company_all_info_info()
|
|
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))]
|
|
35
|
+
|
|
36
|
+
if symbol_list is not None:
|
|
37
|
+
company_all_df = company_all_df.loc[(company_all_df['symbol'].isin(symbol_list))]
|
|
38
|
+
|
|
39
|
+
for stock_one in company_all_df.itertuples():
|
|
40
|
+
try:
|
|
41
|
+
symbol = stock_one.symbol
|
|
42
|
+
market_id = stock_one.market_id
|
|
43
|
+
# 公告应该不多 只更新一页的数据 页码设置100已经是最大
|
|
44
|
+
page_number = 1
|
|
45
|
+
try:
|
|
46
|
+
ths_company_announce_result = ths_company_announce_api.get_company_announce_info(symbol, market_id,
|
|
47
|
+
announce_type,
|
|
48
|
+
page_size,
|
|
49
|
+
page_number)
|
|
50
|
+
except BaseException as e:
|
|
51
|
+
logger.error("更新公告出现异常:{}.{}", e, symbol)
|
|
52
|
+
continue
|
|
53
|
+
ths_company_announce_result['type'] = announce_type
|
|
54
|
+
ths_company_announce_result['symbol'] = symbol
|
|
55
|
+
ths_company_announce_result['_id'] = ths_company_announce_result['guid'] + '_' + \
|
|
56
|
+
ths_company_announce_result['seq'] + "_" + announce_type
|
|
57
|
+
mongodb_util.save_mongo(ths_company_announce_result, db_name_constant.COMPANY_ANNOUNCE_INFO)
|
|
58
|
+
logger.info("更新公告完成:{},{}", symbol, stock_one.name)
|
|
59
|
+
|
|
60
|
+
except BaseException as e:
|
|
61
|
+
logger.error("更新公告出现异常:{}", e)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == '__main__':
|
|
65
|
+
sync_company_announce(None)
|
|
@@ -10,8 +10,7 @@ from datetime import datetime
|
|
|
10
10
|
import pandas as pd
|
|
11
11
|
from loguru import logger
|
|
12
12
|
import mns_common.api.ths.concept.web.ths_company_info_web as ths_company_info_web
|
|
13
|
-
import mns_common.
|
|
14
|
-
import mns_scheduler.company_info.constant.company_constant_data as company_constant_data
|
|
13
|
+
import mns_common.component.em.em_stock_info_api as em_stock_info_api
|
|
15
14
|
import mns_common.component.common_service_fun_api as common_service_fun_api
|
|
16
15
|
import mns_common.component.concept.ths_concept_common_service_api as ths_concept_common_service_api
|
|
17
16
|
from mns_common.db.MongodbUtil import MongodbUtil
|
|
@@ -35,67 +34,6 @@ result_lock = threading.Lock()
|
|
|
35
34
|
result = []
|
|
36
35
|
|
|
37
36
|
|
|
38
|
-
# 计算实际流通比例
|
|
39
|
-
def calculate_circulation_ratio(symbol):
|
|
40
|
-
query = {"symbol": symbol}
|
|
41
|
-
stock_gdfx_free_top_10 = mongodb_util.descend_query(query, 'stock_gdfx_free_top_10', "period", 10)
|
|
42
|
-
if stock_gdfx_free_top_10.shape[0] == 0:
|
|
43
|
-
mv_circulation_ratio = 1
|
|
44
|
-
else:
|
|
45
|
-
# 排除香港结算公司 大于5%减持不用发公告 香港中央结算 HKSCC
|
|
46
|
-
stock_gdfx_free_top_10['is_hk'] = stock_gdfx_free_top_10['shareholder_name'].apply(
|
|
47
|
-
lambda shareholder_name: "HK" if shareholder_name.startswith('香港中央结算') or shareholder_name.startswith(
|
|
48
|
-
'HKSCC') else "A")
|
|
49
|
-
|
|
50
|
-
# 持股大于5% # 排除香港结算公司 大于5%减持不用发公告 香港中央结算 HKSCC
|
|
51
|
-
stock_gdfx_free_top_10 = stock_gdfx_free_top_10.loc[
|
|
52
|
-
(stock_gdfx_free_top_10['circulation_ratio'] >= 5) & (stock_gdfx_free_top_10['is_hk'] == 'A')]
|
|
53
|
-
|
|
54
|
-
circulation_ratio = sum(stock_gdfx_free_top_10['circulation_ratio'])
|
|
55
|
-
mv_circulation_ratio = round((100 - circulation_ratio) / 100, 2)
|
|
56
|
-
# 防止错误数据
|
|
57
|
-
if mv_circulation_ratio < 0:
|
|
58
|
-
mv_circulation_ratio = 1
|
|
59
|
-
return mv_circulation_ratio
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def get_east_money_stock_info():
|
|
63
|
-
all_real_time_quotes = east_money_stock_v2_api.get_all_real_time_quotes()
|
|
64
|
-
all_real_time_quotes = all_real_time_quotes[['symbol',
|
|
65
|
-
'name',
|
|
66
|
-
"now_price",
|
|
67
|
-
'total_mv',
|
|
68
|
-
'flow_mv',
|
|
69
|
-
'pe_ttm',
|
|
70
|
-
'sz_sh',
|
|
71
|
-
'area',
|
|
72
|
-
'pb',
|
|
73
|
-
'list_date',
|
|
74
|
-
'ROE',
|
|
75
|
-
'total_share',
|
|
76
|
-
'flow_share',
|
|
77
|
-
'industry',
|
|
78
|
-
'amount',
|
|
79
|
-
"hk_stock_code",
|
|
80
|
-
"hk_stock_name",
|
|
81
|
-
'concept']]
|
|
82
|
-
|
|
83
|
-
return all_real_time_quotes
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def create_index():
|
|
87
|
-
mongodb_util.create_index('company_info',
|
|
88
|
-
[("classification", 1)])
|
|
89
|
-
mongodb_util.create_index('company_info',
|
|
90
|
-
[("industry", 1)])
|
|
91
|
-
mongodb_util.create_index('company_info',
|
|
92
|
-
[("flow_mv", 1)])
|
|
93
|
-
mongodb_util.create_index('company_info',
|
|
94
|
-
[("list_date", 1)])
|
|
95
|
-
mongodb_util.create_index('company_info',
|
|
96
|
-
[("symbol", 1)])
|
|
97
|
-
|
|
98
|
-
|
|
99
37
|
# 同步公司基本信息
|
|
100
38
|
|
|
101
39
|
def sync_company_base_info(symbol_list):
|
|
@@ -103,6 +41,8 @@ def sync_company_base_info(symbol_list):
|
|
|
103
41
|
result = []
|
|
104
42
|
create_index()
|
|
105
43
|
east_money_stock_info = get_east_money_stock_info()
|
|
44
|
+
east_money_stock_info = east_money_stock_info.sort_values(by=['list_date'], ascending=False)
|
|
45
|
+
|
|
106
46
|
de_listed_stock_list = company_common_service_api.get_de_list_company()
|
|
107
47
|
east_money_stock_info = east_money_stock_info.loc[~(
|
|
108
48
|
east_money_stock_info['symbol'].isin(de_listed_stock_list))]
|
|
@@ -146,6 +86,30 @@ def sync_company_base_info(symbol_list):
|
|
|
146
86
|
single_thread_sync_company_info(fail_df, kpl_real_time_quotes, exist_company_df)
|
|
147
87
|
|
|
148
88
|
|
|
89
|
+
def get_east_money_stock_info():
|
|
90
|
+
all_real_time_quotes = em_stock_info_api.get_a_stock_info()
|
|
91
|
+
all_real_time_quotes = all_real_time_quotes[['symbol',
|
|
92
|
+
'name',
|
|
93
|
+
"now_price",
|
|
94
|
+
'total_mv',
|
|
95
|
+
'flow_mv',
|
|
96
|
+
'pe_ttm',
|
|
97
|
+
'sz_sh',
|
|
98
|
+
'area',
|
|
99
|
+
'pb',
|
|
100
|
+
'list_date',
|
|
101
|
+
'ROE',
|
|
102
|
+
'total_share',
|
|
103
|
+
'flow_share',
|
|
104
|
+
'industry',
|
|
105
|
+
'amount',
|
|
106
|
+
"hk_stock_code",
|
|
107
|
+
"hk_stock_name",
|
|
108
|
+
'concept']]
|
|
109
|
+
|
|
110
|
+
return all_real_time_quotes
|
|
111
|
+
|
|
112
|
+
|
|
149
113
|
def single_thread_sync_company_info(east_money_stock_info,
|
|
150
114
|
kpl_real_time_quotes, exist_company_df):
|
|
151
115
|
global result
|
|
@@ -163,7 +127,11 @@ def single_thread_sync_company_info(east_money_stock_info,
|
|
|
163
127
|
lambda x: x[1:5] + '00')
|
|
164
128
|
company_info_type['third_industry_code'] = company_info_type['hy3code'].apply(
|
|
165
129
|
lambda x: x[1:7])
|
|
166
|
-
|
|
130
|
+
# company_info_type['main_business_list'] = company_info_type['main_business_list']
|
|
131
|
+
# company_info_type['most_profitable_business'] = company_info_type['most_profitable_business']
|
|
132
|
+
# company_info_type['most_profitable_business_rate'] = company_info_type['most_profitable_business_rate']
|
|
133
|
+
# company_info_type['most_profitable_business_profit'] = company_info_type['most_profitable_business_profit']
|
|
134
|
+
#
|
|
167
135
|
company_info_type['first_sw_industry'] = company_info_type['hy']
|
|
168
136
|
company_info_type['second_sw_industry'] = company_info_type['hy2']
|
|
169
137
|
company_info_type['third_sw_industry'] = company_info_type['hy3']
|
|
@@ -198,12 +166,23 @@ def single_thread_sync_company_info(east_money_stock_info,
|
|
|
198
166
|
company_info_type['total_mv_sp'] = company_one.total_mv_sp
|
|
199
167
|
company_info_type['flow_mv_level'] = company_one.flow_mv_level
|
|
200
168
|
company_info_type['classification'] = company_one.classification
|
|
201
|
-
|
|
202
|
-
# 获取同花顺最新概念
|
|
203
|
-
company_info_type = ths_concept_common_service_api.set_ths_concept(company_one.symbol, company_info_type)
|
|
169
|
+
|
|
204
170
|
now_date = datetime.now()
|
|
205
171
|
str_now_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
|
|
172
|
+
|
|
173
|
+
now_str_day = now_date.strftime('%Y-%m-%d')
|
|
206
174
|
company_info_type['sync_date'] = str_now_date
|
|
175
|
+
|
|
176
|
+
result_dict = calculate_circulation_ratio(company_one.symbol, now_str_day)
|
|
177
|
+
|
|
178
|
+
company_info_type['mv_circulation_ratio'] = result_dict['mv_circulation_ratio']
|
|
179
|
+
company_info_type['qfii_type'] = result_dict['qfii_type']
|
|
180
|
+
company_info_type['qfii_number'] = result_dict['qfii_number']
|
|
181
|
+
company_info_type['share_holder_sync_day'] = result_dict['share_holder_sync_day']
|
|
182
|
+
|
|
183
|
+
# 获取同花顺最新概念
|
|
184
|
+
company_info_type = ths_concept_common_service_api.set_ths_concept(company_one.symbol, company_info_type)
|
|
185
|
+
|
|
207
186
|
fix_symbol_industry_df = company_constant_data.get_fix_symbol_industry()
|
|
208
187
|
if company_one.symbol in list(fix_symbol_industry_df['symbol']):
|
|
209
188
|
# fix sw_industry
|
|
@@ -254,6 +233,113 @@ def single_thread_sync_company_info(east_money_stock_info,
|
|
|
254
233
|
result = fail_list
|
|
255
234
|
|
|
256
235
|
|
|
236
|
+
# 计算实际流通比例
|
|
237
|
+
def calculate_circulation_ratio(symbol, now_str_day):
|
|
238
|
+
query = {"symbol": symbol}
|
|
239
|
+
stock_gdfx_free_top_1 = mongodb_util.descend_query(query, 'stock_gdfx_free_top_10', "period", 1)
|
|
240
|
+
if stock_gdfx_free_top_1.shape[0] == 0:
|
|
241
|
+
mv_circulation_ratio = 1
|
|
242
|
+
qfii_number = 0
|
|
243
|
+
qfii_type = 'A股'
|
|
244
|
+
share_holder_sync_day = now_str_day
|
|
245
|
+
else:
|
|
246
|
+
period_time = list(stock_gdfx_free_top_1['period'])[0]
|
|
247
|
+
|
|
248
|
+
query_free = {'symbol': symbol, 'period': period_time}
|
|
249
|
+
stock_gdfx_free_top_10 = mongodb_util.find_query_data('stock_gdfx_free_top_10', query_free)
|
|
250
|
+
|
|
251
|
+
stock_gdfx_free_top_10['shares_number_str'] = stock_gdfx_free_top_10['shares_number'].astype(str)
|
|
252
|
+
|
|
253
|
+
stock_gdfx_free_top_10['id_key'] = stock_gdfx_free_top_10['symbol'] + '_' + stock_gdfx_free_top_10[
|
|
254
|
+
'period'] + '_' + stock_gdfx_free_top_10.shares_number_str
|
|
255
|
+
|
|
256
|
+
stock_gdfx_free_top_10.drop_duplicates('id_key', keep='last', inplace=True)
|
|
257
|
+
|
|
258
|
+
# 排除香港结算公司 大于5%减持不用发公告 香港中央结算 HKSCC
|
|
259
|
+
stock_gdfx_free_top_10['is_hk'] = stock_gdfx_free_top_10['shareholder_name'].apply(
|
|
260
|
+
lambda shareholder_name: "HK" if shareholder_name.startswith('香港中央结算') or shareholder_name.startswith(
|
|
261
|
+
'HKSCC') else "A")
|
|
262
|
+
|
|
263
|
+
# 持股大于5% 减持需要发公告
|
|
264
|
+
# 排除香港结算公司不发公共 小于5%减持不用发公告
|
|
265
|
+
# 香港中央结算 HKSCC
|
|
266
|
+
stock_free_top_greater_than_5 = stock_gdfx_free_top_10.loc[
|
|
267
|
+
(stock_gdfx_free_top_10['circulation_ratio'] >= 5) & (stock_gdfx_free_top_10['is_hk'] == 'A')]
|
|
268
|
+
|
|
269
|
+
stock_free_qfii = stock_gdfx_free_top_10.loc[stock_gdfx_free_top_10['shareholder_nature'] == 'QFII']
|
|
270
|
+
|
|
271
|
+
share_holder_sync_day = list(stock_gdfx_free_top_10['create_day'])[0]
|
|
272
|
+
|
|
273
|
+
# qfii 数量
|
|
274
|
+
qfii_number = stock_free_qfii.shape[0]
|
|
275
|
+
# qfii 类型
|
|
276
|
+
qfii_type = set_qfii_type(qfii_number, stock_free_qfii.copy())
|
|
277
|
+
|
|
278
|
+
circulation_ratio = sum(stock_free_top_greater_than_5['circulation_ratio'])
|
|
279
|
+
mv_circulation_ratio = round((100 - circulation_ratio) / 100, 2)
|
|
280
|
+
# 防止错误数据
|
|
281
|
+
if mv_circulation_ratio < 0:
|
|
282
|
+
mv_circulation_ratio = 1
|
|
283
|
+
|
|
284
|
+
result_dict = {
|
|
285
|
+
'mv_circulation_ratio': mv_circulation_ratio,
|
|
286
|
+
'qfii_type': qfii_type,
|
|
287
|
+
'qfii_number': qfii_number,
|
|
288
|
+
'share_holder_sync_day': share_holder_sync_day
|
|
289
|
+
|
|
290
|
+
}
|
|
291
|
+
return result_dict
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def set_qfii_type(qfii_number, stock_free_qfii):
|
|
295
|
+
if qfii_number > 0:
|
|
296
|
+
stock_free_qfii['new_change'] = stock_free_qfii['change']
|
|
297
|
+
stock_free_qfii.loc[stock_free_qfii['change_ratio'] == 0, 'new_change'] = 0
|
|
298
|
+
stock_free_qfii.loc[stock_free_qfii['change'] == '新进', 'new_change'] = \
|
|
299
|
+
stock_free_qfii['shares_number']
|
|
300
|
+
stock_free_qfii['new_change'] = stock_free_qfii['new_change'].astype(float)
|
|
301
|
+
|
|
302
|
+
stock_free_qfii_new_in = stock_free_qfii.loc[stock_free_qfii['change'] == '新进']
|
|
303
|
+
if data_frame_util.is_not_empty(stock_free_qfii_new_in):
|
|
304
|
+
qfii_type = 1
|
|
305
|
+
return qfii_type
|
|
306
|
+
|
|
307
|
+
stock_free_qfii_add = stock_free_qfii.loc[
|
|
308
|
+
(~stock_free_qfii['change'].isin(['不变', '新进'])) & (stock_free_qfii['new_change'] > 0)]
|
|
309
|
+
|
|
310
|
+
if data_frame_util.is_not_empty(stock_free_qfii_add):
|
|
311
|
+
qfii_type = 2
|
|
312
|
+
return qfii_type
|
|
313
|
+
|
|
314
|
+
stock_free_qfii_not_change = stock_free_qfii.loc[stock_free_qfii['change'] == '不变']
|
|
315
|
+
|
|
316
|
+
if data_frame_util.is_not_empty(stock_free_qfii_not_change):
|
|
317
|
+
qfii_type = 3
|
|
318
|
+
return qfii_type
|
|
319
|
+
|
|
320
|
+
stock_free_qfii_reduce = stock_free_qfii.loc[
|
|
321
|
+
(~stock_free_qfii['change'].isin(['不变', '新进'])) & (stock_free_qfii['new_change'] < 0)]
|
|
322
|
+
|
|
323
|
+
if data_frame_util.is_not_empty(stock_free_qfii_reduce):
|
|
324
|
+
qfii_type = 4
|
|
325
|
+
return qfii_type
|
|
326
|
+
else:
|
|
327
|
+
return 0
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def create_index():
|
|
331
|
+
mongodb_util.create_index('company_info',
|
|
332
|
+
[("classification", 1)])
|
|
333
|
+
mongodb_util.create_index('company_info',
|
|
334
|
+
[("industry", 1)])
|
|
335
|
+
mongodb_util.create_index('company_info',
|
|
336
|
+
[("flow_mv", 1)])
|
|
337
|
+
mongodb_util.create_index('company_info',
|
|
338
|
+
[("list_date", 1)])
|
|
339
|
+
mongodb_util.create_index('company_info',
|
|
340
|
+
[("symbol", 1)])
|
|
341
|
+
|
|
342
|
+
|
|
257
343
|
def set_kpl_data(kpl_real_time_quotes_one, company_info_type, company_one):
|
|
258
344
|
if data_frame_util.is_not_empty(kpl_real_time_quotes_one):
|
|
259
345
|
company_info_type['kpl_plate_name'] = list(kpl_real_time_quotes_one['plate_name_list'])[0]
|
|
@@ -392,19 +478,25 @@ def save_sw_data(company_info_type):
|
|
|
392
478
|
def get_recent_year_income(symbol, company_info_type, exist_company_df):
|
|
393
479
|
now_date = datetime.now()
|
|
394
480
|
hour = now_date.hour
|
|
395
|
-
if hour <= 15:
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
481
|
+
# if hour <= 15:
|
|
482
|
+
# exist_company_one_df = exist_company_df.loc[exist_company_df['_id'] == symbol]
|
|
483
|
+
# if data_frame_util.is_not_empty(exist_company_one_df):
|
|
484
|
+
# company_info_type['operate_profit'] = list(exist_company_one_df['operate_profit'])[0]
|
|
485
|
+
# company_info_type['total_operate_income'] = list(exist_company_one_df['total_operate_income'])[0]
|
|
486
|
+
# if 'operate_date_name' in exist_company_one_df:
|
|
487
|
+
# company_info_type['operate_date_name'] = list(exist_company_one_df['total_operate_income'])[0]
|
|
488
|
+
# else:
|
|
489
|
+
# company_info_type['operate_date_name'] = '暂无年报'
|
|
490
|
+
# else:
|
|
491
|
+
# company_info_type['operate_profit'] = 0
|
|
492
|
+
# company_info_type['total_operate_income'] = 0
|
|
493
|
+
# company_info_type['operate_date_name'] = '暂无年报'
|
|
494
|
+
# return company_info_type
|
|
404
495
|
query = {'symbol': symbol, "REPORT_TYPE": "年报"}
|
|
405
496
|
em_stock_profit = mongodb_util.descend_query(query, db_name_constant.EM_STOCK_PROFIT, 'REPORT_DATE', 1)
|
|
406
497
|
if data_frame_util.is_not_empty(em_stock_profit):
|
|
407
498
|
company_info_type['operate_profit'] = list(em_stock_profit['OPERATE_PROFIT'])[0]
|
|
499
|
+
company_info_type['operate_date_name'] = list(em_stock_profit['REPORT_DATE_NAME'])[0]
|
|
408
500
|
total_operate_income = list(em_stock_profit['TOTAL_OPERATE_INCOME'])[0]
|
|
409
501
|
# 金融机构大多收入计入在这个字段中
|
|
410
502
|
if total_operate_income == 0:
|
|
@@ -414,6 +506,7 @@ def get_recent_year_income(symbol, company_info_type, exist_company_df):
|
|
|
414
506
|
else:
|
|
415
507
|
company_info_type['operate_profit'] = 0
|
|
416
508
|
company_info_type['total_operate_income'] = 0
|
|
509
|
+
company_info_type['operate_date_name'] = '暂无年报'
|
|
417
510
|
company_info_type['operate_profit'] = round(
|
|
418
511
|
company_info_type['operate_profit'] / common_service_fun_api.HUNDRED_MILLION, 2)
|
|
419
512
|
company_info_type['total_operate_income'] = round(
|
|
@@ -434,6 +527,5 @@ if __name__ == '__main__':
|
|
|
434
527
|
# query = {"total_operate_income": 0}
|
|
435
528
|
# un_report_company_info = mongodb_util.find_query_data(db_name_constant.COMPANY_INFO, query)
|
|
436
529
|
# symbol_list = list(un_report_company_info['symbol'])
|
|
437
|
-
|
|
438
|
-
sync_company_base_info(
|
|
439
|
-
# group_by_industry()
|
|
530
|
+
sync_company_base_info(['920009'])
|
|
531
|
+
sync_company_base_info(None)
|
|
@@ -2,7 +2,7 @@ import sys
|
|
|
2
2
|
import os
|
|
3
3
|
|
|
4
4
|
file_path = os.path.abspath(__file__)
|
|
5
|
-
end = file_path.index('mns') +
|
|
5
|
+
end = file_path.index('mns') + 17
|
|
6
6
|
project_path = file_path[0:end]
|
|
7
7
|
sys.path.append(project_path)
|
|
8
8
|
import mns_common.api.ths.company.ths_company_info_api as ths_company_info_api
|
|
@@ -27,11 +27,8 @@ def sync_company_hold_info(symbol):
|
|
|
27
27
|
now_date = datetime.now()
|
|
28
28
|
sync_str_date = now_date.strftime('%Y-%m-%d %H:%M:%S')
|
|
29
29
|
if data_frame_util.is_not_empty(company_hold_info_df):
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if result.acknowledged:
|
|
33
|
-
company_hold_info_df['sync_str_date'] = sync_str_date
|
|
34
|
-
mongodb_util.insert_mongo(company_hold_info_df, db_name_constant.COMPANY_HOLDING_INFO)
|
|
30
|
+
company_hold_info_df['sync_str_date'] = sync_str_date
|
|
31
|
+
mongodb_util.insert_mongo(company_hold_info_df, db_name_constant.COMPANY_HOLDING_INFO)
|
|
35
32
|
except BaseException as e:
|
|
36
33
|
logger.error("同步公司控股子公司信息:{},{}", symbol, e)
|
|
37
34
|
|
|
@@ -0,0 +1,161 @@
|
|
|
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
|
+
import mns_common.component.em.em_stock_info_api as em_stock_info_api
|
|
9
|
+
import mns_common.component.common_service_fun_api as common_service_fun_api
|
|
10
|
+
import mns_common.api.ths.company.company_product_area_industry_index_query as company_product_area_industry_index_query
|
|
11
|
+
from loguru import logger
|
|
12
|
+
from mns_common.db.MongodbUtil import MongodbUtil
|
|
13
|
+
import mns_common.constant.db_name_constant as db_name_constant
|
|
14
|
+
import mns_common.utils.data_frame_util as data_frame_util
|
|
15
|
+
import pandas as pd
|
|
16
|
+
from datetime import datetime
|
|
17
|
+
|
|
18
|
+
mongodb_util = MongodbUtil('27017')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def sync_company_product_area_industry_task(symbol):
|
|
22
|
+
now_date = datetime.now()
|
|
23
|
+
now_year = now_date.year
|
|
24
|
+
now_month = now_date.month
|
|
25
|
+
|
|
26
|
+
if now_month in [1, 2, 3, 4]:
|
|
27
|
+
period_time_year = str(now_year - 1) + "-12-31"
|
|
28
|
+
sync_company_product_area_industry(symbol, period_time_year)
|
|
29
|
+
|
|
30
|
+
if now_month in [4, 5, 6]:
|
|
31
|
+
period_time_one = str(now_year) + "-03-31"
|
|
32
|
+
sync_company_product_area_industry(symbol, period_time_one)
|
|
33
|
+
|
|
34
|
+
elif now_month in [7, 8, 9]:
|
|
35
|
+
period_time_two = str(now_year) + "-06-30"
|
|
36
|
+
sync_company_product_area_industry(symbol, period_time_two)
|
|
37
|
+
|
|
38
|
+
elif now_month in [10, 11, 12]:
|
|
39
|
+
period_time_three = str(now_year) + "-09-30"
|
|
40
|
+
sync_company_product_area_industry(symbol, period_time_three)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def sync_company_product_area_industry(symbol, date):
|
|
44
|
+
real_time_quotes_all_stocks = em_stock_info_api.get_a_stock_info()
|
|
45
|
+
real_time_quotes_all_stocks = common_service_fun_api.classify_symbol(real_time_quotes_all_stocks)
|
|
46
|
+
if symbol is not None:
|
|
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():
|
|
49
|
+
try:
|
|
50
|
+
symbol = stock_one.symbol
|
|
51
|
+
|
|
52
|
+
classification = stock_one.classification
|
|
53
|
+
if classification in ['H', 'K']:
|
|
54
|
+
market = '17'
|
|
55
|
+
elif classification in ['S', 'C']:
|
|
56
|
+
market = '33'
|
|
57
|
+
elif classification in ['X']:
|
|
58
|
+
market = '151'
|
|
59
|
+
|
|
60
|
+
company_product_area_industry_list = company_product_area_industry_index_query.company_product_area_industry(
|
|
61
|
+
symbol, market, date)
|
|
62
|
+
for company_one in company_product_area_industry_list:
|
|
63
|
+
try:
|
|
64
|
+
analysis_type = company_one['analysis_type']
|
|
65
|
+
time_operate_index_item_list = company_one['time_operate_index_item_list']
|
|
66
|
+
time_operate_index_item_df = pd.DataFrame(time_operate_index_item_list)
|
|
67
|
+
if data_frame_util.is_empty(time_operate_index_item_df):
|
|
68
|
+
continue
|
|
69
|
+
time_operate_index_item_df['symbol'] = symbol
|
|
70
|
+
time_operate_index_item_df['analysis_type'] = analysis_type
|
|
71
|
+
|
|
72
|
+
time_operate_index_item_df['_id'] = symbol + '_' + time_operate_index_item_df[
|
|
73
|
+
'time'] + '_' + analysis_type
|
|
74
|
+
handle_industry_area_product(time_operate_index_item_df, symbol)
|
|
75
|
+
except BaseException as e:
|
|
76
|
+
logger.error("同步经营数据异常:{},{}", symbol, e)
|
|
77
|
+
|
|
78
|
+
logger.info("同步经营数据完成:{}", stock_one.symbol)
|
|
79
|
+
except BaseException as e:
|
|
80
|
+
logger.error("同步经营数据:{},{}", stock_one.symbol, e)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def handle_industry_area_product(time_operate_index_item_df, symbol):
|
|
84
|
+
if data_frame_util.is_empty(time_operate_index_item_df):
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
for business_one in time_operate_index_item_df.itertuples():
|
|
88
|
+
time = business_one.time
|
|
89
|
+
analysis_type = business_one.analysis_type
|
|
90
|
+
|
|
91
|
+
product_index_item_list = business_one.product_index_item_list
|
|
92
|
+
for product_one in product_index_item_list:
|
|
93
|
+
try:
|
|
94
|
+
# 初始化数据
|
|
95
|
+
income_amount = 0
|
|
96
|
+
income_percent = 0
|
|
97
|
+
cost_amount = 0
|
|
98
|
+
cost_percent = 0
|
|
99
|
+
gross_profit_amount = 0
|
|
100
|
+
gross_profit_percent = 0
|
|
101
|
+
gross_profit_rate_amount = 0
|
|
102
|
+
gross_profit_rate_percent = 0
|
|
103
|
+
|
|
104
|
+
product_name = product_one['product_name']
|
|
105
|
+
index_analysis_list = product_one['index_analysis_list']
|
|
106
|
+
for index_one in index_analysis_list:
|
|
107
|
+
try:
|
|
108
|
+
index_id = index_one['index_id']
|
|
109
|
+
if index_id == 'income':
|
|
110
|
+
income_amount = index_one['index_value']
|
|
111
|
+
income_percent = index_one['account']
|
|
112
|
+
elif index_id == 'cost':
|
|
113
|
+
cost_amount = index_one['index_value']
|
|
114
|
+
cost_percent = index_one['account']
|
|
115
|
+
elif index_id == 'gross_profit':
|
|
116
|
+
gross_profit_amount = index_one['index_value']
|
|
117
|
+
gross_profit_percent = index_one['account']
|
|
118
|
+
|
|
119
|
+
elif index_id == 'gross_profit_rate':
|
|
120
|
+
gross_profit_rate_amount = index_one['index_value']
|
|
121
|
+
gross_profit_rate_percent = index_one['account']
|
|
122
|
+
except BaseException as e:
|
|
123
|
+
logger.error("同步经营数据异常:{},{}", symbol, e)
|
|
124
|
+
|
|
125
|
+
id_key = symbol + '_' + time + '_' + analysis_type + '_' + product_name
|
|
126
|
+
result_dict = {
|
|
127
|
+
'_id': id_key,
|
|
128
|
+
'symbol': symbol,
|
|
129
|
+
'time': time,
|
|
130
|
+
'analysis_type': analysis_type,
|
|
131
|
+
'product_name': product_name,
|
|
132
|
+
|
|
133
|
+
'income_amount': income_amount,
|
|
134
|
+
'income_percent': income_percent,
|
|
135
|
+
|
|
136
|
+
'cost_amount': cost_amount,
|
|
137
|
+
'cost_percent': cost_percent,
|
|
138
|
+
|
|
139
|
+
'gross_profit_amount': gross_profit_amount,
|
|
140
|
+
'gross_profit_percent': gross_profit_percent,
|
|
141
|
+
|
|
142
|
+
'gross_profit_rate_amount': gross_profit_rate_amount,
|
|
143
|
+
'gross_profit_rate_percent': gross_profit_rate_percent,
|
|
144
|
+
}
|
|
145
|
+
result_dict_df = pd.DataFrame(result_dict, index=[1])
|
|
146
|
+
mongodb_util.save_mongo(result_dict_df, db_name_constant.COMPANY_BUSINESS_INFO)
|
|
147
|
+
except BaseException as e:
|
|
148
|
+
logger.error("同步经营数据异常:{},{}", symbol, e)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
if __name__ == '__main__':
|
|
152
|
+
sync_company_product_area_industry('300211', '2025-09-30')
|
|
153
|
+
# sync_company_product_area_industry('002323')
|
|
154
|
+
# sync_company_product_area_industry('300901')
|
|
155
|
+
# sync_company_product_area_industry('603225')
|
|
156
|
+
# sync_company_product_area_industry('688039')
|
|
157
|
+
# sync_company_product_area_industry('600849')
|
|
158
|
+
# sync_company_product_area_industry('000508')
|
|
159
|
+
# sync_company_product_area_industry('810011')
|
|
160
|
+
|
|
161
|
+
sync_company_product_area_industry(None, None)
|