Administrator
2023-03-17 8b848e8a9fa242b39f92f3a28faf89be10a6e456
首板策略优化
16个文件已修改
2个文件已添加
669 ■■■■■ 已修改文件
alert_util.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
code_volumn_manager.py 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constant.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
gpcode_manager.py 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
juejin.py 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/cancel_buy_strategy.py 82 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/code_price_manager.py 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager.py 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/safe_count_manager.py 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/transaction_progress.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2_data_util.py 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2_trade_test.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ths/l2_listen_pos_health_manager.py 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/l2_trade_factor.py 120 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_manager.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_queue_manager.py 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_result_manager.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
alert_util.py
@@ -9,6 +9,7 @@
def alarm():
    return
    if not tool.is_alert_time() or constant.TEST:
        return
    # TODO 暂时关闭报警
code_volumn_manager.py
@@ -51,6 +51,24 @@
    return _volumn
# 获取量比(今日量/max(60天最大量,昨日量))
def get_volume_rate(code):
    today = get_today_volumn(code)
    max60, yesterday = get_histry_volumn(code)
    if today is None or max60 is None or yesterday is None:
        raise Exception("获取量失败")
    return round(int(today) / max(int(max60), int(yesterday)), 2)
# 获取量比索引
def get_volume_rate_index(volume_rate):
    rates = [0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6]
    for index in range(0, len(rates)):
        if volume_rate <= rates[index]:
            return index
    return len(rates) - 1
# 保存今日量
def save_today_volumn(code, volumn, volumnUnit):
    _volumn = None
constant.py
@@ -10,7 +10,7 @@
BIG_MONEY_NUM = 7888
# S撤比例
S_CANCEL_FIRST_RATE = 0.69
S_CANCEL_MIN_MONEY = 98
S_CANCEL_SECOND_RATE = 0.59
S_CANCEL_THIRD_RATE = 0.49
# s撤守护时间
@@ -18,9 +18,7 @@
# H撤比例
H_CANCEL_FIRST_RATE = 0.69
H_CANCEL_SECOND_RATE = 0.59
H_CANCEL_THIRD_RATE = 0.49
H_CANCEL_MIN_MONEY = 10000000
H_CANCEL_MIN_MONEY = 98
H_CANCEL_MIN_COUNT = 40
H_CANCEL_MIN_BIG_NUM_COUNT = 3
gpcode_manager.py
@@ -11,6 +11,8 @@
import tool
import decimal
from ths import l2_listen_pos_health_manager
__redisManager = redis_manager.RedisManager(0)
@@ -80,7 +82,7 @@
        return val.get(name)
    @classmethod
    def add_first_code_name(cls, code,name):
    def add_first_code_name(cls, code, name):
        val = cls.__get_redis().get("gp_list_names_first")
        if not val:
            return None
@@ -153,6 +155,36 @@
            return True
        else:
            return False
# 想要买的代码
class WantBuyCodesManager:
    redisManager = redis_manager.RedisManager(0)
    __redis_key = "want_buy_codes"
    @classmethod
    def __get_redis(cls):
        return cls.redisManager.getRedis()
    @classmethod
    def clear(cls):
        cls.__get_redis().delete(cls.__redis_key)
    @classmethod
    def add_code(cls, code):
        cls.__get_redis().sadd(cls.__redis_key, code)
    @classmethod
    def remove_code(cls, code):
        cls.__get_redis().srem(cls.__redis_key, code)
    @classmethod
    def is_in(cls, code):
        return cls.__get_redis().sismember(cls.__redis_key, code)
    @classmethod
    def list_code(cls):
        return cls.__get_redis().smembers(cls.__redis_key)
def __parse_codes_data(code_datas):
@@ -480,12 +512,13 @@
        client_ids = client_manager.getValidL2Clients()
    else:
        client_ids.append(client_id)
    random.shuffle(client_ids)
    # random.shuffle(client_ids)
    available_positions = []
    for client_id in client_ids:
        redis_instance = __redisManager.getRedis()
        k = "listen_code-{}-*".format(client_id)
        keys = redis_instance.keys(k)
        random.shuffle(keys)
        # random.shuffle(keys)
        codes = []
        for key in keys:
            index = key.split("-")[-1]
@@ -493,10 +526,9 @@
                continue
            result = redis_instance.get(key)
            if result is None or len(result) == 0:
                return client_id, int(key.replace("listen_code-{}-".format(client_id), ""))
                available_positions.append((client_id, int(key.replace("listen_code-{}-".format(client_id), ""))))
            else:
                codes.append((key, result))
        # 查询是否有重复的代码
        codes_set = set()
        count = 0
@@ -505,6 +537,15 @@
            codes_set.add(code[1])
            if len(codes_set) < count:
                return client_id, int(code[0].replace("listen_code-{}-".format(client_id), ""))
    if available_positions:
        # 获取健康状态
        available_positions_health_states = l2_listen_pos_health_manager.list_health_state(available_positions)
        available_positions.sort(key=lambda x: available_positions_health_states[x], reverse=True)
        # 取第1个数据
        return available_positions[0][0], available_positions[0][1]
    return None, None
@@ -591,6 +632,4 @@
if __name__ == '__main__':
    print(get_free_listen_pos_count())
    print(get_name_code("华脉科技"))
    print(get_name_codes())
    print(get_can_listen_pos())
juejin.py
@@ -85,8 +85,8 @@
        l2_trade_util.init_forbidden_trade_codes()
        # 清空白名单
        l2_trade_util.WhiteListCodeManager.clear()
    # TODO 删除所有首板代码
        # 清空想要买
        gpcode_manager.WantBuyCodesManager.clear()
# 每日初始化
@@ -477,11 +477,11 @@
        return f_results
    @classmethod
    def get_history_tick_n(cls, code, count):
    def get_history_tick_n(cls, code, count, fields=None):
        account_id, s_id, token = getAccountInfo()
        symbols = gpcode_manager.get_gp_list_with_prefix([code])
        gmapi.set_token(token)
        results = gmapi.history_n(symbol=symbols[0], frequency="1d", count=count)
        results = gmapi.history_n(symbol=symbols[0], frequency="1d", count=count, fields=fields)
        return results
    @classmethod
