| | |
| | | from third_data.history_k_data_manager import HistoryKDataManager |
| | | from third_data.history_k_data_util import HistoryKDatasUtils |
| | | from third_data.kpl_data_constant import LimitUpDataConstant |
| | | from trade.radical_buy_data_manager import RedicalBuyDataManager |
| | | from utils import global_util, tool, buy_condition_util, init_data_util |
| | | from log_module import log, async_log_util |
| | | from db import redis_manager_delegate as redis_manager |
| | |
| | | kpl_data_constant.open_limit_up_code_dict_for_radical_buy = temp_dict |
| | | |
| | | @classmethod |
| | | def __get_current_index(cls, code, block, yesterday_limit_up_codes): |
| | | def __get_current_index(cls, code, block, yesterday_limit_up_codes, exclude_codes=None): |
| | | """ |
| | | 获取当前涨停身位 |
| | | @param code: |
| | |
| | | @param yesterday_limit_up_codes: |
| | | @return: 索引,前排代码信息([(代码, 涨停时间)]) |
| | | """ |
| | | if exclude_codes is None: |
| | | exclude_codes = set() |
| | | current_index = 0 |
| | | block_codes_infos = [] |
| | | timestamp_start, timestamp_end = kpl_block_util.open_limit_up_time_range |
| | | limit_up_time = time.time() |
| | | for k in LimitUpDataConstant.current_limit_up_datas: |
| | | _code = k[0] |
| | | if _code in exclude_codes: |
| | | continue |
| | | blocks = LimitUpDataConstant.get_blocks_with_history(_code) |
| | | if not blocks: |
| | | blocks = set() |
| | |
| | | return current_index, before_codes_info |
| | | |
| | | @classmethod |
| | | def __get_history_index(cls, code, block, yesterday_limit_up_codes): |
| | | def __get_history_index(cls, code, block, yesterday_limit_up_codes, exclude_codes=None): |
| | | """ |
| | | 获取历史涨停身位 |
| | | @param code: |
| | |
| | | @param current_limit_up_codes: 目前的涨停代码 |
| | | @return: |
| | | """ |
| | | if exclude_codes is None: |
| | | exclude_codes = set() |
| | | history_index = 0 |
| | | block_codes_infos = [] |
| | | # 开1时间范围 |
| | | timestamp_start, timestamp_end = kpl_block_util.open_limit_up_time_range |
| | | limit_up_time = time.time() |
| | | limit_up_space_ge_60s_codes = set() |
| | | for k in LimitUpDataConstant.history_limit_up_datas: |
| | | _code = k[3] |
| | | if _code in exclude_codes: |
| | | continue |
| | | blocks = LimitUpDataConstant.get_blocks_with_history(_code) |
| | | if _code == code: |
| | | # 获取当前代码涨停时间 |
| | |
| | | # 剔除高位板 |
| | | if _code in yesterday_limit_up_codes: |
| | | continue |
| | | # 剔除炸板代码持续涨停时间小于1分钟的代码 |
| | | # 剔除炸板代码持续涨停时间小于1分钟的代码 且 只能用于不排除前2条数据 |
| | | if _code not in cls.__current_limit_up_codes and _code in cls.__total_limit_up_space_dict and \ |
| | | cls.__total_limit_up_space_dict[_code] < 60: |
| | | cls.__total_limit_up_space_dict[_code] < 60 and not exclude_codes and len( |
| | | limit_up_space_ge_60s_codes) < 3: |
| | | limit_up_space_ge_60s_codes.add(_code) |
| | | continue |
| | | # 代码,涨停时间 |
| | | block_codes_infos.append((_code, int(k[5]))) |
| | |
| | | @param yesterday_limit_up_codes 昨日涨停代码 |
| | | @return: |
| | | """ |
| | | # 9:45点之前才能买入 |
| | | if not constant.TEST: |
| | | if int(tool.get_now_time_str().replace(":", "")) > 94500: |
| | | return False, "超过生效时间" |
| | | |
| | | # 9:45点之前涨停的才能买入 |
| | | # 获取当前代码的涨停时间 |
| | | limit_up_timestamp = LimitUpDataConstant.get_first_limit_up_time(code) |
| | | if not limit_up_timestamp: |
| | | limit_up_timestamp = time.time() |
| | | if int(tool.timestamp_format(limit_up_timestamp, "%H%M%S")) > 94500: |
| | | return False, "超过生效时间" |
| | | # 根据板块聚合数据 |
| | | open_limit_up_block_codes_dict = {} |
| | | for c in kpl_data_constant.open_limit_up_code_dict_for_radical_buy: |
| | |
| | | history_index, history_before_codes_info = cls.__get_history_index(code, block, yesterday_limit_up_codes) |
| | | # ----获取实时身位---- |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, yesterday_limit_up_codes) |
| | | exclude_codes = set() |
| | | if count >= 2 or ( |
| | | count == 1 and kpl_data_constant.open_limit_up_code_dict_for_radical_buy[open_limit_up_block_codes[0]][ |
| | | 0] == 2): |
| | | # 开始数量大于2个或者只有一个2板开1 |
| | | if history_index == 0 and current_index == 0: |
| | | return True, f"开1数量:{count}" |
| | | else: |
| | | return False, f"开1数量:{count},非开1首板身位不匹配:历史-{history_index + 1} 实时-{current_index + 1}" |
| | | exclude_codes.clear() |
| | | else: |
| | | # 买老3 |
| | | if history_index == 1 and current_index == 1: |
| | | return True, f"开1数量:{count}" |
| | | # 获取包含高位板的身位 |
| | | # ----获取历史身位---- |
| | | history_index, history_before_codes_info = cls.__get_history_index(code, block, set()) |
| | | # ----获取实时身位---- |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, set()) |
| | | if history_before_codes_info and current_before_codes_info and history_before_codes_info[0][0] == \ |
| | | current_before_codes_info[0][0]: |
| | | # 前排第一个元素无炸板 |
| | | exclude_codes = {history_before_codes_info[0][0]} |
| | | else: |
| | | return False, f"开1数量:{count},非开1首板身位不匹配:历史-{history_index + 1} 实时-{current_index + 1}" |
| | | return False, f"开1数量:{count},历史-{history_index + 1} 实时-{current_index + 1}" |
| | | |
| | | # 获取主板的身位 |
| | | history_index, history_before_codes_info = cls.__get_history_index(code, block, |
| | | yesterday_limit_up_codes, |
| | | exclude_codes=exclude_codes) |
| | | # 买首板老大/老二 |
| | | # 首板老大不能买时可买老二 |
| | | if history_index > 1: |
| | | return False, f"开1数量:{count},非开1首板身位不匹配:历史-{history_index + 1} 实时-{current_index + 1}" |
| | | if history_index == 1: |
| | | # 当前代码为老2,要判断老大是否可买 |
| | | if RedicalBuyDataManager.can_buy(history_before_codes_info[0][0])[0]: |
| | | return False, f"开1数量:{count},前排代码可买:{history_before_codes_info[0]}" |
| | | return True, f"开1数量:{count},前排代码不可买:{history_before_codes_info[0]}" |
| | | return True, f"开1数量:{count},历史-{history_index + 1} 实时-{current_index + 1}" |
| | | |
| | | @classmethod |
| | | def __is_radical_buy_with_block_up(cls, code, block, yesterday_limit_up_codes): |
| | | """ |
| | | 是否激进买(板块突然涨起来) |
| | | 老大和老二的涨停时间相差5分钟内 |
| | | 老三的涨停时间距离老大涨停在10分钟内就买 |
| | | 1.老大和老二的涨停时间相差5分钟内 |
| | | 2.老三的涨停时间距离老大涨停在10分钟内就买 |
| | | 3.前2个票不能炸板(历史身位与现在身位一致) |
| | | 4.除开前两个代码可买老1与老2 |
| | | 5.买老2的情况:老1不满足买入条件 |
| | | |
| | | @param code: |
| | | @param block: |
| | | @param yesterday_limit_up_codes: |
| | |
| | | """ |
| | | # 获取当前的板块 |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, set()) |
| | | current_before_codes = [x[0] for x in current_before_codes_info] |
| | | |
| | | if len(current_before_codes_info) < 2: |
| | | return False, f"前排代码小于2个" |
| | | if current_before_codes_info[0][1] >= kpl_block_util.open_limit_up_time_range[1]: |
| | | return False, f"有开1" |
| | | if current_index != 2: |
| | | return False, f"只能买老3,当前身位-{current_index + 1}" |
| | | history_index, history_before_codes_info = cls.__get_history_index(code, block, set()) |
| | | if history_index != current_index or len(current_before_codes_info) != len(history_before_codes_info): |
| | | return False, f"前排代码有炸板" |
| | | return False, f"前排代码小于2个:{current_before_codes_info}" |
| | | if current_before_codes_info[0][1] < kpl_block_util.open_limit_up_time_range[1]: |
| | | return False, f"有开1:{current_before_codes_info}" |
| | | |
| | | # 老大,老二必须相隔5分钟内 |
| | | if current_before_codes_info[1][1] - current_before_codes_info[0][1] < 5 * 60: |
| | | # 获取当前代码的涨停时间 |
| | | limit_up_timestamp = LimitUpDataConstant.get_first_limit_up_time(code) |
| | | if not limit_up_timestamp: |
| | | limit_up_timestamp = time.time() |
| | | if limit_up_timestamp - current_before_codes_info[0][1] < 10 * 60: |
| | | return True, f"前排涨停:{current_before_codes_info}" |
| | | return False, "前排涨停时间间隔不满足条件" |
| | | if current_before_codes_info[1][1] - current_before_codes_info[0][1] >= 5 * 60: |
| | | return False, f"老大老二涨停时间必须间隔5分钟内" |
| | | |
| | | # 获取当前代码的涨停时间 |
| | | limit_up_timestamp = LimitUpDataConstant.get_first_limit_up_time(code) |
| | | if not limit_up_timestamp: |
| | | limit_up_timestamp = time.time() |
| | | if limit_up_timestamp - current_before_codes_info[0][1] >= 10 * 60: |
| | | return False, f"距离老大涨停已过去10分钟({current_before_codes_info[0]})" |
| | | |
| | | history_index, history_before_codes_info = cls.__get_history_index(code, block, set()) |
| | | history_before_codes = [x[0] for x in history_before_codes_info] |
| | | |
| | | # 前两个代码是否有炸板 |
| | | dif_codes = set(history_before_codes[:2]) - set(current_before_codes[:2]) |
| | | if dif_codes: |
| | | return False, f"前2代码有炸板:{dif_codes}" |
| | | # 不计算前2的代码 |
| | | exclude_codes = set(current_before_codes[:2]) |
| | | history_index, history_before_codes_info = cls.__get_history_index(code, block, yesterday_limit_up_codes, |
| | | exclude_codes) |
| | | if history_index > 1: |
| | | return False, f"排除前2,目标代码位于历史身位-{history_index + 1},前排代码:{history_before_codes_info}" |
| | | if history_index == 1: |
| | | # 首板老2,判断前面的老大是否是属于不能买的范畴 |
| | | pre_code = history_before_codes_info[0][0] |
| | | # pre_code不能买,才能买 |
| | | if RedicalBuyDataManager.can_buy(pre_code)[0]: |
| | | return False, f"前排代码可买:{pre_code}" |
| | | return True, "满足买入需求" |
| | | |
| | | @classmethod |
| | | def is_radical_buy(cls, code, yesterday_limit_up_codes): |
| | |
| | | result = cls.__is_radical_buy_with_open_limitup(code, b, yesterday_limit_up_codes) |
| | | if result[0]: |
| | | can_buy_blocks.add(b) |
| | | msges.append(f"【{b}】:{result}") |
| | | msges.append(f"【{b}】:{result[1]}") |
| | | fmsges.append("开1判断##" + ",".join(msges)) |
| | | if not can_buy_blocks: |
| | | msges.clear() |
| | | for b in match_blocks: |
| | | for b in keys_: |
| | | # 板块快速启动 |
| | | result = cls.__is_radical_buy_with_block_up(code, b, yesterday_limit_up_codes) |
| | | if result[0]: |
| | | can_buy_blocks.add(b) |
| | | msges.append(f"【{b}】:{result}") |
| | | msges.append(f"【{b}】:{result[1]}") |
| | | fmsges.append("板块快速启动判断##" + ",".join(msges)) |
| | | return can_buy_blocks, " **** ".join(fmsges) |
| | | |