From 8535f56dbf6e410b4a09f02f95d4d49bcc8753f2 Mon Sep 17 00:00:00 2001
From: Administrator <admin@example.com>
Date: 星期一, 27 三月 2023 18:58:54 +0800
Subject: [PATCH] 看盘页面数据调整

---
 code_nature_analyse.py               |   82 ++-
 data_export_util.py                  |    2 
 trade/bidding_money_manager.py       |    8 
 trade/deal_big_money_manager.py      |   14 
 server.py                            |   65 ++
 ocr/ocr_server.py                    |   55 ++
 juejin.py                            |   48 +
 trade/l2_trade_factor.py             |   98 ++++
 third_data/hot_block.py              |    8 
 l2_trade_test.py                     |    2 
 trade/trade_gui.py                   |    2 
 third_data/hot_block_data_process.py |   61 +-
 third_data/kpl_util.py               |   25 +
 trade/first_code_score_manager.py    |  239 +++++++-----
 l2/l2_data_manager_new.py            |   85 ++-
 code_volumn_manager.py               |   22 
 ocr/ocr_util.py                      |    5 
 output/code_info_output.py           |  306 ++++++++++++++++
 18 files changed, 864 insertions(+), 263 deletions(-)

diff --git a/code_nature_analyse.py b/code_nature_analyse.py
index 44b9e22..ac3e760 100644
--- a/code_nature_analyse.py
+++ b/code_nature_analyse.py
@@ -47,15 +47,17 @@
 
 # 璁剧疆鍘嗗彶K绾�
 def set_record_datas(code, limit_up_price, record_datas):
-    k_format = get_k_format(limit_up_price, record_datas)
+    k_format = get_k_format(float(limit_up_price), record_datas)
     CodeNatureRecordManager.save_k_format(code, k_format)
     natures = get_nature(record_datas)
     CodeNatureRecordManager.save_nature(code, natures)
 
+
 # 鑾峰彇K绾垮舰鎬�
 # 杩斿洖 (15涓氦鏄撴棩娑ㄥ箙鏄惁澶т簬24.9%,鏄惁鐮村墠楂橈紝鏄惁瓒呰穼锛屾槸鍚︽帴杩戝墠楂橈紝鏄惁N,鏄惁V)
 def get_k_format(limit_up_price, record_datas):
-    p1 = get_lowest_price_rate(record_datas) >= 0.249
+    p1_data = get_lowest_price_rate(record_datas)
+    p1 = p1_data[0] >= 0.249, p1_data[1]
     p2 = __is_new_top(limit_up_price, record_datas)
     p3 = __is_lowest(record_datas)
     p4 = __is_near_new_top(limit_up_price, record_datas)
@@ -63,13 +65,13 @@
     p6 = __is_v_model(record_datas)
     # N瀛楀瀷鍖呭惈浜哊瀛楀瀷
     if p5:
-        p6 = False
+        p6 = False, ''
     return (p1, p2, p3, p4, p5, p6)
 
 
 # 鏄惁鍏锋湁K绾垮舰鎬�
 def is_has_k_format(limit_up_price, record_datas):
-    is_too_high, is_new_top, is_lowest, is_near_new_top, is_n, is_v = get_k_format(limit_up_price, record_datas)
+    is_too_high, is_new_top, is_lowest, is_near_new_top, is_n, is_v = get_k_format(float(limit_up_price), record_datas)
 
     # if is_too_high:
     #     return False, "15涓氦鏄撴棩娑ㄥ箙澶т簬24.9%"
@@ -91,7 +93,7 @@
 def get_nature(record_datas):
     limit_up = is_have_limit_up(record_datas)
     premium_rate = get_limit_up_premium_rate(record_datas)
-    result = (limit_up, premium_rate >= 0.6)
+    result = (limit_up, premium_rate >= 0.6,premium_rate)
 
     return result
 
@@ -101,10 +103,12 @@
     datas.sort(key=lambda x: x["bob"])
     datas = datas[-15:]
     low_price = datas[0]["close"]
+    date = None
     for data in datas:
         if low_price > data["close"]:
             low_price = data["close"]
-    return (datas[-1]["close"] - low_price) / low_price
+            date = data['bob'].strftime("%Y-%m-%d")
+    return (datas[-1]["close"] - low_price) / low_price, date
 
 
 # 鏄惁鏈夋定鍋�
@@ -114,12 +118,8 @@
         item = datas[i]
         limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"]))
         if abs(limit_up_price - item["close"]) < 0.01:
-            return True
-    return False
-
-
-def is_have_limit_up_by_code(code):
-    return False
+            return True, item['bob'].strftime("%Y-%m-%d")
+    return False, ''
 
 
 # 鏄惁鐮村墠楂�
@@ -131,9 +131,13 @@
     for data in datas:
         if max_price < data["high"]:
             max_price = data["high"]
-    if limit_up_price > max_price:
-        return True
-    return False
+    if limit_up_price >= max_price:
+        return True, ''
+    return False, ''
+
+
+def is_new_top(limit_up_price, datas):
+    return __is_new_top(float(limit_up_price), datas)[0]
 
 
 # 鎺ヨ繎鏂伴珮
@@ -142,15 +146,33 @@
     datas.sort(key=lambda x: x["bob"])
     datas = datas[-80:]
     max_volume = 0
-    price = 0
-    for data in datas:
+    max_volume_index = 0
+
+    for index in range(0, len(datas)):
+        data = datas[index]
         if max_volume < data["volume"]:
             max_volume = data["volume"]
+            max_volume_index = index
+
+    price = 0
+    price_index = 0
+    for index in range(max_volume_index, len(datas)):
+        data = datas[index]
+        if data["high"] > price:
             price = data["high"]
+            price_index = index
+
+    index = price_index
+    # 鏈�澶ч噺褰撴棩鏈�楂樹环姣斿綋鏃ヤ箣鍚庣殑鏈�楂樹环娑ㄥ箙鍦�15%浠ュ唴
+    if (price - datas[max_volume_index]["high"]) / datas[max_volume_index]["high"] < 0.15:
+        price = datas[max_volume_index]["high"]
+        index = max_volume_index
+
     print(max_volume)
-    if limit_up_price < price and (price - limit_up_price) / limit_up_price < 0.03:
-        return True
-    return False
+    rate = (price - limit_up_price) / limit_up_price
+    if 0 < rate < 0.03:
+        return True, datas[index]['bob'].strftime("%Y-%m-%d")
+    return False, ''
 
 
 # 鏄惁璺岀牬绠变綋
@@ -163,13 +185,15 @@
         if min_price > data["low"]:
             min_price = data["low"]
     # 杩�5澶╁唴鐨勬渶浣庝环
+    date = ''
     min_price_5 = 10000
     for data in datas[-5:]:
         if min_price_5 > data["low"]:
             min_price_5 = data["low"]
+            date = data['bob']
     if abs(min_price_5 - min_price) / min_price < 0.015:
-        return True
-    return False
+        return True, date.strftime("%Y-%m-%d")
+    return False, ''
 
 
 # N瀛楀舰
@@ -192,8 +216,8 @@
                 if min_price > item["low"]:
                     min_price = item["low"]
         if max_price > min_price:
-            return True
-    return False
+            return True, ''
+    return False, ''
 
 
 # V瀛楀舰
@@ -215,9 +239,9 @@
             min_price_index = i
 
     if (max_price - min_price) / max_price > 0.249:
-        return True
+        return True, ''
 
-    return False
+    return False, ''
 
 
 # 棣栨澘娑ㄥ仠婧环鐜�
@@ -234,9 +258,13 @@
             rate = (datas[i + 1]["high"] - datas[i + 1]["pre_close"]) / datas[i + 1]["pre_close"]
             first_rate_list.append(rate)
     if not first_rate_list:
-        return 1
+        return 0
     count = 0
     for rate in first_rate_list:
         if rate >= 0.01:
             count += 1
     return count / len(first_rate_list)
+
+
+if __name__ == "__main__":
+    print(CodeNatureRecordManager.get_k_format("603717"))
diff --git a/code_volumn_manager.py b/code_volumn_manager.py
index 97935b7..2582c88 100644
--- a/code_volumn_manager.py
+++ b/code_volumn_manager.py
@@ -5,6 +5,8 @@
 # 璁剧疆鍘嗗彶閲�
 # max60 60澶╂渶澶ч噺
 # yesterday 鏄ㄥぉ鐨勯噺
+import json
+
 import global_util
 import gpcode_manager
 from db import redis_manager
@@ -15,11 +17,11 @@
 
 
 # 璁剧疆鍘嗗彶閲�
-def set_histry_volumn(code, max60, yesterday):
+def set_histry_volumn(code, max60, yesterday, max60_day=''):
     redis = __redis_manager.getRedis()
     global_util.max60_volumn[code] = max60
     global_util.yesterday_volumn[code] = yesterday
-    redis.setex("volumn_max60-{}".format(code), tool.get_expire(), max60)
+    redis.setex("volumn_max60-{}".format(code), tool.get_expire(), json.dumps((max60,max60_day)))
     redis.setex("volumn_yes-{}".format(code), tool.get_expire(), yesterday)
 
 
@@ -30,6 +32,8 @@
     redis = __redis_manager.getRedis()
     if max60 is None:
         max60 = redis.get("volumn_max60-{}".format(code))