@@ -577,24 +577,26 @@
# 获取近90天的最大量与最近的量
# 获取最近一次涨停/涨停下一个交易日的最大值
def get_volumn(code) -> object:
    end = datetime.datetime.now()
    account_id, s_id, token = getAccountInfo()
    gmapi.set_token(token)
    gmapi.set_account_id(account_id)
    results = gmapi.history_n(symbol=gpcode_manager.get_gp_list_with_prefix([code])[0], frequency="1d",
                              count=60,
                              fields="volume",
                              end_time=end)
    if not results:
        return None
    yes_volume = results[-1]["volume"]
    max_volume = results[0]["volume"]
    for result in results:
        volumn = int(result["volume"])
        if volumn > max_volume:
            max_volume = volumn
    return (max_volume, yes_volume)
    datas = JueJinManager.get_history_tick_n(code, 60, "open,high,low,close,volume,pre_close,bob")
    # 计算
    datas.sort(key=lambda x: x["bob"], reverse=True)
    max_volume = 0
    for i in range(len(datas)):
        # 查询涨停
        item = datas[i]
        volume = item["volume"]
        if max_volume < volume:
            max_volume = volume
        # 是否有涨停
        limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"]))
        if abs(limit_up_price - item["high"]) < 0.01:
            next_volume = 0
            if i > 0:
                next_volume = datas[i - 1]["volume"]
            return (max(volume, next_volume), max(volume, next_volume))
    return (max_volume, max_volume)
# 根据涨幅高低分配交易窗口
@@ -609,14 +611,4 @@
if __name__ == '__main__':
    free_count = 0
    if free_count < 2:
        # 空闲位置不足
        listen_codes = gpcode_manager.get_listen_codes()
        for code in listen_codes:
            if not gpcode_manager.is_in_gp_pool(code):
                client_id, pos = gpcode_manager.get_listen_code_pos(code)
                gpcode_manager.set_listen_code_by_pos(client_id, pos, "")
                free_count += 1
                if free_count > 2:
                    break
    print(get_volumn("002291"))
l2/cancel_buy_strategy.py
@@ -25,6 +25,7 @@
class SecondCancelBigNumComputer:
    __redis_manager = redis_manager.RedisManager(0)
    __sCancelParamsManager = l2_trade_factor.SCancelParamsManager
    @classmethod
    def __getRedis(cls):
@@ -61,20 +62,16 @@
    # 计算净大单
    @classmethod
    def __compute_left_big_num(cls, code, buy_single_index, start_index, end_index, total_data, place_order_count):
    def __compute_left_big_num(cls, code, buy_single_index, start_index, end_index, total_data, volume_rate_index):
        # 获取大单的最小手数
        left_big_num = 0
        # 点火大单数量
        fire_count = 5
        if place_order_count <= 4:
            fire_count = 6 - place_order_count
        else:
            fire_count = 2
        fire_count = cls.__sCancelParamsManager.get_max_exclude_count(volume_rate_index)
        for i in range(start_index, end_index + 1):
            data = total_data[i]
            val = data["val"]
            # 去除非大单
            if not l2_data_util.is_big_money(val):
            if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100:
                continue
            if L2DataUtil.is_limit_up_price_buy(val):
@@ -108,12 +105,15 @@
    @classmethod
    def need_cancel(cls, code, buy_single_index, buy_exec_index, start_index, end_index, total_data, is_first_code,
                    buy_volume_rate_index,
                    volume_rate_index,
                    need_cancel=True):
        if start_index >= 217:
            print("进入调试")
        # 只守护30s
        buy_exec_time = total_data[buy_exec_index]["val"]["time"]
        if tool.trade_time_sub(total_data[start_index]["val"]["time"],
                               total_data[buy_exec_index]["val"]["time"]) > constant.S_CANCEL_EXPIRE_TIME:
                               buy_exec_time) > constant.S_CANCEL_EXPIRE_TIME:
            return False, None
        l2_log.cancel_debug(code, "S级是否需要撤单,数据范围:{}-{} ", start_index, end_index)
        logger_l2_s_cancel.debug(f"code-{code} S级是否需要撤单,数据范围:{start_index}-{end_index}")
@@ -157,7 +157,8 @@
            #         if buy_index is not None and a_start_index <= buy_index <= a_end_index:
            #             # 在买入信号之后
            #             cls.__save_cancel_data(code, i)
        range_seconds = cls.__sCancelParamsManager.get_buy_time_range(buy_volume_rate_index)
        cancel_rate_threshold = cls.__sCancelParamsManager.get_cancel_rate(volume_rate_index)
        try:
            for i in range(start_index, end_index + 1):
                data = total_data[i]
@@ -166,18 +167,23 @@
                if process_index_old >= i:
                    # 已经处理过的数据不需要处理
                    continue
                if not l2_data_util.is_big_money(val):
                if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100:
                    continue
                if L2DataUtil.is_limit_up_price_buy(val):
                    buy_num += data["re"] * int(val["num"])
                    # 如果在囊括时间范围内就可以计算买
                    if tool.trade_time_sub(val["time"], buy_exec_time) <= range_seconds:
                        buy_num += data["re"] * int(val["num"])
                elif L2DataUtil.is_limit_up_price_buy_cancel(val):
                    # 查询买入位置
                    buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data(code, data,
                                                                                                     local_today_num_operate_map.get(
                                                                                                         code))
                    if buy_index is not None and buy_single_index <= buy_index:
                        cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"])
                        # 买入时间在囊括范围内
                        if tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds),
                                               total_data[buy_index]["val"]["time"]) >= 0:
                            cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"])
                    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"],
