Administrator
3 天以前 d163fc446359d66afa10e2ab63e860887aa8732c
连续涨停时间记录/新增大单概览接口
5个文件已修改
209 ■■■■■ 已修改文件
api/outside_api_command_callback.py 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cancel_strategy/s_l_h_cancel_strategy.py 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
code_attribute/today_max_price_manager.py 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constant.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
servers/data_server.py 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api/outside_api_command_callback.py
@@ -1439,7 +1439,8 @@
                                    "ignore_block_in_money_market_strong": constant.IGNORE_BLOCK_IN_MONEY_MARKET_STRONG,
                                    "buy_first_limit_up": 1 if constant.CAN_BUY_FIRST_LIMIT_UP else 0,
                                    "can_auto_add_white": 1 if constant.CAN_AUTO_ADD_WHITE else 0,
                                    "can_auto_add_want_buy_codes": 1 if constant.CAN_AUTO_ADD_WANT_BUY_CODES else 0
                                    "can_auto_add_want_buy_codes": 1 if constant.CAN_AUTO_ADD_WANT_BUY_CODES else 0,
                                    "can_auto_l_down_rate_change": 1 if constant.CAN_AUTO_L_DOWN_RATE_CHANGE else 0
                                    }}
                self.send_response({"code": 0, "data": data, "msg": f""},
                                   client_id,
@@ -1469,6 +1470,12 @@
                    if radical_buy.get('can_auto_add_want_buy_codes') is not None:
                        constant.CAN_AUTO_ADD_WANT_BUY_CODES = True if radical_buy.get(
                            'can_auto_add_want_buy_codes') else False
                    if radical_buy.get('can_auto_l_down_rate_change') is not None:
                        constant.CAN_AUTO_L_DOWN_RATE_CHANGE = True if radical_buy.get(
                            'can_auto_l_down_rate_change') else False
                self.send_response({"code": 0, "data": {}, "msg": f""},
                                   client_id,
@@ -1574,7 +1581,7 @@
                # if rate < old_rate:
                # 改小才能重新囊括
                trade_record_log_util.add_common_msg(code, "L后重新囊括", msg=f"修改撤单比例: {old_rate}->{rate}")
                LCancelBigNumComputer().re_compute_l_down_watch_indexes(code, is_force=True)
                LCancelBigNumComputer().re_compute_l_down_watch_indexes(code, is_force=True, is_human=True)
                self.send_response({"code": 0, "data": {}},
                                   client_id,
cancel_strategy/s_l_h_cancel_strategy.py
@@ -4,6 +4,7 @@
import constant
from code_attribute import gpcode_manager, code_volumn_manager
from code_attribute.today_max_price_manager import MaxPriceInfoManager
from db import redis_manager_delegate as redis_manager
from db.redis_manager_delegate import RedisUtils
from l2.code_price_manager import Buy1PriceManager
@@ -590,9 +591,7 @@
                    return max(constant.L_CANCEL_RATE_WITH_MUST_BUY_FOR_REDICAL_BUY, human_rate), True, (
                        constant.L_CANCEL_RATE_WITH_MUST_BUY_FOR_REDICAL_BUY, human_rate)
                else:
                    # deal_big_order_info = radical_buy_data_manager.get_total_deal_big_order_info(code,
                    #                                                                              gpcode_manager.get_limit_up_price_as_num(
                    #                                                                                  code))
                    # # 根据成交额的大单成交占比来计算撤单比例
                    # big_money_rate = radical_buy_data_manager.TotalDealBigOrderInfoManager.get_big_order_rate(code)
                    # if big_money_rate is not None:
@@ -610,6 +609,18 @@
                    #         # 大单足够,将基础比例调整至79%
                    #         threshold_rate = max(threshold_rate, 0.79)
                    threshold_rate = constant.L_CANCEL_RATE
                    if constant.CAN_AUTO_L_DOWN_RATE_CHANGE:
                        # TODO 最长涨停时间超过1分钟
                        try:
                            if MaxPriceInfoManager().get_max_limit_up_time(code) > 60:
                                deal_big_order_info = radical_buy_data_manager.get_total_deal_big_order_info(code,
                                                                                                             gpcode_manager.get_limit_up_price_as_num(
                                                                                                                 code))
                                if deal_big_order_info:
                                    temp_rate = round(deal_big_order_info[1] / deal_big_order_info[5], 2)
                                    threshold_rate = min(max(temp_rate, 0.3), 0.9)
                        except:
                            pass
                    return human_rate if human_rate > 0 else threshold_rate, False, (threshold_rate, human_rate)
            if must_buy:
                if is_up:
@@ -956,7 +967,7 @@
        # 重新计算L上
    # big_sell_info卖单信息,格式:[最近成交索引,最近成交时间(带毫秒)]
    def re_compute_l_down_watch_indexes(self, code, big_sell_info=None, is_force=False):
    def re_compute_l_down_watch_indexes(self, code, big_sell_info=None, is_force=False, is_human=False):
        watch_index_info = self.__cancel_watch_index_info_cache.get(code)
        if not is_force:
            if not watch_index_info or watch_index_info[1] > 0:
@@ -976,13 +987,13 @@
                                 real_place_order_index_info[0],
                                 re_compute=1, min_cancel_time_with_ms=min_cancel_time_with_ms,
                                 msg=f"大单卖: 成交进度-{big_sell_info}" if big_sell_info is not None else '',
                                 is_force=is_force)
                                 is_force=is_force, is_human=is_human)
    # 计算观察索引,倒序计算
    # re_compute:是否是重新计算的
    # min_cancel_time_with_ms:最小撤单时间,大于等于此时间的撤单需要囊括进去
    def compute_watch_index(self, code, buy_single_index, start_index, end_index, re_compute=0,
                            min_cancel_time_with_ms=None, msg="", is_force=False):
                            min_cancel_time_with_ms=None, msg="", is_force=False, is_human=False):
        try:
            l2_log.l_cancel_debug(code, f"计算L后囊括范围:{start_index}-{end_index}")
            total_datas = local_today_datas.get(code)