+        if max60:
+            max60 = json.loads(max60)
     if yesterday is None:
         yesterday = redis.get("volumn_yes-{}".format(code))
     return max60, yesterday
@@ -53,12 +57,15 @@
 
 
 # 鑾峰彇閲忔瘮锛堜粖鏃ラ噺/max(60澶╂渶澶ч噺,鏄ㄦ棩閲�)锛�
-def get_volume_rate(code):
+def get_volume_rate(code, with_info=False):
     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)
+    rate = round(int(today) / max(int(max60[0]), int(yesterday)), 2)
+    if not with_info:
+        return rate
+    return rate, (today, max(int(max60[0]), int(yesterday)))
 
 
 # 鑾峰彇閲忔瘮绱㈠紩
@@ -90,7 +97,10 @@
     if keys is not None:
         for k in keys:
             code = k.split("-")[1]
-            global_util.max60_volumn[code] = redis.get(k)
+            max60_volumn = redis.get(k)
+            if max60_volumn:
+                max60_volumn = json.loads(max60_volumn)
+            global_util.max60_volumn[code] = max60_volumn
     keys = redis.keys("volumn_yes-*")
     if keys is not None:
         for k in keys:
@@ -98,3 +108,5 @@
             global_util.yesterday_volumn[code] = redis.get(k)
 
 
+if __name__ == "__main__":
+    print(get_histry_volumn("603717"))
\ No newline at end of file
diff --git a/data_export_util.py b/data_export_util.py
index e3cec61..665b35a 100644
--- a/data_export_util.py
+++ b/data_export_util.py
@@ -196,6 +196,6 @@
 
 
 if __name__ == "__main__":
-    codes = ["000977"]
+    codes = ["003021"]
     for code in codes:
         export_l2_excel(code)
diff --git a/juejin.py b/juejin.py
index 0740ea7..b9230f4 100644
--- a/juejin.py
+++ b/juejin.py
@@ -592,23 +592,37 @@
 
 
 # 瑙f瀽鏈�澶ч噺
-def parse_max_volume(datas):
+def parse_max_volume(datas, is_new_top=False):
     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"]
-            volume = max(volume, next_volume)
-            return (volume, volume)
-    return (max_volume, max_volume)
+
+    max_volume_date = None
+    if is_new_top:
+        # 濡傛灉鏄獊鐮村墠楂樺氨鍙栨渶澶ч噺
+        for item in datas:
+            if max_volume < item["volume"]:
+                max_volume = item["volume"]
+                max_volume_date = item["bob"]
+    else:
+        date = None
+        for i in range(len(datas)):
+            # 鏌ヨ娑ㄥ仠
+            item = datas[i]
+            volume = item["volume"]
+            if max_volume < volume:
+                max_volume = volume
+                max_volume_date = item['bob']
+            # 鏄惁鏈夋定鍋�
+            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"]
+                date = datas[i]["bob"]
+                if volume < next_volume:
+                    volume = next_volume
+                    date = datas[i - 1]["bob"]
+                return volume, volume, date.strftime("%Y-%m-%d")
+    return max_volume, max_volume, max_volume_date.strftime("%Y-%m-%d")
 
 
 # 鏄惁鏈夋定鍋�
@@ -654,6 +668,6 @@
 
 
 if __name__ == '__main__':
-    datas=(get_volumns_by_code("603083", 150))
+    datas = (get_volumns_by_code("603083", 150))
     print(datas)
     print(get_limit_up_money_percent(datas))
diff --git a/l2/l2_data_manager_new.py b/l2/l2_data_manager_new.py
index bc39a88..2a71f52 100644
--- a/l2/l2_data_manager_new.py
+++ b/l2/l2_data_manager_new.py
@@ -16,7 +16,7 @@
 import ths_industry_util
 import tool
 from trade import trade_data_manager, trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \
-    trade_result_manager
+    trade_result_manager, first_code_score_manager
 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
@@ -160,7 +160,7 @@
     __ths_l2_trade_queue_manager = trade_queue_manager.thsl2tradequeuemanager()
     __thsBuy1VolumnManager = trade_queue_manager.THSBuy1VolumnManager()
     __buyL2SafeCountManager = safe_count_manager.BuyL2SafeCountManager()
-    __l2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager()
+    __l2PlaceOrderParamsManagerDict = {}
 
     @classmethod
     # 鏁版嵁澶勭悊鍏ュ彛
@@ -226,13 +226,23 @@
                                            "l2鏁版嵁棰勫鐞嗘椂闂�")
 
         if len(add_datas) > 0:
+            # 鏄惁涓洪鏉夸唬鐮�
+            is_first_code = gpcode_manager.FirstCodeManager.is_in_first_record(code)
             # 璁$畻閲�
             volume_rate = code_volumn_manager.get_volume_rate(code)
             volume_rate_index = code_volumn_manager.get_volume_rate_index(volume_rate)
-            l2_log.debug(code,"閲忔瘮锛歿}锛岄噺绱㈠紩锛歿}",volume_rate,volume_rate_index)
+            # 璁$畻鍒嗗��
+            limit_up_time = limit_up_time_manager.get_limit_up_time(code)
+            if limit_up_time is None:
+                limit_up_time = tool.get_now_time_str()
+            score = first_code_score_manager.get_score(code, volume_rate, limit_up_time)
+            cls.__l2PlaceOrderParamsManagerDict[code] = l2_trade_factor.L2PlaceOrderParamsManager(code, is_first_code,
+                                                                                                  volume_rate,
+                                                                                                  volume_rate_index,
+                                                                                                  score)
+            l2_log.debug(code, "閲忔瘮锛歿}锛岄噺绱㈠紩锛歿}", volume_rate, volume_rate_index)
             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"]
             # 鏃堕棿宸笉鑳藉お澶ф墠鑳藉鐞�
             if not l2_trade_util.is_in_forbidden_trade_codes(code):
@@ -321,7 +331,8 @@
                 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),
+                                                                                      code_volumn_manager.get_volume_rate_index(
+                                                                                          buy_volume_rate),
                                                                                       cls.volume_rate_info[code][1],
                                                                                       is_first_code)
                 if b_need_cancel:
@@ -438,7 +449,11 @@
     @classmethod
     def __buy(cls, code, capture_timestamp, last_data, last_data_index, is_first_code):
         __start_time = tool.get_now_timestamp()
-        can, need_clear_data, reason = cls.__can_buy(code, is_first_code)
+        can, need_clear_data, reason = False,False,""
+        if not is_first_code:
+            can, need_clear_data, reason = cls.__can_buy(code)
+        else:
+            can, need_clear_data, reason = cls.__can_buy_first(code)
         __start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - __start_time, "鏈�鍚庡垽鏂槸鍚﹁兘涓嬪崟", force=True)
         # 鍒犻櫎铏氭嫙涓嬪崟
         if code in cls.unreal_buy_dict:
@@ -504,18 +519,8 @@
     # 鏄惁鍙互涔�
     # 杩斿洖鏄惁鍙互涔�,鏄惁闇�瑕佹竻闄や箣鍓嶇殑涔板叆淇℃伅锛屽師鍥�
     @classmethod
-    def __can_buy(cls, code, is_first_code):
+    def __can_buy(cls, code):
         __start_time = t.time()
-        # 鍒ゆ柇鏄惁涓洪鏉夸唬鐮�
-        if is_first_code:
-            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])
-                if not code_price_manager.Buy1PriceManager.is_can_buy(code):
-                    return False, True, "棣栨澘浠g爜锛屾病鍦ㄦ兂瑕佷拱鍚嶅崟涓笖鏈墦寮�娑ㄥ仠鏉�"
-                if not is_limited_up:
-                    return False, True, "棣栨澘浠g爜锛屾病鍦ㄦ兂瑕佷拱鍚嶅崟涓笖鏈定鍋滆繃"
-
             # 涔嬪墠鐨勪唬鐮�
             # 棣栨澘浠g爜涓斿皻鏈定鍋滆繃鐨勪笉鑳戒笅鍗�
             # is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code)
@@ -566,16 +571,15 @@
 
             # 閲忔瘮瓒呰繃1.3鐨勪笉鑳戒拱
             volumn_rate = cls.volume_rate_info[code][0]
-            if not is_first_code and volumn_rate >= 1.3:
+            if volumn_rate >= 1.3:
                 return False, False, "鏈�澶ч噺姣旇秴杩�1.3涓嶈兘涔�"
-            elif is_first_code and volumn_rate >= 1.1:
-                return False, False, "棣栨澘鏈�澶ч噺姣旇秴杩�1.1涓嶈兘涔�"
+
 
             limit_up_time = limit_up_time_manager.get_limit_up_time(code)
             if limit_up_time is not None:
                 limit_up_time_seconds = l2.l2_data_util.L2DataUtil.get_time_as_second(
                     limit_up_time)