@@ -187,28 +193,21 @@
                            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 += data["re"] * int(val["num"])
                                # 买入时间在囊括范围内
                                if tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds),
                                                       total_data[buy_index]["val"]["time"]) >= 0:
                                    cancel_num += data["re"] * int(val["num"])
                    # 保存数据
                    if need_cancel:
                        cancel_rate_threshold = constant.S_CANCEL_FIRST_RATE
                        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 is_first_code:
                            cancel_rate_threshold += 0.1
                            cancel_rate_threshold = round(cancel_rate_threshold, 2)
                        if cancel_num / max(buy_num, 1) > cancel_rate_threshold:
                            return True, total_data[i]
        finally:
            l2_log.cancel_debug(code, "S级大单 范围:{}-{} 取消计算结果:{}/{},比例:{}", start_index, end_index, cancel_num,
                                buy_num, round(cancel_num / max(buy_num, 1), 2))
            l2_log.cancel_debug(code, "S级大单 范围:{}-{} 取消计算结果:{}/{},比例:{} 目标比例:{} 计算时间范围:{}", start_index, end_index, cancel_num,
                                buy_num, round(cancel_num / max(buy_num, 1), 2), cancel_rate_threshold,range_seconds)
            # 保存处理进度与数据
            cls.__save_compute_data(code, process_index, buy_num, cancel_num)
@@ -225,6 +224,7 @@
    __redis_manager = redis_manager.RedisManager(0)
    __tradeBuyQueue = TradeBuyQueue()
    __buyL2SafeCountManager = BuyL2SafeCountManager()
    __hCancelParamsManager = l2_trade_factor.HCancelParamsManager()
    @classmethod
    def __getRedis(cls):
@@ -307,12 +307,14 @@
    @classmethod
    def need_cancel(cls, code, buy_exec_index, start_index, end_index, total_data, local_today_num_operate_map,
                    buy_volume_index, volume_index,
                    is_first_code):
        time_space = tool.trade_time_sub(total_data[start_index]["val"]["time"],
                                         total_data[buy_exec_index]["val"]["time"])
        if time_space >= constant.S_CANCEL_EXPIRE_TIME - 1:
            # 开始计算需要监控的单
            cls.__compute_watch_indexs_after_exec(code, buy_exec_index, total_data, local_today_num_operate_map)
            cls.__compute_watch_indexs_after_exec(code, buy_exec_index, total_data, local_today_num_operate_map,
                                                  buy_volume_index)
        # 守护30s以外的数据
        if time_space <= constant.S_CANCEL_EXPIRE_TIME:
@@ -346,16 +348,7 @@
        l2_log.cancel_debug(code, "H级是否需要撤单,数据范围:{}-{} ", start_index, end_index)
        # 获取下单次数
        place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code)
        cancel_rate_threshold = constant.H_CANCEL_FIRST_RATE
        if place_order_count <= 1:
            cancel_rate_threshold = constant.H_CANCEL_FIRST_RATE
        elif place_order_count <= 2:
            cancel_rate_threshold = constant.H_CANCEL_SECOND_RATE
        else:
            cancel_rate_threshold = constant.H_CANCEL_THIRD_RATE
        if is_first_code:
            cancel_rate_threshold += 0.1
            cancel_rate_threshold = round(cancel_rate_threshold,2)
        cancel_rate_threshold = cls.__hCancelParamsManager.get_cancel_rate(volume_index)
        process_index = start_index
        try:
            for i in range(start_index, end_index + 1):
@@ -374,9 +367,9 @@
                        if cancel_num / total_nums > cancel_rate_threshold:
                            return True, data
        finally:
            l2_log.cancel_debug(code, "H级撤单计算结果 范围:{}-{} 处理进度:{} 取消计算结果:{}/{}", start_index, end_index,
            l2_log.cancel_debug(code, "H级撤单计算结果 范围:{}-{} 处理进度:{} 取消计算结果:{}/{} 目标撤单比例:{}", start_index, end_index,
                                process_index, cancel_num,
                                total_nums)
                                total_nums,cancel_rate_threshold)
            logger_l2_h_cancel.info(
                f"code-{code} H级撤单计算结果 范围:{start_index}-{end_index} 处理进度:{process_index} 目标比例:{cancel_rate_threshold} 取消计算结果:{cancel_num}/{total_nums}")
            # 保存处理进度与数据
@@ -475,7 +468,7 @@
            if left_count > 0:
                data = total_data[i]
                val = data["val"]
                if val["num"] * float(val["price"]) <= 9900:
                if val["num"] * float(val["price"]) <= constant.H_CANCEL_MIN_MONEY*100:
                    continue
                total_count += left_count
                watch_set.add((i, val["num"], left_count))
@@ -492,7 +485,8 @@
    # 计算执行位置之后的需要监听的数据
    @classmethod
    def __compute_watch_indexs_after_exec(cls, code, buy_exec_index, total_data, local_today_num_operate_map):
    def __compute_watch_indexs_after_exec(cls, code, buy_exec_index, total_data, local_today_num_operate_map,
                                          buy_volume_index):
        watch_list, process_index_old, total_count_old, big_num_count_old, finish = cls.__get_watch_index_set_after_exec(
            code)
        if watch_list and finish:
@@ -509,7 +503,7 @@
        big_num_count = big_num_count_old
        total_count = total_count_old
        # H撤单
        MIN_H_COUNT = l2_trade_factor.L2TradeFactorUtil.get_h_cancel_min_count(code)
        MIN_H_COUNT = cls.__hCancelParamsManager.get_max_watch_count(buy_volume_index)
        for i in range(buy_exec_index, total_data[-1]["index"] + 1):
            if i <= process_index_old:
@@ -523,7 +517,7 @@
            if left_count > 0:
                data = total_data[i]
                val = data["val"]
                if val["num"] * float(val["price"]) <= 9900:
                if val["num"] * float(val["price"]) <= constant.H_CANCEL_MIN_MONEY*100:
                    continue
                total_count += left_count
                watch_set.add((i, val["num"], left_count))
