| | |
| | | if left_count > 0: |
| | | total_num += val["num"] |
| | | total_fast_num += val['num'] |
| | | if total_num * float(limit_up_price) < 800 * 100 and tool.trade_time_sub(sell_time_str, total_datas[real_order_index]['val']['time']) < 15 * 60: |
| | | if total_num * float(limit_up_price) < 800 * 100 and tool.trade_time_sub(sell_time_str, |
| | | total_datas[real_order_index][ |
| | | 'val']['time']) < 15 * 60: |
| | | # 15分钟内真实成交位距离真实下单位,金额≤800万 ,大单阈值变为200w |
| | | threash_money_w = threash_money_danger_w |
| | | except Exception as e: |
| | |
| | | __last_trade_progress_dict = {} |
| | | __real_place_order_index_dict = {} |
| | | __cancel_watch_index_info_cache = {} |
| | | # L后真实成交位之后的位置索引 |
| | | __cancel_l_down_after_place_order_index_cache = {} |
| | | # 成交位附近临近大单索引 |
| | | __near_by_trade_progress_index_cache = {} |
| | | |
| | |
| | | CodeDataCacheUtil.set_cache(cls.__near_by_trade_progress_index_cache, code, val) |
| | | except: |
| | | pass |
| | | keys = RedisUtils.keys(__redis, "l_cancel_down_after_place_order_index-*") |
| | | for k in keys: |
| | | code = k.split("-")[-1] |
| | | val = RedisUtils.get(__redis, k) |
| | | try: |
| | | val = json.loads(val) |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_l_down_after_place_order_index_cache, code, val) |
| | | except: |
| | | pass |
| | | |
| | | |
| | | finally: |
| | | RedisUtils.realse(__redis) |
| | | |
| | |
| | | return cache_result[1] |
| | | return None |
| | | |
| | | def __set_cancel_l_down_after_place_order_index(self, code, watch_index, index): |
| | | if code not in self.__cancel_l_down_after_place_order_index_cache: |
| | | self.__cancel_l_down_after_place_order_index_cache[code] = {} |
| | | self.__cancel_l_down_after_place_order_index_cache[code][str(watch_index)] = index |
| | | RedisUtils.setex_async(self.__db, f"l_cancel_down_after_place_order_index-{code}", tool.get_expire(), |
| | | json.dumps(self.__cancel_l_down_after_place_order_index_cache[code])) |
| | | |
| | | def __get_cancel_l_down_after_place_order_index_dict(self, code): |
| | | return self.__cancel_l_down_after_place_order_index_cache.get(code) |
| | | |
| | | def del_watch_index(self, code): |
| | | CodeDataCacheUtil.clear_cache(self.__cancel_watch_index_info_cache, code) |
| | | RedisUtils.delete_async(self.__db, f"l_cancel_watch_index_info-{code}") |
| | |
| | | if code in self.__real_place_order_index_dict: |
| | | self.__real_place_order_index_dict.pop(code) |
| | | RedisUtils.delete_async(self.__db, f"l_cancel_real_place_order_index-{code}") |
| | | if code in self.__cancel_l_down_after_place_order_index_cache: |
| | | self.__cancel_l_down_after_place_order_index_cache.pop(code) |
| | | RedisUtils.delete_async(self.__db, f"l_cancel_down_after_place_order_index-{code}") |
| | | else: |
| | | keys = RedisUtils.keys(self.__get_redis(), f"l_cancel_watch_index_info-*") |
| | | for k in keys: |
| | |
| | | self.__real_place_order_index_dict.pop(code) |
| | | self.del_watch_index(code) |
| | | keys = RedisUtils.keys(self.__get_redis(), f"l_cancel_real_place_order_index-*") |
| | | for k in keys: |
| | | RedisUtils.delete(self.__get_redis(), k) |
| | | # 清除L后真实下单位置之后囊括的索引 |
| | | self.__cancel_l_down_after_place_order_index_cache.clear() |
| | | keys = RedisUtils.keys(self.__get_redis(), f"l_cancel_down_after_place_order_index-*") |
| | | for k in keys: |
| | | RedisUtils.delete(self.__get_redis(), k) |
| | | |
| | |
| | | after_count += 1 |
| | | if l2_data_util.is_big_money(val): |
| | | watch_indexes.add(i) |
| | | self.__set_cancel_l_down_after_place_order_index(code, i, after_count - 1) |
| | | except Exception as e: |
| | | pass |
| | | self.__set_watch_indexes(code, buy_single_index, re_compute, watch_indexes) |
| | |
| | | left_count_after += 1 |
| | | if l2_data_util.is_big_money(val) and j not in watch_indexes: |
| | | watch_indexes.add(j) |
| | | self.__set_cancel_l_down_after_place_order_index(code, j, left_count_after - 1) |
| | | break |
| | | except: |
| | | pass |
| | |
| | | self.__set_watch_indexes(code, watch_indexes_info[0], watch_indexes_info[1], watch_indexes) |
| | | |
| | | def __compute_need_cancel(self, code, buy_exec_index, start_index, end_index, total_data, is_first_code): |
| | | """ |
| | | L后撤单; |
| | | 撤单计算规则:计算撤单比例时,将真实下单位置之后的数据按权重(离下单位最近的权重越大)加入分子,不加入分母(总囊括手数)计算 |
| | | @param code: |
| | | @param buy_exec_index: |
| | | @param start_index: |
| | | @param end_index: |
| | | @param total_data: |
| | | @param is_first_code: |
| | | @return: |
| | | """ |
| | | watch_indexes_info = self.__get_watch_indexes_cache(code) |
| | | if not watch_indexes_info: |
| | | return False, None |
| | |
| | | # 计算监听的总条数 |
| | | total_num = 0 |
| | | max_num = 0 |
| | | # 这是下单位置之后的索引: key为字符串 |
| | | after_place_order_index_dict = self.__get_cancel_l_down_after_place_order_index_dict(code) |
| | | if after_place_order_index_dict is None: |
| | | after_place_order_index_dict = {} |
| | | for wi in watch_indexes: |
| | | if str(wi) in after_place_order_index_dict: |
| | | continue |
| | | 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 = True |
| | | break |
| | | if need_compute: |
| | | |
| | | # 计算撤单比例 |
| | | watch_indexes_list = list(watch_indexes) |
| | | watch_indexes_list.sort() |
| | |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if cancel_data: |
| | | canceled_num += total_data[wi]["val"]["num"] * total_data[wi]["re"] |
| | | if str(wi) in after_place_order_index_dict: |
| | | # 真实下单位置之后的按照权重比例来计算 |
| | | canceled_num += total_data[wi]["val"]["num"] * ( |
| | | 10 - after_place_order_index_dict[str(wi)]) // 10 |
| | | else: |
| | | canceled_num += total_data[wi]["val"]["num"] |
| | | |
| | | canceled_indexes.append(cancel_data["index"]) |
| | | # if wi == watch_indexes_list[-1] and left_count == 0: |
| | | # # 离下单位置最近的一个撤单,必须触发撤单 |
| | |
| | | if not must_buy: |
| | | 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"L后计算范围:{start_index}-{end_index},已撤单比例:{rate}/{thresh_hold_rate}") |
| | | l2_log.l_cancel_debug(code, |
| | | f"L后计算范围:{start_index}-{end_index},已撤单比例:{rate}/{thresh_hold_rate}, 下单位之后的索引:{after_place_order_index_dict}") |
| | | if rate >= thresh_hold_rate: |
| | | canceled_indexes.sort() |
| | | l2_log.l_cancel_debug(code, f"L后撤单,撤单位置:{canceled_indexes[-1]}") |
| | |
| | | def cancel_success(self, code): |
| | | self.clear(code) |
| | | |
| | | def test(self): |
| | | code = "000333" |
| | | self.__set_cancel_l_down_after_place_order_index(code, 121, 0) |
| | | time.sleep(6) |
| | | self.__set_cancel_l_down_after_place_order_index(code, 121, 0), |
| | | time.sleep(6) |
| | | self.__set_cancel_l_down_after_place_order_index(code, 122, 1) |
| | | |
| | | print(self.__get_cancel_l_down_after_place_order_index_dict(code)) |
| | | |
| | | |
| | | # 新F撤,根据成交数据来撤 |
| | | class FCancelBigNumComputer: |