| | |
| | | if cancel_result[0]: |
| | | L2TradeDataProcessor.cancel_buy(code, f"F撤:{cancel_result[1]}", |
| | | cancel_type=trade_constant.CANCEL_TYPE_F) |
| | | return |
| | | else: |
| | | l2_log.f_cancel_debug(code, f"获取真实成交位的F撤未生效:{cancel_result[1]}") |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | # 判断与执行位置的间隔时间 |
| | | if order_begin_pos.mode != OrderBeginPosInfo.MODE_RADICAL: |
| | | # 非扫入下单要判断执行位置与真实下单位的间隔时间 |
| | | total_datas = local_today_datas.get(code) |
| | | if 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"])) > 2000: |
| | | L2TradeDataProcessor.cancel_buy(code, f"真实下单位({index})与执行位({order_begin_pos.buy_exec_index})相差2s以上", |
| | | cancel_type=trade_constant.CANCEL_TYPE_F) |
| | | return |
| | | |
| | | |
| | | # 处理华鑫L2数据 |
| | | @classmethod |
| | |
| | | continue |
| | | findexes.add(index) |
| | | return findexes |
| | | |
| | | # 统计买入净买量,不计算在买入信号之前的买撤单 |
| | | @classmethod |
| | | def __sum_buy_num_for_order_3(cls, code, compute_start_index, compute_end_index, origin_num, origin_count, |
| | | threshold_money, buy_single_index, max_num_set, at_limit_up=False): |
| | | _start_time = t.time() |
| | | total_datas = local_today_datas[code] |
| | | # is_first_code = gpcode_manager.FirstCodeManager().is_in_first_record_cache(code) |
| | | |
| | | buy_nums = origin_num |
| | | buy_count = origin_count |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | if limit_up_price is None: |
| | | raise Exception("涨停价无法获取") |
| | | limit_up_price = float(limit_up_price) |
| | | |
| | | threshold_num = None |
| | | # 大目标手数(满足这个就不需要看安全笔数) |
| | | threshold_max_num = None |
| | | |
| | | # 目标订单数量 |
| | | threshold_count = cls.__l2PlaceOrderParamsManagerDict[code].get_safe_count() |
| | | |
| | | # 最大间隔时间ms |
| | | max_space_time_ms = cls.__l2PlaceOrderParamsManagerDict[code].get_time_range() * 1000 |
| | | |
| | | # ----------------调整板上下单的m值与安全笔数---------------- |
| | | if at_limit_up: |
| | | # 板上买,获取最近一次闪电下单的总卖额 |
| | | sell_data = cls.__latest_fast_place_order_info_dict.get(code) |
| | | if sell_data: |
| | | # 有过闪电下单 |
| | | # 总卖的一半作为m值 |
| | | threshold_num = int(sell_data[1] / (limit_up_price * 100)) // 2 |
| | | threshold_max_num = 1 |
| | | # 信号为之前有待成交的大单(不是正在成交) |
| | | trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code) |
| | | if not is_default and trade_index is not None: |
| | | temp_big_num = int(30000 / limit_up_price) |
| | | for i in range(trade_index + 1, buy_single_index): |
| | | data = total_datas[i] |
| | | val = data['val'] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | # 判断是否有大单未成交 |
| | | if temp_big_num > val["num"]: |
| | | continue |
| | | |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, |
| | | data[ |
| | | "index"], |
| | | total_datas, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if left_count > 0: |
| | | # 安全笔数与囊括时间范围修改 |
| | | threshold_count = 3 |
| | | max_space_time_ms = 9 * 1000 |
| | | break |
| | | |
| | | if not threshold_num: |
| | | # 目标手数 |
| | | threshold_num = round(threshold_money / (limit_up_price * 100)) |
| | | if not threshold_max_num: |
| | | threshold_max_num = int(threshold_num * 1.2) |
| | | |
| | | # place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code) |
| | | |
| | | # buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"]) |
| | | |
| | | # 可以触发买,当有涨停买信号时才会触发买 |
| | | trigger_buy = True |
| | | |
| | | # 如果大单含有率大于50%,则时间囊括范围提高到3s |
| | | if max_num_set and origin_count: |
| | | if len(max_num_set) / origin_count > 0.5: |
| | | max_space_time_ms = 3 * 1000 |
| | | |
| | | # 最大买量 |
| | | max_buy_num = 0 |
| | | max_buy_num_set = set(max_num_set) |
| | | |
| | | # 需要的最小大单笔数 |
| | | big_num_count = cls.__l2PlaceOrderParamsManagerDict[code].get_big_num_count() |
| | | |
| | | # 较大单的手数 |
| | | bigger_num = round(5000 / limit_up_price) |
| | | |
| | | not_buy_msg = "" |
| | | is_ge_code = tool.is_ge_code(code) |
| | | for i in range(compute_start_index, compute_end_index + 1): |
| | | data = total_datas[i] |
| | | _val = total_datas[i]["val"] |
| | | trigger_buy = False |
| | | # 必须为连续2秒内的数据 |
| | | if L2DataUtil.time_sub_as_ms(_val, total_datas[buy_single_index]["val"]) > max_space_time_ms: |
| | | cls.__TradePointManager.delete_buy_point(code) |
| | | if i == compute_end_index: |
| | | # 数据处理完毕 |
| | | return None, buy_nums, buy_count, None, max_buy_num_set, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms" |
| | | else: |
| | | # 计算买入信号,不能同一时间开始计算 |
| | | for ii in range(buy_single_index + 1, compute_end_index + 1): |
| | | if total_datas[buy_single_index]["val"]["time"] != total_datas[ii]["val"]["time"]: |
| | | return None, buy_nums, buy_count, ii, max_buy_num_set, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms" |
| | | # 涨停买 |
| | | if L2DataUtil.is_limit_up_price_buy(_val): |
| | | if l2_data_util.is_big_money(_val, is_ge_code): |
| | | max_buy_num_set.add(i) |
| | | if _val["num"] >= bigger_num: |
| | | trigger_buy = True |
| | | # 只统计59万以上的金额 |
| | | buy_nums += int(_val["num"]) * int(total_datas[i]["re"]) |
| | | buy_count += int(total_datas[i]["re"]) |
| | | if (buy_nums >= threshold_num and buy_count >= threshold_count) or buy_nums >= threshold_max_num: |
| | | l2_log.info(code, logger_l2_trade_buy, |
| | | f"{code}获取到买入执行点:{i} 统计纯买手数:{buy_nums} 目标纯买手数:{threshold_num}/{threshold_max_num} 统计纯买单数:{buy_count} 目标纯买单数:{threshold_count}, 大单数量:{len(max_buy_num_set)}") |
| | | elif L2DataUtil.is_limit_up_price_buy_cancel(_val): |
| | | if _val["num"] >= bigger_num: |
| | | # 只统计59万以上的金额 |
| | | # 涨停买撤 |
| | | # 判断买入位置是否在买入信号之前 |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i], |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | if buy_index is not None: |
| | | # 找到买撤数据的买入点 |
| | | if buy_index >= buy_single_index: |
| | | buy_nums -= int(_val["num"]) * int(data["re"]) |
| | | buy_count -= int(data["re"]) |
| | | # 大单撤销 |
| | | max_buy_num_set.discard(buy_index) |
| | | l2_log.buy_debug(code, "{}数据在买入信号之后 撤买纯买手数:{} 目标手数:{}", i, buy_nums, threshold_num) |
| | | else: |
| | | l2_log.buy_debug(code, "{}数据在买入信号之前,买入位:{}", i, buy_index) |
| | | if total_datas[buy_single_index]["val"]["time"] == total_datas[buy_index]["val"]["time"]: |
| | | # 同一秒,当作买入信号之后处理 |
| | | buy_nums -= int(_val["num"]) * int(data["re"]) |
| | | buy_count -= int(data["re"]) |
| | | # 大单撤销 |
| | | max_buy_num_set.discard(buy_index) |
| | | l2_log.buy_debug(code, "{}数据买入位与预估买入位在同一秒", i) |
| | | else: |
| | | # 未找到买撤数据的买入点 |
| | | l2_log.buy_debug(code, "未找到买撤数据的买入点: 位置-{} 数据-{}", i, data) |
| | | buy_nums -= int(_val["num"]) * int(total_datas[i]["re"]) |
| | | buy_count -= int(total_datas[i]["re"]) |
| | | l2_log.buy_debug(code, "位置-{},总手数:{},目标手数:{}", i, |
| | | buy_nums, threshold_num) |
| | | |
| | | max_buy_num_set_count = 0 |
| | | max_buy_num_set = cls.__filter_not_deal_indexes(code, max_buy_num_set) |
| | | for i1 in max_buy_num_set: |
| | | max_buy_num_set_count += total_datas[i1]["re"] |
| | | |
| | | if buy_nums < threshold_num: |
| | | not_buy_msg = f"【{i}】纯买额不足,{buy_nums}/{threshold_num}" |
| | | continue |
| | | |
| | | if buy_count < threshold_count: |
| | | not_buy_msg = f"【{i}】安全笔数不够,{buy_count}/{threshold_count}" |
| | | continue |
| | | |
| | | if not trigger_buy: |
| | | not_buy_msg = f"【{i}】没有买单触发" |
| | | continue |
| | | |
| | | if max_buy_num_set_count < big_num_count: |
| | | not_buy_msg = f"【{i}】大单数量不足,{max_buy_num_set_count}/{big_num_count}" |
| | | continue |
| | | |
| | | try: |
| | | info = cls.__trade_log_placr_order_info_dict[code] |
| | | info.set_trade_factor(threshold_money, threshold_count, list(max_buy_num_set)) |
| | | except Exception as e: |
| | | async_log_util.error(logger_l2_error, f"记录交易因子出错:{str(e)}") |
| | | |
| | | return i, buy_nums, buy_count, None, max_buy_num_set, "可以下单" |
| | | |
| | | l2_log.buy_debug(code, "尚未获取到买入执行点,起始计算位置:{} 统计纯买手数:{} 目标纯买手数:{} 统计纯买单数:{} 目标纯买单数:{} 大单数量:{} 目标大单数量:{}", |
| | | compute_start_index, |
| | | buy_nums, |
| | | threshold_num, buy_count, threshold_count, max_buy_num_set_count, big_num_count) |
| | | |
| | | return None, buy_nums, buy_count, None, max_buy_num_set, not_buy_msg |
| | | |
| | | # 返回(买入执行点, 总手, 总笔数, 从新计算起点, 纯买额阈值) |
| | | # 计算快速买入 |