"""
|
网络代理管理器
|
"""
|
# 本地看盘网络代理
|
import decimal
|
import json
|
import time
|
from urllib.parse import parse_qs, urlparse
|
|
from juejin_core import JueJinApi
|
from kpl import kpl_util, kpl_api
|
from kpl.kpl_data_manager import KPLLimitUpDataManager
|
from utils import tool, xgb_api
|
|
|
class LocalKanPanNetworkDelegate:
|
# 保存代码涨幅
|
__code_limit_rate_dict = {}
|
|
# HTTP代理请求
|
@classmethod
|
def http_delegate_request(cls, url):
|
if url.startswith("/kpl/get_limit_up_list"):
|
return cls.__get_limit_up_list(url)
|
|
elif url.startswith("/kpl/get_market_data"):
|
return cls.__get_market_data(url)
|
|
elif url.startswith("/get_last_trade_day_reasons"):
|
return cls.__get_last_trade_day_reasons(url)
|
|
elif url.startswith("/get_xgb_limit_up_reasons"):
|
return cls.__get_xgb_limit_up_reasons(url)
|
|
elif url.startswith("/get_kpl_market_feelings"):
|
return cls.__get_kpl_market_feelings()
|
|
return None, False
|
|
@classmethod
|
def __get_limit_up_list(cls, url):
|
# (代码, 名称, 首次涨停时间, 最近涨停时间, 几板, 涨停原因, 板块, 实际流通, 主力净额, 涨停原因代码, 涨停原因代码数量)
|
records = KPLLimitUpDataManager().get_limit_up_history_datas()
|
currents = KPLLimitUpDataManager().get_limit_up_current_datas()
|
current_codes = [d[0] for d in currents]
|
fresult = []
|
# 计算涨停时间排序
|
record_reason_dict = {}
|
current_reason_dict = {}
|
for r in records:
|
if r[5] not in record_reason_dict:
|
record_reason_dict[r[5]] = []
|
record_reason_dict[r[5]].append(r)
|
for r in currents:
|
if r[5] not in current_reason_dict:
|
current_reason_dict[r[5]] = []
|
current_reason_dict[r[5]].append(r)
|
|
for k in record_reason_dict:
|
record_reason_dict[k].sort(key=lambda x: x[2])
|
|
for r in records:
|
if r[0] in current_codes:
|
limit_up_state = 1
|
else:
|
limit_up_state = 2
|
rank = 0
|
for i in range(len(record_reason_dict[r[5]])):
|
if record_reason_dict[r[5]][i][0] == r[0]:
|
rank = i
|
# (代码, 名称, 涨停状态(0 - 无状态 1-涨停 2-炸板), 龙几, 首板, 分值, 涨停时间, 原因, 相同原因代码数量, 自由流通, 涨停原因是否变化,涨停原因的流入净额,下单简介)
|
fresult.append((r[0], r[1], limit_up_state, f"龙{rank + 1}", r[4], 0,
|
tool.time_format(int(r[2])), r[5], r[10], tool.money_desc(r[7]),
|
'', '', ''))
|
|
# (板块名称,涨停代码数量,炸板数量,涨停时间)
|
limit_up_reason_statistic_info = [(k, len(record_reason_dict[k]), len(record_reason_dict[k]) - len(
|
current_reason_dict.get(k) if k in current_reason_dict else []),
|
record_reason_dict[k][0][5]) for k in record_reason_dict]
|
limit_up_reason_statistic_info.sort(key=lambda x: x[1] - x[2])
|
limit_up_reason_statistic_info.reverse()
|
result = json.dumps({"code": 0, "data": {"limit_up_count": len(currents),
|
"open_limit_up_count": len(records) - len(currents),
|
"limit_up_reason_statistic": limit_up_reason_statistic_info,
|
"limit_up_codes": fresult}})
|
return result, True
|
|
@classmethod
|
def __get_market_data(cls, url):
|
ps_dict = dict([(k, v[0]) for k, v in parse_qs(urlparse(url).query).items()])
|
type_ = int(ps_dict['type'])
|
result = []
|
if type_ == 0:
|
# 行业,主力净额倒序
|
result = kpl_api.getMarketIndustryRealRankingInfo(True)
|
result = kpl_util.parseMarketIndustry(result)
|
elif type_ == 1:
|
# 行业,主力净额顺序
|
result = kpl_api.getMarketIndustryRealRankingInfo(False)
|
result = kpl_util.parseMarketIndustry(result)
|
elif type_ == 2:
|
# 精选,主力净额倒序
|
result = kpl_api.getMarketJingXuanRealRankingInfo(True)
|
result = kpl_util.parseMarketJingXuan(result)
|
elif type_ == 3:
|
# 精选,主力净额顺序
|
result = kpl_api.getMarketJingXuanRealRankingInfo(False)
|
result = kpl_util.parseMarketJingXuan(result)
|
fresult = []
|
forbidden_plates = []
|
for d in result:
|
d = list(d)
|
d.append(1 if d[1] in forbidden_plates else 0)
|
fresult.append(d)
|
response_data = json.dumps({"code": 0, "data": fresult})
|
return response_data, True
|
|
@classmethod
|
def get_codes_limit_rate(cls, codes):
|
return cls.__get_codes_limit_rate(codes)
|
|
# 获取昨日收盘价
|
__pre_close_cache = {}
|
|
@classmethod
|
def __get_codes_limit_rate(cls, codes):
|
latest_info_codes = set()
|
for code in codes:
|
if code not in cls.__pre_close_cache:
|
latest_info_codes.add(code)
|
if latest_info_codes:
|
datas = JueJinApi.get_gp_latest_info(latest_info_codes, fields="sec_id,pre_close")
|
for data in datas:
|
code = data["sec_id"]
|
pre_close = data['pre_close']
|
cls.__pre_close_cache[code] = pre_close
|
|
current_info = JueJinApi.get_gp_current_info(codes, fields="symbol,price")
|
now_prices = [(c["symbol"].split(".")[1], c["price"]) for c in current_info]
|
f_results = []
|
for data in now_prices:
|
code = data[0]
|
price = data[1]
|
pre_price = float(cls.__pre_close_cache.get(code))
|
rate = round((price - pre_price) * 100 / pre_price, 2)
|
f_results.append((code, rate))
|
f_results.sort(key=lambda tup: tup[1])
|
f_results.reverse()
|
return f_results
|
|
@classmethod
|
def __get_limit_rate_list(cls, codes):
|
if not codes:
|
return []
|
need_request_codes = set()
|
if tool.trade_time_sub(tool.get_now_time_str(), "09:30:00") < 0:
|
need_request_codes |= set(codes)
|
else:
|
now_time = time.time()
|
for c in codes:
|
if c not in cls.__code_limit_rate_dict:
|
need_request_codes.add(c)
|
elif now_time - cls.__code_limit_rate_dict[c][1] > 60:
|
need_request_codes.add(c)
|
if need_request_codes:
|
_limit_rate_list = cls.__get_codes_limit_rate(list(need_request_codes))
|
for d in _limit_rate_list:
|
cls.__code_limit_rate_dict[d[0]] = (d[1], time.time())
|
return [(c_, cls.__code_limit_rate_dict[c_][0]) for c_ in codes]
|
|
@classmethod
|
def __get_last_trade_day_reasons(cls, url):
|
# 获取 昨日涨停数据
|
ps_dict = dict([(k, v[0]) for k, v in parse_qs(urlparse(url).query).items()])
|
code = ps_dict["code"]
|
# 获取昨日涨停数据
|
day = JueJinApi.get_previous_trading_date_cache(tool.get_now_date_str())
|
# (代码, 名称, 首次涨停时间, 最近涨停时间, 几板, 涨停原因, 板块, 实际流通, 主力净额, 涨停原因代码, 涨停原因代码数量)
|
limit_up_records = KPLLimitUpDataManager().get_limit_up_history_datas_cache(day)
|
if not limit_up_records:
|
limit_up_records = []
|
reasons = []
|
for d in limit_up_records:
|
if d[0] == code:
|
reasons.append(d)
|
# 获取代码的原因
|
if reasons:
|
reasons = list(reasons)
|
reasons.sort(key=lambda x: x[9])
|
reason = reasons[-1][5]
|
# 获取涨停数据
|
datas = KPLLimitUpDataManager().get_limit_up_current_datas_cache(day)
|
# (代码,名称,首次涨停时间,最近涨停时间,几板,涨停原因,板块,实际流通,主力净额,涨停原因代码,涨停原因代码数量)
|
yesterday_result_list = []
|
percent_rate = 0
|
if datas:
|
yesterday_codes = set()
|
for d in datas:
|
if d[5] == reason:
|
yesterday_codes.add(d[0])
|
# 获取涨幅
|
limit_rate_list = cls.__get_limit_rate_list(yesterday_codes)
|
limit_rate_dict = {}
|
if limit_rate_list:
|
total_rate = 0
|
for d in limit_rate_list:
|
limit_rate_dict[d[0]] = d[1]
|
total_rate += d[1]
|
percent_rate = round(total_rate / len(limit_rate_list), 2)
|
|
for d in datas:
|
if d[5] == reason:
|
yesterday_codes.add(d[0])
|
if d[0] != code:
|
# (代码,名称, 涨幅)
|
yesterday_result_list.append((d[0], d[1], limit_rate_dict.get(d[0])))
|
|
current_limit_up_list = KPLLimitUpDataManager().get_limit_up_current_datas()
|
current_result_list = []
|
if current_limit_up_list:
|
for c in current_limit_up_list:
|
if c[5] == reason and c[0] != code:
|
current_result_list.append((c[0], c[1]))
|
response_data = json.dumps({"code": 0, "data": {"reason": reason, "reason_rate": percent_rate,
|
"data": {"yesterday": yesterday_result_list,
|
"current": current_result_list}}})
|
else:
|
response_data = json.dumps({"code": 1, "msg": "昨日未涨停"})
|
|
return response_data, True
|
|
@classmethod
|
def __get_xgb_limit_up_reasons(cls, url):
|
# 获取 昨日涨停数据
|
ps_dict = dict([(k, v[0]) for k, v in parse_qs(urlparse(url).query).items()])
|
code = ps_dict["code"]
|
reasons = xgb_api.get_code_limit_up_reasons(code)
|
if reasons:
|
response_data = json.dumps(
|
{"code": 0, "data": {"reasons": reasons[0], "description": reasons[1], "blocks": reasons[2],
|
"zylt": f"{reasons[3]}亿"}})
|
else:
|
response_data = json.dumps({"code": 1, "msg": "尚未获取到涨停原因"})
|
|
return response_data, True
|
|
@classmethod
|
def __get_kpl_market_feelings(cls):
|
market_feelings = kpl_api.getMarketFelling()
|
ps = [('涨停', market_feelings['ZT'], 'red')]
|
ps.append(('>%7', int(market_feelings['8']) + int(market_feelings['9']) + int(
|
market_feelings['10']), 'red'))
|
ps.append(('7~5%', int(market_feelings['6']) + int(market_feelings['7']), 'red'))
|
ps.append(('5~2%', int(market_feelings['3']) + int(market_feelings['4']) + int(market_feelings['5']), 'red'))
|
ps.append(('2~0%', int(market_feelings['2']) + int(market_feelings['1']), 'red'))
|
ps.append(('平', int(market_feelings['0']), 'gray'))
|
ps.append(('0~2%', int(market_feelings['-1']) + int(market_feelings['-2']), 'green'))
|
ps.append(
|
('2~5%', int(market_feelings['-3']) + int(market_feelings['-4']) + int(market_feelings['-5']), 'green'))
|
ps.append(('5~7%', int(market_feelings['-6']) + int(market_feelings['-7']), 'green'))
|
ps.append(
|
('7%<', int(market_feelings['-8']) + int(market_feelings['-9']) + int(market_feelings['-10']), 'green'))
|
ps.append(('跌停', market_feelings['DT'], 'green'))
|
fdata = {"map": ps, "SJZT": market_feelings['SJZT'], "SJDT": market_feelings['SJDT'],
|
"SZJS": market_feelings['SZJS'], "XDJS": market_feelings['XDJS'], "sign": market_feelings['sign']}
|
# 获取市场情绪
|
return json.dumps(
|
{"code": 0, "data": fdata}), True
|
|
|
if __name__ == "__main__":
|
codes = ["002523", "603095"]
|
datas = LocalKanPanNetworkDelegate.get_kpl_market_feelings(codes)
|
|
print(datas)
|