From 3a87b1c89a76d858e8e7e4e54ff360dc0b8670f5 Mon Sep 17 00:00:00 2001
From: Administrator <admin@example.com>
Date: 星期四, 11 九月 2025 16:27:20 +0800
Subject: [PATCH] L撤删除L前撤单与L后后半段撤单

---
 trade/l2_trade_factor.py |  349 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 315 insertions(+), 34 deletions(-)

diff --git a/trade/l2_trade_factor.py b/trade/l2_trade_factor.py
index 0564ab3..602d8fe 100644
--- a/trade/l2_trade_factor.py
+++ b/trade/l2_trade_factor.py
@@ -4,21 +4,280 @@
 
 # l2浜ゆ槗鍥犲瓙
 
-import big_money_num_manager
-import global_data_loader
-import global_util
-import limit_up_time_manager
+from code_attribute import big_money_num_manager, limit_up_time_manager, global_data_loader, gpcode_manager
+import constant
+from trade import trade_manager, deal_big_money_manager, trade_constant
+from utils import global_util, tool
+
+
+# 涓嬪崟鍙傛暟
+
+
+class L2PlaceOrderParamsManager:
+
+    # 鑾峰彇涔板叆绛夌骇鎻忚堪
+    def get_buy_rank_desc(self):
+        continue_count = self.get_begin_continue_buy_count()
+        time_range = self.get_time_range()
+        m = self.get_m_val()[0]
+        m = m // 10000
+
+        desc = ""
+        if self.buy_rank == 0:
+            desc = f"涔板叆淇″彿({continue_count})"
+        elif self.buy_rank == 1:
+            desc = f"涔板叆淇″彿({continue_count})+M鍊尖墺{m}涓�"
+        elif self.buy_rank == 2:
+            desc = f"涔板叆淇″彿({continue_count})+M鍊尖墺{m}涓�+鑷冲皯鍚�1绗斿ぇ鍗�"
+        elif self.buy_rank == 3:
+            desc = f"涔板叆淇″彿({continue_count})+M鍊尖墺{m}涓�+鑷冲皯鍚�2绗斿ぇ鍗�"
+        else:
+            desc = "甯歌涔板叆"
+        desc += f"+鍥婃嫭鏃堕棿{time_range}s"
+        return desc
+
+    # 鑾峰彇涔板叆绛夌骇
+    # 0:涔板叆淇″彿
+    # 1:涔板叆淇″彿+M1000涓�
+    # 2:涔板叆淇″彿+M1000涓�+1绗斿ぇ鍗�
+    # 3:涔板叆淇″彿+M1000+2绗斿ぇ鍗�
+    # 100:鎵ц涔嬪墠鍥烘湁鏂规
+    def get_buy_rank(self):
+        if self.score_index == 0:
+            return 0
+        elif self.score_index == 1:
+            return 1
+        elif self.score_index == 2:
+            return 2
+        else:
+            return 100
+        # 鏆傛椂涓嶉渶瑕佹姝や腑绛栫暐
+        # # 鍒ゆ柇鏈夋病鏈夌偢寮�
+        # if code_price_manager.Buy1PriceManager().is_can_buy(self.code):
+        #     # 鍥炲皝
+        #     if self.score_index == 0:
+        #         return 0
+        #     elif self.score_index == 1:
+        #         return 1
+        #     elif self.score_index == 2:
+        #         return 2
+        #     else:
+        #         return 100
+        # else:
+        #     # 棣栧皝
+        #     if tool.trade_time_sub(self.now_time, "10:30:00") < 0 or tool.trade_time_sub(self.now_time, "14:00:00") > 0:
+        #         if self.score_index == 0:
+        #             return 1
+        #         elif self.score_index == 1:
+        #             return 2
+        #         elif self.score_index == 2:
+        #             return 3
+        #         else:
+        #             return 100
+        #     else:
+        #         if self.score_index == 0:
+        #             return 2
+        #         elif self.score_index == 1:
+        #             return 3
+        #         elif self.score_index == 2:
+        #             return 100
+        #         else:
+        #             return 100
+
+    # 寰楀垎
+    def __init__(self, code, is_first_code, volume_rate, volume_rate_index, score, now_time=tool.get_now_time_str()):
+        self.code = code
+        self.is_first_code = is_first_code
+        score_ranks = [constant.BUY_SCORE_RANK_3, constant.BUY_SCORE_RANK_2, constant.BUY_SCORE_RANK_1,
+                       constant.BUY_SCORE_RANK_0]
+        # self.score = score[0][0]
+        # self.score_info = score
+        # 涓哄垎鏁拌缃瓑绾�
+        # score_index = -1
+        # for i in range(0, len(score_ranks)):
+        #     if self.score >= score_ranks[i]:
+        #         score_index = i
+        #         break
+        # 鍥哄畾璁剧疆涓�2
+        self.score_index = 2
+        # 鍙鍔犲叆鎯充拱鍗曠殑锛屽叏閮ㄦ墽琛屼富鍔ㄤ拱鍏ヤ簩鏄熸柟妗�
+        if gpcode_manager.WantBuyCodesManager().is_in_cache(code):
+            self.score_index = 1
+            self.is_want_buy = True
+        else:
+            self.is_want_buy = False
+            # 娌℃湁鍔犲叆鎯充拱鍗曠殑锛�2鏄�/3鏄熷皢涓�1鏄�
+            if self.score_index == 0 or self.score_index == 1:
+                self.score_index = 2
+
+        self.volume_rate = volume_rate
+        self.volume_rate_index = volume_rate_index
+        self.now_time = now_time
+        self.buy_rank = self.get_buy_rank()
+
+    # 鏄惁鏄垵娆′笅鍗�
+    @classmethod
+    def is_first_place_order(cls, code):
+        return trade_manager.CodesTradeStateManager().get_trade_state_cache(code) == trade_constant.TRADE_STATE_NOT_TRADE
+
+    # 璁剧疆鍒嗘暟
+    def set_score(self, score):
+        score_ranks = [constant.BUY_SCORE_RANK_3, constant.BUY_SCORE_RANK_2, constant.BUY_SCORE_RANK_1,
+                       constant.BUY_SCORE_RANK_0]
+        self.score = score[0][0]
+        self.score_info = score
+        # 涓哄垎鏁拌缃瓑绾�
+        score_index = -1
+        for i in range(0, len(score_ranks)):
+            if self.score >= score_ranks[i]:
+                score_index = i
+                break
+        self.score_index = score_index
+
+    # 鑾峰彇淇″彿杩炵画涔扮瑪鏁�
+    def get_begin_continue_buy_count(self):
+        counts = [3, 3, 3, 2, 2, 2, 2]
+        volume_rate_index = self.volume_rate_index
+        if self.volume_rate_index >= len(counts):
+            volume_rate_index = -1
+        return counts[volume_rate_index]
+
+    # 鑾峰彇鏃堕棿璁$畻鑼冨洿锛岃繑鍥瀞
+    def get_time_range(self):
+        # 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)]
+        ts = [pow(2, 1), pow(2, 1), pow(2, 1), pow(2, 1), pow(2, 1), pow(2, 1), pow(2, 1), pow(2, 1)]
+        # 鏆傛椂鍘婚櫎鍒嗙殑褰卞搷
+        # if -1 < self.score_index < 3:
+        #     return ts[0]
+        volume_rate_index = self.volume_rate_index
+        if self.volume_rate_index >= len(ts):
+            volume_rate_index = -1
+        # 棣栨涓嬪崟蹇呴』鍚�1s
+        if self.is_first_place_order(self.code):
+            return 1
+        return ts[volume_rate_index]
+
+    # 鑾峰彇闇�瑕佺殑澶у崟涓暟
+    def get_big_num_count(self):
+        # counts = [1, 1, 1, 1, 0, 0, 0, 0]
+        # volume_rate_index = self.volume_rate_index
+        # if self.volume_rate_index >= len(counts):
+        #     volume_rate_index = -1
+        # return counts[volume_rate_index]
+        # 鏈夊ぇ鍗曟垚浜ゅ氨涓嶉渶瑕佸ぇ鍗曚簡锛屾病鏈夊ぇ鍗曟垚浜ゅ氨闇�瑕佸ぇ鍗�
+        deal_big_money_count = deal_big_money_manager.get_deal_big_money_count(self.code)
+        if deal_big_money_count > 0:
+            return 0
+        else:
+            return 1
+
+    # 鑾峰彇瀹夊叏绗旀暟褰卞搷姣斾緥
+    def get_safe_count_rate(self):
+        rates = [0, -0.1, -0.2, -0.3, -0.4, -0.5, -0.6, -0.7]
+        volume_rate_index = self.volume_rate_index
+        if self.volume_rate_index >= len(rates):
+            volume_rate_index = -1
+        return rates[volume_rate_index]
+
+    def get_safe_count(self):
+        # if self.is_first_code:
+        #     if self.buy_rank < 4:
+        #         return 2
+        base_count, min_count, max_count = L2TradeFactorUtil.get_safe_buy_count(self.code, True)
+        rate = self.get_safe_count_rate()
+        count = int(round(base_count * (1 + rate)))
+        # 鏈�灏�8绗�
+        return max(count, 8)
+
+    # 鑾峰彇m鍊煎奖鍝嶆瘮渚�
+    @classmethod
+    def get_m_val_rate(cls, volume_rate_index):
+        rates = [0.0, -0.1, -0.15, -0.2, -0.25, -0.3, -0.35, -0.4]
+        if volume_rate_index >= len(rates):
+            volume_rate_index = -1
+        return rates[volume_rate_index]
+
+    @classmethod
+    def get_base_m_val(cls, code):
+        zyltgb = global_util.zyltgb_map.get(code)
+        if zyltgb is None:
+            global_data_loader.load_zyltgb()
+            zyltgb = global_util.zyltgb_map.get(code)
+        base_m = L2TradeFactorUtil.get_base_safe_val(zyltgb)
+        return base_m
+
+    # 鑾峰彇m鍊�
+    def get_m_val(self):
+        base_m = self.get_base_m_val(self.code)
+        if self.is_first_place_order(self.code) and tool.is_sz_code(self.code):
+            base_m = int(base_m * 2)
+        rate = self.get_m_val_rate(self.volume_rate_index)
+        m = round(base_m * (1 + rate))
+        return m, ""
+
+
+# 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]
+
+    # 鑾峰彇涔版椂闂磋寖鍥�(璺濈鎵ц浣�)锛岃繑鍥瀞
+    @staticmethod
+    def get_buy_time_range(volume_rate_index):
+        # rates = [0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6]
+        seconds = [pow(2, 1), pow(2, 2), pow(2, 3), pow(2, 4), pow(2, 5), pow(2, 5), pow(2, 4), pow(2, 4)]
+        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.34, 0.44, 0.54, 0.64, 0.74, 0.84, 0.94, 1.04]
+        if volume_rate_index >= len(rates):
+            volume_rate_index = -1
+        return 0.79  # 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.35, 0.45, 0.55, 0.65, 0.65, 0.75, 0.75, 0.75]
+        # if volume_rate_index >= len(rates):
+        #     volume_rate_index = -1
+        # return rates[volume_rate_index]
+        return 0.89
 
 
 class L2TradeFactorUtil:
     # 鑾峰彇鍩虹m鍊硷紝杩斿洖鍗曚綅涓哄厓
     @classmethod
     def get_base_safe_val(cls, zyltgb):