-                if not is_first_code and limit_up_time_seconds >= l2.l2_data_util.L2DataUtil.get_time_as_second(
+                if  limit_up_time_seconds >= l2.l2_data_util.L2DataUtil.get_time_as_second(
                         "13:00:00"):
                     return False, False, "浜屾澘涓嬪崍娑ㄥ仠鐨勪笉鑳戒拱锛屾定鍋滄椂闂翠负{}".format(limit_up_time)
                 if limit_up_time_seconds >= l2.l2_data_util.L2DataUtil.get_time_as_second("14:55:00"):
@@ -640,6 +644,27 @@
             return True, False, None
         finally:
             l2_data_log.l2_time(code, round((t.time() - __start_time) * 1000), "鏄惁鍙互涓嬪崟璁$畻")
+
+    @classmethod
+    def __can_buy_first(cls, code):
+
+        if not gpcode_manager.WantBuyCodesManager.is_in(code):
+            # 鏌ョ湅鍒嗘暟绛夌骇
+            score_index = cls.__l2PlaceOrderParamsManagerDict[code].score_index
+            score = cls.__l2PlaceOrderParamsManagerDict[code].score
+            if score_index < 0:
+                return False, True, f"鍒嗗�硷細{score}鏈揪鍒伴渶瑕佷拱鍏ョ殑鍒嗘暟绾�"
+            if -1 < score_index < 3:
+                return True, False, f"鍒嗗�硷細{score}杈惧埌涓诲姩涔板叆鐨勫垎鏁扮嚎锛屼拱鍏ョ瓑绾э細f{score_index}"
+            is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code)
+            gpcode_manager.FirstCodeManager.add_limited_up_record([code])
+            if not code_price_manager.Buy1PriceManager.is_can_buy(code):
+                return False, True, f"棣栨澘浠g爜锛屾病鍦ㄦ兂瑕佷拱鍚嶅崟涓笖鏈墦寮�娑ㄥ仠鏉�,鍒嗘暟锛歿score}"
+            if not is_limited_up:
+                return False, True, f"棣栨澘浠g爜锛屾病鍦ㄦ兂瑕佷拱鍚嶅崟涓笖鏈定鍋滆繃,鍒嗘暟锛歿score}"
+            return True, False, ""
+        else:
+            return True, False, "鍦ㄦ兂涔板悕鍗曚腑"
 
     @classmethod
     def __cancel_buy(cls, code):
@@ -708,7 +733,7 @@
         # 鏄惁涓烘柊鑾峰彇鍒扮殑浣嶇疆
         new_get_single = False
         if buy_single_index is None:
-            continue_count = cls.__l2PlaceOrderParamsManager.get_begin_continue_buy_count(cls.volume_rate_info[code][1])
+            continue_count = cls.__l2PlaceOrderParamsManagerDict[code].get_begin_continue_buy_count()
             # 鏈変拱鍏ヤ俊鍙�
             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,
@@ -765,8 +790,8 @@
             return
 
         if compute_index is not None:
