Administrator
2023-02-08 3ec79004bd769828c8dc18ed35280f81cfb473ff
l2/cancel_buy_strategy.py
@@ -12,12 +12,12 @@
import big_money_num_manager
import constant
import gpcode_manager
import l2_data_log
import l2_data_util
from db import redis_manager
import tool
from l2.transaction_progress import TradeBuyQueue
from trade import trade_data_manager, trade_queue_manager, l2_trade_factor
from l2 import l2_log
from l2 import l2_log, l2_data_log
from l2.l2_data_util import L2DataUtil, local_today_num_operate_map, local_today_datas
from log import logger_buy_1_volumn
@@ -60,9 +60,15 @@
    # 计算净大单
    @classmethod
    def __compute_left_big_num(cls, code, start_index, end_index, total_data):
    def __compute_left_big_num(cls, code, buy_single_index, start_index, end_index, total_data, place_order_count):
        # 获取大单的最小手数
        left_big_num = 0
        # 点火大单数量
        fire_count = 5
        if place_order_count <= 4:
            fire_count = 6 - place_order_count
        else:
            fire_count = 2
        for i in range(start_index, end_index + 1):
            data = total_data[i]
            val = data["val"]
@@ -71,14 +77,21 @@
                continue
            if L2DataUtil.is_limit_up_price_buy(val):
                left_big_num += val["num"] * data["re"]
                if i - buy_single_index < fire_count:
                    # 点火大单不算
                    left_big_num += 0
                else:
                    left_big_num += val["num"] * data["re"]
            elif L2DataUtil.is_limit_up_price_buy_cancel(val):
                # 查询买入位置
                buy_index, buy_data = l2_data_util.get_buy_data_with_cancel_data(data,
                                                                                 local_today_num_operate_map.get(
                                                                                     code))
                if buy_index is not None and start_index <= buy_index <= end_index:
                    left_big_num -= val["num"] * data["re"]
                    if buy_index - buy_single_index < fire_count:
                        left_big_num -= 0
                    else:
                        left_big_num -= val["num"] * data["re"]
                elif buy_index is None:
                    # 有部分撤销从而导致的无法溯源,这时就需要判断预估买入时间是否在a_start_index到a_end_index的时间区间
                    min_space, max_space = l2_data_util.compute_time_space_as_second(val["cancelTime"],
@@ -112,10 +125,14 @@
        # 如果start_index与buy_single_index相同,即是下单后的第一次计算
        # 需要查询买入信号之前的同1s是否有涨停撤的数据
        process_index = -1
        process_index = process_index_old
        # 下单次数
        place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code)
        if buy_single_index == start_index:
            # 第1次计算需要计算买入信号-执行位的净值
            left_big_num = cls.__compute_left_big_num(code, buy_single_index, buy_exec_index, total_data)
            left_big_num = cls.__compute_left_big_num(code, buy_single_index, buy_single_index, buy_exec_index,
                                                      total_data, place_order_count)
            buy_num += left_big_num
            # 设置买入信号-买入执行位的数据不需要处理
            start_index = end_index + 1
