| | |
| | | import copy |
| | | import logging |
| | | import threading |
| | | import time |
| | | import time as t |
| | | |
| | | from cancel_strategy.s_l_h_cancel_strategy import HourCancelBigNumComputer, LCancelRateManager |
| | |
| | | from l2.place_order_single_data_manager import L2TradeSingleDataProcessor |
| | | from log_module import async_log_util, log_export |
| | | from third_data import kpl_data_manager, block_info |
| | | from third_data.kpl_data_constant import LimitUpDataConstant |
| | | from trade.buy_radical.block_special_codes_manager import BlockSpecialCodesManager |
| | | from trade.buy_radical.radical_buy_data_manager import EveryLimitupBigDealOrderManager |
| | | from utils import global_util, tool, buy_condition_util, buy_strategy_util, trade_util |
| | | import l2_data_util |
| | |
| | | from trade import trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \ |
| | | trade_result_manager, current_price_process_manager, trade_data_manager, trade_huaxin, trade_record_log_util, \ |
| | | trade_constant, buy_open_limit_up_strategy |
| | | from trade.buy_radical import radical_buy_data_manager |
| | | from trade.buy_radical import radical_buy_data_manager, radical_buy_strategy |
| | | from l2 import l2_data_manager, l2_log, l2_data_source_util, code_price_manager, \ |
| | | transaction_progress, cancel_buy_strategy, place_order_single_data_manager |
| | | from l2.cancel_buy_strategy import DCancelBigNumComputer, \ |
| | |
| | | num_splites = [round(5000 / limit_up_price), round(10000 / limit_up_price), round(20000 / limit_up_price), |
| | | round(30000 / limit_up_price)] |
| | | total_num = 0 |
| | | buyno_map = local_today_buyno_map.get(code) |
| | | for i in range(max(start_index, processed_index), end_index + 1): |
| | | data = total_datas[i] |
| | | if not L2DataUtil.is_limit_up_price_buy_cancel(data["val"]) and not L2DataUtil.is_limit_up_price_buy( |
| | |
| | | if L2DataUtil.is_limit_up_price_buy_cancel(data["val"]): |
| | | # 获取买入信号 |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i], |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | buyno_map) |
| | | if buy_index is not None and buy_index < begin_pos: |
| | | continue |
| | | |
| | |
| | | |
| | | # print("m值大单计算范围:{}-{} 时间:{}".format(max(start_index, processed_index), end_index, |
| | | # round(t.time() * 1000) - start_time)) |
| | | |
| | | |
| | | class HumanRadicalBuySingleManager: |
| | | """ |
| | | 人为买入管理 |
| | | """ |
| | | # 人为下单标记:{"代码":(信号时间, 间隔时间,信号截至时间, radical_result)} |
| | | __human_radical_buy_mark_info = {} |
| | | |
| | | @classmethod |
| | | def add_single(cls, code, latest_data, radical_result): |
| | | """ |
| | | 添加买入信号 |
| | | @param code: |
| | | @param latest_data: |
| | | @param radical_result: |
| | | @return: |
| | | """ |
| | | start_time_with_ms = L2DataUtil.get_time_with_ms(latest_data["val"]) |
| | | if tool.is_sh_code(code): |
| | | cls.__human_radical_buy_mark_info[code] = ( |
| | | start_time_with_ms, 400, tool.trade_time_add_millionsecond(start_time_with_ms, 3000), radical_result) |
| | | else: |
| | | cls.__human_radical_buy_mark_info[code] = ( |
| | | start_time_with_ms, 30, tool.trade_time_add_millionsecond(start_time_with_ms, 2000), radical_result) |
| | | |
| | | @classmethod |
| | | def remove_single(cls, code): |
| | | """ |
| | | 移除信号 |
| | | @param code: |
| | | @return: |
| | | """ |
| | | if code in cls.__human_radical_buy_mark_info: |
| | | cls.__human_radical_buy_mark_info.pop(code) |
| | | |
| | | @classmethod |
| | | def has_single(cls, code): |
| | | """ |
| | | 是否有信号 |
| | | @param code: |
| | | @return: |
| | | """ |
| | | if code in cls.__human_radical_buy_mark_info: |
| | | return True |
| | | |
| | | @classmethod |
| | | def is_valid(cls, code, data): |
| | | """ |
| | | 信号是否有效 |
| | | @param code: |
| | | @return: 是否有效,无效消息/有效对象 |
| | | """ |
| | | if code not in cls.__human_radical_buy_mark_info: |
| | | return False, "没有人买入信号" |
| | | single_time_ms, space_time_ms, expire_time_ms, _ = cls.__human_radical_buy_mark_info[code] |
| | | now_time_ms = L2DataUtil.get_time_with_ms(data["val"]) |
| | | if tool.trade_time_sub_with_ms(now_time_ms, |
| | | expire_time_ms) > 0: |
| | | cls.__human_radical_buy_mark_info.pop(code) |
| | | async_log_util.info(logger_l2_not_buy_reasons, f"{code}#大单足够,人为下单: 超过信号生效时间-{now_time_ms}/{expire_time_ms}") |
| | | return False, "超过信号生效时间" |
| | | return True, cls.__human_radical_buy_mark_info[code] |
| | | |
| | | |
| | | class L2TradeDataProcessor: |
| | |
| | | cls.unreal_buy_dict.pop(code) |
| | | |
| | | @classmethod |
| | | def set_real_place_order_index(cls, code, index, order_begin_pos: OrderBeginPosInfo): |
| | | def set_real_place_order_index(cls, code, index, order_begin_pos: OrderBeginPosInfo, last_data): |
| | | trade_record_log_util.add_real_place_order_position_log(code, index, order_begin_pos.buy_single_index) |
| | | total_datas = local_today_datas.get(code) |
| | | use_time = tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(total_datas[index]["val"]), |
| | | L2DataUtil.get_time_with_ms( |
| | | total_datas[order_begin_pos.buy_exec_index]["val"])) |
| | | trade_record_log_util.add_place_order_use_time(code, |
| | | f"执行位时间:{L2DataUtil.get_time_with_ms(total_datas[order_begin_pos.buy_exec_index]['val'])} 耗时:{use_time}") |
| | | l2_log.debug(code, "设置真实下单位:{}", index) |
| | | cancel_buy_strategy.set_real_place_position(code, index, order_begin_pos.buy_single_index, is_default=False) |
| | | # 获取真实下单位置之后需要判断F撤 |
| | |
| | | limit_up_price = round(float(limit_up_price), 2) |
| | | # if trade_price_info and limit_up_price and trade_price_info[0] == limit_up_price: |
| | | # filter_limit_up_sell = True |
| | | L2LimitUpSellDataManager.add_l2_origin_data(code, origin_datas) |
| | | |
| | | datas = l2_huaxin_util.get_format_l2_datas(code, origin_datas, limit_up_price, _start_index, |
| | | filter_limit_up_sell) |
| | | L2LimitUpSellDataManager.add_l2_data(code, datas) |
| | | __start_time = round(t.time() * 1000) |
| | | if len(datas) > 0: |
| | | cls.process_add_datas(code, datas, 0, __start_time) |
| | |
| | | finally: |
| | | if datas: |
| | | l2.l2_data_util.save_l2_data(code, None, datas) |
| | | origin_datas.clear() |
| | | # origin_datas.clear() |
| | | |
| | | @classmethod |
| | | def __recompute_real_order_index(cls, code, pre_real_order_index, order_info, compute_type): |
| | | # 因为数据慢的问题重新计算 |
| | | real_order_index = huaxin_delegate_postion_manager.recompute_for_slow_time(code, order_info, |
| | | pre_real_order_index, compute_type) |
| | | if real_order_index: |
| | | # 1s之后重新计算 |
| | | time.sleep(1) |
| | | real_order_index = huaxin_delegate_postion_manager.RealDelegateOrderPositionManager().recompute_l2_place_order_position( |
| | | code, order_info, pre_real_order_index, compute_type) |
| | | if real_order_index and pre_real_order_index != real_order_index: |
| | | try: |
| | | exec_index = order_info[6] |
| | | exec_index = order_info[3] |
| | | order_begin_pos = cls.__get_order_begin_pos( |
| | | code) |
| | | async_log_util.info(logger_debug, |
| | | f"下单位矫正:真实下单位-{real_order_index} 订单信息-{order_info} 下单信息-{order_begin_pos.to_dict()}") |
| | | if order_begin_pos and order_begin_pos.buy_exec_index == exec_index: |
| | | cls.set_real_place_order_index(code, real_order_index, order_begin_pos) |
| | | cls.set_real_place_order_index(code, real_order_index, order_begin_pos, order_info[1]) |
| | | async_log_util.info(logger_real_place_order_position, |
| | | f"真实下单位置矫正:{code}-({real_order_index},1)") |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | async_log_util.error(logger_debug, f"重新寻找真实下单位异常:{code}-{order_info}") |
| | | |
| | | @classmethod |
| | | def process_add_datas(cls, code, add_datas, capture_timestamp, __start_time): |
| | | now_time_str = tool.get_now_time_str() |
| | | # 将本次中断设置为 |
| | | cls.__break_current_batch_data_for_buy_dict[code] = False |
| | | if len(add_datas) > 0: |
| | | if add_datas: |
| | | # 记录当前批数据的索引 |
| | | cls.__processing_data_indexes[code] = (add_datas[0]["index"], add_datas[-1]["index"]) |
| | | if code not in cls.__trade_log_placr_order_info_dict: |
| | |
| | | buy_open_limit_up_strategy.BuyOpenLimitupDataManager().remove_place_order_info(code) |
| | | |
| | | # 获取下单位置 |
| | | place_order_index, order_info, compute_type = huaxin_delegate_postion_manager.get_l2_place_order_position( |
| | | code, float( |
| | | gpcode_manager.get_limit_up_price(code)), add_datas) |
| | | |
| | | if constant.IS_NEW_VERSION_PLACE_ORDER: |
| | | place_order_index, order_info, compute_type = huaxin_delegate_postion_manager.RealDelegateOrderPositionManager.compute_l2_place_order_position( |
| | | code, add_datas) |
| | | else: |
| | | place_order_index, order_info, compute_type = huaxin_delegate_postion_manager.get_l2_place_order_position( |
| | | code, float( |
| | | gpcode_manager.get_limit_up_price(code)), add_datas) |
| | | |
| | | if place_order_index: |
| | | order_begin_pos = cls.__get_order_begin_pos( |
| | | code) |
| | | cls.set_real_place_order_index(code, place_order_index, order_begin_pos) |
| | | cls.set_real_place_order_index(code, place_order_index, order_begin_pos, order_info[1]) |
| | | try: |
| | | cls.__re_compute_threading_pool.submit( |
| | | cls.__recompute_real_order_index, code, place_order_index, order_info, compute_type) |
| | | cls.__recompute_real_order_index, code, place_order_index, order_info, |
| | | compute_type) |
| | | except: |
| | | pass |
| | | async_log_util.info(logger_l2_process, f"code:{code} 获取到下单真实位置:{place_order_index}") |
| | |
| | | b_need_cancel, b_cancel_data, extra_msg = RDCancelBigNumComputer().need_cancel(code, start_index, |
| | | end_index) |
| | | if b_need_cancel and b_cancel_data: |
| | | big_order_info = radical_buy_data_manager.get_total_deal_big_order_info(code, |
| | | gpcode_manager.get_limit_up_price_as_num( |
| | | code)) |
| | | if big_order_info[0]>0: |
| | | big_order_info = radical_buy_data_manager.get_total_deal_big_order_info(code, |
| | | gpcode_manager.get_limit_up_price_as_num( |
| | | code)) |
| | | if big_order_info[0] > 0: |
| | | return b_cancel_data, f"RD撤({extra_msg})", trade_constant.CANCEL_TYPE_RD |
| | | except Exception as e: |
| | | async_log_util.error(logger_l2_error, |
| | |
| | | now_time_int = int(tool.get_now_time_str().replace(":", "")) |
| | | if now_time_int >= 145700: |
| | | return False, True, f"14:57后不能交易", True |
| | | if now_time_int < 93100: |
| | | return False, True, f"09:31之前不能交易", True |
| | | # if now_time_int < 93100: |
| | | # return False, True, f"09:31之前不能交易", True |
| | | # 二板以上的票不买 |
| | | yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes() |
| | | if yesterday_codes and code in yesterday_codes: |
| | |
| | | if not cls.__WantBuyCodesManager.is_in_cache( |
| | | code) and not gpcode_manager.GreenListCodeManager().is_in_cache(code): |
| | | return False, True, f"只买想买:没在想买单和绿单", True |
| | | if not cls.__WantBuyCodesManager.is_in_cache(code): |
| | | average_rate = cls.__Buy1PriceManager.get_average_rate(code) |
| | | if average_rate and average_rate <= 0.05: |
| | | return False, True, f"均价涨幅({average_rate})小于5%", True |
| | | if cls.__TradeTargetCodeModeManager.get_mode_cache() == TradeTargetCodeModeManager.MODE_ONLY_BUY_SPECIAL_CODES: |
| | | special_blocks = BlockSpecialCodesManager().get_code_blocks(code) |
| | | if not special_blocks: |
| | | return False, True, f"只买辨识度", True |
| | | # if not cls.__WantBuyCodesManager.is_in_cache(code): |
| | | average_rate = cls.__Buy1PriceManager.get_average_rate(code) |
| | | if average_rate: |
| | | if tool.is_ge_code(code): |
| | | if average_rate < 0.08: |
| | | return False, True, f"均价涨幅({average_rate})小于8%", True |
| | | else: |
| | | if average_rate < 0.04: |
| | | return False, True, f"均价涨幅({average_rate})小于4%", True |
| | | |
| | | return True, False, f"", False |
| | | |
| | |
| | | params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc() |
| | | l2_log.debug(code, params_desc) |
| | | #################清除本次下单的大单数据############### |
| | | EveryLimitupBigDealOrderManager.clear(code) |
| | | EveryLimitupBigDealOrderManager.clear(code, "下单成功") |
| | | ############记录下单时的数据############ |
| | | try: |
| | | jx_blocks, jx_blocks_by = KPLCodeJXBlockManager().get_jx_blocks_cache( |
| | |
| | | def __buy(cls, code, capture_timestamp, last_data, last_data_index, is_first_code, block_info=None): |
| | | pre_result = cls.__is_pre_can_buy(code) |
| | | if not pre_result[0]: |
| | | async_log_util.info(logger_l2_not_buy_reasons, f"{code}#{pre_result[2]}") |
| | | return False |
| | | # 添加买入锁 |
| | | if code not in cls.__buy_lock_dict: |
| | |
| | | local_today_datas.get(code)) |
| | | return False |
| | | else: |
| | | l2_log.debug(code, "可以下单,原因:{}, 下单模式:{}", reason, order_begin_pos.mode) |
| | | |
| | | try: |
| | | |
| | | # 判断是否为首封下单 |
| | | order_begin_pos.first_limit_up_buy = radical_buy_data_manager.is_first_limit_up_buy(code) |
| | | |
| | | if not constant.CAN_BUY_FIRST_LIMIT_UP and order_begin_pos.first_limit_up_buy: |
| | | reason = "首封不下单" |
| | | l2_log.debug(code, "不可以下单,原因:{}", reason) |
| | | trade_record_log_util.add_cant_place_order_log(code, reason) |
| | | cls.__break_current_batch_data_for_buy_dict[code] = True |
| | | trade_result_manager.real_cancel_success(code, order_begin_pos.buy_single_index, |
| | | order_begin_pos.buy_exec_index, |
| | | local_today_datas.get(code)) |
| | | return False |
| | | l2_log.debug(code, "可以下单,原因:{}, 下单模式:{}", reason, order_begin_pos.mode) |
| | | l2_log.debug(code, "开始执行买入") |
| | | trade_manager.start_buy(code, capture_timestamp, last_data, |
| | | last_data_index, order_begin_pos.mode, order_begin_pos.buy_exec_index) |
| | |
| | | is_limit_up_buy = False |
| | | return is_limit_up_buy |
| | | |
| | | @classmethod |
| | | def __is_big_order_deal_enough(cls, code): |
| | | """ |
| | | 大单成交是否足够 |
| | | @param code: |
| | | @param volume_rate: |
| | | @return: |
| | | """ |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | refer_volume = code_volumn_manager.CodeVolumeManager().get_max_volume_in_5days(code) |
| | | if refer_volume is None: |
| | | refer_volume = 0 |
| | | |
| | | money_y = int(refer_volume * limit_up_price / 1e8) |
| | | money_y = min(money_y, 50) |
| | | money_y = max(money_y, 5) |
| | | # 计算大单参考数量 |
| | | threshold_count = int(round(0.4 * money_y)) * 4 |
| | | threshold_money = threshold_count * 299 * 10000 |
| | | volume_rate_info = cls.volume_rate_info.get(code) |
| | | |
| | | deal_big_order_money = BigOrderDealManager().get_total_buy_money(code) |
| | | if deal_big_order_money >= threshold_money: |
| | | return True, f"量比-{volume_rate_info}, 总大单成交金额({deal_big_order_money})>={threshold_money}" |
| | | else: |
| | | return False, f"量比-{volume_rate_info}, 总大单成交金额({deal_big_order_money})<{threshold_money}" |
| | | |
| | | @classmethod |
| | | def __can_buy_first(cls, code): |
| | | """ |
| | | 是否可以下单 |
| | | @param code: |
| | | @return:(是否可以下单, 是否清理信号数据, 不能下单消息, 是否算有效执行) |
| | | """ |
| | | |
| | | pre_result = cls.__is_pre_can_buy(code) |
| | | if not pre_result[0]: |
| | | return pre_result[0], pre_result[1], pre_result[2], pre_result[3] |
| | | |
| | | now_time_int = int(tool.get_now_time_str().replace(":", "")) |
| | | if 130100 >= now_time_int >= 112900 or now_time_int < 93100: |
| | | if now_time_int < 93100: |
| | | # 判断近120天是否有涨停 |
| | | k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code) |
| | | if k_format and len(k_format) >= 12 and not k_format[11]: |
| | | return False, True, f"09:31:00之前下单,90个交易日无涨停", True |
| | | |
| | | # 判断成交的大单数量 |
| | | data_list = BigOrderDealManager().get_total_buy_money_list(code) |
| | | bigger_money = 2990000 |
| | | fdatas = [] |
| | | for d in data_list: |
| | | if d < bigger_money: |
| | | continue |
| | | fdatas.append(d) |
| | | thresh_count = 3 if tool.is_sh_code(code) else 1 |
| | | if len(fdatas) < thresh_count: |
| | | return False, True, f"09:31:00之前下单,成交大单数量({len(fdatas)})不足{thresh_count}个", True |
| | | else: |
| | | # 判断数据是否卡 |
| | | total_datas = local_today_datas.get(code) |
| | | if tool.trade_time_sub_with_ms(tool.get_now_time_with_ms_str(), |
| | | L2DataUtil.get_time_with_ms(total_datas[-1]["val"])) > 500: |
| | | return False, True, f"09:31:00之前下单,L2数据时间相差500ms以上", True |
| | | else: |
| | | return False, True, f"09:31:00之前,11:29:00-13:01:00不能交易", True |
| | | |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | |
| | | if constant.MIN_CODE_PRICE < limit_up_price < constant.MAX_CODE_PRICE: |
| | | # 满足条件的单价 |
| | | pass |
| | | elif limit_up_price > constant.MAX_CODE_PRICE: |
| | | # HighIncreaseCodeManager().add_code(code) |
| | | # 小市值高股价可买 |
| | | zyltgb = global_util.zyltgb_map.get(code) |
| | | if zyltgb > 25e8 or limit_up_price > constant.MAX_SUBSCRIPT_CODE_PRICE: |
| | | return False, True, f"股价大于{constant.MAX_CODE_PRICE}块/小于{constant.MIN_CODE_PRICE}块", True |
| | | else: |
| | | return False, True, f"股价小于{constant.MIN_CODE_PRICE}块", True |
| | | |
| | | # place_order_count = cls.__PlaceOrderCountManager.get_place_order_count(code) |
| | | # if place_order_count and place_order_count >= 10: |
| | | # l2_trade_util.forbidden_trade(code, msg="当日下单次数已达10次") |
| | | # return False, True, f"当日下单次数已达10次" |
| | | |
| | | # ---------均价约束------------- |
| | | average_rate = cls.__Buy1PriceManager.get_average_rate(code) |
| | | if average_rate and average_rate <= 0.01 and tool.trade_time_sub(tool.get_now_time_str(), "10:30:00") >= 0: |
| | | return False, True, f"均价涨幅({average_rate})小于1%", True |
| | | |
| | | total_data = local_today_datas.get(code) |
| | | |
| | | # 9:32之前上证开1的票不买 |
| | | if tool.is_sh_code(code) and int(total_data[-1]["val"]["time"].replace(":", "")) <= int("093100"): |
| | | # 获取涨停时间 |
| | | limit_up_data = kpl_data_manager.KPLLimitUpDataRecordManager.record_code_dict.get(code) |
| | | if limit_up_data: |
| | | limit_up_time = tool.to_time_str(limit_up_data[2]) |
| | | if int(limit_up_time.replace(":", "")) < int("093000"): |
| | | return False, True, f"上证开一09:32之前不下单", True |
| | | |
| | | # ------------挂单时间约束---------- |
| | | order_begin_pos = cls.__get_order_begin_pos( |
| | | code) |
| | | if not trade_result_manager.can_place_order_for_cancel_time(code, total_data[ |
| | | order_begin_pos.buy_exec_index]) and not gpcode_manager.GreenListCodeManager().is_in_cache(code): |
| | | return False, True, f"距离上次挂单小于时间限制", True |
| | | |
| | | # ------------板块约束------------- |
| | | if not cls.__WantBuyCodesManager.is_in_cache(code): |
| | | # 想买单无板块约束 |
| | | block_buy_result = buy_strategy_util.is_block_can_buy(code, cls.__get_can_buy_block(code)) |
| | | if not block_buy_result[0]: |
| | | return block_buy_result[0], block_buy_result[1], block_buy_result[2], True |
| | | |
| | | if constant.L2_SOURCE_TYPE == constant.L2_SOURCE_TYPE_HUAXIN: |
| | | # ---------------------判断是否为板上放量---------------------- |
| | | trade_price = current_price_process_manager.get_trade_price(code) |
| | | if trade_price is None: |
| | | return False, True, f"尚未获取到当前成交价", True |
| | | # 判断是否为板上放量: |
| | | # 1.当前成交价为涨停价 |
| | | # 2.距离最近的非板上成交的时间大于一个阈值 |
| | | if abs(limit_up_price - float(trade_price)) < 0.001: |
| | | is_limit_up_buy = cls.__is_at_limit_up_buy(code, order_begin_pos.buy_exec_index) |
| | | if is_limit_up_buy: |
| | | # 板上买且非加绿 |
| | | # 获取最近的非涨停价成交时间 |
| | | not_limit_up_trade_time_with_ms = current_price_process_manager.get_trade_not_limit_up_time_with_ms( |
| | | code) |
| | | # 判断成交进度到当前数据的笔数,如果少于10笔且还有未成交的大单(>=299)就可以下单 |
| | | trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code) |
| | | if trade_index is None: |
| | | trade_index = 0 |
| | | can_place_order, msg = buy_strategy_util.is_near_by_trade_index(code, trade_index) |
| | | if not can_place_order: |
| | | try: |
| | | # 不能下单,判断小群撤是否可以下 |
| | | if buy_strategy_util.is_has_small_batch_cancel(code, trade_index, |
| | | order_begin_pos.buy_single_index): |
| | | # 判断撤单比例是否足够 |
| | | cancel_rate_reieved_info = buy_strategy_util.is_cancel_rate_reieved(code, 0.69, |
| | | trade_index, |
| | | order_begin_pos.buy_single_index) |
| | | if not cancel_rate_reieved_info[0]: |
| | | return False, True, f"板上放量距离远({not_limit_up_trade_time_with_ms}),有小群撤, 整体撤单比例不足({trade_index}-{order_begin_pos.buy_single_index}){cancel_rate_reieved_info[1]}", False |
| | | else: |
| | | return False, True, f"板上放量距离远({not_limit_up_trade_time_with_ms}),没有小群撤({trade_index}-{order_begin_pos.buy_single_index})", False |
| | | except Exception as e: |
| | | l2_log.info(code, logger_l2_error, f"板上放量({not_limit_up_trade_time_with_ms})不足异常:{str(e)}") |
| | | logger_l2_error.exception(e) |
| | | return False, True, f"板上放量计算异常", False |
| | | |
| | | # -------是否距离成交进度位太远-------- |
| | | buy1_money = code_price_manager.Buy1PriceManager().get_latest_buy1_money(code) |
| | | buy1_price = code_price_manager.Buy1PriceManager().get_buy1_price(code) |
| | | if buy1_price and abs(limit_up_price - buy1_price) > 0.0001: |
| | | # 买1未涨停 |
| | | buy1_money = 0 |
| | | if not buy1_money: |
| | | buy1_money = 1 |
| | | if buy_strategy_util.is_far_away_from_trade_index(code, trade_index, buy1_money): |
| | | return False, True, f"距离成交进度位太远:成交进度-{trade_index} 买1-{buy1_money}", False |
| | | |
| | | # ------------------上证下单需要有成交大单(包含主动买与被动买)或者挂买的大单----------------- |
| | | if tool.is_sh_code(code): |
| | | deal_big_order_count = BigOrderDealManager().get_total_buy_count(code) |
| | | if deal_big_order_count < 1: |
| | | # 统计挂买大单 |
| | | trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code) |
| | | if trade_index is None: |
| | | trade_index = 0 |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | # 从成交进度位到截至位置计算大单 |
| | | min_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) |
| | | left_count, left_money = cancel_buy_strategy.L2DataComputeUtil.compute_left_buy_order(code, |
| | | trade_index, |
| | | total_data[ |
| | | -1][ |
| | | "index"], |
| | | limit_up_price, |
| | | min_money=min_money) |
| | | if left_count < 1: |
| | | return False, False, f"没有已挂或者成交的大单", False |
| | | if not cls.__WantBuyCodesManager.is_in_cache(code): |
| | | # 想买单不需要大单约束 |
| | | big_deal_order_info = cls.__is_big_order_deal_enough(code) |
| | | if not big_deal_order_info[0]: |
| | | return False, False, big_deal_order_info[1], False |
| | | |
| | | place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code) |
| | | # ------------------第一和第二次下单都必须要有至少一笔未成交的大单-------------------------- |
| | | # 计算大单 |
| | | total_datas = local_today_datas.get(code) |
| | | if place_order_count < 2: |
| | | trade_index, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code) |
| | | if trade_index is None: |
| | | trade_index = 0 |
| | | min_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) |
| | | left_count, left_num = L2DataComputeUtil.compute_left_buy_order(code, trade_index, |
| | | total_datas[-1]["index"], |
| | | limit_up_price, min_money) |
| | | if left_count < 1: |
| | | return False, False, f"第{place_order_count + 1}次下单无待成交的大单", False |
| | | |
| | | # -------判断是否是量化下单,如果是就不跟到下单-------- |
| | | # 重要:量化下单会增加下单次数,板块下单中有下单次数的使用,所以板块需要在量化判断之前 |
| | | # 只有板块满足下单之后才能判断其它条件 |
| | | range_indexes = cls.__processing_data_indexes.get(code) |
| | | if range_indexes: |
| | | # 是否是量化单 |
| | | is_quantization_result = buy_strategy_util.is_quantization(code, range_indexes[0], range_indexes[1]) |
| | | if is_quantization_result[0] and not gpcode_manager.GreenListCodeManager().is_in_cache(code): |
| | | # 量化单且没有加绿 |
| | | cls.__next_buy_time_dict[code] = is_quantization_result[1] |
| | | return False, True, is_quantization_result[2], True |
| | | return True, False, "满足下单条件", True |
| | | |
| | | # 获取可以买的板块 |
| | | @classmethod |
| | | def __get_can_buy_block(cls, code): |
| | |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.total_datas, |
| | | latest_current_limit_up_records, |
| | | block_info.get_before_blocks_dict(), |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.get_current_limit_up_reason_codes_dict(), codes_delegate, codes_success) |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.get_current_limit_up_reason_codes_dict(), |
| | | codes_delegate, codes_success) |
| | | can_buy_result = CodePlateKeyBuyManager.can_buy(code) |
| | | return can_buy_result |
| | | |
| | |
| | | # 是否是交易队列触发 |
| | | # 扫入下单只有L撤能撤单 |
| | | if order_begin_pos and order_begin_pos.mode == OrderBeginPosInfo.MODE_RADICAL and cancel_type not in { |
| | | trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_L, trade_constant.CANCEL_TYPE_RD}: |
| | | trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_L, trade_constant.CANCEL_TYPE_RD, |
| | | trade_constant.CANCEL_TYPE_P}: |
| | | l2_log.cancel_debug(code, "撤单中断,原因:{}", "扫入下单不是L撤") |
| | | return False |
| | | # 加绿只有L撤/人撤生效 |
| | | if gpcode_manager.GreenListCodeManager().is_in_cache(code): |
| | | if cancel_type not in {trade_constant.CANCEL_TYPE_L, trade_constant.CANCEL_TYPE_L_UP, |
| | | trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_RD}: |
| | | trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_RD, |
| | | trade_constant.CANCEL_TYPE_P}: |
| | | l2_log.cancel_debug(code, "撤单中断,原因:{}", "加绿不是L撤") |
| | | return False |
| | | |
| | |
| | | order_begin_pos.threshold_money, |
| | | order_begin_pos.num, |
| | | order_begin_pos.count, order_begin_pos.at_limit_up, total_datas[order_begin_pos.buy_exec_index], |
| | | cls.volume_rate_info[code], order_begin_pos.mode) |
| | | cls.volume_rate_info[code], order_begin_pos.mode_desc) |
| | | cls.__save_order_begin_data(code, order_begin_pos) |
| | | cls.__LimitUpTimeManager.save_limit_up_time(code, total_datas[order_begin_pos.buy_exec_index]["val"]["time"]) |
| | | l2_log.debug(code, "delete_buy_cancel_point") |
| | |
| | | _start_time = tool.get_now_timestamp() |
| | | total_datas = local_today_datas[code] |
| | | |
| | | # ---------计算激进买入的信号--------- |
| | | radical_result = cls.__compute_radical_order_begin_pos(code, compute_start_index, compute_end_index) |
| | | if radical_result[0]: |
| | | if not HumanRadicalBuySingleManager.has_single(code): |
| | | # ---------计算激进买入的信号--------- |
| | | radical_result = cls.__compute_radical_order_begin_pos(code, compute_start_index, compute_end_index) |
| | | else: |
| | | human_radical_result = cls.__compute_human_radical_order_begin_pos(code, compute_start_index, |
| | | compute_end_index) |
| | | l2_log.debug(code, f"大单足够,人为下单计算结果({compute_start_index}-{compute_end_index}):{human_radical_result}") |
| | | if human_radical_result[0]: |
| | | radical_result = list(human_radical_result[2]) |
| | | # 改变执行位置 |
| | | radical_result[1] = human_radical_result[1]["index"] |
| | | else: |
| | | radical_result = None |
| | | if radical_result and radical_result[0]: |
| | | |
| | | if not HumanRadicalBuySingleManager.has_single(code): |
| | | big_order_deal_enough_result = radical_buy_data_manager.is_big_order_deal_enough(code, |
| | | code_volumn_manager.CodeVolumeManager().get_volume_rate_refer_in_5days( |
| | | code), 0) |
| | | if big_order_deal_enough_result[6] <= 0: |
| | | HumanRadicalBuySingleManager.add_single(code, total_datas[-1], radical_result) |
| | | async_log_util.info(logger_l2_not_buy_reasons, f"{code}#大单足够,需要根据人为下单({compute_start_index}-{compute_end_index}):{radical_result[1]}") |
| | | return |
| | | # 下单前一步,移除人为下单信号 |
| | | is_human_radical_buy = HumanRadicalBuySingleManager.has_single(code) |
| | | HumanRadicalBuySingleManager.remove_single(code) |
| | | |
| | | buy_single_index, buy_exec_index = radical_result[1], radical_result[1] |
| | | buy_volume_rate = cls.volume_rate_info[code][0] |
| | | refer_sell_data = cls.__L2MarketSellManager.get_refer_sell_data(code, total_datas[buy_single_index]["val"][ |
| | |
| | | max_num_set=set(), |
| | | buy_volume_rate=buy_volume_rate, |
| | | mode=OrderBeginPosInfo.MODE_RADICAL, |
| | | mode_desc=f"大单不足扫入:{radical_result[2]}", |
| | | mode_desc=f"大单不足扫入:{radical_result[2]} 是否跟人买入-{is_human_radical_buy}", |
| | | sell_info=sell_info, |
| | | threshold_money=threshold_money) |
| | | order_begin_pos_info.at_limit_up = cls.__is_at_limit_up_buy(code) |
| | |
| | | # 监听大单 |
| | | RDCancelBigNumComputer().set_watch_indexes(code, radical_result[4]) |
| | | return |
| | | else: |
| | | radical_result = cls.__compute_radical_order_begin_pos_for_many_sell(code, compute_start_index, |
| | | compute_end_index) |
| | | if radical_result[0]: |
| | | buy_single_index, buy_exec_index = radical_result[0][0], radical_result[0][1] |
| | | buy_volume_rate = cls.volume_rate_info[code][0] |
| | | refer_sell_data = cls.__L2MarketSellManager.get_refer_sell_data(code, |
| | | total_datas[buy_single_index]["val"][ |
| | | "time"]) |
| | | if refer_sell_data: |
| | | sell_info = (refer_sell_data[0], refer_sell_data[1]) |
| | | else: |
| | | sell_info = (total_datas[buy_single_index]["val"]["time"], 0) |
| | | threshold_money = 0 |
| | | |
| | | order_begin_pos_info = OrderBeginPosInfo(buy_single_index=buy_single_index, |
| | | buy_exec_index=buy_exec_index, |
| | | buy_compute_index=buy_exec_index, |
| | | num=total_datas[buy_single_index]["val"]["num"], count=1, |
| | | max_num_set=set(), |
| | | buy_volume_rate=buy_volume_rate, |
| | | mode=OrderBeginPosInfo.MODE_RADICAL, |
| | | mode_desc=f"总抛压大扫入:{radical_result[2]}", |
| | | sell_info=sell_info, |
| | | threshold_money=threshold_money) |
| | | order_begin_pos_info.at_limit_up = cls.__is_at_limit_up_buy(code) |
| | | ordered = cls.__process_with_find_exec_index(code, order_begin_pos_info, compute_end_index, |
| | | block_info=radical_result[2]) |
| | | if ordered: |
| | | radical_buy_data_manager.BlockPlaceOrderRecordManager().add_record(code, radical_result[2]) |
| | | if RadicalBuyDealCodesManager().get_code_blocks(code): |
| | | # 已经扫入下过单 |
| | | return |
| | |
| | | return False, -1, "未获取到积极买的起始信号", '', OrderBeginPosInfo.MODE_NORMAL |
| | | |
| | | # 计算激进买的下单信号 |
| | | # 计算激进买的下单信号 |
| | | @classmethod |
| | | def __compute_radical_order_begin_pos(cls, code, start_index, end_index): |
| | | """ |
| | |
| | | |
| | | def __can_order(): |
| | | # 判断是否是板上放量 |
| | | if cls.__is_at_limit_up_buy(code, start_index): |
| | | return False, None, "板上放量", None |
| | | # if cls.__is_at_limit_up_buy(code, start_index): |
| | | # return False, None, "板上放量", None |
| | | total_datas = local_today_datas[code] |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | bigger_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) |
| | | min_num = int(bigger_money / limit_up_price / 100) |
| | | bigger_money_num, current_min_num, total_min_num = int(bigger_money / limit_up_price / 100), int( |
| | | bigger_money / limit_up_price / 100), int(5000 / limit_up_price) |
| | | |
| | | refer_sell_data = L2MarketSellManager().get_refer_sell_data(code, radical_data[3]) |
| | | # 参考总卖额 |
| | | refer_sell_money = 0 |
| | | if refer_sell_data: |
| | | refer_sell_money = refer_sell_data[1] |
| | | # 大单判断结果 |
| | | # 判断还需大单的金额(max(每次上板大单,累计成交大单)) |
| | | big_order_deal_enough_result = radical_buy_data_manager.is_big_order_deal_enough(code, |
| | | code_volumn_manager.CodeVolumeManager().get_volume_rate_refer_in_5days( |
| | | code), |
| | | refer_sell_money) |
| | | refer_sell_money, |
| | | for_buy=True, |
| | | is_almost_open_limit_up= |
| | | radical_data[5]) |
| | | # 缺乏的大单金额 |
| | | lack_money = big_order_deal_enough_result[3] |
| | | current_lack_money = int(big_order_deal_enough_result[5]) |
| | | total_lack_money = int(big_order_deal_enough_result[6]) |
| | | # 如果有大单成交就不需要看大单 |
| | | if constant.CAN_RADICAL_BUY_NEED_BIG_ORDER_EVERYTIME: |
| | | # 每次下单都需要大单 |
| | |
| | | # 60s以上就不下单了 |
| | | return False, None, "距离上次统计大单时间过去60s", set() |
| | | |
| | | if lack_money == 0: |
| | | min_num = int(5000 / limit_up_price) |
| | | if max(current_lack_money, total_lack_money) <= 0: |
| | | # 已经不缺少大单了 |
| | | # if not tool.is_sh_code(code): |
| | | # 非上证的票看50w |
| | | current_min_num = int(5000 / limit_up_price) |
| | | # 如果累计大单成交足够,只需看50w |
| | | # if big_order_deal_enough_result[4]: |
| | | # min_num = int(5000 / limit_up_price) |
| | | # 需要监听的大单 |
| | | watch_indexes = set() |
| | | # 总委托大单金额 |
| | |
| | | val = data["val"] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | if val["num"] < min_num: |
| | | continue |
| | | # 撤单不算 |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, i, |
| | | total_datas, |
| | |
| | | # 判断是否为大单 |
| | | order_money = dealing_active_order_info[2] + round(val["price"], 2) * val["num"] * 100 |
| | | if order_money >= bigger_money: |
| | | lack_money -= order_money |
| | | watch_indexes.add(i) |
| | | if lack_money < 0: |
| | | if val["num"] >= bigger_money_num: |
| | | watch_indexes.add(i) |
| | | if val["num"] >= current_min_num: |
| | | current_lack_money -= order_money |
| | | if val["num"] >= total_min_num: |
| | | total_lack_money -= order_money |
| | | if max(current_lack_money, total_lack_money) < 0: |
| | | single_index = i |
| | | break |
| | | |
| | | if int(val["orderNo"]) <= radical_data[1]: |
| | | # 主动买单后的数据不算 |
| | | continue |
| | | watch_indexes.add(i) |
| | | lack_money -= round(val["price"], 2) * val["num"] * 100 |
| | | if lack_money < 0: |
| | | |
| | | if val["num"] >= bigger_money_num: |
| | | watch_indexes.add(i) |
| | | |
| | | if val["num"] >= current_min_num: |
| | | current_lack_money -= round(val["price"], 2) * val["num"] * 100 |
| | | |
| | | if val["num"] >= total_min_num: |
| | | total_lack_money -= round(val["price"], 2) * val["num"] * 100 |
| | | |
| | | if max(current_lack_money, total_lack_money) < 0: |
| | | single_index = i |
| | | break |
| | | if single_index is not None: |
| | | return True, single_index, "有大单", watch_indexes |
| | | return False, None, f"大单不足:{trade_index}-{end_index} 缺少的大单-{lack_money}", watch_indexes |
| | | return True, single_index, f"有大单,大单情况:{big_order_deal_enough_result[1]}", watch_indexes |
| | | return False, None, f"大单不足:{trade_index}-{end_index} 缺少的大单-{max(current_lack_money, total_lack_money)} 大单情况:{big_order_deal_enough_result[1]}", watch_indexes |
| | | |
| | | radical_data = RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.get(code) |
| | | record_codes = radical_buy_data_manager.BlockPlaceOrderRecordManager().get_codes() |
| | |
| | | return False, None, "超过生效时间" |
| | | |
| | | result = __can_order() |
| | | l2_log.debug(code, f"L2扫入判断:{result}") |
| | | l2_log.debug(code, f"L2扫入判断({start_index}-{end_index}):{result}") |
| | | if result[0]: |
| | | # 已经扫入下过单且允许板上放量扫入的就需要判断板上放量的距离 |
| | | if is_radical_buy and constant.CAN_RADICAL_BUY_AT_LIMIT_UP: |
| | |
| | | if not constant.CAN_RADICAL_BUY_AT_LIMIT_UP and code in RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict: |
| | | RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.pop(code) |
| | | return True, result[1], radical_data[2], radical_data[4], result[3] |
| | | else: |
| | | async_log_util.info(logger_l2_not_buy_reasons, f"{code}#{result[2]}") |
| | | return result |
| | | |
| | | @classmethod |
| | | def __compute_human_radical_order_begin_pos(cls, code, start_index, end_index): |
| | | """ |
| | | 处理跟人买 |
| | | @param code: |
| | | @param start_index: |
| | | @param end_index: |
| | | @return: |
| | | """ |
| | | total_datas = local_today_datas.get(code) |
| | | result = HumanRadicalBuySingleManager.is_valid(code, total_datas[start_index]) |
| | | if not result[0]: |
| | | return False, None, result[1] |
| | | result = result[1] |
| | | single_time_ms, space_time_ms, expire_time_ms, radical_result = result[0], result[1], result[2], result[3] |
| | | |
| | | bigger_num = l2_data_util.get_big_money_val(gpcode_manager.get_limit_up_price_as_num(code), |
| | | tool.is_ge_code(code)) // ( |
| | | gpcode_manager.get_limit_up_price_as_num(code) * 100) |
| | | canceled_buyno_map = local_today_buyno_map.get(code) |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_datas[i] |
| | | val = data["val"] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | if val["num"] < bigger_num: |
| | | continue |
| | | |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, i, |
| | | total_datas, |
| | | canceled_buyno_map) |
| | | if left_count == 0: |
| | | continue |
| | | |
| | | # 判断是否超过生效时间 |
| | | if tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(total_datas[i]["val"]), |
| | | expire_time_ms) > 0: |
| | | HumanRadicalBuySingleManager.remove_single(code) |
| | | return False, None, "超过信号生效时间" |
| | | is_valid = False |
| | | # 判断距离上个50w买单的时间是否超过了space_time_ms |
| | | for ii in range(i - 1, -1, -1): |
| | | data_child = total_datas[ii] |
| | | val_child = data_child["val"] |
| | | if not L2DataUtil.is_limit_up_price_buy(val_child): |
| | | continue |
| | | if val_child["num"] * float(val_child["price"]) < 5000: |
| | | continue |
| | | if tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(val), |
| | | L2DataUtil.get_time_with_ms(val_child)) > space_time_ms: |
| | | is_valid = True |
| | | break |
| | | if is_valid: |
| | | return True, data, radical_result |
| | | return False, None, "没有有效信号" |
| | | |
| | | # 总卖额参考时间使用记录 |
| | | __refer_sell_used_times = {} |
| | | |
| | | @classmethod |
| | | def __compute_radical_order_begin_pos_for_many_sell(cls, code, start_index, end_index): |
| | | """ |
| | | 计算深证高抛压的卖的买入信号 |
| | | @param code: |
| | | @param start_index: |
| | | @param end_index: |
| | | @return: 信号信息(信号位,执行位), 消息, 可买入的板块 |
| | | """ |
| | | if not tool.is_sz_code(code): |
| | | return None, "非深证的票", None |
| | | # 判断抛压是否大于5000w |
| | | total_datas = local_today_datas.get(code) |
| | | refer_sell_data = cls.__L2MarketSellManager.get_refer_sell_data(code, total_datas[-1]["val"]["time"]) |
| | | if not refer_sell_data or refer_sell_data[1] < 5e7: |
| | | return None, "总卖额小于5000万", None |
| | | if code in cls.__refer_sell_used_times and refer_sell_data[0] in cls.__refer_sell_used_times: |
| | | return None, f"时间已经被使用:{refer_sell_data[0]}", None |
| | | |
| | | deal_codes = RadicalBuyDealCodesManager().get_deal_codes() |
| | | if code in deal_codes: |
| | | return None, f"已经成交", None |
| | | |
| | | f_buy_blocks, orgin_buy_blocks = radical_buy_strategy.compute_can_radical_buy_blocks(code, deal_codes) |
| | | if not f_buy_blocks: |
| | | return None, f"板块不可买入", None |
| | | |
| | | # 判断是否有涨停买的数据 |
| | | has_limit_up = False |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_datas[i] |
| | | val = data["val"] |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | | has_limit_up = True |
| | | break |
| | | if not has_limit_up: |
| | | return None, "无涨停买数据", None |
| | | # 查找计数起点 |
| | | refer_sell_time_int = int(refer_sell_data[0].replace(":", "")) |
| | | begin_index = start_index |
| | | for i in range(start_index - 1, -1, -1): |
| | | data = total_datas[i] |
| | | val = data["val"] |
| | | if int(val["time"].replace(":", "")) < refer_sell_time_int: |
| | | begin_index = i + 1 |
| | | break |
| | | threshold_num = int(round(refer_sell_data[1] / gpcode_manager.get_limit_up_price_as_num(code) / 100)) |
| | | total_num = 0 |
| | | for i in range(begin_index, end_index + 1): |
| | | data = total_datas[i] |
| | | val = data["val"] |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | | total_num += val["num"] |
| | | elif L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | total_num -= val["num"] |
| | | if total_num > threshold_num: |
| | | if code not in cls.__refer_sell_used_times: |
| | | cls.__refer_sell_used_times[code] = set() |
| | | cls.__refer_sell_used_times[code].add(refer_sell_data[0]) |
| | | return (begin_index, end_index), "可以下单", f_buy_blocks |
| | | return None, "总买额不满足", None |
| | | |
| | | @classmethod |
| | | def test__compute_active_order_begin_pos(cls, code, continue_count, start_index, end_index): |
| | |
| | | if place_order_count is None: |
| | | place_order_count = 0 |
| | | is_ge_code = tool.is_ge_code(code) |
| | | buy_no_map = local_today_buyno_map.get(code) |
| | | for i in range(compute_start_index, compute_end_index + 1): |
| | | data = total_datas[i] |
| | | _val = total_datas[i]["val"] |
| | |
| | | elif L2DataUtil.is_limit_up_price_buy_cancel(_val): |
| | | # 判断买入位置是否在买入信号之前 |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i], |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | buy_no_map) |
| | | if buy_index is not None: |
| | | |
| | | # 找到买撤数据的买入点 |
| | | if buy_index >= buy_single_index: |
| | | max_buy_num_set.discard(buy_index) |
| | |
| | | max_buy_num_set = set(max_num_set) |
| | | active_buy_blocks = cls.get_active_buy_blocks(code) |
| | | is_ge_code = tool.is_ge_code(code) |
| | | buyno_map = local_today_buyno_map.get(code) |
| | | for i in range(compute_start_index, compute_end_index + 1): |
| | | data = total_datas[i] |
| | | _val = total_datas[i]["val"] |
| | |
| | | elif L2DataUtil.is_limit_up_price_buy_cancel(_val): |
| | | # 判断买入位置是否在买入信号之前 |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i], |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | buyno_map) |
| | | if buy_index is not None: |
| | | |
| | | # 找到买撤数据的买入点 |