-            l2_log.debug(code, "鑾峰彇鍒颁拱鍏ユ墽琛屼綅缃細{} m鍊硷細{} 绾拱鎵嬫暟锛歿} 绾拱鍗曟暟锛歿} 鏁版嵁锛歿}", compute_index, threshold_money, buy_nums,
-                         buy_count, total_datas[compute_index])
+            l2_log.debug(code, "鑾峰彇鍒颁拱鍏ユ墽琛屼綅缃細{} m鍊硷細{} 绾拱鎵嬫暟锛歿} 绾拱鍗曟暟锛歿} 鏁版嵁锛歿} ,閲忔瘮:{} ", compute_index, threshold_money, buy_nums,
+                         buy_count, total_datas[compute_index],cls.volume_rate_info[code][0])
 
             f1 = dask.delayed(cls.__save_order_begin_data)(code, buy_single_index, compute_index, compute_index,
                                                            buy_nums, buy_count, max_num_set_new,
@@ -902,7 +927,7 @@
 
     @classmethod
     def __get_threshmoney(cls, code):
-        return l2_trade_factor.L2TradeFactorUtil.compute_m_value(code, cls.volume_rate_info[code][1])
+        return cls.__l2PlaceOrderParamsManagerDict[code].get_m_val()
 
     # 璁$畻涓囨墜鍝ョ瑪鏁�
     @classmethod
@@ -937,9 +962,7 @@
 
         # place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code)
         # 鐩爣璁㈠崟鏁伴噺
-        threshold_count = cls.__buyL2SafeCountManager.get_safe_count(code, is_first_code,
-                                                                     cls.__l2PlaceOrderParamsManager.get_safe_count_rate(
-                                                                         cls.volume_rate_info[code][1]))
+        threshold_count = cls.__l2PlaceOrderParamsManagerDict[code].get_safe_count()
 
         buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"])
 
@@ -947,13 +970,13 @@
         trigger_buy = True
 
         # 闂撮殧鏈�澶ф椂闂翠緷娆′负锛�3,9,27,81
-        max_space_time = cls.__l2PlaceOrderParamsManager.get_time_range(cls.volume_rate_info[code][1])
+        max_space_time = cls.__l2PlaceOrderParamsManagerDict[code].get_time_range()
         # 鏈�澶т拱閲�
         max_buy_num = 0
         max_buy_num_set = set(max_num_set)
 
         # 闇�瑕佺殑鏈�灏忓ぇ鍗曠瑪鏁�
-        big_num_count = cls.__l2PlaceOrderParamsManager.get_big_num_count(cls.volume_rate_info[code][1])
+        big_num_count = cls.__l2PlaceOrderParamsManagerDict[code].get_big_num_count()
 
         # 杈冨ぇ鍗曠殑鎵嬫暟
         bigger_num = round(5900 / limit_up_price)
diff --git a/l2_trade_test.py b/l2_trade_test.py
index 6019ad0..1fb10b2 100644
--- a/l2_trade_test.py
+++ b/l2_trade_test.py
@@ -85,7 +85,7 @@
                 except Exception as e:
                     pass
 
-    # @unittest.skip("璺宠繃姝ゅ崟鍏冩祴璇�")
+    @unittest.skip("璺宠繃姝ゅ崟鍏冩祴璇�")
     def test_trade(self):
         code = "603801"
         clear_trade_data(code)
diff --git a/ocr/ocr_server.py b/ocr/ocr_server.py
index 433a44b..2babf65 100644
--- a/ocr/ocr_server.py
+++ b/ocr/ocr_server.py
@@ -1,3 +1,4 @@
+import base64
 import json
 import logging
 import socketserver
@@ -7,6 +8,8 @@
 import ths_industry_util
 from ocr import ocr_util
 from ocr.ocr_util import OcrUtil
+from third_data import kpl_util
+from trade import bidding_money_manager
 
 
 class OCRServer(BaseHTTPRequestHandler):
@@ -32,11 +35,14 @@
         try:
             data = ""
             try:
-                data = json.loads(_str)
-            except:
+                if type(_str) == str:
+                    data = json.loads(_str)
+                else:
+                    data = _str
+            except Exception as e1:
                 raise Exception("json瑙f瀽澶辫触")
-            type = data["type"]
-            if type == 100:
+            _type = data["type"]
+            if _type == 100:
                 data = data["data"]
                 matId = data["matId"]
                 index = data["index"]
@@ -68,7 +74,7 @@
                         return_str = json.dumps({"code": 2, "msg": "鏁版嵁鍑洪敊"})
                 else:
                     return_str = json.dumps({"code": 1, "msg": "鏁版嵁灏氭湭涓婁紶瀹�"})
-            elif type == 101:
+            elif _type == 101:
                 data = data["data"]
                 matId = data["matId"]
                 index = data["index"]
@@ -101,6 +107,15 @@
                         return_str = json.dumps({"code": 2, "msg": "鏁版嵁鍑洪敊"})
                 else:
                     return_str = json.dumps({"code": 1, "msg": "鏁版嵁灏氭湭涓婁紶瀹�"})
+            elif _type == 201:
+                imgdata = base64.b64decode(data["img"])
+                results = ocr_util.OcrUtil.easy_ocr(imgdata)
+                print(results)
+                kpl_datas = kpl_util.parse_kpl_datas(results)
+                if kpl_datas:
+                    bidding_money_manager.set_bidding_money(kpl_datas)
+                with open("D:/kpl.png", mode="wb") as f:
+                    f.write(imgdata)
         except Exception as e:
             logging.exception(e)
             if str(e).__contains__("json瑙f瀽澶辫触"):
@@ -120,18 +135,21 @@
         datas = self.rfile.read(int(self.headers['content-length']))
         _str = str(datas, encoding="gbk")
         # print(_str)
-        start = 0
-        while True:
-            start = _str.find("Content-Disposition: form-data;", start + 1)
-            if start <= 0:
-                break
-            name_start = start + len("Content-Disposition: form-data;")
-            name_end = _str.find("\r\n\r\n", start)
+        if _str.find("Content-Disposition: form-data;") > -1:
+            start = 0
+            while True:
+                start = _str.find("Content-Disposition: form-data;", start + 1)
+                if start <= 0:
+                    break
+                name_start = start + len("Content-Disposition: form-data;")
+                name_end = _str.find("\r\n\r\n", start)
 
-            val_end = _str.find("------", name_end)
-            key = _str[name_start:name_end].strip()[6:-1]
-            val = _str[name_end:val_end].strip()
-            params[key] = val
+                val_end = _str.find("------", name_end)
+                key = _str[name_start:name_end].strip()[6:-1]
+                val = _str[name_end:val_end].strip()
+                params[key] = val
+        else:
+            params = json.loads(_str)
         return params
 
 
@@ -140,3 +158,8 @@
     httpd = socketserver.TCPServer((addr, port), handler)
     print("HTTP server is at: http://%s:%d/" % (addr, port))
     httpd.serve_forever()
+
+
+if __name__ == "__main__":
+    str_={"id":"123"}
+    print(type(str_)==str)
\ No newline at end of file
diff --git a/ocr/ocr_util.py b/ocr/ocr_util.py
index 8f02f3c..2070c56 100644
--- a/ocr/ocr_util.py
+++ b/ocr/ocr_util.py
@@ -16,6 +16,11 @@
         res = cls.__ocr.ocr(mat)
         return res
 
+    @classmethod
+    def easy_ocr(cls, mat):
+        res = cls.reader.readtext(mat, detail=1)
+        return res
+
     # 杩斿洖(璇嗗埆鍐呭,浣嶇疆淇℃伅)
     @classmethod
     def ocr_with_key(cls, mat, key):
diff --git a/output/code_info_output.py b/output/code_info_output.py
new file mode 100644
index 0000000..451522f
--- /dev/null
+++ b/output/code_info_output.py
@@ -0,0 +1,306 @@
+"""
+浠g爜淇℃伅瀵瑰杈撳嚭
+"""
+
+# score_info 寰楀垎淇℃伅
+# 涓嬪崟鍙傛暟淇℃伅
+# 閫夎偂瀹�
+# 甯傚満鐑害
+import code_volumn_manager
+import global_data_loader
+import global_util
+import gpcode_manager
+import juejin
+import limit_up_time_manager
+import tool
+from l2 import l2_data_manager, l2_data_util, transaction_progress
+from third_data import hot_block_data_process
+from trade import first_code_score_manager, l2_trade_factor
+from trade.l2_trade_factor import L2TradeFactorUtil
+
+
+def __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos):
+    html = ""
+    html += f"<h2>{code_info[1]} {code_info[0]}</h2><br>"
+    if score_info:
+        html += "-----涔板墠璇勫垎-------<br>"
+        score_types = ["鎹㈡墜閲忚兘", "绔炰环寮哄害", "璧勯噾鍔涘害", "鏃ョ嚎褰㈡��", "鍘嗗彶鑲℃��", "鏉垮潡鐑害", "涓婃澘鏃堕棿", "甯傚�煎ぇ灏�", "鑲′环澶у皬"]
+        html += "<table style='font-size:25px'>"
+        for i in range(0, len(score_info[1])):
+            html += f"<tr><td>{score_types[i]}</td><td>{score_info[1][i]}</td><td>{score_info[2][i]}</td></tr>"
+        html += f"<tr><td><b>璇勫垎姹傚拰锛�</td><td>{score_info[0]}</b></td><td></td></tr>"
+        html += f"</table>"
+
+    if buy_params_info:
+        html += "<br>-----浜ゆ槗鍙傛暟-------<br><table>"
+        titles = ["涔板叆鎰忔効", "瀹夊叏绗旀暟", "鍔ㄦ�丮鍊�", "涔板墠澶у崟", "鎴愪氦杩涘害", "涔板叆淇″彿", "涔板叆鎵ц浣�"]
+        for i in range(0, len(titles)):
+            html += f"<tr><td>{titles[i]}锛�</td><td>{buy_params_info[i]}</td></tr>"
+        html += "</table>"
+
+    if xgb_code_info:
+        html += "<br>-----閫夎偂瀹�---------<br>"
+        xgb_code_info_dates = ["浠婂ぉ", "鏄ㄥぉ", "鍓嶅ぉ", "涔嬪墠"]
+        for i in range(0, len(xgb_code_info)):
+            html += f"{xgb_code_info_dates[i]}锛�<br>"
+            if xgb_code_info[i]:
+                for info in xgb_code_info[i]:
+                    if i == 0:
+                        html += f"銆�<font color='red'>{info[0]}</font>銆戯紝鍏便��<font color='red'>{info[1]}</font>銆戝彧绁ㄦ定鍋�<br>绗��<font color='red'>{info[2]}</font>銆戞定鍋滐紝鐜颁环銆�<font color='red'>{info[3]}</font>銆戝厓锛屾定骞呫��<font color='red'>{info[4]}</font>銆�<br><br>"
+                    else:
+                        html += f"銆恵info[0]}銆戯紝鍏便�恵info[1]}銆戝彧绁ㄦ定鍋�<br>绗�恵info[2]}銆戞定鍋滐紝鐜颁环銆恵info[3]}銆戝厓锛屾定骞呫�恵info[4]}銆�<br><br>"
+            else:
+                html += f"鏃�<br>"
+    if xgb_infos:
+        html += "<br>-----甯傚満鐑害-------<br><table>"
+        for info in xgb_infos:
+            html += f"<tr><td>{info}</td></tr>"
+        html += "</tr>"
+    return html
+
+
+def get_output_html(code):
+    day = tool.get_now_date_str()
+    is_target_code = gpcode_manager.FirstCodeManager.is_in_first_record(code)
+    code_info = [code, gpcode_manager.get_code_name(code)]
+    score_info = None
+    buy_params_info = None
+    xgb_infos = None
+    if is_target_code:
+        limit_up_price = gpcode_manager.get_limit_up_price(code)
+        limit_up_time = limit_up_time_manager.get_limit_up_time(code)
+        volume_rate, volume_info = code_volumn_manager.get_volume_rate(code, True)
+        (score, score_list), score_source_list = first_code_score_manager.get_score(code, volume_rate, limit_up_time,
+                                                                                    True)
+        ################################涔板墠璇勫垎################################
+        # ["鎹㈡墜閲忚兘", "绔炰环寮哄害", "璧勯噾鍔涘害", "K绾垮舰鎬�", "鍘嗗彶鑲℃��", "鏉垮潡鐑害", "涓婃澘鏃堕棿", "甯傚�煎ぇ灏�","鑲′环澶у皬"]
+        score_list_new = []
+        score_source_list_new = []
+        # 鎹㈡墜閲忚兘
+        score_list_new.append(score_list[6])
+        # 鑾峰彇褰撳墠閲忎俊鎭�
+        max_60, yest = code_volumn_manager.get_histry_volumn(code)
+        today = code_volumn_manager.get_today_volumn(code)
+        score_source_list_new.append(f"瀹炴椂閲忋�恵round(int(today)/10000,2)}涓囨墜銆懨峰墠楂橀噺銆恵round(max_60[0]/10000,2)}涓囨墜-{max_60[1]}銆�=銆恵round(score_source_list[6]*100,2)}%銆�")
+        # 绔炰环寮哄害
+        score_list_new.append(score_list[2])
+        score_source_list_new.append(f"寮�鐩樺暒浠婃棩濮斿仠銆恵score_source_list[2] if score_source_list[2] else 0}涓囥��")
+        # 璧勯噾鍔涘害
+        score_list_new.append(score_list[8])
+        score_source_list_new.append(f"绱閲戦銆恵score_source_list[8][0] / 10000}涓囥��&鍥哄畾m鍊笺�恵score_source_list[8][1] / 10000}涓囥��")
+        # K绾垮舰鎬�
+        k_score = 0
+        k_source = []
+        for k in score_list[3]:
+            k_score += k
+
+        # (15涓氦鏄撴棩鏄惁娑ㄥ箙24.9%,鏄惁鐮村墠楂橈紝鏄惁瓒呰穼锛屾槸鍚︽帴杩戝墠楂橈紝鏄惁N,鏄惁V)
+        for k in range(0, len(score_source_list[3])):
+            if k == 0:
+                if score_source_list[3][k][0]:
+                    k_source.append("銆愭定骞呰繃楂樸��")
+            elif k == 1:
+                if score_source_list[3][k][0]:
+                    k_source.append("銆愮獊鐮村墠楂樸��")
+            elif k == 2:
+                if score_source_list[3][k][0]:
+                    k_source.append("銆愯秴璺岃ˉ娑ㄣ��")
+            elif k == 3:
+                if score_source_list[3][k][0]:
+                    k_source.append(f"銆愰�艰繎鍓嶉珮-{score_source_list[3][k][1]}銆�")
+            elif k == 4:
+                if score_source_list[3][k][0]:
+                    k_source.append("銆怤瀛楀瀷銆�")
+            elif k == 5:
+                if score_source_list[3][k][0]:
+                    k_source.append("銆怴瀛楀瀷銆�")
+
+        if not score_source_list[3][1][0] and not score_source_list[3][2][0] and not score_source_list[3][4][0] and not \
+                score_source_list[3][5][0]:
+            k_source.append("銆愪笉婊¤冻浠讳綍褰㈡�併��")
+
+        score_list_new.append(k_score)
+        score_source_list_new.append("/".join(k_source))
+        # 鍘嗗彶鑲℃��
+        nature_score = 0
+        nature_source = []
+        for k in score_list[4]:
+            nature_score += k
+
+        for n in range(0, len(score_source_list[4])):
+            if n == 0:
+                if not score_source_list[4][n]:
+                    nature_source.append("鏃犳定鍋�")
+                else:
+                    nature_source.append("鏈夋定鍋�")
+            if n == 1:
+                nature_source.append(f"棣栨澘婧环鐜囥�恵score_source_list[4][2]}銆�")
+
+        score_list_new.append(nature_score)
+        score_source_list_new.append(",".join(nature_source))
+
+        # 鏉垮潡鐑害
+        hot_block_score = 0
+        hot_block_source = []
+        for k in score_list[5]:
+            hot_block_score += k
+        for n in range(0, len(score_source_list[5])):
+            if n == 1:
+                hot_block_source.append(f"銆恵score_source_list[5][0]}銆戝叡{score_source_list[5][n]}涓定鍋�")
+            elif n == 2:
+                hot_block_source.append(f"鍏眥score_source_list[5][n]}涓偢鏉�")
+        score_list_new.append(hot_block_score)
+        score_source_list_new.append(",".join(hot_block_source))
+
+        # 涓婃澘鏃堕棿
+        score_list_new.append(score_list[7])
+        score_source_list_new.append(f"涓婃澘鏃堕棿銆恵score_source_list[7]}銆�")
+        # 甯傚�煎ぇ灏�
+        score_list_new.append(score_list[0])
+        score_source_list_new.append(f"鑷敱甯傚�笺�恵round(score_source_list[0] / 100000000, 2)}浜裤��")
+        # 鑲′环澶у皬
+        score_list_new.append(score_list[1])
+        score_source_list_new.append(f"鐜颁环銆恵score_source_list[1]}銆戝厓")
+
+        score_info = (score, score_list_new, score_source_list_new)
+
+        # zyltgb, limit_price, bidding, k_form, code_nature, hot_block, volume_rate, limit_up_time,
+        # deal_big_money
+
+        ###############################涓嬪崟淇℃伅###############################
+        # 鑾峰彇涔板叆鎰忔効
+        volume_rate = score_source_list[6]
+        __L2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager(code, True, volume_rate,
+                                                                                code_volumn_manager.get_volume_rate_index(
+                                                                                    volume_rate),
+                                                                                (score, score_list))
+        __base_L2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager(code, False, volume_rate,
+                                                                                     code_volumn_manager.get_volume_rate_index(
+                                                                                         volume_rate),
+                                                                                     (score, score_list))
+        buy_params_info = []
+        if -1 < __L2PlaceOrderParamsManager.score_index < 3:
+            buy_params_info.append("<font color='red'>銆愪富鍔ㄤ拱鍏ャ��</font>")
+        elif __L2PlaceOrderParamsManager.score_index < 0:
+            buy_params_info.append("銆愪笉鎵ц涔板叆銆�")
+        else:
+            buy_params_info.append("銆愯鍔ㄤ拱鍏ャ��")
+        # 瀹夊叏绗旀暟
+        safe_count = __L2PlaceOrderParamsManager.get_safe_count()
+        base_safe_count, min_count, max_count = L2TradeFactorUtil.get_safe_buy_count(code, True)
+        buy_params_info.append(f"鍥哄畾瀹夊叏绗旀暟銆恵base_safe_count}銆戠瑪,琛板噺鍚庡畨鍏ㄧ瑪鏁般�恵safe_count}銆戠瑪")
+        # 鍔ㄦ�丮鍊�
+        m = __L2PlaceOrderParamsManager.get_m_val()
+        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)
+        buy_params_info.append(f"鍥哄畾M鍊笺�恵base_m / 10000}涓囥�戯紝鍔ㄦ�丮鍊笺�恵m[0] / 10000}涓囥��	")
+        # 涔板墠澶у崟
+        big_num = __L2PlaceOrderParamsManager.get_big_num_count()
+        base_big_num = __base_L2PlaceOrderParamsManager.get_big_num_count()
+        buy_params_info.append(f"鍥哄畾涔板墠澶у崟銆恵base_big_num}銆戠瑪锛岃“鍑忓悗涔板墠澶у崟銆恵big_num}銆戠瑪")
+        # 鎴愪氦杩涘害
+        total_datas = l2_data_util.local_today_datas.get(code)
+        if total_datas is None:
+            l2_data_util.load_l2_data(code)
+            total_datas = l2_data_util.local_today_datas.get(code)
+        trade_progress, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code)
+        if trade_progress is None or trade_progress < 0 or is_default:
+            buy_params_info.append("鏈瘑鍒�")
+        else:
+            data = total_datas[trade_progress]
+            buy_params_info.append(
+                f"銆恵data['val']['time']}銆戙�併�恵data['val']['num']}鎵嬨�戙�併�恵round(data['val']['num'] * float(data['val']['price']) * 100 / 10000, 1)}涓囥��")
+
+        # 涔板叆淇″彿
+        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_single_index is None:
+            buy_params_info.append("鏃犱俊鍙�")
+        else:
+            data = total_datas[buy_single_index]
+            buy_params_info.append(
+                f"銆恵data['val']['time']}銆戙�併�恵data['val']['num']}鎵嬨�戙�併�恵round(data['val']['num'] * float(data['val']['price']) * 100 / 10000, 1)}涓囥��")
+
+        if buy_exec_index is None or buy_exec_index < 0:
+            buy_params_info.append("鏈笅鍗�")
+        else:
+            data = total_datas[buy_exec_index]
+            buy_params_info.append(
+                f"銆恵data['val']['time']}銆戙�併�恵data['val']['num']}鎵嬨�戙�併�恵round(data['val']['num'] * float(data['val']['price']) * 100 / 10000, 1)}涓囥��")
+
+    ##############################閫夎偂瀹�##################################
+    xgb_code_info = []
+    for i in range(0, 4):
+        xgb_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_code(code, day)
+        datas = []
+        if xgb_datas:
+            for data in xgb_datas:
+                block = data[2]
+                block_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_block(block, day)
+                block_datas = list(block_datas)
+                limit_up_count = 0
+                limit_up_time = None
+                for d in block_datas:
+                    if len(d[4]) > 6:
+                        limit_up_count += 1
+                        if d[3] == code:
+                            limit_up_time = d[4]
+
+                # 鏍规嵁娑ㄥ仠鏃堕棿鎺掑簭
+                block_datas.sort(key=lambda d: (d[4] if len(d[4]) > 6 else '15:00:00'))
+
+                for i in range(len(block_datas)):
+                    if block_datas[i][3] == code:
+                        datas.append(
+                            (block, limit_up_count, (i + 1) if limit_up_time is not None else (limit_up_count + 1),
+                             block_datas[i][5], block_datas[i][6]))
+                        break
+        xgb_code_info.append(datas)
+        day = juejin.JueJinManager.get_previous_trading_date(day)
+
+    ##############################鐑棬椋庡彛##################################
+    xgb_infos = []
+    xgb_latest_datas = hot_block_data_process.XGBHotBlockDataManager.latest_datas
+    if not xgb_latest_datas:
+        xgb_infos.append('鏆傛湭鑾峰彇鍒版暟鎹�')
+    else:
+        for block in xgb_latest_datas:
+            limit_up_count = 0
+            for code_data in block[2]:
+                if len(code_data[4]) > 6:
+                    limit_up_count += 1
+            xgb_infos.append(f"銆恵block[0]}銆戯紝娑ㄥ箙銆恵block[1]}銆戯紝鍏便�恵limit_up_count}銆戜釜娑ㄥ仠")
+
+    return __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos)
+
+
+if __name__ == '__main__':
+    code = "002410"
+    day = '2023-03-27'
+    xgb_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_code(code, day)
+    datas = []
+    if xgb_datas:
+        for data in xgb_datas:
+            block = data[2]
+            block_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_block(block, day)
+            block_datas = list(block_datas)
+            limit_up_count = 0
+            limit_up_time = None
+            for d in block_datas:
+                if len(d[4]) > 6:
+                    limit_up_count += 1
+                    if d[3] == code:
+                        limit_up_time = d[4]
+
+            # 鏍规嵁娑ㄥ仠鏃堕棿鎺掑簭
+            block_datas.sort(key=lambda d: (d[4] if len(d[4]) > 6 else '15:00:00'))
+
+            for i in range(len(block_datas)):
+                if block_datas[i][3] == code:
+                    datas.append((block, limit_up_count, (i + 1) if limit_up_time is not None else (limit_up_count + 1),
+                                  block_datas[i][5], block_datas[i][6]))
+                    break
diff --git a/server.py b/server.py
index 5faf62e..1478572 100644
--- a/server.py
+++ b/server.py
@@ -30,9 +30,11 @@
 import ths_industry_util
 import ths_util
 import tool