@@ -139,13 +156,16 @@
            for i in range(start_index, end_index + 1):
                data = total_data[i]
                val = data["val"]
                process_index = i
                if process_index_old >= i:
                    # 已经处理过的数据不需要处理
                    continue
                if not l2_data_util.is_big_money(val):
                    continue
                process_index = i
                if L2DataUtil.is_limit_up_price_buy_cancel(val):
                if L2DataUtil.is_limit_up_price_buy(val):
                    buy_num += data["re"] * int(val["num"])
                elif L2DataUtil.is_limit_up_price_buy_cancel(val):
                    # 查询买入位置
                    buy_index, buy_data = l2_data_util.get_buy_data_with_cancel_data(data,
                                                                                     local_today_num_operate_map.get(
@@ -161,56 +181,42 @@
                            buy_time = tool.trade_time_add_second(val["time"], 0 - min_space)
                            if int(total_data[buy_single_index]["val"]["time"].replace(":", "")) <= int(
                                    buy_time.replace(":", "")):
                                cancel_num += buy_data["re"] * int(buy_data["val"]["num"])
                                cancel_num += data["re"] * int(val["num"])
                    # 保存数据
                    if need_cancel:
                        cancel_rate_threshold = constant.S_CANCEL_FIRST_RATE
                        place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code)
                        if place_order_count <= 1:
                            cancel_rate_threshold = constant.S_CANCEL_FIRST_RATE
                        elif place_order_count <= 2:
                            cancel_rate_threshold = constant.S_CANCEL_SECOND_RATE
                        else:
                            cancel_rate_threshold = constant.S_CANCEL_THIRD_RATE
                        if cancel_num / buy_num > cancel_rate_threshold:
                        if cancel_num / max(buy_num, 1) > cancel_rate_threshold:
                            return True, total_data[i]
        finally:
            l2_log.cancel_debug(threadId, code, "S级大单 范围:{}-{} 取消计算结果:{}/{}", start_index, end_index, cancel_num,
                                buy_num)
            l2_log.cancel_debug(threadId, code, "S级大单 范围:{}-{} 取消计算结果:{}/{},比例:{}", start_index, end_index, cancel_num,
                                buy_num, round(cancel_num / buy_num, 2))
            # 保存处理进度与数据
            cls.__save_compute_data(code, process_index, buy_num, cancel_num)
        return False, None
    # 下单成功
    @classmethod
    def place_order_success(cls, code, buy_single_index, buy_exec_index):
    def cancel_success(cls, code):
        cls.__clear_data(code)
# --------------------------------H撤-------------------------------
class HourCancelBigNumComputer:
    __redis_manager = redis_manager.RedisManager(0)
    __tradeBuyQueue = TradeBuyQueue()
    @classmethod
    def __getRedis(cls):
        return cls.__redis_manager.getRedis()
    # 保存成交进度
    @classmethod
    def __save_trade_progress(cls, code, index):
        key = f"trade_progress_index-{code}"
        cls.__getRedis().setex(key, tool.get_expire(), index)
    # 保存成交进度
    @classmethod
    def __get_trade_progress(cls, code):
        key = f"trade_progress_index-{code}"
        val = cls.__getRedis().get(key)
        if val is None:
            return None
        return int(val)
    @classmethod
    def __save_watch_index_set(cls, code, datas):
@@ -320,30 +326,33 @@
    @classmethod
    def place_order_success(cls, code, buy_single_index, buy_exec_index, total_data, local_today_num_operate_map):
        cls.__clear_data(code)
        cls.set_trade_progress(code, buy_exec_index, total_data, local_today_num_operate_map)
        cls.set_trade_progress(code, buy_exec_index, total_data, local_today_num_operate_map, True)
    # 设置成交进度
    @classmethod
    def set_trade_progress(cls, code, index, total_data, local_today_num_operate_map):
    def set_trade_progress(cls, code, index, total_data, local_today_num_operate_map, is_default=False):
        l2_log.cancel_debug(0, code, "成交进度:{}", index)
        last_index, is_default = cls.__tradeBuyQueue.get_traded_index(code)
        # 成交进度
        cls.__save_trade_progress(code, index)
        cls.compute_watch_end_index(code, total_data, local_today_num_operate_map)
        if is_default:
            cls.__tradeBuyQueue.set_default_traded_index(code, index)
        if last_index is None or last_index != index:
            cls.compute_watch_end_index(code, total_data, local_today_num_operate_map)
    @classmethod
    def compute_watch_end_index(cls, code, total_data, local_today_num_operate_map):
        trade_progress_index = cls.__get_trade_progress(code)
        threshold_money = l2_trade_factor.L2TradeFactorUtil.compute_m_value(code) * 2
        # 最小值1500万
        if threshold_money < 15000000:
            threshold_money = 15000000
        trade_progress_index, is_default = cls.__tradeBuyQueue.get_traded_index(code)
        threshold_money, msg = l2_trade_factor.L2TradeFactorUtil.compute_m_value(code)
        if threshold_money < constant.H_CANCEL_MIN_MONEY:
            threshold_money = constant.H_CANCEL_MIN_MONEY
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        threshold_num = round(threshold_money / (limit_up_price * 100))
        if trade_progress_index is None:
            raise Exception("尚未获取到成交进度")
        total_num = 0
        watch_set = set()
        for i in range(trade_progress_index + 1, total_data[-1]["index"] + 1):
        total_count = 0
        for i in range(trade_progress_index, total_data[-1]["index"] + 1):
            data = total_data[i]
            val = data["val"]
            if L2DataUtil.is_limit_up_price_buy(val):
@@ -360,15 +369,20 @@
                            # 已经买撤
                            total_num -= buy_data["val"]["num"] * cancel_data["re"]
                            canceled = True
                            if data["re"] - cancel_data["re"] > 0:
                                watch_set.add((i, data["re"] - cancel_data["re"]))
                            count = data["re"] - cancel_data["re"]
                            if count > 0:
                                total_count += count
                                watch_set.add((i, count))
                            break
                if not canceled:
                    watch_set.add((i, data["re"]))
                    count = data["re"]
                    total_count += count
                    watch_set.add((i, count))
                # 判断是否达到阈值
                if total_num >= threshold_num:
                    l2_log.cancel_debug(0, code, "获取到H撤监听数据:{}", json.dumps(watch_set))
                if total_num >= threshold_num and total_count >= constant.H_CANCEL_MIN_COUNT:
                    # 最小8笔
                    l2_log.cancel_debug(0, code, "获取到H撤监听数据:{}", json.dumps(list(watch_set)))
                    break
        # 保存计算范围
        cls.__save_watch_index_set(code, watch_set)