+        if zyltgb is None:
+            return 10000000
         yi = round(zyltgb / 100000000)
         if yi < 1:
             yi = 1
-        m = 5000000 + (yi - 1) * 500000
-        return round(m * 0.7)
+        return int(-0.058 * yi * yi + 60.9 * yi) * 10000
+        # m = 5000000 + (yi - 1) * 500000
+        # return round(m * (1 - 0.3))
 
     # 鑾峰彇琛屼笟褰卞搷姣斾緥
     # total_limit_percent涓虹粺璁$殑姣斾緥涔嬪拰涔樹互100
@@ -53,8 +312,8 @@
         if today is None:
             return 0
         old_volumn = int(yest)
-        if int(day60_max) > int(yest):
-            old_volumn = int(day60_max)
+        if int(day60_max[0]) > int(yest):
+            old_volumn = int(day60_max[0])
         r = round(int(today) / old_volumn, 2)
         if r < 0.01:
             r = 0.01
@@ -180,11 +439,11 @@
         # 棣栨娑ㄥ仠鏃堕棿
         limit_up_time = global_util.limit_up_time.get(code)
         if limit_up_time is None:
-            limit_up_time = limit_up_time_manager.get_limit_up_time(code)
+            limit_up_time = limit_up_time_manager.LimitUpTimeManager().get_limit_up_time_cache(code)
 
         big_money_num = global_util.big_money_num.get(code)
         if big_money_num is None:
-            big_money_num = big_money_num_manager.get_num(code)
+            big_money_num = big_money_num_manager.get_num_cache(code)
         return (
             zyltgb, total_industry_limit_percent, volumn_day60_max, volumn_yest, volumn_today, limit_up_time,
             big_money_num)
@@ -203,43 +462,63 @@
         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()
             zyltgb = global_util.zyltgb_map.get(code)
             if zyltgb is None:
                 print("娌℃湁鑾峰彇鍒拌嚜鐢辨祦閫氬競鍊�")
-                return 10000000
+                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)
+
+        return round(zyltgb * (1 + rate)), ""
 
     # 鑾峰彇瀹夊叏绗旀暟
     @classmethod
-    def get_safe_buy_count(cls, code):
+    def get_safe_buy_count(cls, code, is_first=False):
         gb = cls.get_zyltgb(code)
+        return cls.get_safe_buy_count_by_gp(gb, is_first)
+
+    @classmethod
+    def get_safe_buy_count_by_gp(cls, gb, is_first=False):
+        MIN_VAL = 8
+        MAX_VAL = 16
+        if is_first:
+            MIN_VAL = 5
+            MAX_VAL = 13
         if not gb:
             # 榛樿8绗�
-            return 8
+            return MIN_VAL, MIN_VAL, MAX_VAL
         count = gb // 100000000