@@ -534,8 +528,8 @@
                # 判断是否达到阈值
                if total_count >= MIN_H_COUNT and big_num_count >= constant.H_CANCEL_MIN_BIG_NUM_COUNT:  # and total_num >= threshold_num
                    finished = True
                    l2_log.cancel_debug(code, "获取到H撤监听数据:{},计算截至位置:{}", json.dumps(list(watch_set)),
                                        total_data[-1]["index"])
                    l2_log.cancel_debug(code, "获取到H撤监听数据:{},计算截至位置:{},目标计算数量:{}", json.dumps(list(watch_set)),
                                        total_data[-1]["index"],MIN_H_COUNT)
                    break
        final_watch_list = list(watch_set)
l2/code_price_manager.py
New file
@@ -0,0 +1,66 @@
"""
代码价格管理
"""
import json
import tool
from db import redis_manager
class Buy1PriceManager:
    __redisManager = redis_manager.RedisManager(1)
    @classmethod
    def __get_redis(cls):
        return cls.__redisManager.getRedis()
    # 保存买1价格信息
    @classmethod
    def __save_buy1_price_info(cls, code, limit_up_time, open_limit_up_time):
        cls.__get_redis().setex(f"buy1_price_limit_up_info-{code}", tool.get_expire(),
                                json.dumps((limit_up_time, open_limit_up_time)))
    @classmethod
    def __get_buy1_price_info(cls, code):
        data = cls.__get_redis().get(f"buy1_price_limit_up_info-{code}")
        if not data:
            return None, None
        data = json.loads(data)
        return data[0], data[1]
    # 处理
    @classmethod
    def process(cls, code, buy_1_price, time_str, limit_up_price):
        # 买1价格不能小于1块
        if float(buy_1_price) < 1.0:
            return
        is_limit_up = abs(float(limit_up_price) - float(buy_1_price)) < 0.01
        old_limit_up_time, old_open_limit_up_time = cls.__get_buy1_price_info(code)
        if old_limit_up_time and old_open_limit_up_time:
            return
        if is_limit_up and old_limit_up_time is None:
            cls.__save_buy1_price_info(code, time_str, None)
        elif old_limit_up_time and not is_limit_up and old_open_limit_up_time is None:
            # 有涨停时间,当前没有涨停,之前没有打开涨停
            cls.__save_buy1_price_info(code, old_limit_up_time, time_str)
    # 是否可以下单
    @classmethod
    def is_can_buy(cls, code):
        old_limit_up_time, old_open_limit_up_time = cls.__get_buy1_price_info(code)
        if old_limit_up_time and old_open_limit_up_time:
            return True
        return False
if __name__ == "__main__":
    code = "000333"
    limit_up_price = "54.00"
    Buy1PriceManager.process("000333", "53.00", "09:56:00", limit_up_price)
    print(Buy1PriceManager.is_can_buy(code))
    Buy1PriceManager.process("000333", "54.00", "09:57:00", limit_up_price)
    print(Buy1PriceManager.is_can_buy(code))
    Buy1PriceManager.process("000333", "53.00", "09:58:00", limit_up_price)
    print(Buy1PriceManager.is_can_buy(code))
    Buy1PriceManager.process("000333", "54.00", "09:59:00", limit_up_price)
    print(Buy1PriceManager.is_can_buy(code))
l2/l2_data_manager.py
@@ -48,9 +48,9 @@
        _key = "buy_compute_index_info-{}".format(code)
        _data_json = redis.get(_key)
        if _data_json is None:
            return None, None, None, 0, 0, []
            return None, None, None, 0, 0, [],0
        _data = json.loads(_data_json)
        return _data[0], _data[1], _data[2], _data[3], _data[4], _data[5]
        return _data[0], _data[1], _data[2], _data[3], _data[4], _data[5], _data[6]
    # 设置买入点的值
    # buy_single_index 买入信号位
@@ -58,17 +58,17 @@
    # compute_index 计算位置
    # nums 累计纯买额
    @staticmethod
    def set_buy_compute_start_data(code, buy_single_index, buy_exec_index, compute_index, nums, count, max_num_sets):
    def set_buy_compute_start_data(code, buy_single_index, buy_exec_index, compute_index, nums, count, max_num_sets, volume_rate):
        redis = TradePointManager.__get_redis()
        expire = tool.get_expire()
        _key = "buy_compute_index_info-{}".format(code)
        if buy_single_index is not None:
            redis.setex(_key, expire,
                        json.dumps((buy_single_index, buy_exec_index, compute_index, nums, count, list(max_num_sets))))
                        json.dumps((buy_single_index, buy_exec_index, compute_index, nums, count, list(max_num_sets),volume_rate)))
        else:
            _buy_single_index, _buy_exec_index, _compute_index, _nums, _count, _max_num_index = TradePointManager.get_buy_compute_start_data(code)
            _buy_single_index, _buy_exec_index, _compute_index, _nums, _count, _max_num_index,_volume_rate = TradePointManager.get_buy_compute_start_data(code)
            redis.setex(_key, expire,
                        json.dumps((_buy_single_index, buy_exec_index, compute_index, nums, count, list(max_num_sets))))
                        json.dumps((_buy_single_index, buy_exec_index, compute_index, nums, count, list(max_num_sets),volume_rate)))
    # 获取撤买入开始计算的信息
    # 返回数据的内容为:撤销点索引 撤买纯买额 计算的数据索引
l2/l2_data_manager_new.py
@@ -4,6 +4,7 @@
import big_money_num_manager
import code_data_util
import code_volumn_manager
import constant
import global_util
import gpcode_manager
@@ -16,7 +17,7 @@
import tool
from trade import trade_data_manager, trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \
    trade_result_manager
from l2 import safe_count_manager, l2_data_manager, l2_data_log, l2_log, l2_data_source_util
from l2 import safe_count_manager, l2_data_manager, l2_data_log, l2_log, l2_data_source_util, code_price_manager
from l2.cancel_buy_strategy import SecondCancelBigNumComputer, HourCancelBigNumComputer, L2LimitUpMoneyStatisticUtil, \
    L2LimitUpSellStatisticUtil
