"""
|
首板目标代码处理器
|
"""
|
|
# 处理首板代码信息
|
|
import constant
|
from code_attribute import gpcode_manager, gpcode_first_screen_manager, code_nature_analyse, \
|
code_volumn_manager
|
from code_attribute.code_data_util import ZYLTGBUtil
|
from code_attribute.code_nature_analyse import HighIncreaseCodeManager
|
from code_attribute.gpcode_manager import WantBuyCodesManager
|
from log_module import async_log_util
|
from log_module.log import logger_first_code_record, logger_l2_codes_subscript, logger_debug
|
from third_data import history_k_data_manager
|
from third_data.code_plate_key_manager import CodesHisReasonAndBlocksManager
|
from third_data.history_k_data_manager import HistoryKDataManager
|
from third_data.history_k_data_util import HistoryKDatasUtils, JueJinApi
|
from ths import l2_code_operate
|
from trade import trade_data_manager, l2_trade_util
|
from settings.trade_setting import MarketSituationManager
|
from utils import global_util, tool, init_data_util, buy_condition_util
|
|
__CodesPlateKeysManager = CodesHisReasonAndBlocksManager()
|
|
|
def __is_normal_in_5d(code):
|
"""
|
最近5天是否处于正常状态
|
@param code:
|
@return:
|
"""
|
now_day = tool.get_now_date_str()
|
results = JueJinApi.get_history_instruments(JueJinApi.get_juejin_code_list_with_prefix([code]),
|
tool.date_sub(now_day, 30), tool.date_sub(now_day, 1))
|
results = results[-5:]
|
normal = True
|
for r in results:
|
if r["sec_level"] != 1:
|
normal = False
|
break
|
return normal
|
|
|
def process_first_codes_datas(dataList, request_id=None):
|
logger_l2_codes_subscript.info(f"{request_id}加载l2代码相关数据")
|
# 获取最近5天的交易日期,为后面的数据计算做准备
|
dates = HistoryKDatasUtils.get_latest_trading_date_cache(5)
|
latest_trading_date = None
|
if dates:
|
latest_trading_date = dates[0]
|
|
limit_up_price_dict = {}
|
temp_codes = []
|
codes = []
|
tick_datas = []
|
if dataList:
|
for data in dataList:
|
code = data["code"]
|
codes.append(code)
|
|
# ---查询想买单,如果没有在列表中就需要强行加入列表
|
want_codes = gpcode_manager.WantBuyCodesManager().list_code_cache()
|
if want_codes:
|
# 没有在现价采集中的想买代码
|
diff_codes = set(want_codes) - set(codes)
|
if diff_codes:
|
# 想买单的代码还没有在目标代码中
|
for code in diff_codes:
|
# 获取涨停价
|
_limit_up_price = gpcode_manager.get_limit_up_price(code)
|
if not _limit_up_price:
|
history_k_data_manager.re_set_price_pres([code], True)
|
# 再次获取涨停价
|
_limit_up_price = gpcode_manager.get_limit_up_price(code)
|
if _limit_up_price:
|
# 成功获取到了涨停价,构造虚拟的现价信息
|
codes.append(code)
|
dataList.append({"code": code, "price": f"{_limit_up_price}", "volume": "0",
|
"volumeUnit": 0, "time": "00:00:00", "zyltgb": "100",
|
"zyltgbUnit": 0})
|
# 获取昨日收盘价
|
need_get_limit_up_codes = set()
|
for code in codes:
|
# 如果涨停价是空值就需要设置昨日收盘价格
|
if gpcode_manager.get_limit_up_price(code) is None:
|
need_get_limit_up_codes.add(code)
|
if need_get_limit_up_codes:
|
history_k_data_manager.re_set_price_pres(list(need_get_limit_up_codes), True)
|
logger_l2_codes_subscript.info(f"{request_id}加载l2代码涨停价结束")
|
# 获取60天最大记录
|
for code in codes:
|
need_get_volumn = False
|
if code not in global_util.max60_volumn or global_util.max60_volumn.get(
|
code) is None or code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code) is None:
|
need_get_volumn = True
|
# if not need_get_volumn and code_nature_analyse.CodeNatureRecordManager.get_nature_cache(
|
# code) is None:
|
# need_get_volumn = True
|
if need_get_volumn:
|
limit_up_price = gpcode_manager.get_limit_up_price(code)
|
if limit_up_price is None:
|
continue
|
try:
|
# 首先从缓存里面获取
|
volumes_data = None
|
if latest_trading_date:
|
volumes_data = HistoryKDataManager().get_history_bars(code, latest_trading_date)
|
if not volumes_data:
|
volumes_data = init_data_util.get_volumns_by_code(code, 150)
|
async_log_util.info(logger_l2_codes_subscript, f"{request_id}从网络加载K线数据:{code}")
|
if not volumes_data:
|
continue
|
volumes = init_data_util.parse_max_volume(code, volumes_data[:90],
|
code_nature_analyse.is_new_top(code,
|
limit_up_price,
|
volumes_data[
|
:90]) or code_nature_analyse.is_near_top(
|
code,
|
limit_up_price,
|
volumes_data[:90]))
|
async_log_util.info(logger_first_code_record, f"{code} 获取到首板60天最大量:{volumes}")
|
code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1], volumes[2], volumes[3])
|
|
# 保存K线形态
|
k_format = code_nature_analyse.get_k_format(code, limit_up_price, volumes_data)
|
code_nature_analyse.CodeNatureRecordManager().save_k_format(code, k_format)
|
|
# 是否具有辨识度
|
is_special = True if k_format and k_format[8][0] else False
|
if not WantBuyCodesManager().is_in_cache(code):
|
if not is_special:
|
situation = MarketSituationManager().get_situation_cache()
|
zylt_threshold_as_yi = buy_condition_util.get_zyltgb_threshold(situation)
|
if global_util.zyltgb_map.get(code) and global_util.zyltgb_map.get(code) > zylt_threshold_as_yi[
|
1] * 100000000:
|
l2_trade_util.forbidden_trade(code,
|
f"无辨识度,自由流通市值({global_util.zyltgb_map.get(code) // 100000000})>{zylt_threshold_as_yi[1]}亿")
|
continue
|
elif limit_up_price and float(limit_up_price) >= constant.MAX_CODE_PRICE:
|
l2_trade_util.forbidden_trade(code,
|
f"无辨识度,涨停价({limit_up_price})>{constant.MAX_CODE_PRICE}")
|
continue
|
if code_nature_analyse.is_price_too_high_in_days(code, volumes_data, limit_up_price)[
|
0] and code.find("30") != 0:
|
# 判断是否太高
|
l2_trade_util.forbidden_trade(code, "6天内股价长得太高")
|
continue
|
pass
|
|
if len(k_format) > 14 and k_format[14]:
|
l2_trade_util.forbidden_trade(code, "昨日炸板")
|
continue
|
|
if code_nature_analyse.is_continue_limit_up_not_enough_fall_dwon(code, volumes_data):
|
# 判断是否太高
|
l2_trade_util.forbidden_trade(code, "回踩不够")
|
continue
|
try:
|
if not __is_normal_in_5d(code):
|
l2_trade_util.forbidden_trade(code, "最近5天有ST/非正常状态")
|
continue
|
except Exception as e:
|
logger_debug.error(f"{code}出错__is_normal_in_5d")
|
logger_debug.exception(e)
|
|
if code_nature_analyse.is_up_too_high_in_10d_with_limit_up(code, volumes_data):
|
# 判断是否太高
|
HighIncreaseCodeManager().add_code(code)
|
|
if code_nature_analyse.is_up_too_high_in_120d(code, volumes_data):
|
# 判断是否太高
|
# l2_trade_util.forbidden_trade(code, "120天内股价长得太高")
|
# HighIncreaseCodeManager().add_code(code)
|
pass
|
|
if code_nature_analyse.is_have_latest_max_volume(code, volumes_data, 2):
|
# 最近2天是否是最高量
|
code_nature_analyse.LatestMaxVolumeManager().set_has_latest_max_volume(code)
|
|
# 判断K线形态
|
# is_has_k_format, msg = code_nature_analyse.is_has_k_format(
|
# gpcode_manager.get_limit_up_price(code), volumes_data)
|
# if not is_has_k_format:
|
# logger_first_code_record.info("{}首板K线形态不好,{}", code, msg)
|
# # 股性不好,就不要加入
|
# bad_codes.add(code)
|
# # 加入禁止交易代码
|
# l2_trade_util.forbidden_trade(code)
|
# 暂时不保存K线形态
|
# code_nature_analyse.set_record_datas(code,
|
# gpcode_manager.get_limit_up_price(code),
|
# volumes_data)
|
except Exception as e:
|
logger_first_code_record.error(f"{request_id}-{code}:{str(e)}")
|
logger_first_code_record.exception(e)
|
|
async_log_util.info(logger_l2_codes_subscript, f"{request_id}加载l2代码K线结束")
|
|
gpcode_manager.FirstCodeManager().add_record(codes)
|
# 初始化板块信息,暂时删除
|
# for code in codes:
|
# block_info.init_code(code)
|
# 保存现价
|
if dataList:
|
situation = MarketSituationManager().get_situation_cache()
|
zyltgb_thresholds = buy_condition_util.get_zyltgb_threshold(situation)
|
want_codes = gpcode_manager.WantBuyCodesManager().list_code_cache()
|
for data in dataList:
|
code = data["code"]
|
codes.append(code)
|
limit_up_price = gpcode_manager.get_limit_up_price(code)
|
if limit_up_price is not None:
|
limit_up_price_dict[code] = limit_up_price
|
else:
|
temp_codes.append(code)
|
# 自由流通市值不符合标准
|
if not want_codes or code not in want_codes:
|
# 没在想买单
|
zyltgb = global_util.zyltgb_map.get(code)
|
if zyltgb:
|
zyltgb_as_yi = round(zyltgb / 100000000, 2)
|
if zyltgb_as_yi < zyltgb_thresholds[0] or zyltgb_as_yi > zyltgb_thresholds[6]:
|
# 想买单中的不能排除
|
continue
|
elif zyltgb_as_yi > zyltgb_thresholds[1]:
|
# 比最大可买大的,如果没有短期辨识度就不买
|
k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code)
|
if k_format and k_format[8][0] and k_format[8][1].find("短期") >= 0:
|
pass
|
else:
|
# 无短期辨识度
|
continue
|
|
tick_datas.append({"code": code, "price": data["price"], "volume": data["volume"],
|
"volumeUnit": data["volumeUnit"]})
|
# 获取涨停价
|
if temp_codes:
|
# 获取涨停价
|
history_k_data_manager.re_set_price_pres(temp_codes)
|
# 重新获取涨停价
|
for code in temp_codes:
|
limit_up_price = gpcode_manager.get_limit_up_price(code)
|
if limit_up_price is not None:
|
limit_up_price_dict[code] = limit_up_price
|
|
# 首板数据加工
|
prices = []
|
for data in dataList:
|
code = data["code"]
|
price = data["price"]
|
limit_up_time = data["time"]
|
if limit_up_time == "00:00:00":
|
limit_up_time = None
|
if code not in limit_up_price_dict:
|
continue
|
is_limit_up = abs(float(limit_up_price_dict[code]) - float(price)) < 0.001
|
# 纠正数据
|
if is_limit_up and limit_up_time is None:
|
limit_up_time = tool.get_now_time_str()
|
pricePre = gpcode_manager.CodePrePriceManager.get_price_pre_cache(code)
|
if pricePre is None:
|
history_k_data_manager.re_set_price_pres([code])
|
|
rate = round((float(price) - pricePre) * 100 / pricePre, 1)
|
prices.append(
|
{"code": code, "time": limit_up_time, "rate": rate,
|
"limit_up": is_limit_up})
|
|
gpcode_first_screen_manager.process_ticks(prices)
|
async_log_util.info(logger_l2_codes_subscript, f"({request_id})l2代码相关数据加载完成")
|
return tick_datas
|