-        if count <= 6:
-            count = 8
-        elif count < 32:
-            count = round(8 + 0.5 * (count - 6))
-        else:
-            count = 21
-
-        # volumn_day60_max, volumn_yest, volumn_today = cls.__get_volumns(code)
-        # rate = cls.get_volumn_rate(volumn_day60_max, volumn_yest, volumn_today)
-        # 鍙栧ぇ鍗曞奖鍝嶅�间笌琛屼笟褰卞搷鍊肩殑杈冨ぇ鍊�
-        # count = round(count * (1 - rate))
-        if count < 8:
-            count = 8
-        elif count > 21:
-            count = 21
-        return count
+        if True:
+            if count < 8:
+                count = MIN_VAL
+            elif count < 11:
+                count = MIN_VAL + 1
+            elif count < 14:
+                count = MIN_VAL + 2
+            elif count < 17:
+                count = MIN_VAL + 3
+            elif count < 20:
+                count = MIN_VAL + 4
+            elif count < 23:
+                count = MIN_VAL + 5
+            elif count < 26:
+                count = MIN_VAL + 6
+            elif count < 29:
+                count = MIN_VAL + 7
+            else:
+                count = MAX_VAL
+        if count < MIN_VAL:
+            count = MIN_VAL
+        elif count > MAX_VAL:
+            count = MAX_VAL
+        return count, MIN_VAL, MAX_VAL
 
 
 # l2鍥犲瓙褰掑洜鏁版嵁
@@ -259,10 +538,12 @@
 
 
 if __name__ == "__main__":
-    print(L2TradeFactorUtil.get_safe_buy_count("003005"))
+    # 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("002864"))
+
+    # for i in range(2, 150):
+    print(22, L2TradeFactorUtil.get_base_safe_val(100000000 * 22))
     # 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"))

--
Gitblit v1.8.0