| | |
| | | SecondCancelBigNumComputer().set_real_place_order_index(code, index) |
| | | LCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index=buy_single_index) |
| | | HourCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index) |
| | | GCancelBigNumComputer().set_real_place_order_index(code, index) |
| | | |
| | | |
| | | class SecondCancelBigNumComputer: |
| | |
| | | code)) |
| | | cancel_num += val['num'] * (data['re'] - left_count) |
| | | rate = round(cancel_num / total_num, 4) |
| | | must_buy_cancel_rate = constant.H_CANCEL_RATE |
| | | must_buy_cancel_rate = constant.H_CANCEL_RATE |
| | | try: |
| | | temp_rate = gpcode_manager.MustBuyCodesManager().get_cancel_rate_cache(code) |
| | | if temp_rate: |
| | |
| | | if must_buy_cancel_rate is not None: |
| | | return must_buy_cancel_rate |
| | | except Exception as e: |
| | | async_log_util.error(logger_l2_l_cancel,str(e)) |
| | | async_log_util.error(logger_l2_l_cancel, str(e)) |
| | | |
| | | base_rate = constant.L_CANCEL_RATE |
| | | if is_up: |
| | |
| | | __near_by_trade_progress_index_cache = {} |
| | | |
| | | __SecondCancelBigNumComputer = SecondCancelBigNumComputer() |
| | | |
| | | |
| | | |
| | | __last_l_up_compute_info = {} |
| | | |
| | |
| | | watch_indexes = set([int(i) for i in watch_indexes_info[2]]) |
| | | # 计算监听的总条数 |
| | | total_num = 0 |
| | | max_num = 0 |
| | | for wi in watch_indexes: |
| | | total_num += total_data[wi]["val"]["num"] * total_data[wi]["re"] |
| | | if total_data[wi]["val"]["num"] > max_num: |
| | | max_num = total_data[wi]["val"]["num"] |
| | | # 判断撤单中是否有监听中的索引 |
| | | need_compute = False |
| | | for i in range(start_index, end_index + 1): |
| | |
| | | |
| | | rate = round(canceled_num / total_num, 3) |
| | | thresh_hold_rate = LCancelRateManager.get_cancel_rate(code) |
| | | # 除开最大单的影响权重 |
| | | temp_thresh_hold_rate = round((total_num - max_num)*0.9/total_num, 2) |
| | | thresh_hold_rate = min(thresh_hold_rate, temp_thresh_hold_rate) |
| | | l2_log.l_cancel_debug(code, f"计算范围:{start_index}-{end_index},已撤单比例:{rate}/{thresh_hold_rate}") |
| | | if rate >= thresh_hold_rate: |
| | | canceled_indexes.sort() |
| | |
| | | |
| | | def need_cancel(self, code, buy_exec_index, start_index, end_index, total_data, is_first_code): |
| | | if buy_exec_index is None: |
| | | return False, "尚未找到下单位置", "" |
| | | return False, None, "尚未找到下单位置" |
| | | # 守护S撤以外的数据 |
| | | if int(tool.get_now_time_str().replace(":", "")) > int("145700") and not constant.TEST: |
| | | return False, None, "" |
| | |
| | | |
| | | # ---------------------------------G撤------------------------------- |
| | | class GCancelBigNumComputer: |
| | | __SecondCancelBigNumComputer = SecondCancelBigNumComputer() |
| | | __real_place_order_index_dict = {} |
| | | __instance = None |
| | | |
| | | # 开始撤单 |
| | | def start_cancel(self, code, buy_no, total_datas, m_val_num): |
| | | # TODO 暂时注释掉G撤 |
| | | return False, "暂时不执行G撤" |
| | | thresh_num = int(m_val_num * 1) |
| | | place_order_index = self.__SecondCancelBigNumComputer.get_real_place_order_index_cache(code) |
| | | if place_order_index is None: |
| | | raise Exception("未获取到下单真实位置") |
| | | buy_data = buy_order_no_map.get(buy_no) |
| | | if not buy_data: |
| | | raise Exception(f"尚未获取到撤买单详情数据: order_no:{buy_no} map数量:{len(buy_order_no_map)}") |
| | | # 从成交位置到下单位置计算m值 |
| | | transaction_index = buy_data["index"] |
| | | need_cancel = True |
| | | buy_nums = 0 |
| | | for index in range(transaction_index + 1, place_order_index): |
| | | data = total_datas[index] |
| | | if L2DataUtil.is_limit_up_price_buy(data["val"]): |
| | | # 获取是否在买入执行信号周围2s |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, index, |
| | | total_datas, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if left_count > 0: |
| | | buy_nums += left_count * data["val"]["num"] |
| | | if buy_nums > thresh_num: |
| | | break |
| | | if buy_nums > thresh_num: |
| | | need_cancel = False |
| | | return need_cancel, f"成交进度位({transaction_index})-真实下单位({place_order_index}) 纯买手数:{buy_nums}/1.8倍m值手数:{thresh_num}" |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(GCancelBigNumComputer, cls).__new__(cls, *args, **kwargs) |
| | | return cls.__instance |
| | | |
| | | def set_real_place_order_index(self, code, index): |
| | | self.__real_place_order_index_dict[code] = index |
| | | |
| | | def clear(self, code=None): |
| | | if code: |
| | | if code in self.__real_place_order_index_dict: |
| | | self.__real_place_order_index_dict.pop(code) |
| | | else: |
| | | self.__real_place_order_index_dict.clear() |
| | | |
| | | def need_cancel(self, code, buy_exec_index, start_index, end_index): |
| | | if code not in self.__real_place_order_index_dict: |
| | | return False, None, "没有找到真实下单位" |
| | | real_place_order_index = self.__real_place_order_index_dict.get(code) |
| | | total_datas = local_today_datas.get(code) |
| | | # 30s内有效 |
| | | if tool.trade_time_sub(total_datas[end_index]["val"]["time"], total_datas[buy_exec_index]["val"]["time"]) > 30: |
| | | return False, None, "下单30s内才生效" |
| | | |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_datas[i] |
| | | val = data["val"] |
| | | if not L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | continue |
| | | if val["num"] * float(val["price"]) < 30000: |
| | | continue |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(data, |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | if buy_index is not None and buy_index < real_place_order_index: |
| | | return True, data, "" |
| | | return False, None, "" |
| | | |
| | | def place_order_success(self, code): |
| | | self.clear(code) |
| | | |
| | | def cancel_success(self, code): |
| | | self.clear(code) |
| | | |
| | | |
| | | # ---------------------------------独苗撤------------------------------- |