from l2.l2_data_manager import L2DataException, TradePointManager
@@ -153,12 +154,13 @@
class L2TradeDataProcessor:
    unreal_buy_dict = {}
    volume_rate_info = {}
    l2BigNumForMProcessor = L2BigNumForMProcessor()
    __codeActualPriceProcessor = CodeActualPriceProcessor()
    buy1PriceManager = trade_queue_manager.Buy1PriceManager()
    __ths_l2_trade_queue_manager = trade_queue_manager.thsl2tradequeuemanager()
    __thsBuy1VolumnManager = trade_queue_manager.THSBuy1VolumnManager()
    __buyL2SafeCountManager = safe_count_manager.BuyL2SafeCountManager()
    __l2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager()
    @classmethod
    # 数据处理入口
@@ -224,6 +226,10 @@
                                           "l2数据预处理时间")
        if len(add_datas) > 0:
            # 计算量
            volume_rate = code_volumn_manager.get_volume_rate(code)
            volume_rate_index = code_volumn_manager.get_volume_rate_index(volume_rate)
            cls.volume_rate_info[code] = (volume_rate, volume_rate_index)
            # 是否为首板代码
            is_first_code = gpcode_manager.FirstCodeManager.is_in_first_record(code)
            latest_time = add_datas[len(add_datas) - 1]["val"]["time"]
@@ -315,6 +321,9 @@
                b_need_cancel, b_cancel_data = SecondCancelBigNumComputer.need_cancel(code, buy_single_index,
                                                                                      buy_exec_index, start_index,
                                                                                      end_index, total_data,
                                                                                      code_volumn_manager.get_volume_rate_index(
                                                                                          buy_volume_rate),
                                                                                      cls.volume_rate_info[code][1],
                                                                                      is_first_code)
                if b_need_cancel:
                    return b_cancel_data, "S大单撤销比例触发阈值"
@@ -333,7 +342,11 @@
                b_need_cancel, b_cancel_data = HourCancelBigNumComputer.need_cancel(code, buy_exec_index, start_index,
                                                                                    end_index, total_data,
                                                                                    local_today_num_operate_map.get(
                                                                                        code), is_first_code)
                                                                                        code),
                                                                                    code_volumn_manager.get_volume_rate_index(
                                                                                        buy_volume_rate),
                                                                                    cls.volume_rate_info[code][1],
                                                                                    is_first_code)
                if b_need_cancel and b_cancel_data:
                    return b_cancel_data, "H撤销比例触发阈值"
            except Exception as e:
@@ -380,7 +393,8 @@
        total_data = local_today_datas.get(code)
        _start_time = tool.get_now_timestamp()
        # 获取买入信号起始点
        buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = cls.__get_order_begin_pos(code)
        buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos(
            code)
        f1 = compute_safe_count()
        f2 = compute_m_big_num()
@@ -389,6 +403,9 @@
        f5 = buy_1_cancel()
        f6 = sell_cancel()
        dask_result = is_need_cancel(f1, f2, f3, f4, f5, f6)
        if is_first_code:
            dask_result = is_need_cancel(f3, f4)
        cancel_data, cancel_msg = dask_result.compute()
        _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
@@ -431,7 +448,7 @@
        if not can:
            l2_log.debug(code, "不可以下单,原因:{}", reason)
            if need_clear_data:
                buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = cls.__get_order_begin_pos(
                buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos(
                    code)
                trade_result_manager.real_cancel_success(code, buy_single_index, buy_exec_index,
                                                         local_today_datas.get(code))
@@ -492,15 +509,24 @@
        __start_time = t.time()
        # 判断是否为首板代码
        if is_first_code:
            # 首板代码且尚未涨停过的不能下单
            is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code)
            if not is_limited_up:
            if not gpcode_manager.WantBuyCodesManager.is_in(code):
                is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code)
                gpcode_manager.FirstCodeManager.add_limited_up_record([code])
                place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(
                    code)
                if place_order_count == 0:
                    trade_data_manager.placeordercountmanager.place_order(code)
                return False, True, "首板代码,且尚未涨停过"
                if not code_price_manager.Buy1PriceManager.is_can_buy(code):
                    return False, True, "首板代码,没在想要买名单中且未打开涨停板"
                if not is_limited_up:
                    return False, True, "首板代码,没在想要买名单中且未涨停过"
            # 之前的代码
            # 首板代码且尚未涨停过的不能下单
            # is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code)
            # if not is_limited_up:
            #     gpcode_manager.FirstCodeManager.add_limited_up_record([code])
            #     place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(
            #         code)
            #     if place_order_count == 0:
            #         trade_data_manager.placeordercountmanager.place_order(code)
            #     return False, True, "首板代码,且尚未涨停过"
        try:
            # 买1价格必须为涨停价才能买
@@ -523,7 +549,7 @@
                if sell1_time is not None and sell1_volumn > 0:
                    # 获取执行位信息
                    buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = cls.__get_order_begin_pos(
                    buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos(
                        code)
                    buy_nums = num
                    for i in range(buy_exec_index + 1, total_datas[-1]["index"] + 1):
@@ -629,7 +655,7 @@
    @classmethod
    def cancel_buy(cls, code, msg=None, source="l2"):
        # 是否是交易队列触发
        buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = cls.__get_order_begin_pos(
        buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos(
            code)
        total_datas = local_today_datas[code]
        if source == "trade_queue":
@@ -675,17 +701,13 @@
                                                      local_today_num_operate_map.get(code))
        # 获取买入信号计算起始位置
        buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = cls.__get_order_begin_pos(
        buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos(
            code)
        # 是否为新获取到的位置
        new_get_single = False
        if buy_single_index is None:
            place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code)
            continue_count = 3
            # 前2次的信号连续笔数为3,后面为2
            if place_order_count > 2:
                continue_count = 2
            continue_count = cls.__l2PlaceOrderParamsManager.get_begin_continue_buy_count(cls.volume_rate_info[code][1])
            # 有买入信号
            has_single, _index = cls.__compute_order_begin_pos(code, max(
                (compute_start_index - continue_count - 1) if new_add else compute_start_index, 0), continue_count,
@@ -732,7 +754,7 @@
                                                                                                             max_num_set)
        _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "纯买额统计时间")
        l2_log.debug(code, "m值-{} m值因子-{}", threshold_money, msg)
        l2_log.debug(code, "m值-{} 量比:{}", threshold_money, cls.volume_rate_info[code][0])
        # 买入信号位与计算位置间隔2s及以上了
        if rebegin_buy_pos is not None:
@@ -746,7 +768,8 @@
                         buy_count, total_datas[compute_index])
            f1 = dask.delayed(cls.__save_order_begin_data)(code, buy_single_index, compute_index, compute_index,
                                                           buy_nums, buy_count, max_num_set_new)
                                                           buy_nums, buy_count, max_num_set_new,
                                                           cls.volume_rate_info[code][0])
            f2 = dask.delayed(limit_up_time_manager.save_limit_up_time)(code, total_datas[compute_index]["val"]["time"])
            f3 = dask.delayed(cls.__virtual_buy)(code, buy_single_index, compute_index, capture_time)
            f4 = dask.delayed(l2_data_manager.TradePointManager.delete_buy_cancel_point)(code)
@@ -781,6 +804,8 @@
                                                                                  compute_index,
                                                                                  buy_single_index, compute_index,
                                                                                  total_datas, is_first_code,
                                                                                  cls.volume_rate_info[code][1],
                                                                                  cls.volume_rate_info[code][1],
                                                                                  True)
                _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
                                                  "S级大单处理耗时", force=True)
@@ -794,7 +819,9 @@
                    cls.__buy(code, capture_time, total_datas[compute_index], compute_index, is_first_code)
            else:
                SecondCancelBigNumComputer.need_cancel(code, buy_single_index, compute_index, buy_single_index,
                                                       compute_index, total_datas, is_first_code, False)
                                                       compute_index, total_datas, is_first_code,
                                                       cls.volume_rate_info[code][1],
                                                       cls.volume_rate_info[code][1], False)
                _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time,
                                                  "S级大单处理耗时", force=True)
@@ -809,7 +836,7 @@
            # 未达到下单条件,保存纯买额,设置纯买额
            # 记录买入信号位置
            cls.__save_order_begin_data(code, buy_single_index, -1, compute_end_index, buy_nums, buy_count,
                                        max_num_set_new)
                                        max_num_set_new, None)
            print("保存大单时间", round((t.time() - _start_time) * 1000))
            _start_time = t.time()
        pass
@@ -817,15 +844,16 @@
    # 获取下单起始信号
    @classmethod
    def __get_order_begin_pos(cls, code):
        buy_single_index, buy_exec_index, compute_index, num, count, max_num_set = l2_data_manager.TradePointManager.get_buy_compute_start_data(
        buy_single_index, buy_exec_index, compute_index, num, count, max_num_set, volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data(
            code)
        return buy_single_index, buy_exec_index, compute_index, num, count, max_num_set
        return buy_single_index, buy_exec_index, compute_index, num, count, max_num_set, volume_rate
    # 保存下单起始信号
    @classmethod
    def __save_order_begin_data(self, code, buy_single_index, buy_exec_index, compute_index, num, count, max_num_set):
    def __save_order_begin_data(self, code, buy_single_index, buy_exec_index, compute_index, num, count, max_num_set,
                                volume_rate):
        TradePointManager.set_buy_compute_start_data(code, buy_single_index, buy_exec_index, compute_index, num, count,
                                                     max_num_set)
                                                     max_num_set, volume_rate)
    # 计算下单起始信号
    # compute_data_count 用于计算的l2数据数量
@@ -873,7 +901,7 @@
    @classmethod
    def __get_threshmoney(cls, code):
        return l2_trade_factor.L2TradeFactorUtil.compute_m_value(code)
        return l2_trade_factor.L2TradeFactorUtil.compute_m_value(code, cls.volume_rate_info[code][1])
    # 计算万手哥笔数
    @classmethod
@@ -901,34 +929,30 @@
        buy_nums = origin_num
        buy_count = origin_count
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        buy1_price = cls.buy1PriceManager.get_price(code)
        if limit_up_price is None:
            raise Exception("涨停价无法获取")
        # 目标手数
        threshold_num = round(threshold_money / (limit_up_price * 100))
        place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code)
        # place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code)
        # 目标订单数量
        threshold_count = cls.__buyL2SafeCountManager.get_safe_count(code, is_first_code, place_order_count)
        threshold_count = cls.__buyL2SafeCountManager.get_safe_count(code, is_first_code,
                                                                     cls.__l2PlaceOrderParamsManager.get_safe_count_rate(
                                                                         cls.volume_rate_info[code][1]))
        buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"])
        # 可以触发买,当有涨停买信号时才会触发买
        trigger_buy = True
        if place_order_count > 3:
            place_order_count = 3
        # 间隔最大时间依次为:3,9,27,81
        max_space_time = pow(3, place_order_count + 1) - 1
        max_space_time = cls.__l2PlaceOrderParamsManager.get_time_range(cls.volume_rate_info[code][1])
        # 最大买量
        max_buy_num = 0
        max_buy_num_set = set(max_num_set)
        # 需要的最小大单笔数
        big_num_count = 2
        if place_order_count > 1:
            # 第一次下单需要大单最少2笔,以后只需要1笔
            big_num_count = 1
        big_num_count = cls.__l2PlaceOrderParamsManager.get_big_num_count(cls.volume_rate_info[code][1])
        # 较大单的手数
        bigger_num = round(5900 / limit_up_price)