+from output import code_info_output
 from third_data import hot_block_data_process
 from ths import l2_listen_pos_health_manager
-from trade import trade_gui, trade_data_manager, trade_manager, l2_trade_util, deal_big_money_manager
+from trade import trade_gui, trade_data_manager, trade_manager, l2_trade_util, deal_big_money_manager, \
+    first_code_score_manager
 import l2_code_operate
 from code_data_util import ZYLTGBUtil
 import l2.transaction_progress
@@ -286,11 +288,18 @@
                             logger_first_code_record.info("鏂板棣栨澘锛歿}", new_add_codes)
                             # 鑾峰彇60澶╂渶澶ц褰�
                             for code in codes:
+                                need_get_volumn = False
                                 if code not in global_util.max60_volumn or global_util.max60_volumn.get(code) is None:
+                                    need_get_volumn = True
+                                if not need_get_volumn and code_nature_analyse.CodeNatureRecordManager.get_nature(
+                                        code) is None:
+                                    need_get_volumn = True
+                                if need_get_volumn:
                                     volumes_data = juejin.get_volumns_by_code(code, 150)
-                                    volumes = juejin.parse_max_volume(volumes_data[:60])
+                                    volumes = juejin.parse_max_volume(volumes_data[:60], code_nature_analyse.is_new_top(
+                                        gpcode_manager.get_limit_up_price(code), volumes_data[:60]))
                                     logger_first_code_record.info("{} 鑾峰彇鍒伴鏉�60澶╂渶澶ч噺锛歿}", code, volumes)
