| | |
| | | from l2.huaxin import l2_huaxin_util |
| | | from l2.l2_data_manager import OrderBeginPosInfo |
| | | from l2.l2_sell_manager import L2LimitUpSellManager |
| | | from l2.l2_transaction_data_manager import HuaXinBuyOrderManager |
| | | from l2.l2_transaction_data_manager import HuaXinBuyOrderManager, HuaXinSellOrderStatisticManager |
| | | from log_module import async_log_util |
| | | from trade.deal_big_money_manager import DealOrderNoManager |
| | | from trade.sell.sell_rule_manager import TradeRuleManager |
| | |
| | | from l2 import l2_log, l2_data_source_util |
| | | from l2.l2_data_util import L2DataUtil, local_today_num_operate_map, local_today_datas, local_today_buyno_map, \ |
| | | local_today_canceled_buyno_map |
| | | from log_module.log import logger_buy_1_volumn, logger_l2_l_cancel, logger_l2_h_cancel |
| | | from log_module.log import logger_buy_1_volumn, logger_l2_l_cancel, logger_l2_h_cancel, logger_l2_s_cancel |
| | | from utils.tool import CodeDataCacheUtil |
| | | |
| | | |
| | |
| | | __recompute_l_down_time_dict = {} |
| | | # 最近处理的卖单号 |
| | | __latest_process_sell_order_no = {} |
| | | |
| | | # S慢砸包含的范围 |
| | | __s_slow_sell_watch_indexes_dict = {} |
| | | |
| | | # 成交进度位置 |
| | | __trade_progress_index_dict = {} |
| | | |
| | | __instance = None |
| | | |
| | |
| | | def __clear_data(self, code): |
| | | CodeDataCacheUtil.clear_cache(self.__s_cancel_real_place_order_index_cache, code) |
| | | CodeDataCacheUtil.clear_cache(self.__s_down_watch_indexes_dict, code) |
| | | |
| | | CodeDataCacheUtil.clear_cache(self.__trade_progress_index_dict, code) |
| | | CodeDataCacheUtil.clear_cache(self.__s_slow_sell_watch_indexes_dict, code) |
| | | ks = ["s_big_num_cancel_compute_data-{}".format(code), "s_cancel_real_place_order_index-{}".format(code)] |
| | | for key in ks: |
| | | RedisUtils.delete_async(self.__db, key) |
| | |
| | | # 设置真实下单位置 |
| | | def set_real_place_order_index(self, code, index, is_default): |
| | | self.__save_real_place_order_index(code, index, is_default) |
| | | if not is_default: |
| | | self.__compute_s_slow_sell(code) |
| | | |
| | | def set_transaction_index(self, code, buy_single_index, index): |
| | | self.__trade_progress_index_dict[code] = index |
| | | self.__compute_s_slow_sell(code) |
| | | |
| | | def clear_data(self): |
| | | ks = ["s_big_num_cancel_compute_data-*", "s_cancel_real_place_order_index-*"] |
| | |
| | | if left_count > 0: |
| | | total_num += val["num"] |
| | | |
| | | # 大于300w |
| | | if total_deal_money >= 300 * 10000: |
| | | total_money = total_num * 100 * big_sell_order_info[1][-1][2] |
| | | deal_rate = round(total_deal_money / total_money, 4) |
| | | if deal_rate >= 0.3: |
| | | l2_log.s_cancel_debug(code, f"S撤触发的卖单:{big_sell_order_info}") |
| | | return True, f"有300w大卖单成交比例:{deal_rate}({total_deal_money}/{total_money})" |
| | | # 大于10w |
| | | if total_deal_money >= 10 * 10000: |
| | | cancel_result = self.__need_cancel_for_slow_sell(code,total_datas) |
| | | if cancel_result[0]: |
| | | return True, f"S慢砸:{ cancel_result[1]}" |
| | | |
| | | if total_deal_money >= 100 * 10000: |
| | | start_order_no = big_sell_order_info[1][-1][4][1] |
| | |
| | | real_trade_index, latest_deal_time_ms)) |
| | | |
| | | return False, "" |
| | | |
| | | def __need_cancel_for_slow_sell(self, code, total_datas): |
| | | if code not in self.__s_slow_sell_watch_indexes_dict: |
| | | return False, "S慢砸没有囊括" |
| | | # 下单3分钟内有效 |
| | | real_place_order_info = self.get_real_place_order_index_cache(code) |
| | | if not real_place_order_info: |
| | | return False, "没有获取到真实下单位" |
| | | if tool.trade_time_sub(total_datas[-1]['val']['time'], |
| | | total_datas[real_place_order_info[0]]['val']['time']) > 180: |
| | | return False, "超过守护时间" |
| | | |
| | | # 格式:[{监听index},当时正在成交的订单号,已经成交的手数] |
| | | watch_info = self.__s_slow_sell_watch_indexes_dict.get(code) |
| | | # 计算总买额 |
| | | total_num = 0 |
| | | for i in watch_info[0]: |
| | | data = total_datas[i] |
| | | val = data['val'] |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, i, |
| | | total_datas, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if left_count > 0: |
| | | total_num += val['num'] |
| | | if val['orderNo'] == watch_info[1]: |
| | | total_num -= watch_info[2] |
| | | min_index = min(watch_info[0]) |
| | | sell_orders = HuaXinSellOrderStatisticManager.get_latest_transaction_datas(code,total_datas[min_index]['val']['orderNo']) |
| | | sell_order_num = sum([x[1] for x in sell_orders]) // 100 |
| | | rate = round(sell_order_num/total_num,2) |
| | | if rate > 0.49: |
| | | return True, f"慢砸成交比例:{rate}/0.49" |
| | | else: |
| | | return False, f"尚未触发撤单比例:{rate}" |
| | | |
| | | |
| | | |
| | | # 计算S后撤监听的数据范围 |
| | | def __compute_down_cancel_watch_index(self, code, big_sell_order_info, total_datas): |
| | |
| | | # self.__compute_down_cancel_watch_index(code, big_sell_order_info, total_datas) |
| | | return False, "不满足撤单条件" |
| | | finally: |
| | | self.__latest_process_sell_order_no[code] = big_sell_order_info[1][-1][0] |
| | | # self.__latest_process_sell_order_no[code] = big_sell_order_info[1][-1][0] |
| | | pass |
| | | |
| | | def need_cancel_for_down(self, code, start_index, end_index): |
| | | watch_index_info = self.__s_down_watch_indexes_dict.get(code) |
| | |
| | | |
| | | return False, "没达到撤单比例" |
| | | |
| | | # ----------------------------S慢砸范围计算------------------------------------ |
| | | def __compute_s_slow_sell(self, code): |
| | | try: |
| | | if code in self.__s_slow_sell_watch_indexes_dict: |
| | | return |
| | | real_place_order_info = self.__get_real_place_order_index_info_cache(code) |
| | | if not real_place_order_info or real_place_order_info[1]: |
| | | return |
| | | trade_index = self.__trade_progress_index_dict.get(code) |
| | | if trade_index is None: |
| | | return |
| | | start_index = trade_index |
| | | end_index = real_place_order_info[0] |
| | | total_datas = local_today_datas.get(code) |
| | | watch_indexes = set() |
| | | for i in range(start_index, end_index): |
| | | data = total_datas[i] |
| | | val = data['val'] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | if val['num'] * float(val['price']) < 5000: |
| | | continue |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, i, |
| | | total_datas, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if left_count > 0: |
| | | watch_indexes.add(i) |
| | | |
| | | dealing_order_no = None |
| | | dealed_num = 0 |
| | | # 格式:[监听的索引,正在成交索引,已成交的数量] |
| | | dealing_info = HuaXinBuyOrderManager.get_dealing_order_info(code) |
| | | if dealing_info: |
| | | dealing_order_no = dealing_info[0] |
| | | dealed_num = dealing_info[1] // 100 |
| | | watch_info = [watch_indexes, dealing_order_no, dealed_num] |
| | | self.__s_slow_sell_watch_indexes_dict[code] = watch_info |
| | | l2_log.s_cancel_debug(code, f"S慢砸监听范围:{watch_info}") |
| | | except Exception as e: |
| | | logger_l2_s_cancel.exception(e) |
| | | |
| | | |
| | | # --------------------------------H撤------------------------------- |
| | | class HourCancelBigNumComputer: |