l2/safe_count_manager.py
@@ -73,21 +73,22 @@
        return l2_trade_factor.L2TradeFactorUtil.get_safe_buy_count(code, is_first)
    # 获取最后的安全笔数
    def get_safe_count(self, code, is_first_code, place_order_count=None):
    def get_safe_count(self, code, is_first_code, rate):
        rate = self.__get_rate(code)
        # 第4次下单按第一次算
        if place_order_count and place_order_count >= 3:
            rate = 1
        print("--------------------------------")
        print("安全笔数比例:", rate)
        print("--------------------------------")
        count, min_count, max_count = self.__get_base_save_count(code, is_first_code)
        count = round(count * rate)
        if count < min_count:
            count = min_count
        if count > max_count:
            count = max_count
        return count
        # 第4次下单按第一次算
        # if place_order_count and place_order_count >= 3:
        #     rate = 1
        # print("--------------------------------")
        # print("安全笔数比例:", rate)
        # print("--------------------------------")
        # count, min_count, max_count = self.__get_base_save_count(code, is_first_code)
        # count = round(count * rate)
        # if count < min_count:
        #     count = min_count
        # if count > max_count:
        #     count = max_count
        return int(round(count*(1+rate),0))
    # 计算留下来的比例
    # last_buy_single_index 上一次下单信号起始位置
l2/transaction_progress.py
@@ -83,7 +83,7 @@
        # 忽略第一条数据
        for i in range(1, len(queues)):
            num = queues[i]
            if num > min_num:
            if num > min_num and len(num_list) < 4:
                num_list.append(num)
        # 保存列表
        self.__save_buy_queue_data(code, num_list)
@@ -96,7 +96,7 @@
        index = None
        if True:
            # 最多5个数据
            buyQueueBigTemp = buyQueueBig[:5]
            buyQueueBigTemp = buyQueueBig
            last_index, is_default = self.get_traded_index(code)
            c_last_index = 0
            if not is_default and last_index is not None:
l2_data_util.py
@@ -40,11 +40,15 @@
            return True
        else:
            return False
    # if int(val["num"]) >= constant.BIG_MONEY_NUM:
    #     return True
    # if int(val["num"]) * limit_up_price >= constant.BIG_MONEY_AMOUNT:
    #     return True
    # return False_
# if int(val["num"]) >= constant.BIG_MONEY_NUM:
#     return True
# if int(val["num"]) * limit_up_price >= constant.BIG_MONEY_AMOUNT:
#     return True
# return False_
def compare_time(time1, time2):
@@ -69,8 +73,6 @@
    json_value = json.loads(value)
    _data = {"key": key, "val": item, "re": json_value["re"], "index": int(json_value["index"])}
    return _data