-                                    code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1])
+                                    code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1], volumes[2])
                                     # 鍒ゆ柇K绾垮舰鎬�
                                     is_has_k_format, msg = code_nature_analyse.is_has_k_format(
                                         gpcode_manager.get_limit_up_price(code), volumes_data)
@@ -300,11 +309,9 @@
                                         bad_codes.add(code)
                                         # 鍔犲叆绂佹浜ゆ槗浠g爜
                                         l2_trade_util.forbidden_trade(code)
-                                        break
-                                    else:
-                                        code_nature_analyse.set_record_datas(code,
-                                                                             gpcode_manager.get_limit_up_price(code),
-                                                                             volumes_data)
+                                    code_nature_analyse.set_record_datas(code,
+                                                                         gpcode_manager.get_limit_up_price(code),
+                                                                         volumes_data)
 
                             # 绉婚櫎浠g爜
                             listen_codes = gpcode_manager.get_listen_codes()
@@ -704,9 +711,22 @@
                                         {"block_name": block, "block_size": len(block_datas), "index": i,
                                          "price": block_datas[i][5], "rate": block_datas[i][6]})
                                     break
-                    final_data = {'code': code, 'today': today_datas, 'last_day': last_datas}
+                    final_data = {'code': code, 'data': code_info_output.get_output_html(code)}
                     return_str = json.dumps({"code": 0, "data": final_data})
                     pass
+                # 鑾峰彇鏈�杩�2涓氦鏄撴棩娑ㄥ仠浠g爜
+                elif type == 72:
+                    day = tool.get_now_date_str()
+                    last_day = juejin.JueJinManager.get_previous_trading_date(day)
+                    data_list = list(hot_block_data_process.XGBHotBlockDataManager.list_all(day))
+                    data_list_last = list(hot_block_data_process.XGBHotBlockDataManager.list_all(last_day))
+                    data_list.extend(data_list_last)
+                    codes_set = set()
+                    if data_list:
+                        for d in data_list:
+                            if len(d[4]) > 6:
+                                codes_set.add(d[3])
+                    return_str = json.dumps({"code": 0, "data": list(codes_set)})
                 elif type == 201:
                     # 鍔犲叆榛戝悕鍗�
                     data = json.loads(_str)
@@ -872,18 +892,29 @@
 
 
 if __name__ == "__main__":
-    codes = ["601698"]
+    codes = ["002153", "002253", "002351"]
     for code in codes:
-        volumes_data = juejin.get_volumns_by_code(code, 150)
-        volumes_data = volumes_data[1:]
         global_data_loader.load_zyltgb()
         limit_up_price = float(gpcode_manager.get_limit_up_price(code))
-        # 鍒ゆ柇鑲℃��
-        # is_k_format, msg = code_nature_analyse.is_has_k_format(float(limit_up_price), volumes_data)
-        # print(code, is_k_format, msg)
+        volumes_data = juejin.get_volumns_by_code(code, 150)
+        volumes_data = volumes_data[1:]
+        volumes = juejin.parse_max_volume(volumes_data[:60],
+                                          code_nature_analyse.is_new_top(gpcode_manager.get_limit_up_price(code),
+                                                                         volumes_data[:60]))
+        logger_first_code_record.info("{} 鑾峰彇鍒伴鏉�60澶╂渶澶ч噺锛歿}", code, volumes)
+        code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1], volumes[2])
+        # 鍒ゆ柇K绾垮舰鎬�
+        is_has_k_format, msg = code_nature_analyse.is_has_k_format(
+            gpcode_manager.get_limit_up_price(code), volumes_data)
+        if not is_has_k_format:
+            logger_first_code_record.info("{}棣栨澘K绾垮舰鎬佷笉濂�,{}", code, msg)
+            # 鍔犲叆绂佹浜ゆ槗浠g爜
+            l2_trade_util.forbidden_trade(code)
 
         code_nature_analyse.set_record_datas(code,
-                                             limit_up_price,
+                                             gpcode_manager.get_limit_up_price(code),
                                              volumes_data)
 
-        print(code_nature_analyse.get_k_format(float(limit_up_price), volumes_data))
+        # code_nature_analyse.set_record_datas(code,
+        #                                      limit_up_price,
+        #                                      volumes_data)
diff --git a/third_data/hot_block.py b/third_data/hot_block.py
index f2524f8..9ddfb71 100644
--- a/third_data/hot_block.py
+++ b/third_data/hot_block.py
@@ -70,10 +70,10 @@
         time.sleep(3)
         # 浜ゆ槗鏃堕棿鎵嶈瘑鍒�
         time_str = datetime.datetime.now().strftime("%H%M%S")
-        if int(time_str) < int("092500") or int(time_str) > int("150000"):
-            continue
-        if int("113000") < int(time_str) < int("130000"):
-            continue
+        # if int(time_str) < int("092500") or int(time_str) > int("150000"):
+        #     continue
+        # if int("113000") < int(time_str) < int("130000"):
+        #     continue
         try:
             day, result = __parseData(driver)
             callback(day, result)
diff --git a/third_data/hot_block_data_process.py b/third_data/hot_block_data_process.py
index 11afd89..6ff6a26 100644
--- a/third_data/hot_block_data_process.py
+++ b/third_data/hot_block_data_process.py
@@ -16,10 +16,12 @@
 
 class XGBHotBlockDataManager:
     total_datas = []
-    __last_datas={}
+    __last_datas = {}
+    latest_datas = None
 
     @classmethod
-    def save(cls,day, datas):
+    def save(cls, day, datas):
+        cls.latest_datas = datas
         mysqldb = mysql_data.Mysqldb()
         # 缁熻浠g爜鎵�灞炴澘鍧�
         code_block_dict = {}
@@ -35,15 +37,22 @@
                 code = code_info[0].split(".")[0]
                 _id = f"{day}_{data[0]}_{code}"
 
-                result = mysqldb.select_one("select count(*) from xgb_hot_block where _id='{}'".format(_id))
-                if not result[0]:
+                result = mysqldb.select_one("select * from xgb_hot_block where _id='{}'".format(_id))
+                limit_up_time = code_info[4]
+                if len(limit_up_time) <= 6:
+                    limit_up_time = ''
+                if not result:
                     mysqldb.execute(
-                        f"insert into xgb_hot_block(_id,_day,_block_name,_code,_limit_up_time,_price,_rate,_update_time) values('{_id}','{day}','{data[0]}','{code}','{code_info[4]}','{code_info[2]}','{code_info[3]}',now())")
+                        f"insert into xgb_hot_block(_id,_day,_block_name,_code,_limit_up_time,_price,_rate,_update_time,_first_limit_up_time) values('{_id}','{day}','{data[0]}','{code}','{code_info[4]}','{code_info[2]}','{code_info[3]}',now(),'{limit_up_time}')")
                 else:
                     # 濡傛灉涓婃鐨勬暟鎹拰杩欐涓�鏍峰氨涓嶆洿鏂帮紝鍚﹀垯闇�瑕佹洿鏂版暟鎹�
                     if cls.__last_datas.get(_id) != code_info:
-                        # 鏇存柊
-                        mysqldb.execute(f"update xgb_hot_block set _limit_up_time='{code_info[4]}',_price='{code_info[2]}',_rate='{code_info[3]}' where _id='{_id}'")
+                        mysqldb.execute(
+                            f"update xgb_hot_block set _limit_up_time='{code_info[4]}',_price='{code_info[2]}',_rate='{code_info[3]}',_update_time=now() where _id='{_id}'")
+                        if (not result[8] or len(result[8]) <= 6) and len(limit_up_time) >= 6:
+                            mysqldb.execute(
+                                f"update xgb_hot_block set _first_limit_up_time='{limit_up_time}',_update_time=now() where _id='{_id}'")
+
                 cls.__last_datas[_id] = code_info
                 # 鑾峰彇鍘熸潵鐨勪唬鐮佹墍灞炴澘鍧�,鍒犻櫎涔嬪墠閿欒鐨勬澘鍧�
                 old_datas = XGBHotBlockDataManager.list_by_code(code, day)
@@ -85,37 +94,37 @@
         return None
 
     limit_up_codes_set = set()
-    for block in latest_datas:
-        if block[0] == target_block:
-            for code_data in block[2]:
-                if len(code_data[4]) > 6:
-                    limit_up_codes_set.add(code_data[0].split('.')[0])
+    if XGBHotBlockDataManager.latest_datas:
+        for block in XGBHotBlockDataManager.latest_datas:
+            if block[0] == target_block:
+                for code_data in block[2]:
+                    if len(code_data[4]) > 6:
+                        limit_up_codes_set.add(code_data[0].split('.')[0])
     limit_up_codes_set.discard(code)
     limit_up_count = len(limit_up_codes_set)
 
     total_datas = XGBHotBlockDataManager.total_datas
-    codes = set()
+    break_codes = set()
     for data in total_datas:
         block = data[2]
         if block != target_block:
             continue
         code = data[3]
         limit_up_time = data[4]
