mns-common 1.4.1.8__py3-none-any.whl → 1.5.7.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_common/api/akshare/__init__.py +0 -1
- mns_common/api/akshare/k_line_api.py +19 -2
- mns_common/api/akshare/stock_bid_ask_api.py +10 -3
- mns_common/api/akshare/stock_zb_pool.py +2 -0
- mns_common/api/akshare/stock_zt_pool_api.py +1 -1
- mns_common/api/em/gd/east_money_stock_gdfx_free_top_10_api.py +62 -7
- mns_common/api/em/real_time/__init__.py +1 -1
- mns_common/api/em/real_time/east_money_debt_api.py +140 -70
- mns_common/api/em/real_time/east_money_etf_api.py +138 -27
- mns_common/api/em/real_time/east_money_stock_a_api.py +24 -28
- mns_common/api/em/real_time/east_money_stock_a_v2_api.py +97 -53
- mns_common/api/em/real_time/east_money_stock_common_api.py +174 -0
- mns_common/api/em/real_time/east_money_stock_hk_api.py +223 -272
- mns_common/api/em/real_time/east_money_stock_hk_gtt_api.py +260 -0
- mns_common/api/em/real_time/east_money_stock_multi_thread_api_v3.py +154 -0
- mns_common/api/em/real_time/east_money_stock_us_api.py +146 -82
- mns_common/api/em/real_time/real_time_quotes_repeat_api.py +195 -0
- mns_common/api/k_line/stock_k_line_data_api.py +11 -1
- mns_common/api/kpl/common/kpl_common_api.py +35 -0
- mns_common/api/proxies/liu_guan_proxy_api.py +55 -5
- mns_common/api/ths/company/company_product_area_industry_index_query.py +46 -0
- mns_common/api/ths/company/ths_company_info_api.py +2 -1
- mns_common/api/ths/company/ths_company_info_web.py +159 -0
- mns_common/api/ths/concept/app/ths_concept_index_app.py +3 -1
- mns_common/api/ths/wen_cai/ths_wen_cai_api.py +1 -1
- mns_common/api/ths/zt/ths_stock_zt_pool_api.py +20 -1
- mns_common/api/ths/zt/ths_stock_zt_pool_v2_api.py +105 -29
- mns_common/api/xueqiu/xue_qiu_k_line_api.py +2 -2
- mns_common/component/common_service_fun_api.py +26 -6
- mns_common/component/data/data_init_api.py +13 -8
- mns_common/component/deal/deal_service_api.py +70 -8
- mns_common/component/deal/deal_service_v2_api.py +167 -0
- mns_common/component/em/em_stock_info_api.py +9 -3
- mns_common/component/main_line/main_line_zt_reason_service.py +237 -0
- mns_common/component/proxies/proxy_common_api.py +141 -45
- mns_common/component/us/us_stock_etf_info_api.py +125 -0
- mns_common/constant/db_name_constant.py +40 -16
- mns_common/constant/extra_income_db_name.py +79 -19
- mns_common/constant/strategy_classify.py +17 -2
- mns_common/db/MongodbUtil.py +3 -0
- mns_common/db/MongodbUtilLocal.py +3 -0
- {mns_common-1.4.1.8.dist-info → mns_common-1.5.7.2.dist-info}/METADATA +1 -1
- {mns_common-1.4.1.8.dist-info → mns_common-1.5.7.2.dist-info}/RECORD +47 -41
- mns_common/api/ths/concept/web/ths_company_info_web.py +0 -163
- mns_common/component/qmt/qmt_buy_service.py +0 -172
- mns_common/component/task/real_time_data_sync_check.py +0 -110
- /mns_common/component/{qmt → main_line}/__init__.py +0 -0
- /mns_common/component/{task → us}/__init__.py +0 -0
- {mns_common-1.4.1.8.dist-info → mns_common-1.5.7.2.dist-info}/WHEEL +0 -0
- {mns_common-1.4.1.8.dist-info → mns_common-1.5.7.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
file_path = os.path.abspath(__file__)
|
|
5
|
+
end = file_path.index('mns') + 16
|
|
6
|
+
project_path = file_path[0:end]
|
|
7
|
+
sys.path.append(project_path)
|
|
8
|
+
|
|
9
|
+
import requests
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def company_product_area_industry(symbol, market, date):
|
|
13
|
+
if date is None:
|
|
14
|
+
url = (
|
|
15
|
+
f"https://basic.10jqka.com.cn/basicapi/operate/index/v1/product_index_query/?code={symbol}&market={market}"
|
|
16
|
+
f"&type=stock&account=1&timeField=date&analysisTypes=product,area,industry&sortIndex=income¤cy=CNY&level=1&expands=product_introduction&locale=zh_CN")
|
|
17
|
+
else:
|
|
18
|
+
|
|
19
|
+
url = (
|
|
20
|
+
f"https://basic.10jqka.com.cn/basicapi/operate/index/v1/product_index_query/?code={symbol}&market={market}&date={date}"
|
|
21
|
+
f"&type=stock&account=1&timeField=date&analysisTypes=product,area,industry&sortIndex=income¤cy=CNY&level=1&expands=product_introduction&locale=zh_CN")
|
|
22
|
+
|
|
23
|
+
headers = {
|
|
24
|
+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
|
25
|
+
"Accept-Language": "zh-CN,zh;q=0.9",
|
|
26
|
+
"Cache-Control": "max-age=0",
|
|
27
|
+
"Connection": "keep-alive",
|
|
28
|
+
"Sec-Fetch-Dest": "document",
|
|
29
|
+
"Sec-Fetch-Mode": "navigate",
|
|
30
|
+
"Sec-Fetch-Site": "cross-site",
|
|
31
|
+
"Sec-Fetch-User": "?1",
|
|
32
|
+
"Upgrade-Insecure-Requests": "1",
|
|
33
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36",
|
|
34
|
+
"sec-ch-ua": "\"Google Chrome\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"",
|
|
35
|
+
"sec-ch-ua-mobile": "?0",
|
|
36
|
+
"sec-ch-ua-platform": "\"Windows\"",
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
response = requests.get(url, headers=headers)
|
|
40
|
+
data_json = response.json()
|
|
41
|
+
data_list = data_json['data']
|
|
42
|
+
return data_list
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if __name__ == '__main__':
|
|
46
|
+
company_product_area_industry('688551', '17', None)
|
|
@@ -177,5 +177,6 @@ mongodb_util = MongodbUtil('27017')
|
|
|
177
177
|
if __name__ == '__main__':
|
|
178
178
|
stock_account_info = mongodb_util.find_query_data('stock_account_info', {"type": "ths_cookie", })
|
|
179
179
|
ths_cookie_test = list(stock_account_info['cookie'])[0]
|
|
180
|
-
company_df_test = get_company_hot_info('
|
|
180
|
+
company_df_test = get_company_hot_info('600756', ths_cookie_test)
|
|
181
|
+
target_title = company_df_test.split("\n")[0] # 关键修改:提取第一行
|
|
181
182
|
print(company_df_test)
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
file_path = os.path.abspath(__file__)
|
|
5
|
+
end = file_path.index('mns') + 14
|
|
6
|
+
project_path = file_path[0:end]
|
|
7
|
+
sys.path.append(project_path)
|
|
8
|
+
|
|
9
|
+
from loguru import logger
|
|
10
|
+
import pandas as pd
|
|
11
|
+
import requests
|
|
12
|
+
from bs4 import BeautifulSoup
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# 获取股票基本信息
|
|
16
|
+
# https://basic.10jqka.com.cn/mobile/301016/companyprofilen.html?showtab=1&broker=anelicaiapp
|
|
17
|
+
def get_company_info(symbol: str = "688272") -> pd.DataFrame:
|
|
18
|
+
url = f"http://basic.10jqka.com.cn/mobile/{symbol}/companyprofilen.html?broker=pingan"
|
|
19
|
+
headers = {
|
|
20
|
+
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 iOS AYLCAPP/9.1.2.0/h4526a24eb9445522492fd64caae11b1f scheme/anelicaiapp deviceinfo/I|9.1.2.0|NA|h4526a24eb9445522492fd64caae11b1f pastheme/0",
|
|
21
|
+
"Cookie": "ps_login_app_name=AYLCAPP;ps_login_token_id=N_C993F777ACC500B354C762A2627A8862348FC8163799A08EBEB2301C28A2135D220475787D0E81425C1134E15D8CC8761D639FEDBD46C00FE8EA6482C1E42D9801B19918FB3F5C34;ps_login_union_id=edc29089a2b64e3882062297030a0386;PAS.CURRENTUNIONID=edc29089a2b64e3882062297030a0386"
|
|
22
|
+
}
|
|
23
|
+
r = requests.get(url, headers=headers)
|
|
24
|
+
soup = BeautifulSoup(r.content.decode("utf-8"), 'lxml')
|
|
25
|
+
soup.find('table', attrs={'class': 'leveldatail-tab'}).find_all('tr')
|
|
26
|
+
temp_df = pd.read_html(r.content)[0]
|
|
27
|
+
temp_df = temp_df.T
|
|
28
|
+
temp_df = temp_df.iloc[1:2]
|
|
29
|
+
temp_df.rename(columns={
|
|
30
|
+
0: "name",
|
|
31
|
+
1: "former_name",
|
|
32
|
+
2: "registered_address",
|
|
33
|
+
3: "chairman",
|
|
34
|
+
4: "board_secretary",
|
|
35
|
+
5: "main_business",
|
|
36
|
+
6: "company_type",
|
|
37
|
+
7: "controlling_shareholder",
|
|
38
|
+
8: "actual_controller",
|
|
39
|
+
9: "ultimate_controller",
|
|
40
|
+
10: "list_date",
|
|
41
|
+
11: "issue_price",
|
|
42
|
+
12: "number_workers",
|
|
43
|
+
13: "tel",
|
|
44
|
+
14: "url",
|
|
45
|
+
15: "email"
|
|
46
|
+
}, inplace=True)
|
|
47
|
+
|
|
48
|
+
return temp_df
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# 获取股票详细信息
|
|
52
|
+
# HK市场 https://basic.10jqka.com.cn/mobile/HK1456/profile.html https://basic.10jqka.com.cn/mobile/HK1456/company.html
|
|
53
|
+
# https://basic.10jqka.com.cn/new/HK1456/company.html
|
|
54
|
+
# https://basic.10jqka.com.cn/astockph/briefinfo/index.html?showhead=0&fromshare=1&code=300430&marketid=33&client_userid=ESgcM&back_source=hyperlink&share_hxapp=isc&fontzoom=no#/company/ziliao
|
|
55
|
+
def get_company_info_detail(symbol: str = "688272", market_id: str = "31") -> pd.DataFrame:
|
|
56
|
+
url = f'https://basic.10jqka.com.cn/basicapi/company_info/merge_info/v1/base_info/?code={symbol}&market={market_id}&type=stock'
|
|
57
|
+
headers = {
|
|
58
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0',
|
|
59
|
+
'Host': 'basic.10jqka.com.cn',
|
|
60
|
+
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
|
|
61
|
+
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
|
|
62
|
+
'Accept-Encoding': 'gzip, deflate, br',
|
|
63
|
+
'Connection': 'keep-alive',
|
|
64
|
+
'Cookie': 'v=A0CN8EBXN21LtMtpV6ldAxf6Ec8XySSbxq14l7rRDNvuNe77Ytn0Ixa9SDQJ',
|
|
65
|
+
'Upgrade-Insecure-Requests': '1',
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
r = requests.get(url, headers=headers)
|
|
69
|
+
data_json = r.json()
|
|
70
|
+
status_code = data_json['status_code']
|
|
71
|
+
status_msg = data_json['status_msg']
|
|
72
|
+
if status_code != 0 or status_msg != 'success':
|
|
73
|
+
logger.error("获取symbol公司详细信息异常:{}", symbol)
|
|
74
|
+
return pd.DataFrame()
|
|
75
|
+
if len(data_json['data']['industry']) == 0:
|
|
76
|
+
return pd.DataFrame()
|
|
77
|
+
data_df = pd.DataFrame(data_json['data']['industry'], index=[0])
|
|
78
|
+
data_df = data_df[[
|
|
79
|
+
'hy',
|
|
80
|
+
'hycode',
|
|
81
|
+
'hy2',
|
|
82
|
+
'hy2code',
|
|
83
|
+
'hy3',
|
|
84
|
+
'hy3code',
|
|
85
|
+
]]
|
|
86
|
+
|
|
87
|
+
business_nature = data_json['data']['business_nature']
|
|
88
|
+
name = data_json['data']['code_name']
|
|
89
|
+
intro = data_json['data']['intro']
|
|
90
|
+
base_business = data_json['data']['base_business']
|
|
91
|
+
|
|
92
|
+
address = data_json['data']['address']
|
|
93
|
+
data_df['symbol'] = symbol
|
|
94
|
+
data_df['name'] = name
|
|
95
|
+
|
|
96
|
+
data_df['business_nature'] = business_nature
|
|
97
|
+
|
|
98
|
+
if len(data_json['data']['management']['holder_controller']) > 0:
|
|
99
|
+
holder_controller = pd.DataFrame(data_json['data']['management']['holder_controller'])
|
|
100
|
+
holder_controller_name = str(list(holder_controller['name'])).strip('[').strip(']').replace("'", "")
|
|
101
|
+
holder_controller_rate = holder_controller['rate']
|
|
102
|
+
data_df['holder_controller_name'] = holder_controller_name
|
|
103
|
+
data_df['holder_controller_rate'] = sum(holder_controller_rate)
|
|
104
|
+
else:
|
|
105
|
+
data_df['holder_controller_name'] = '暂无'
|
|
106
|
+
data_df['holder_controller_rate'] = 0
|
|
107
|
+
if len(data_json['data']['management']['final_controller']) > 0:
|
|
108
|
+
final_controller = pd.DataFrame(data_json['data']['management']['final_controller'])
|
|
109
|
+
final_controller_name = str(list(final_controller['name'])).strip('[').strip(']').replace("'", "")
|
|
110
|
+
final_controller_rate = sum(final_controller['rate'])
|
|
111
|
+
data_df['final_controller_name'] = final_controller_name
|
|
112
|
+
data_df['final_controller_rate'] = final_controller_rate
|
|
113
|
+
else:
|
|
114
|
+
data_df['final_controller_name'] = '暂无'
|
|
115
|
+
data_df['final_controller_rate'] = 0
|
|
116
|
+
if len(data_json['data']['management']['actual_controller']) > 0:
|
|
117
|
+
actual_controller = pd.DataFrame(data_json['data']['management']['actual_controller'])
|
|
118
|
+
actual_controller_name = str(list(actual_controller['name'])).strip('[').strip(']').replace("'", "")
|
|
119
|
+
actual_controller_rate = sum(actual_controller['rate'])
|
|
120
|
+
data_df['actual_controller_name'] = actual_controller_name
|
|
121
|
+
data_df['actual_controller_rate'] = actual_controller_rate
|
|
122
|
+
else:
|
|
123
|
+
data_df['actual_controller_name'] = '暂无'
|
|
124
|
+
data_df['actual_controller_rate'] = 0
|
|
125
|
+
|
|
126
|
+
data_df['base_business'] = base_business
|
|
127
|
+
data_df['intro'] = intro
|
|
128
|
+
data_df['address'] = address
|
|
129
|
+
market_id = data_json['data']['market_id']
|
|
130
|
+
data_df['market_id'] = market_id
|
|
131
|
+
# 初始化数据
|
|
132
|
+
data_df['main_business_list'] = [[]]
|
|
133
|
+
data_df['most_profitable_business'] = ''
|
|
134
|
+
data_df['most_profitable_business_rate'] = ''
|
|
135
|
+
data_df['most_profitable_business_profit'] = ''
|
|
136
|
+
|
|
137
|
+
# 业务构成
|
|
138
|
+
main_business_list = data_json['data']['main_business']
|
|
139
|
+
|
|
140
|
+
if len(main_business_list) > 0:
|
|
141
|
+
# 最盈利业务
|
|
142
|
+
profitable_business = data_json['data']['profitable_business']
|
|
143
|
+
|
|
144
|
+
data_df['main_business_list'] = [main_business_list]
|
|
145
|
+
|
|
146
|
+
most_profitable_business = profitable_business['name']
|
|
147
|
+
|
|
148
|
+
most_profitable_business_rate = profitable_business['profit_rate']
|
|
149
|
+
|
|
150
|
+
most_profitable_business_profit = profitable_business['profit']
|
|
151
|
+
|
|
152
|
+
data_df['most_profitable_business'] = most_profitable_business
|
|
153
|
+
data_df['most_profitable_business_rate'] = most_profitable_business_rate
|
|
154
|
+
data_df['most_profitable_business_profit'] = most_profitable_business_profit
|
|
155
|
+
return data_df
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
if __name__ == '__main__':
|
|
159
|
+
get_company_info_detail('603683','17')
|
|
@@ -152,7 +152,9 @@ from mns_common.db.MongodbUtil import MongodbUtil
|
|
|
152
152
|
|
|
153
153
|
mongodb_util = MongodbUtil('27017')
|
|
154
154
|
if __name__ == '__main__':
|
|
155
|
-
|
|
155
|
+
get_new_concept_from_app_search('886104')
|
|
156
|
+
|
|
157
|
+
end_time_test = '20241011093500'
|
|
156
158
|
result_df_test = get_ths_concept_his_info('20241011093000', end_time_test, 500, 2)
|
|
157
159
|
result_df_test['block_code'] = result_df_test['block_code'].astype(int)
|
|
158
160
|
result_df_test['_id'] = result_df_test['block_code']
|
|
@@ -115,7 +115,7 @@ def get_concept_detail_by_wen_cai(concept_name):
|
|
|
115
115
|
|
|
116
116
|
|
|
117
117
|
if __name__ == '__main__':
|
|
118
|
-
zt_df = wen_cai_api('
|
|
118
|
+
zt_df = wen_cai_api('001203涨停分析', 'stock', )
|
|
119
119
|
print(zt_df)
|
|
120
120
|
# concept_detail_df = get_concept_detail_by_wen_cai("光纤概念")
|
|
121
121
|
# concept_df = get_concept_index_by_wen_cai()
|
|
@@ -274,5 +274,24 @@ def zt_reason_group(zt_pool_df):
|
|
|
274
274
|
return result_group_df
|
|
275
275
|
|
|
276
276
|
|
|
277
|
+
def zt_analyse_reason(symbol):
|
|
278
|
+
try:
|
|
279
|
+
key = symbol + '涨停分析'
|
|
280
|
+
zt_dict = ths_wen_cai_api.wen_cai_api(key, 'stock')
|
|
281
|
+
zt_analyse_detail = zt_dict['涨停揭秘'][0]['content']['value']
|
|
282
|
+
zt_reason = zt_dict['涨停揭秘'][0]['title']['value']
|
|
283
|
+
|
|
284
|
+
result_dict = {
|
|
285
|
+
'zt_analyse_detail': zt_analyse_detail,
|
|
286
|
+
'zt_reason': zt_reason
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return result_dict
|
|
290
|
+
except BaseException as e:
|
|
291
|
+
logger.error("获取涨停分享异常b:{},{}", symbol, str(e))
|
|
292
|
+
return ''
|
|
293
|
+
|
|
294
|
+
|
|
277
295
|
if __name__ == '__main__':
|
|
278
|
-
|
|
296
|
+
zt_analyse_reason('003027')
|
|
297
|
+
# get_real_time_zt_info()
|
|
@@ -140,7 +140,8 @@ def convert_statistics(stat):
|
|
|
140
140
|
# 获取实时行情涨停列表
|
|
141
141
|
def get_real_time_zt_info():
|
|
142
142
|
real_time_df = em_real_time_quotes_api.get_real_time_quotes_now(None, None)
|
|
143
|
-
real_time_df_zt = real_time_df.loc[
|
|
143
|
+
real_time_df_zt = real_time_df.loc[
|
|
144
|
+
(real_time_df['chg'] > common_service_fun_api.ZT_CHG) | (real_time_df['wei_bi'] == 100)]
|
|
144
145
|
if data_frame_util.is_empty(real_time_df_zt):
|
|
145
146
|
return pd.DataFrame()
|
|
146
147
|
real_time_df_zt = real_time_df_zt[[
|
|
@@ -197,24 +198,83 @@ def get_now_zt_pool_with_reason(str_day):
|
|
|
197
198
|
real_time_zt_df = get_real_time_zt_info()
|
|
198
199
|
# 昨日涨停列表
|
|
199
200
|
last_trade_zt = zt_common_service_api.get_last_trade_day_zt(str_day)
|
|
200
|
-
|
|
201
|
-
|
|
201
|
+
|
|
202
|
+
try:
|
|
203
|
+
# 东方财富涨停列表
|
|
204
|
+
em_now_zt_pool = stock_zt_pool_api.stock_em_zt_pool_df(date_handle_util.no_slash_date(str_day))
|
|
205
|
+
except BaseException as e:
|
|
206
|
+
em_now_zt_pool = pd.DataFrame()
|
|
207
|
+
logger.error("获取东方财富涨停列表异常:{}", e)
|
|
208
|
+
|
|
202
209
|
if data_frame_util.is_not_empty(em_now_zt_pool):
|
|
203
210
|
real_time_zt_df_wei_bi_100 = real_time_zt_df.loc[real_time_zt_df['symbol'].isin(em_now_zt_pool['symbol'])]
|
|
204
211
|
real_time_zt_df_high_chg = real_time_zt_df.loc[~(real_time_zt_df['symbol'].isin(em_now_zt_pool['symbol']))]
|
|
212
|
+
|
|
213
|
+
em_now_zt_pool = em_now_zt_pool[['symbol',
|
|
214
|
+
'connected_boards_numbers',
|
|
215
|
+
'statistics',
|
|
216
|
+
'closure_funds',
|
|
217
|
+
'first_closure_time',
|
|
218
|
+
'last_closure_time',
|
|
219
|
+
'frying_plates_numbers']]
|
|
220
|
+
|
|
221
|
+
em_now_zt_pool = em_now_zt_pool.set_index(['symbol'], drop=True)
|
|
222
|
+
real_time_zt_df_wei_bi_100 = real_time_zt_df_wei_bi_100.set_index(['symbol'], drop=False)
|
|
223
|
+
real_time_zt_df_wei_bi_100 = pd.merge(real_time_zt_df_wei_bi_100, em_now_zt_pool, how='outer',
|
|
224
|
+
left_index=True, right_index=True)
|
|
225
|
+
|
|
226
|
+
now_continue_zt = last_trade_zt.loc[
|
|
227
|
+
last_trade_zt['symbol'].isin(list(real_time_zt_df_wei_bi_100['symbol']))]
|
|
228
|
+
|
|
205
229
|
else:
|
|
206
|
-
|
|
230
|
+
real_time_zt_df_wei_bi_100 = real_time_zt_df.loc[real_time_zt_df['wei_bi'] == 100]
|
|
231
|
+
|
|
232
|
+
real_time_zt_df_wei_bi_100['connected_boards_numbers'] = 1
|
|
233
|
+
real_time_zt_df_wei_bi_100['statistics'] = '1/1'
|
|
234
|
+
real_time_zt_df_wei_bi_100['closure_funds'] = real_time_zt_df_wei_bi_100['now_price'] * \
|
|
235
|
+
real_time_zt_df_wei_bi_100['buy_1_num'] * 100
|
|
236
|
+
real_time_zt_df_wei_bi_100['first_closure_time'] = '153000'
|
|
237
|
+
real_time_zt_df_wei_bi_100['last_closure_time'] = '153000'
|
|
238
|
+
real_time_zt_df_wei_bi_100['frying_plates_numbers'] = 0
|
|
239
|
+
now_continue_zt = last_trade_zt.loc[
|
|
240
|
+
last_trade_zt['symbol'].isin(list(real_time_zt_df_wei_bi_100['symbol']))]
|
|
241
|
+
|
|
242
|
+
if data_frame_util.is_not_empty(now_continue_zt):
|
|
243
|
+
now_continue_zt = now_continue_zt[['symbol', 'connected_boards_numbers', 'statistics']]
|
|
244
|
+
|
|
245
|
+
connected_boards_map = now_continue_zt.set_index('symbol')['connected_boards_numbers'].to_dict()
|
|
246
|
+
|
|
247
|
+
# 将映射的值加到原DataFrame上
|
|
248
|
+
real_time_zt_df_wei_bi_100['connected_boards_numbers'] = real_time_zt_df_wei_bi_100[
|
|
249
|
+
'connected_boards_numbers'] + \
|
|
250
|
+
real_time_zt_df_wei_bi_100['symbol'].map(
|
|
251
|
+
connected_boards_map).fillna(0)
|
|
252
|
+
|
|
253
|
+
real_time_zt_df_wei_bi_100 = real_time_zt_df_wei_bi_100.sort_values(by=['connected_boards_numbers'],
|
|
254
|
+
ascending=False)
|
|
255
|
+
|
|
256
|
+
real_time_zt_df_high_chg = real_time_zt_df.loc[real_time_zt_df['wei_bi'] != 100]
|
|
257
|
+
|
|
258
|
+
# todo
|
|
259
|
+
# 高涨幅处理
|
|
260
|
+
now_zt_pool_df = handle_high_chg(real_time_zt_df_high_chg, last_trade_zt, real_time_zt_df_wei_bi_100)
|
|
261
|
+
|
|
262
|
+
now_zt_pool_df = merge_zt_reason(now_zt_pool_df, str_day, last_trade_zt, now_continue_zt)
|
|
263
|
+
|
|
264
|
+
result_first = now_zt_pool_df.loc[now_zt_pool_df['connected_boards_numbers'] == 1]
|
|
265
|
+
result_connected_boards = now_zt_pool_df.loc[now_zt_pool_df['connected_boards_numbers'] > 1]
|
|
266
|
+
result_connected_boards = result_connected_boards.sort_values(by=['connected_boards_numbers'], ascending=False)
|
|
267
|
+
result_first = result_first.sort_values(by=['first_closure_time'], ascending=True)
|
|
268
|
+
|
|
269
|
+
now_zt_pool_df = pd.concat([result_connected_boards,
|
|
270
|
+
result_first])
|
|
271
|
+
now_zt_pool_df = now_zt_pool_df.fillna('未知数据')
|
|
272
|
+
now_zt_pool_df.drop_duplicates('symbol', keep='last', inplace=True)
|
|
207
273
|
|
|
208
|
-
|
|
209
|
-
['symbol', 'connected_boards_numbers',
|
|
210
|
-
'statistics', 'closure_funds', 'first_closure_time',
|
|
211
|
-
'last_closure_time', 'frying_plates_numbers']]
|
|
274
|
+
return now_zt_pool_df
|
|
212
275
|
|
|
213
|
-
em_now_zt_pool = em_now_zt_pool.set_index(['symbol'], drop=True)
|
|
214
|
-
real_time_zt_df_wei_bi_100 = real_time_zt_df_wei_bi_100.set_index(['symbol'], drop=False)
|
|
215
|
-
real_time_zt_df_wei_bi_100 = pd.merge(real_time_zt_df_wei_bi_100, em_now_zt_pool, how='outer',
|
|
216
|
-
left_index=True, right_index=True)
|
|
217
276
|
|
|
277
|
+
def handle_high_chg(real_time_zt_df_high_chg, last_trade_zt, real_time_zt_df_wei_bi_100):
|
|
218
278
|
# 初始化数据
|
|
219
279
|
real_time_zt_df_high_chg['closure_funds'] = 0
|
|
220
280
|
real_time_zt_df_high_chg['first_closure_time'] = '153000'
|
|
@@ -228,6 +288,7 @@ def get_now_zt_pool_with_reason(str_day):
|
|
|
228
288
|
|
|
229
289
|
last_trade_zt_copy_today_high_chg = last_trade_zt.loc[
|
|
230
290
|
last_trade_zt['symbol'].isin(real_time_zt_df_high_chg_last_trade_zt['symbol'])]
|
|
291
|
+
|
|
231
292
|
last_trade_zt_copy_today_high_chg = last_trade_zt_copy_today_high_chg[
|
|
232
293
|
['symbol', 'connected_boards_numbers', 'statistics']]
|
|
233
294
|
last_trade_zt_copy_today_high_chg['connected_boards_numbers'] = last_trade_zt_copy_today_high_chg[
|
|
@@ -247,21 +308,10 @@ def get_now_zt_pool_with_reason(str_day):
|
|
|
247
308
|
real_time_zt_df_high_chg_last_trade_zt,
|
|
248
309
|
real_time_zt_df_high_chg_last_trade_no_zt])
|
|
249
310
|
|
|
250
|
-
now_zt_pool_df = merge_zt_reason(now_zt_pool_df, str_day, last_trade_zt)
|
|
251
|
-
|
|
252
|
-
result_first = now_zt_pool_df.loc[now_zt_pool_df['connected_boards_numbers'] == 1]
|
|
253
|
-
result_connected_boards = now_zt_pool_df.loc[now_zt_pool_df['connected_boards_numbers'] > 1]
|
|
254
|
-
result_connected_boards = result_connected_boards.sort_values(by=['connected_boards_numbers'], ascending=False)
|
|
255
|
-
result_first = result_first.sort_values(by=['first_closure_time'], ascending=True)
|
|
256
|
-
|
|
257
|
-
now_zt_pool_df = pd.concat([result_connected_boards,
|
|
258
|
-
result_first])
|
|
259
|
-
now_zt_pool_df = now_zt_pool_df.fillna('未知数据')
|
|
260
|
-
now_zt_pool_df.drop_duplicates('symbol', keep='last', inplace=True)
|
|
261
311
|
return now_zt_pool_df
|
|
262
312
|
|
|
263
313
|
|
|
264
|
-
def merge_zt_reason(now_zt_pool_df, str_day, last_trade_zt):
|
|
314
|
+
def merge_zt_reason(now_zt_pool_df, str_day, last_trade_zt, now_continue_zt):
|
|
265
315
|
try:
|
|
266
316
|
zt_reason_df = get_ths_stock_zt_reason_with_cache(str_day)
|
|
267
317
|
except BaseException as e:
|
|
@@ -269,9 +319,17 @@ def merge_zt_reason(now_zt_pool_df, str_day, last_trade_zt):
|
|
|
269
319
|
logger.error("获取涨停原因异常:{}", e)
|
|
270
320
|
|
|
271
321
|
last_trade_zt_copy = last_trade_zt.copy()
|
|
322
|
+
|
|
272
323
|
if "zt_reason" not in last_trade_zt.columns:
|
|
273
324
|
last_trade_zt_copy['zt_reason'] = '暂无'
|
|
274
|
-
|
|
325
|
+
|
|
326
|
+
if 'main_line' not in last_trade_zt.columns:
|
|
327
|
+
last_trade_zt['main_line'] = ''
|
|
328
|
+
|
|
329
|
+
if 'sub_main_line' not in last_trade_zt.columns:
|
|
330
|
+
last_trade_zt['sub_main_line'] = ''
|
|
331
|
+
|
|
332
|
+
last_trade_zt_copy = last_trade_zt_copy[['symbol', 'zt_reason', 'sub_main_line', 'main_line']]
|
|
275
333
|
|
|
276
334
|
if data_frame_util.is_empty(zt_reason_df):
|
|
277
335
|
now_zt_pool_df['zt_reason'] = '暂无'
|
|
@@ -289,6 +347,21 @@ def merge_zt_reason(now_zt_pool_df, str_day, last_trade_zt):
|
|
|
289
347
|
zt_reason_df_copy = zt_reason_df_copy.set_index(['symbol'], drop=True)
|
|
290
348
|
now_zt_pool_df = now_zt_pool_df.set_index(['symbol'], drop=False)
|
|
291
349
|
|
|
350
|
+
if data_frame_util.is_not_empty(now_continue_zt):
|
|
351
|
+
now_continue_zt = now_continue_zt[['symbol', 'main_line', 'sub_main_line']]
|
|
352
|
+
|
|
353
|
+
# 创建一个 symbol 到 main_line 的映射
|
|
354
|
+
main_line_mapping = now_continue_zt.set_index('symbol')['main_line'].to_dict()
|
|
355
|
+
|
|
356
|
+
# 使用 map 更新 main_line 列
|
|
357
|
+
now_zt_pool_df['main_line'] = now_zt_pool_df['symbol'].map(main_line_mapping).fillna("")
|
|
358
|
+
|
|
359
|
+
# 创建一个 symbol 到 main_line 的映射
|
|
360
|
+
sub_main_line_mapping = now_continue_zt.set_index('symbol')['sub_main_line'].to_dict()
|
|
361
|
+
|
|
362
|
+
# 使用 map 更新 sub_main_line 列
|
|
363
|
+
now_zt_pool_df['sub_main_line'] = now_zt_pool_df['symbol'].map(sub_main_line_mapping).fillna("")
|
|
364
|
+
|
|
292
365
|
result_zt_df = pd.merge(now_zt_pool_df, zt_reason_df_copy, how='outer',
|
|
293
366
|
left_index=True, right_index=True)
|
|
294
367
|
|
|
@@ -299,8 +372,12 @@ def merge_zt_reason(now_zt_pool_df, str_day, last_trade_zt):
|
|
|
299
372
|
last_trade_zt_copy = last_trade_zt_copy.set_index(['symbol'], drop=True)
|
|
300
373
|
del zt_reason_na['zt_reason']
|
|
301
374
|
zt_reason_na = zt_reason_na.set_index(['symbol'], drop=False)
|
|
375
|
+
del last_trade_zt_copy['main_line']
|
|
376
|
+
del last_trade_zt_copy['sub_main_line']
|
|
377
|
+
|
|
302
378
|
zt_reason_na = pd.merge(zt_reason_na, last_trade_zt_copy, how='outer',
|
|
303
379
|
left_index=True, right_index=True)
|
|
380
|
+
|
|
304
381
|
zt_reason_na['zt_reason'] = zt_reason_na['zt_reason'].fillna('0')
|
|
305
382
|
# 删除昨日涨停 今日未涨停的
|
|
306
383
|
zt_reason_na.dropna(subset=['symbol'], inplace=True)
|
|
@@ -363,12 +440,11 @@ def zt_reason_group(zt_pool_df):
|
|
|
363
440
|
|
|
364
441
|
|
|
365
442
|
if __name__ == '__main__':
|
|
366
|
-
str_day_test = '
|
|
367
|
-
|
|
443
|
+
str_day_test = '2025-10-28'
|
|
444
|
+
# 同花顺涨停
|
|
445
|
+
ths_zt_pool_df = get_now_zt_pool_with_reason(str_day_test)
|
|
368
446
|
# 东财涨停池
|
|
369
447
|
em_now_zt_pool_test = stock_zt_pool_api.stock_em_zt_pool_df(date_handle_util.no_slash_date(str_day_test))
|
|
370
|
-
# 同花顺涨停
|
|
371
|
-
ths_zt_pool_df = get_zt_reason(str_day_test)
|
|
372
448
|
|
|
373
449
|
miss_zt_df = em_now_zt_pool_test.loc[~(em_now_zt_pool_test['symbol'].isin(ths_zt_pool_df['symbol']))]
|
|
374
450
|
pass
|
|
@@ -76,8 +76,8 @@ def get_xue_qiu_k_line(symbol, period, cookie, end_time, hq):
|
|
|
76
76
|
|
|
77
77
|
if __name__ == '__main__':
|
|
78
78
|
number = 1
|
|
79
|
-
cookies ='cookiesu=
|
|
79
|
+
cookies ='cookiesu=291756518429127; device_id=8c5eef4332e51dbcbcd92943b0dd91e4; s=bz17174k1c; xq_a_token=b9c7e702181cba3ed732d5019efe2dfe2fb054b0; xqat=b9c7e702181cba3ed732d5019efe2dfe2fb054b0; xq_r_token=c1edaf05e1c6fdf8122671eced8049e8df8a4290; xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOi0xLCJpc3MiOiJ1YyIsImV4cCI6MTc2MTYxNDEwNywiY3RtIjoxNzU5OTc2NzUxOTI3LCJjaWQiOiJkOWQwbjRBWnVwIn0.JwQMnAT6E1lPSqfK-GnFpLNQz-Jr-xtZ6HoUfnCfeRTNKrDJqf0l5_iY7dhEo6A5m38MmXj0hgR-xYkzPm35fFcQCQnZ06dOK0XCP6AE9r5KVFd73GyqbXLijKDFPQVM0sPgbgCs9fTOmB7Nlju_7B_raPmZ8IIHzZRU6uSK9oXsrnwpo4TD0Mr2nMF3ktVwEQHdkZsjm9mdSZaT9fkDvayFKKmg_O-JbHDZ6mTF1i-zR6oH-5r3g6HJJU9-_NwzZMeBEVnLG8IWwO8_n9CWdpbqQ-qC-iue4yEHFdiTLBCRRgyFauVv0kJS1ZNKvvefxkETTVr-WgXobT82ED7ApA; u=291756518429127; Hm_lvt_1db88642e346389874251b5a1eded6e3=1759765103,1759808830,1759970243,1759976801; HMACCOUNT=4C4F802C04F4D70A; Hm_lpvt_1db88642e346389874251b5a1eded6e3=1759978805'
|
|
80
80
|
while True:
|
|
81
|
-
test_df = get_xue_qiu_k_line('
|
|
81
|
+
test_df = get_xue_qiu_k_line('SZ300188', '1m', cookies, '1760065317680', '')
|
|
82
82
|
print(number)
|
|
83
83
|
number = number + 1
|
|
@@ -71,23 +71,36 @@ def classify_symbol_one(symbol):
|
|
|
71
71
|
# 添加前缀
|
|
72
72
|
def add_pre_prefix_one(symbol):
|
|
73
73
|
symbol_simple = symbol[0:6]
|
|
74
|
+
if bool(1 - is_valid_symbol(symbol_simple)):
|
|
75
|
+
return symbol
|
|
76
|
+
|
|
74
77
|
if symbol_simple.startswith('6'):
|
|
75
|
-
return 'SH' +
|
|
78
|
+
return 'SH' + symbol_simple
|
|
76
79
|
elif symbol_simple.startswith('0') or symbol_simple.startswith('3'):
|
|
77
|
-
return 'SZ' +
|
|
80
|
+
return 'SZ' + symbol_simple
|
|
78
81
|
else:
|
|
79
|
-
return 'BJ' +
|
|
82
|
+
return 'BJ' + symbol_simple
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def is_valid_symbol(symbol):
|
|
86
|
+
# 确保输入是字符串(避免数字或其他类型)
|
|
87
|
+
if not isinstance(symbol, str):
|
|
88
|
+
return False
|
|
89
|
+
# 检查长度是否为6且所有字符都是数字
|
|
90
|
+
return len(symbol) == 6 and symbol.isdigit()
|
|
80
91
|
|
|
81
92
|
|
|
82
93
|
# 添加后缀
|
|
83
94
|
def add_after_prefix_one(symbol):
|
|
84
95
|
symbol_simple = symbol[0:6]
|
|
96
|
+
if bool(1 - is_valid_symbol(symbol_simple)):
|
|
97
|
+
return symbol
|
|
85
98
|
if symbol_simple.startswith('6'):
|
|
86
|
-
return
|
|
99
|
+
return symbol_simple + '.SH'
|
|
87
100
|
elif symbol_simple.startswith('0') or symbol_simple.startswith('3'):
|
|
88
|
-
return
|
|
101
|
+
return symbol_simple + '.SZ'
|
|
89
102
|
else:
|
|
90
|
-
return
|
|
103
|
+
return symbol_simple + '.BJ'
|
|
91
104
|
|
|
92
105
|
|
|
93
106
|
def symbol_amount_simple(real_time_quotes_now_df):
|
|
@@ -181,6 +194,8 @@ def group_by_industry_sum(real_time_quotes_now, field1, field2):
|
|
|
181
194
|
|
|
182
195
|
|
|
183
196
|
def symbol_add_prefix(symbol):
|
|
197
|
+
if bool(1 - symbol.isdigit()):
|
|
198
|
+
return symbol
|
|
184
199
|
symbol_simple = symbol[0:6]
|
|
185
200
|
if symbol_simple.startswith('6'):
|
|
186
201
|
return '1.' + symbol_simple
|
|
@@ -188,3 +203,8 @@ def symbol_add_prefix(symbol):
|
|
|
188
203
|
return '0.' + symbol_simple
|
|
189
204
|
else:
|
|
190
205
|
return '0.' + symbol_simple
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
# 排除改变代码的北交所
|
|
209
|
+
def exclude_change_bjs_code(df):
|
|
210
|
+
return df[~df['symbol'].str.startswith(('8', '4'))]
|
|
@@ -60,16 +60,21 @@ def calculate_parameter_factor(real_time_quotes_now):
|
|
|
60
60
|
real_time_quotes_now['large_inflow_multiple'] = round(
|
|
61
61
|
(real_time_quotes_now['large_order_net_inflow'] / real_time_quotes_now['reference_main_inflow']), 2)
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
if 'real_disk_diff_amount_exchange' not in real_time_quotes_now.columns:
|
|
64
|
+
real_time_quotes_now.loc[:, 'real_disk_diff_amount_exchange'] = round(
|
|
65
|
+
(real_time_quotes_now['disk_diff_amount_exchange'] / real_time_quotes_now['mv_circulation_ratio']), 2)
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
67
|
+
if 'real_main_inflow_multiple' not in real_time_quotes_now.columns:
|
|
68
|
+
real_time_quotes_now.loc[:, 'real_main_inflow_multiple'] = round(
|
|
69
|
+
(real_time_quotes_now['main_inflow_multiple'] / real_time_quotes_now['mv_circulation_ratio']), 2)
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
if 'real_super_main_inflow_multiple' not in real_time_quotes_now.columns:
|
|
72
|
+
real_time_quotes_now.loc[:, 'real_super_main_inflow_multiple'] = round(
|
|
73
|
+
(real_time_quotes_now['super_main_inflow_multiple'] / real_time_quotes_now['mv_circulation_ratio']), 2)
|
|
74
|
+
|
|
75
|
+
if 'real_exchange' not in real_time_quotes_now.columns:
|
|
76
|
+
real_time_quotes_now.loc[:, 'real_exchange'] = round(
|
|
77
|
+
(real_time_quotes_now['exchange'] / real_time_quotes_now['mv_circulation_ratio']), 2)
|
|
73
78
|
|
|
74
79
|
real_time_quotes_now.loc[:, 'max_real_main_inflow_multiple'] = real_time_quotes_now[
|
|
75
80
|
['real_main_inflow_multiple', 'real_super_main_inflow_multiple']].max(axis=1)
|