@@ -1037,7 +1048,11 @@
                MIN_MONEYS = [300, 200, 100]
                watch_indexes = set()
                for min_money in MIN_MONEYS:
                    for i in range(end_index, re_start_index - 1, -1):
                    start_index_for_compute = re_start_index - 1
                    if is_human and min_money >= 300:
                        # 人为囊括优先囊括所有大单
                        start_index_for_compute = start_index - 1
                    for i in range(end_index, start_index_for_compute, -1):
                        try:
                            data = total_datas[i]
                            val = data['val']
@@ -1134,9 +1149,11 @@
                        big_order_list.sort(key=lambda x: x[1], reverse=True)
                        watch_indexes |= set([x[0] for x in big_order_list[:2]])
                    # 获取真实下单位后面10笔大单
                    watch_indexes_after = self.__compute_l_down_watch_index_after_real_place_order_index(code)
                    if watch_indexes_after:
                        watch_indexes |= watch_indexes_after
                    if not is_human:
                        # 人为不需要设置
                        watch_indexes_after = self.__compute_l_down_watch_index_after_real_place_order_index(code)
                        if watch_indexes_after:
                            watch_indexes |= watch_indexes_after
                    self.__set_watch_indexes(code, buy_single_index, re_compute, watch_indexes)
                    l2_log.l_cancel_debug(code,
                                          f"设置监听范围({msg}){'(重新计算)' if re_compute else ''}, 数据范围:{re_start_index}-{end_index} 监听范围-{watch_indexes}")
@@ -1561,9 +1578,8 @@
        # 计算监听的总条数
        total_num = 0
        # 超大单的手数
        super_big_num_thresold = int(2e7/gpcode_manager.get_limit_up_price_as_num(code)/100)
        super_big_num_thresold = int(2e7 / gpcode_manager.get_limit_up_price_as_num(code) / 100)
        max_num, max_num_count = 0, 0
        thresh_hold_rate, must_buy, cancel_rate_info = LCancelRateManager.get_cancel_rate(code)
        for wi in watch_indexes:
@@ -2045,6 +2061,106 @@
    def cancel_success(self, code):
        self.clear(code)
    def statistic_l_down_watch_indexes_of_big_order_info(self, code):
        """
        统计L后的大单信息
        @param code:
        @return: 囊括金额列表, 成交金额列表, 撤单金额列表, 待成交列表
        """
        watch_indexes_info = self.__get_watch_indexes_cache(code)
        if not watch_indexes_info:
            return None
        trade_index, is_default = TradeBuyQueue().get_traded_index(code)
        if trade_index is None:
            trade_index = 0
        real_place_order_index_info = self.__real_place_order_index_dict.get(code)
        if not real_place_order_index_info:
            return None
        total_datas = local_today_datas.get(code)
        # 统计囊括,已成,已撤,待成交
        all_indexes = set()
        deal_indexes = set()
        canceled_indexes = set()
        not_deal_indexes = set()
        for index in watch_indexes_info[2]:
            if index > real_place_order_index_info[0]:
                continue
            all_indexes.add(index)
            data = total_datas[index]
            val = data["val"]
            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:
                canceled_indexes.add(index)
                continue
            if index < trade_index:
                deal_indexes.add(index)
                continue
            not_deal_indexes.add(index)
        all_money_list = [int(float(total_datas[x]['val']['price'] * total_datas[x]['val']['num'] * 100)) for x in
                          all_indexes]
        deal_money_list = [int(float(total_datas[x]['val']['price'] * total_datas[x]['val']['num'] * 100)) for x in
                           deal_indexes]
        canceled_money_list = [int(float(total_datas[x]['val']['price'] * total_datas[x]['val']['num'] * 100)) for x in
                               canceled_indexes]
        not_deal_money_list = [int(float(total_datas[x]['val']['price'] * total_datas[x]['val']['num'] * 100)) for x in
                               not_deal_indexes]
        return all_money_list, deal_money_list, canceled_money_list, not_deal_money_list
    def statistic_total_big_order_info(self, code):
        """
        统计L后的大单信息
        @param code:
        @return: 囊括金额列表, 成交金额列表, 撤单金额列表, 待成交列表
        """
        trade_index, is_default = TradeBuyQueue().get_traded_index(code)
        if trade_index is None:
            trade_index = 0
        real_place_order_index_info = self.__real_place_order_index_dict.get(code)
        if not real_place_order_index_info:
            return None
        total_datas = local_today_datas.get(code)
        # 统计囊括,已成,已撤,待成交
        all_indexes = set()
        deal_indexes = set()
        canceled_indexes = set()
        not_deal_indexes = set()
        big_money_threshold = l2_data_util.get_big_money_val(gpcode_manager.get_limit_up_price_as_num(code), tool.is_ge_code(code))
        big_num_threshold = int(big_money_threshold/gpcode_manager.get_limit_up_price_as_num(code)/100)
        for index in range(0,total_datas[-1]):
            data = total_datas[index]
            val = data["val"]
            if val['num']<big_num_threshold:
                continue
            if not L2DataUtil.is_limit_up_price_buy(val):
                continue
            all_indexes.add(index)
            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:
                canceled_indexes.add(index)
                continue
            if index < trade_index:
                deal_indexes.add(index)
                continue
            not_deal_indexes.add(index)
        all_money_list = [int(float(total_datas[x]['val']['price'] * total_datas[x]['val']['num'] * 100)) for x in
                          all_indexes]
        deal_money_list = [int(float(total_datas[x]['val']['price'] * total_datas[x]['val']['num'] * 100)) for x in
                           deal_indexes]
        canceled_money_list = [int(float(total_datas[x]['val']['price'] * total_datas[x]['val']['num'] * 100)) for x in
                               canceled_indexes]
        not_deal_money_list = [int(float(total_datas[x]['val']['price'] * total_datas[x]['val']['num'] * 100)) for x in
                               not_deal_indexes]
        return all_money_list, deal_money_list, canceled_money_list, not_deal_money_list
    def statistic_l_down_watch_indexes_info(self, code):
        """
        统计L后监听数据信息
code_attribute/today_max_price_manager.py
@@ -4,6 +4,7 @@
"""
import json
from code_attribute import gpcode_manager
from db import redis_manager_delegate as redis_manager
from db.redis_manager_delegate import RedisUtils
from log_module import async_log_util
@@ -13,6 +14,11 @@
class MaxPriceInfoManager:
    __max_price_info_cache = {}
    # 历史涨停数据:{代码:[(涨停时间, 炸板时间)]}
    __limit_up_records_cache = {}
    # 最近的涨停数据:{代码:涨停时间}
    __limit_up_latest_info_cache = {}
    __db = 4
    _redisManager = redis_manager.RedisManager(4)
    __instance = None