-        if len(limit_up_time) > 6:
-            codes.add(code)
-    codes.discard(code)
-    codes.difference(limit_up_codes_set)
+        first_limit_up_time = data[8]
+        if len(limit_up_time) <= 6 and first_limit_up_time and len(first_limit_up_time) > 6:
+            break_codes.add(code)
+    # 鎺掗櫎鑷繁
+    break_codes.discard(code)
+    # 鎺掗櫎宸茬粡娑ㄥ仠鐨勪唬鐮�
+    break_codes = break_codes.difference(limit_up_codes_set)
     # 鐐告澘涓暟
-    break_size = len(codes)
-    return (limit_up_count,break_size)
-
-
-latest_datas = []
+    break_size = len(break_codes)
+    return target_block, limit_up_count, break_size
 
 
 # 淇濆瓨鏁版嵁
 def save_datas(day, datas):
-    latest_datas = datas
     XGBHotBlockDataManager.save(day, datas)
     code_block_dict = {}
     block_codes_dict = {}
@@ -167,5 +176,7 @@
 
 
 if __name__ == "__main__":
-    XGBHotBlockDataManager.total_datas=XGBHotBlockDataManager.list_all("2023-03-23")
-    get_info('002230')
+    # XGBHotBlockDataManager.total_datas=XGBHotBlockDataManager.list_all("2023-03-23")
+    # get_info('002230')
+    codes = set([1, 2, 3, 4])
+    print(codes.difference(set([1, 2])))
diff --git a/third_data/kpl_util.py b/third_data/kpl_util.py
new file mode 100644
index 0000000..466f985
--- /dev/null
+++ b/third_data/kpl_util.py
@@ -0,0 +1,25 @@
+def parse_kpl_datas(results):
+    start_y = -1
+    end_x = -1
+    index = 0
+    datas = []
+    for result in results:
+        text = result[1]
+        if text.find("鑲$エ鍚嶇О") > -1:
+            start_y = result[0][0][1]
+
+        if text.find("绔炰环娑ㄥ箙") > -1:
+            end_x = result[0][0][0]
+        if start_y > 0 and end_x > 0:
+            if result[0][0][0] < end_x and result[0][0][1] > start_y and (result[0][1][0] - result[0][0][0]) > 30:
+                datas.append(text)
+                index += 1
+    datas = datas[:3 * 5]
+    fdatas = []
+    temp = []
+    for data in datas:
+        temp.append(data)
+        if len(temp) == 3:
+            fdatas.append((temp[2][:6], temp[1]))
+            temp = []
+    return fdatas
diff --git a/trade/bidding_money_manager.py b/trade/bidding_money_manager.py
index 02a37c0..56577af 100644
--- a/trade/bidding_money_manager.py
+++ b/trade/bidding_money_manager.py
@@ -28,7 +28,7 @@
 
 
 # 鑾峰彇绔炰环閲戦
-def get_bidding_money(code):
+def get_bidding_money(code) -> object:
     val = __get_redis().get("bidding_money")
     if not val:
         return None
@@ -37,3 +37,9 @@
         if v[0] == code:
             return v[1]
     return None
+
+
+if __name__ == "__main__":
+    # datas = [('002229', '10.92浜�'), ('000977', '2592涓�'), ('000829', '2294涓�'), ('002467', '1869涓�'), ('002217', '1546涓�')]
+    # set_bidding_money(datas)
+    print(get_bidding_money("000977"))
\ No newline at end of file
diff --git a/trade/deal_big_money_manager.py b/trade/deal_big_money_manager.py
index 0e5fb42..91b71c2 100644
--- a/trade/deal_big_money_manager.py
+++ b/trade/deal_big_money_manager.py
@@ -28,6 +28,19 @@
     return None
 
 
+def __save_traded_index(code, index):
+    __get_redis().sadd(f"deal_indexes-{code}", index)
+    __get_redis().expire(f"deal_indexes-{code}", tool.get_expire())
+
+
+def __get_traded_indexes(code):
+    return __get_redis().smembers(f"deal_indexes-{code}")
+
+
+# 鑾峰彇鎴愪氦鐨勭储寮�
+def get_traded_indexes(code):
+    return __get_traded_indexes(code)
+
 # 鑾峰彇鎴愪氦璁$畻杩涘害
 def __get_deal_compute_progress(code):
     val = __get_redis().get(f"deal_compute_info-{code}")
@@ -60,6 +73,7 @@
             cancel_data = __get_cancel_data(code, data, local_today_num_operate_map)
             if cancel_data is None:
                 deal_num += val["num"]
+                __save_traded_index(code, data["index"])
     __set_deal_compute_progress(code, progress, deal_num)
 
 
diff --git a/trade/first_code_score_manager.py b/trade/first_code_score_manager.py
index f4a6755..3b08089 100644
--- a/trade/first_code_score_manager.py
+++ b/trade/first_code_score_manager.py
@@ -21,151 +21,192 @@
 
 def __get_score(zyltgb, limit_price, bidding, k_form, code_nature, hot_block, volume_rate, limit_up_time,
                 deal_big_money):
-    score = 0
     score_list = []
-    # 寮�鐩樺墠绔炰环
-    if bidding:
-        score += 25
-        score_list.append(25)
-    else:
-        score_list.append(0)
-    # 澶у崟鎴愪氦
-    if deal_big_money:
-        score += 30
-        score_list.append(30)
-    else:
-        score_list.append(0)
-    # 閲�
-    volume_score = [0, 40, 50, 40, 30, 10, -150, -1000]
-    volume_rates = [0, 0.499, 0.649, 0.799, 0.949, 1.099, 1.249, 1.399]
-    for i in range(1, len(volume_rates)):
-        if volume_rates[i - 1] <= volume_rate < volume_rates[i]:
-            score += volume_score[i - 1]
-            score_list.append(volume_score[i - 1])
-            break
-
-    # 15涓氦鏄撴棩鏄惁娑ㄥ箙24.9%
-    if k_form[0]:
-        score += -100
-        score_list.append(-100)
-    else:
-        score_list.append(0)
-    # 鏄惁鐮村墠楂�
-    if k_form[1]:
-        score += 50
-        score_list.append(50)
-    else:
-        score_list.append(0)
-    # 鏄惁瓒呰穼
-    if k_form[2]:
-        score += 40
-        score_list.append(40)
-    else:
-        score_list.append(0)
-
-    # 鏄惁鎺ヨ繎鍓嶉珮
-    if k_form[3]:
-        score += -50
-        score_list.append(-50)
-    else:
-        score_list.append(0)
-    # 鏄惁N
-    if k_form[4]:
-        score += 35
-        score_list.append(35)
-    else:
-        score_list.append(0)
-    # 鏄惁V
-    if k_form[5]:
-        score += 30
-        score_list.append(30)
-    else:
-        score_list.append(0)
-
-    if not code_nature[0]:
-        score += 5
-        score_list.append(5)
-    else:
-        score_list.append(0)
-    if code_nature[1]:
-        score += 20
-        score_list.append(20)
-    else:
-        score_list.append(0)
-
-    if hot_block[0] >= 2:
-        score += 40
-        score_list.append(40)
-    else:
-        score += 30
-        score_list.append(30)
-    if hot_block[1] > 0:
-        score += 10
-        score_list.append(10)
-    else:
-        score_list.append(0)
-
     if zyltgb:
-        score += -80
-        score_list.append(-80)
+        zyltgbs = [0, 10, 31, 51, 101, 150, 250, 1000000]
+        zyltgb_score = [5, 25, 20, 15, 10, 5, -80]
+        for i in range(1, len(zyltgbs)):
+            if zyltgbs[i - 1] <= zyltgb / 100000000 < zyltgbs[i]:
+                score_list.append(zyltgb_score[i - 1])
     else:
         score_list.append(0)
 
     if limit_price:
-        score += -1000
         score_list.append(-1000)
     else:
         score_list.append(0)
 
+    # 寮�鐩樺墠绔炰环
+    if bidding:
+        score_list.append(25)
+    else:
+        score_list.append(0)
+
+    k_score = []
+    # 15涓氦鏄撴棩鏄惁娑ㄥ箙24.9%
+    if k_form[0]:
+        k_score.append(-25)
+    else:
+        k_score.append(0)
+    # 鏄惁鐮村墠楂�
+
+    if k_form[1]:
+        k_score.append(50)
+    else:
+        k_score.append(0)
+    # 鏄惁瓒呰穼
+    if k_form[2]:
+        k_score.append(40)
+    else:
+        k_score.append(0)
+
+    # 鏄惁鎺ヨ繎鍓嶉珮
+    if k_form[3]:
+        k_score.append(-25)
+    else:
+        k_score.append(0)
+    # 鏄惁N
+    if k_form[4]:
+        k_score.append(35)
+    else:
+        k_score.append(0)
+    # 鏄惁V
+    if k_form[5]:
+        k_score.append(30)
+    else:
+        k_score.append(0)
+    score_list.append(k_score)
+
+    nature_score = []
+
+    if code_nature is None:
+        code_nature = [True, False]
+
+    if not code_nature[0]:
+        nature_score.append(5)
+    else:
+        nature_score.append(0)
+    if code_nature[1]:
+        nature_score.append(20)
+    else:
+        nature_score.append(0)
+
+    score_list.append(nature_score)
+
+    hot_block_score = []
+
+    if hot_block[1] >= 2:
+        hot_block_score.append(40)
+    else:
+        hot_block_score.append(30)
+    if hot_block[2] > 0:
+        hot_block_score.append(10)
+    else:
+        hot_block_score.append(0)
+    score_list.append(hot_block_score)
+
+    # 閲�
+    volume_score = [0, 40, 50, 40, 30, 10, -15, -35]
+    volume_rates = [0, 0.499, 0.649, 0.799, 0.949, 1.099, 1.249, 1.399]
+    volume_add = False
+    for i in range(1, len(volume_rates)):
+        if volume_rates[i - 1] <= volume_rate < volume_rates[i]:
+            score_list.append(volume_score[i - 1])
+            volume_add = True
+            break
+    if not volume_add:
+        score_list.append(volume_score[-1])
+
     if limit_up_time:
-        score += 20
         score_list.append(20)
     else:
         score_list.append(0)
 
+        # 澶у崟鎴愪氦
+    if deal_big_money:
+        score_list.append(30)
+    else:
+        score_list.append(0)
+
+    score = 0
+    for s in score_list:
+        if type(s) == list:
+            for ss in s:
+                score += ss
+        else:
+            score += s
     return score, score_list
 
 
-def get_score(code, volume_rate, limit_up_time):
-    bidding_money = bidding_money_manager.get_bidding_money(code)
-    bidding = False
-    if bidding_money and bidding_money >= 5000:
-        bidding = True
+def get_score(code, volume_rate, limit_up_time, with_source_data=False):
+    source_datas = []
+
     # 鑾峰彇鑷敱娴侀�氳偂鏈�
     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:
         zyltgb = 100 * 100000000
+    source_datas.append(zyltgb)
+
+    limit_price = float(gpcode_manager.get_limit_up_price(code))
+    source_datas.append(limit_price)
+
+    # 绔炰环閲戦
+    bidding_money = bidding_money_manager.get_bidding_money(code)
+    source_datas.append(bidding_money)
+    bidding = False
+    if bidding_money and bidding_money >= 5000:
+        bidding = True
 
     k_form = code_nature_analyse.CodeNatureRecordManager.get_k_format(code)
     if k_form is None:
-        k_form = [True, False, False, False, False, False]
+        k_form = [(True, ''), (False, ''), (False, ''), (False, ''), (False, ''), (False, '')]
+    source_datas.append(k_form)
+
     code_nature = code_nature_analyse.CodeNatureRecordManager.get_nature(code)
+    source_datas.append(code_nature)
 
     hot_block = hot_block_data_process.get_info(code)
     if hot_block is None:
-        hot_block = (1, 0)
+        hot_block = ('鏃犳澘鍧�', 1, 0)
     else:
         # 鍔犱笂鑷繁
-        hot_block = (hot_block[0] + 1, hot_block[1])
+        hot_block = (hot_block[0], hot_block[1] + 1, hot_block[2])
 
+    source_datas.append(hot_block)
+
+    source_datas.append(volume_rate)
+
+    source_datas.append(limit_up_time)
     if limit_up_time and tool.trade_time_sub(limit_up_time, "10:00:00") < 0:
         limit_up_time = True
     else:
         limit_up_time = False
+
     # 鑾峰彇鎴愪氦澶у崟
     deal_big_num = deal_big_money_manager.get_deal_big_money_num(code)
     m = l2_trade_factor.L2TradeFactorUtil.get_base_safe_val(zyltgb)
-    limit_price = float(gpcode_manager.get_limit_up_price(code))
+    source_datas.append((deal_big_num * limit_price * 100, m))
+
     if deal_big_num * limit_price * 100 > m:
         deal_big_num = True
     else:
         deal_big_num = False
 
-    return __get_score(zyltgb >= 250 * 100000000, limit_price > 100, bidding, k_form, code_nature, hot_block,
-                       volume_rate, limit_up_time, deal_big_num)
+    k_form_1 = []
+    for d in k_form:
+        k_form_1.append(d[0])
+
+    result = __get_score(zyltgb, limit_price > 100, bidding, k_form_1, code_nature, hot_block,
+                         volume_rate, limit_up_time, deal_big_num)
+    if with_source_data:
+        return result, source_datas
+    return result
 
 
 if __name__ == "__main__":
     global_data_loader.load_zyltgb()
-    score = get_score("601698", 1.2, "15:00:01")
+    score = get_score("000779", 1.2, "15:00:01", True)
     print(score)
diff --git a/trade/l2_trade_factor.py b/trade/l2_trade_factor.py
index 9aec3cb..1702ab7 100644
--- a/trade/l2_trade_factor.py
+++ b/trade/l2_trade_factor.py
@@ -13,45 +13,105 @@
 
 # 涓嬪崟鍙傛暟
 class L2PlaceOrderParamsManager:
+
+    # 寰楀垎
+    def __init__(self, code, is_first_code, volume_rate, volume_rate_index, score):
+        self.code = code
+        self.is_first_code = is_first_code
+        score_ranks = [200, 190, 180, 100]
+        self.score = score[0]
+        # 涓哄垎鏁拌缃瓑绾�
+        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
+        self.volume_rate = volume_rate
+        self.volume_rate_index = volume_rate_index
+
     # 鑾峰彇淇″彿杩炵画涔扮瑪鏁�
-    @staticmethod
-    def get_begin_continue_buy_count(volume_rate_index):
+
+    def get_begin_continue_buy_count(self):
         counts = [3, 3, 3, 2, 2, 2, 2]
-        if volume_rate_index >= len(counts):
+        volume_rate_index = self.volume_rate_index
+        if self.volume_rate_index >= len(counts):
             volume_rate_index = -1
         return counts[volume_rate_index]
 
     # 鑾峰彇鏃堕棿璁$畻鑼冨洿锛岃繑鍥瀞
-    @staticmethod
-    def get_time_range(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)]
-        if volume_rate_index >= len(ts):
+        volume_rate_index = self.volume_rate_index
+        if self.volume_rate_index >= len(ts):
             volume_rate_index = -1
         return ts[volume_rate_index]
 
     # 鑾峰彇闇�瑕佺殑澶у崟涓暟
-    @staticmethod
-    def get_big_num_count(volume_rate_index):
+    def get_big_num_count(self):
+        if self.is_first_code:
+            if self.score_index == 0:
+                return 0
+            elif self.score_index == 1:
+                return 0
+            elif self.score_index == 2:
+                return 1
+            elif self.score_index < 0:
+                return 65535
         counts = [3, 1, 1, 1, 0, 0, 0, 0]
-        if volume_rate_index >= len(counts):
+        volume_rate_index = self.volume_rate_index
+        if self.volume_rate_index >= len(counts):
             volume_rate_index = -1
         return counts[volume_rate_index]
 
     # 鑾峰彇瀹夊叏绗旀暟褰卞搷姣斾緥
-    @staticmethod
-    def get_safe_count_rate(volume_rate_index):
+    def get_safe_count_rate(self):
         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 = 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 3 > self.score_index > -1:
+                return 0
+            elif self.score_index < 0:
+                return 65535
+        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)))
+        return count
+
     # 鑾峰彇m鍊煎奖鍝嶆瘮渚�
-    @staticmethod
-    def get_m_val_rate(volume_rate_index):
+    @classmethod
+    def get_m_val_rate(cls, 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]
+
+    # 鑾峰彇m鍊�
+    def get_m_val(self):
+        if self.is_first_code:
+            if self.score_index == 0:
+                return 0, ""
+            elif self.score_index == 1:
+                return 1000 * 10000, ""
+            elif self.score_index == 2:
+                return 1000 * 10000, ""
+            elif self.score_index < 0:
+                return 65535 * 10000, ""
+        # 鑾峰彇鍥哄畾m鍊�
+        zyltgb = global_util.zyltgb_map.get(self.code)
+        if zyltgb is None:
+            global_data_loader.load_zyltgb()
+            zyltgb = global_util.zyltgb_map.get(self.code)
+
+        base_m = L2TradeFactorUtil.get_base_safe_val(zyltgb)
+        rate = self.get_m_val_rate(self.volume_rate_index)
+        m = round(base_m * (1 + rate))
+        return m, ""
 
 
 # S鎾ゅ弬鏁�
@@ -105,11 +165,13 @@
     # 鑾峰彇鍩虹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*(1-0.3))
+        return round(m * (1 - 0.3))
 
     # 鑾峰彇琛屼笟褰卞搷姣斾緥
     # total_limit_percent涓虹粺璁$殑姣斾緥涔嬪拰涔樹互100
@@ -144,8 +206,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
@@ -325,7 +387,7 @@
             MAX_VAL = 13
         if not gb:
             # 榛樿8绗�
-            return MIN_VAL
+            return MIN_VAL,MIN_VAL, MAX_VAL
         count = gb // 100000000
         if True:
             if count < 8:
diff --git a/trade/trade_gui.py b/trade/trade_gui.py
index b7aff07..e39d965 100644
--- a/trade/trade_gui.py
+++ b/trade/trade_gui.py
@@ -568,7 +568,7 @@
         main_hwnds = []
         win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWndList)
         for hwnd in hWndList:
-            if THSGuiUtil.getText(hwnd) == "涓撲笟鐗堜笅鍗�":
+            if win32gui.IsWindowVisible(hwnd) and THSGuiUtil.getText(hwnd) == "涓撲笟鐗堜笅鍗�":
                 main_hwnds.append(hwnd)
         if not main_hwnds:
             raise Exception("涓撲笟鐗堜笅鍗曟湭鎵撳紑")

--
Gitblit v1.8.0