# 减去时间
l2_trade_test.py
@@ -63,7 +63,7 @@
                        decimal.Decimal("0.00"))
                    # 获取执行位时间
                    exec_time = None
                    buy_single_index, buy_exec_index, compute_index, num, count, max_num_set = l2_data_manager.TradePointManager.get_buy_compute_start_data(
                    buy_single_index, buy_exec_index, compute_index, num, count, max_num_set,volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data(
                        code)
                    if buy_exec_index:
                        try:
ths/l2_listen_pos_health_manager.py
New file
@@ -0,0 +1,67 @@
"""
同花顺l2监听位置健康度管理
"""
# 不健康
import tool
from db import redis_manager
UN_HEALTHY = 0
UN_KNOWN = 1
HEALTHY = 2
__redisManager = redis_manager.RedisManager(0)
def __get_redis():
    return __redisManager.getRedis()
def __set_health_state(client_id, pos, state):
    __get_redis().setex(f"l2_pos_health_state-{client_id}-{pos}", tool.get_expire(), state)
def __get_health_state(client_id, pos):
    val = __get_redis().get(f"l2_pos_health_state-{client_id}-{pos}")
    if val is None:
        return UN_KNOWN
    return int(val)
# 初始化所有的健康度
def init_all(clients):
    for client_info in clients:
        init(client_info[0], client_info[1])
# 初始化健康度
def init(client_id, pos):
    __set_health_state(client_id, pos, UN_KNOWN)
# 设置不健康
def set_healthy(client_id, pos):
    __set_health_state(client_id, pos, HEALTHY)
# 设置不健康
def set_unhealthy(client_id, pos):
    # 如果是未知状态才能设置
    state = __get_health_state(client_id, pos)
    if state == UN_KNOWN:
        __set_health_state(client_id, pos, UN_HEALTHY)
# 查询所有的健康状态
def list_health_state(poses):
    dict_ = {}
    for client_info in poses:
        dict_[client_info] = __get_health_state(client_info[0], client_info[1])
    return dict_
if __name__ == '__main__':
    # init_all([(2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6)])
    set_healthy(2, 0)
    print(list_health_state([(2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6)]))
    set_unhealthy(2, 0)
    set_healthy(2, 0)
trade/l2_trade_factor.py
@@ -11,6 +11,96 @@
import limit_up_time_manager
# 下单参数
class L2PlaceOrderParamsManager:
    # 获取信号连续买笔数
    @staticmethod
    def get_begin_continue_buy_count(volume_rate_index):
        counts = [3, 3, 3, 2, 2, 2, 2]
        if volume_rate_index >= len(counts):
            volume_rate_index = -1
        return counts[volume_rate_index]
    # 获取时间计算范围,返回s
    @staticmethod
    def get_time_range(volume_rate_index):
        ts = [pow(3, 1), pow(3, 1), pow(3, 1), pow(3, 2), pow(3, 2), pow(3, 3), pow(3, 3), pow(3, 3)]
        if volume_rate_index >= len(ts):
            volume_rate_index = -1
        return ts[volume_rate_index]
    # 获取需要的大单个数
    @staticmethod
    def get_big_num_count(volume_rate_index):
        counts = [4, 3, 2, 1, 1, 1, 1]
        if volume_rate_index >= len(counts):
            volume_rate_index = -1
        return counts[volume_rate_index]
    # 获取安全笔数影响比例
    @staticmethod
    def get_safe_count_rate(volume_rate_index):
        rates = [0, -0.1, -0.2, -0.4, -0.6, -0.8, -0.8, -0.8]
        if volume_rate_index >= len(rates):
            volume_rate_index = -1
        return rates[volume_rate_index]
    # 获取m值影响比例
    @staticmethod
    def get_m_val_rate(volume_rate_index):
        rates = [0.0, 0.0, 0.0, -0.3, -0.4, -0.5, -0.6, -0.7]
        if volume_rate_index >= len(rates):
            volume_rate_index = -1
        return rates[volume_rate_index]
# S撤参数
class SCancelParamsManager:
    # 剔除前几的点火大单
    @staticmethod
    def get_max_exclude_count(volume_rate_index):
        counts = [5, 4, 3, 2, 1, 1, 1, 1]
        if volume_rate_index >= len(counts):
            volume_rate_index = -1
        return counts[volume_rate_index]
    # 获取买时间范围(距离执行位),返回s
    @staticmethod
    def get_buy_time_range(volume_rate_index):
        seconds = [pow(2, 1), pow(2, 2), pow(2, 3), pow(2, 4), pow(2, 4), pow(2, 5), pow(2, 6), pow(2, 6)]
        if volume_rate_index >= len(seconds):
            volume_rate_index = -1
        return seconds[volume_rate_index]
    # 获取撤销比例
    @staticmethod
    def get_cancel_rate(volume_rate_index):
        rates = [0.39, 0.49, 0.59, 0.69, 0.69, 0.79, 0.79, 0.79]
        if volume_rate_index >= len(rates):
            volume_rate_index = -1
        return rates[volume_rate_index]
# H撤参数
class HCancelParamsManager:
    # 获取最大的观察笔数
    @staticmethod
    def get_max_watch_count(volume_rate_index):
        counts = [40, 36, 32, 28, 24, 20, 16, 12]
        if volume_rate_index >= len(counts):
            volume_rate_index = -1
        return counts[volume_rate_index]
    # 获取撤销比例
    @staticmethod
    def get_cancel_rate(volume_rate_index):
        rates = [0.39, 0.49, 0.59, 0.69, 0.69, 0.79, 0.79, 0.79]
        if volume_rate_index >= len(rates):
            volume_rate_index = -1
        return rates[volume_rate_index]
class L2TradeFactorUtil:
    # 获取基础m值,返回单位为元
    @classmethod
@@ -19,7 +109,7 @@
        if yi < 1:
            yi = 1
        m = 5000000 + (yi - 1) * 500000
        return round(m * 0.7)
        return round(m)
    # 获取行业影响比例
    # total_limit_percent为统计的比例之和乘以100
@@ -204,7 +294,7 @@
        return zyltgb
    @classmethod
    def compute_m_value(cls, code):
    def compute_m_value(cls, code,volume_rate):
        zyltgb = global_util.zyltgb_map.get(code)
        if zyltgb is None:
            global_data_loader.load_zyltgb()
@@ -213,22 +303,12 @@
                print("没有获取到自由流通市值")
                return 10000000, ""
        zyltgb = cls.get_base_safe_val(zyltgb)
        rate, msg = cls.compute_rate_by_code(code)
        # 暂时注释
        # rate, msg = cls.compute_rate_by_code(code)
        # print("m值获取:", code, round(zyltgb * rate))
        return round(zyltgb * rate), msg
        rate = L2PlaceOrderParamsManager.get_m_val_rate(volume_rate)
    @classmethod
    def get_h_cancel_min_count(cls, code):
        volumn_day60_max, volumn_yest, volumn_today = cls.__get_volumns(code)
        if volumn_day60_max is None or volumn_yest is None or volumn_today is None:
            return constant.H_CANCEL_MIN_COUNT
        rate = round(int(volumn_today) / max(int(volumn_day60_max), int(volumn_yest)), 2)
        counts = [40, 36, 32, 28, 24, 20, 16]
        rates = [0.3, 0.55, 0.8, 1.05, 1.3, 1.55, 10]
        for index in range(0,len(rates)):
            if rate < rates[index]:
                return counts[index]
        return counts[0]
        return round(zyltgb * (1+rate)), ""
    # 获取安全笔数
    @classmethod
@@ -293,12 +373,8 @@
    # print(L2TradeFactorUtil.get_safe_buy_count("003005"))
    # print(L2TradeFactorUtil.get_rate_factors("003004"))
    # print(L2TradeFactorUtil.factors_to_string("003004"))
    print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 4))
    print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 7))
    print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 10))
    print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 16))
    print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 22))
    print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 31))
    for i in range(2, 151):
        print(i, L2TradeFactorUtil.get_base_safe_val(100000000 * i))
    # print(L2TradeFactorUtil.get_limit_up_time_rate("11:30:00"))
    # print(L2TradeFactorUtil.get_limit_up_time_rate("13:00:00"))
    # print(L2TradeFactorUtil.get_limit_up_time_rate("13:48:00"))
trade/trade_manager.py
@@ -23,7 +23,7 @@
TRADE_STATE_BUY_PLACE_ORDER = 10
# 已委托买
TRADE_STATE_BUY_DELEGATED = 11
# 委托进行中
# 委托取消进行中
TRADE_STATE_BUY_CANCEL_ING = 13
# 撤销成功
TRADE_STATE_BUY_CANCEL_SUCCESS = 14
trade/trade_queue_manager.py
@@ -208,35 +208,6 @@
        return time_str, volumn
# 买1实时价格管理器
class Buy1PriceManager:
    __redisManager = redis_manager.RedisManager(0)
    def __init__(self):
        self.latest_prices = {}
    def __get_redis(self):
        return self.__redisManager.getRedis()
    def __save_recod(self, code, price):
        # 保存每一次的
        key = "buy1_price-{}".format(code)
        self.__get_redis().setex(key, tool.get_expire(), price)
    def __get_record(self, code):
        key = "buy1_price-{}".format(code)
        val = self.__get_redis().get(key)
        return val
    # 保存数据
    def save(self, code, price):
        if self.latest_prices.get(code) == price:
            return
        self.latest_prices[code] = price
        self.__save_recod(code, price)
    def get_price(self, code):
        return self.__get_record(code)
class thsl2tradequeuemanager:
trade/trade_result_manager.py
@@ -60,7 +60,7 @@
            logging.exception(e)
            logger_l2_error.exception(e)
    buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = l2_data_manager.TradePointManager.get_buy_compute_start_data(
    buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set,volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data(
        code)
    f1 = clear_max_buy1_volume(code)