@@ -34,6 +40,16 @@
                val = json.loads(val)
                cls.__max_price_info_cache[code] = val
    def __is_limit_up(self, code, price, sell1_info):
        limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
        if not limit_up_price:
            return False
        if sell1_info[1] > 0:
            return False
        if abs(price - limit_up_price) >= 0.001:
            return False
        return True
    def set_price_info(self, code, price, time, sell1_info):
        """
        设置价格信息
@@ -51,6 +67,35 @@
        RedisUtils.setex_async(
            self.__db, "max_price_info-{}".format(code), tool.get_expire(), json.dumps(price_info))
        async_log_util.info(logger_debug, f"最大现价:{code}-{price_info}")
        if self.__is_limit_up(code, price, sell1_info):
            if code not in self.__limit_up_latest_info_cache:
                self.__limit_up_latest_info_cache[code] = time
        else:
            if code not in self.__limit_up_records_cache:
                self.__limit_up_records_cache[code] = []
            if code in self.__limit_up_latest_info_cache:
                self.__limit_up_records_cache[code].append((self.__limit_up_latest_info_cache.get(code), time))
                self.__limit_up_latest_info_cache.pop(code)
    def get_max_limit_up_time(self, code):
        """
        获取最大涨停持续时间
        @param code:
        @return:
        """
        try:
            max_space_time = 0
            if code in self.__limit_up_latest_info_cache:
                max_space_time = tool.trade_time_sub(tool.get_now_time_str(), self.__limit_up_latest_info_cache[code])
            if code in self.__limit_up_records_cache:
                max_item = max(self.__limit_up_records_cache[code], key=lambda x: tool.trade_time_sub(x[1], x[0]))
                max_space_time_his = tool.trade_time_sub(max_item[1], max_item[0])
                if max_space_time_his > max_space_time:
                    max_space_time = max_space_time_his
            return max_space_time
        except Exception as e:
            async_log_util.error(logger_debug, f"获取最大涨停时间出错:{str(e)}")
        return 0
    def get_price_info_cache(self, code):
        return self.__max_price_info_cache.get(code)
constant.py
@@ -245,4 +245,7 @@
# 可以自动加想
CAN_AUTO_ADD_WANT_BUY_CODES = True
# L后撤单比例自动变化
CAN_AUTO_L_DOWN_RATE_CHANGE = True
servers/data_server.py
@@ -36,7 +36,7 @@
from log_module import log_analyse, log_export, async_log_util
from l2 import code_price_manager, l2_data_util, transaction_progress
from cancel_strategy.s_l_h_cancel_strategy import HourCancelBigNumComputer, LCancelRateManager, \
    CancelRateHumanSettingManager
    CancelRateHumanSettingManager, LCancelBigNumComputer
from output.limit_up_data_filter import IgnoreCodeManager
from third_data import kpl_util, kpl_data_manager, kpl_api, block_info
from third_data.code_plate_key_manager import RealTimeKplMarketData, KPLPlateForbiddenManager
@@ -1197,6 +1197,14 @@
                response_data = json.dumps({"code": 0, "data": fdatas})
            except Exception as e:
                logger_debug.exception(e)
        elif url.path == "/get_l2_down_watch_index_overview":
            ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()])
            code = ps_dict.get('code')
            # 大单概览
            l2_down_data = LCancelBigNumComputer().statistic_l_down_watch_indexes_of_big_order_info(code)
            total_big_order_info = LCancelBigNumComputer().statistic_total_big_order_info(code)
            response_data = json.dumps({"code": 0, "data": {"l_down":l2_down_data,"total":total_big_order_info}})
        async_log_util.info(logger_request_api, f"结束请求{tool.get_thread_id()}-{url}")
        self.send_response(200)
        # 发给请求客户端的响应数据