From 994079acd0ac30a32e2b0391881890be16b0afc0 Mon Sep 17 00:00:00 2001
From: Administrator <admin@example.com>
Date: 星期二, 17 六月 2025 11:01:13 +0800
Subject: [PATCH] ‘功能完善

---
 strategy/test.py                      |   18 +
 strategy/data_analyzer.py             |   29 +
 strategy/time_series_backtest.py      |   25 +
 third_data/kpl_api.py                 |    2 
 strategy/strategy_variable_factory.py |   40 +++
 strategy/strategy_script_v7.py        |  167 +++++++++++++
 strategy/strategy_script_v6.py        |   37 +--
 api/outside_api_callback.py           |   29 ++
 third_data/kpl_block_manager.py       |   55 ++++
 strategy/strategy_manager.py          |   14 
 strategy/low_suction_strategy.py      |   29 ++
 strategy/back_test.py                 |    5 
 main.py                               |   41 +++
 server/local_data_server.py           |  167 +++++++++++++
 strategy/strategy_params_settings.py  |    2 
 strategy/env_info.py                  |   11 
 16 files changed, 616 insertions(+), 55 deletions(-)

diff --git a/api/outside_api_callback.py b/api/outside_api_callback.py
index 647730f..be5a8fe 100644
--- a/api/outside_api_callback.py
+++ b/api/outside_api_callback.py
@@ -3,11 +3,13 @@
 import threading
 
 from api.outside_api_command_manager import ActionCallback
+from huaxin_client import l1_subscript_codes_manager
 from huaxin_client.client_network import SendResponseSkManager
 from strategy import strategy_params_settings, env_info
 from strategy.env_info import RealTimeEnvInfo
 from strategy.strategy_variable_factory import DataLoader
 from third_data.history_k_data_manager import TradeDateManager
+from third_data.kpl_block_manager import KPLCodeJXBlocksManager
 from utils import socket_util, middle_api_protocol, tool
 
 
@@ -87,6 +89,11 @@
                 # 濡傛灉鍦�16:00涔嬪悗閲囩敤涓嬩竴涓氦鏄撴棩
                 day = tool.get_now_date_str()
             fdata["history_data"]["k_bars_count"] = env_info.get_history_k_bars(day)
+
+            day = tool.get_now_date_str()
+            fdata["history_data"]["kpl_code_jx_blocks_count"] = env_info.get_kpl_code_jx_blocks(day)
+
+
         return {"code": 0, "data": fdata, "msg": "娴嬭瘯缁撴灉"}
 
     def __on_update_leading_limit_up_datas(self):
@@ -111,6 +118,23 @@
         threading.Thread(target=lambda: update(), daemon=True).start()
         return {"code": 0}
 
+    def __on_update_kpl_code_jx_blocks_datas(self):
+        """
+        鏇存柊寮�鐩樺暒绮鹃�夋澘鍧楁暟鎹�
+        @return:
+        """
+
+        def update():
+            codes = set()
+            codes_sh, codes_sz = l1_subscript_codes_manager.get_codes()
+            codes |= set([x.decode() for x in codes_sh])
+            codes |= set([x.decode() for x in codes_sz])
+            KPLCodeJXBlocksManager(day, codes).start_download_blocks()
+            # 濡傛灉鍦�16:00涔嬪墠閲囩敤褰撳墠鏃ユ湡
+        day = tool.get_now_date_str()
+        threading.Thread(target=lambda: update(), daemon=True).start()
+        return {"code": 0}
+
     def OnCommonRequest(self, client_id, request_id, data):
         ctype = data["ctype"]
         result_json = {}
@@ -120,7 +144,12 @@
             del data["ctype"]
             result_json = self.__on_set_settings(data)
         elif ctype == 'get_env':
+            # 鑾峰彇鐜鏁版嵁
             result_json = self.__on_get_env(data.get("history"))
         elif ctype == 'update_leading_limit_up_datas':
+            # 鏇存柊棰嗘定鏁版嵁
             result_json = self.__on_update_leading_limit_up_datas()
+        elif ctype == 'update_kpl_code_jx_blocks_datas':
+            # 鏇存柊寮�鐩樺暒绮鹃�夋暟鎹�
+            result_json = self.__on_update_kpl_code_jx_blocks_datas()
         self.send_response(result_json, client_id, request_id)
diff --git a/main.py b/main.py
index 2e20643..c9ad640 100644
--- a/main.py
+++ b/main.py
@@ -4,17 +4,19 @@
 import time
 
 import requests
+import schedule
 
 from api import outside_api_callback
 from api.outside_api_command_manager import ApiCommandManager
 from db.redis_manager_delegate import RedisUtils
-from huaxin_client import l2_market_client, trade_client
+from huaxin_client import l2_market_client, trade_client, l1_subscript_codes_manager
 from log_module import async_log_util
 from log_module.log import logger_debug
 from server import data_server
 from strategy import strategy_manager
 from strategy.env_info import RealTimeEnvInfo
 from third_data import hx_qc_value_util
+from third_data.kpl_block_manager import KPLCodeJXBlocksManager
 from trade.huaxin import huaxin_trade_api
 from utils import tool, middle_api_protocol
 
@@ -27,7 +29,7 @@
                 if data.get("type") == 'set_target_codes':
                     # [(浠g爜, 鏃堕棿鎴�, 浠锋牸, 鎬讳氦鏄撻噺, 鎬讳氦鏄撻, 涔�5, 鍗�5)]
                     market_data_list = data["data"]["data"]
-                    if  strategy_manager.low_suction_strtegy:
+                    if strategy_manager.low_suction_strtegy:
                         strategy_manager.low_suction_strtegy.add_ticks(market_data_list)
                     RealTimeEnvInfo().ticks = (tool.get_now_time_str(), len(market_data_list))
             except Exception as e:
@@ -39,6 +41,32 @@
                                               args=(queue_l1_w_strategy_r,))
     l2MarketProcess.start()
     read_results()
+
+
+def __init():
+    """
+    鍒濆鍖�
+    @return:
+    """
+
+    # 瀹氭椂鏇存柊浠g爜绮鹃�夋澘鍧�
+    def run_pending():
+        # 鏇存柊浠婃棩浠g爜绮鹃�夋澘鍧�
+        codes = set()
+        codes_sh, codes_sz = l1_subscript_codes_manager.get_codes()
+        codes |= set([x.decode() for x in codes_sh])
+        codes |= set([x.decode() for x in codes_sz])
+        day = tool.get_now_date_str()
+        schedule.every().day.at("11:05:00").do(lambda: KPLCodeJXBlocksManager(day, codes).start_download_blocks())
+        while True:
+            try:
+                schedule.run_pending()
+            except:
+                pass
+            finally:
+                time.sleep(1)
+
+    threading.Thread(target=run_pending, daemon=True).start()
 
 
 def test():
@@ -66,9 +94,9 @@
     threading.Thread(target=lambda: RedisUtils.run_loop(), daemon=True).start()
 
     # --------鍚姩鏈湴API鎺ュ彛----------
-    manager = ApiCommandManager(middle_api_protocol.SERVER_HOST, middle_api_protocol.SERVER_PORT, outside_api_callback.MyAPICallback())
+    manager = ApiCommandManager(middle_api_protocol.SERVER_HOST, middle_api_protocol.SERVER_PORT,
+                                outside_api_callback.MyAPICallback())
     manager.run(blocking=False)
-
 
     # --------鍚姩浜ゆ槗----------
     huaxin_trade_api.run()
@@ -76,9 +104,14 @@
     threading.Thread(target=test, daemon=True).start()
     # test()
 
+    # ----鍒濆鍖�------------
+    __init()
+
     # 鍒濆鍖栨暟鎹�
     strategy_manager.low_suction_strtegy = strategy_manager.LowSuctionStrategy(tool.get_now_date_str())
 
+
+
     # -------鍚姩L2 market璁㈤槄------
     __run_l2_market_subscript()
     print("鍚姩瀹屾垚")
diff --git a/server/local_data_server.py b/server/local_data_server.py
new file mode 100644
index 0000000..9e5ebd9
--- /dev/null
+++ b/server/local_data_server.py
@@ -0,0 +1,167 @@
+"""
+鏈湴http鏈嶅姟鍣�
+"""
+import json
+from http.server import SimpleHTTPRequestHandler, HTTPServer
+import urllib.parse as urlparse
+from urllib.parse import parse_qs
+
+import constant
+from db.mysql_data_delegate import Mysqldb
+
+from strategy.low_suction_strategy import LowSuctionOriginDataExportManager
+from strategy.strategy_variable_factory import DataLoader
+from third_data import kpl_util
+from utils import tool, output_util, huaxin_util
+
+
+class CORSRequestHandler(SimpleHTTPRequestHandler):
+    def end_headers(self):
+        # 娣诲姞 CORS 澶�
+        self.send_header('Access-Control-Allow-Origin', '*')
+        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
+        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
+        super().end_headers()
+
+    # 澶勭悊 OPTIONS 棰勬璇锋眰
+    def do_OPTIONS(self):
+        self.send_response(200)
+        self.end_headers()
+
+    def do_GET(self) -> None:
+        path = self.path
+        url = urlparse.urlparse(path)
+        ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()])
+        response_data = ""
+        if url.path == "/get_limit_up_plate_list":
+            date = ps_dict.get("date")
+            time_str = ps_dict.get("time")
+            __LowSuctionOriginDataExportManager = LowSuctionOriginDataExportManager(date)
+            # [(浠g爜, 浠g爜鍚嶇О, 娑ㄥ仠鍘熷洜, 娑ㄥ仠鏃堕棿, 楂樺害淇℃伅, 鑷敱娴侀�氬競鍊硷紝鏄惁鐐告澘)]
+            results = __LowSuctionOriginDataExportManager.export_current_limit_up_records()
+            results = [x for x in results if tool.to_time_str(int(x[3])) <= time_str]
+            code_plates = __LowSuctionOriginDataExportManager.export_code_plates()
+            # 鏈�缁堟定鍋滅殑浠g爜
+            limit_up_codes = [x[0] for x in results if not x[6]]
+            if date == tool.get_now_date_str():
+                limit_up_list = __LowSuctionOriginDataExportManager.export_limit_up_list()
+                if limit_up_list:
+                    limit_up_list = [x for x in limit_up_list if x[0][:8] <= time_str]
+                    limit_up_list = limit_up_list[-1][1]
+                    limit_up_codes = [x[0] for x in limit_up_list]
+
+            code_infos = {x[0]: x for x in results}
+            plate_codes = {}
+            for code in code_infos.keys():
+                plates = code_plates.get(code)
+                if not plates:
+                    plates = {kpl_util.filter_block(code_infos[code][2])}
+                plates -= constant.KPL_INVALID_BLOCKS
+                for p in plates:
+                    if p not in plate_codes:
+                        plate_codes[p] = set()
+                    plate_codes[p].add(code)
+            # (鏉垮潡鍚嶇О, 娑ㄥ仠鏁帮紝鐐告澘鏁�)
+            data = [(p, len(plate_codes[p]), len([code for code in plate_codes[p] if code not in limit_up_codes])) for p
+                    in
+                    plate_codes]
+            data.sort(key=lambda x: x[1] - x[2], reverse=True)
+            response_data = json.dumps({"code": 0, "data": data})
+
+        elif url.path == "/get_plate_codes":
+            date = ps_dict.get("date")
+            plate = ps_dict.get("plate")
+            time_str = ps_dict.get("time")
+            __LowSuctionOriginDataExportManager = LowSuctionOriginDataExportManager(date)
+            results = __LowSuctionOriginDataExportManager.export_current_limit_up_records()
+            for r in results:
+                r[3] = tool.to_time_str(int(r[3]))
+                r[5] = output_util.money_desc(r[5])
+            results = [x for x in results if x[3] <= time_str]
+            # 鏈�缁堟定鍋滅殑浠g爜
+            limit_up_codes = [x[0] for x in results if not x[6]]
+            if date == tool.get_now_date_str():
+                limit_up_list = __LowSuctionOriginDataExportManager.export_limit_up_list()
+                if limit_up_list:
+                    limit_up_list = [x for x in limit_up_list if x[0][:8] <= time_str]
+                    limit_up_list = limit_up_list[-1][1]
+                    limit_up_codes = [x[0] for x in limit_up_list]
+                for x in results:
+                    x[6] = x[0] not in limit_up_codes
+
+            # [(浠g爜, 浠g爜鍚嶇О, 娑ㄥ仠鍘熷洜, 娑ㄥ仠鏃堕棿, 楂樺害淇℃伅, 鑷敱娴侀�氬競鍊硷紝鏄惁鐐告澘)]
+            code_plates = __LowSuctionOriginDataExportManager.export_code_plates()
+            code_infos = {x[0]: x for x in results}
+            plate_codes = {}
+            for code in code_infos.keys():
+                plates = code_plates.get(code)
+                if not plates:
+                    plates = {kpl_util.filter_block(code_infos[code][2])}
+                plates -= constant.KPL_INVALID_BLOCKS
+                for p in plates:
+                    if p not in plate_codes:
+                        plate_codes[p] = set()
+                    plate_codes[p].add(code)
+            codes = plate_codes.get(plate)
+            datas = [code_infos[code] for code in codes]
+            datas.sort(key=lambda x: x[3])
+            response_data = json.dumps({"code": 0, "data": datas})
+        elif url.path == "/get_big_order_list":
+            date = ps_dict.get("date")
+            code = ps_dict.get("code")
+            __LowSuctionOriginDataExportManager = LowSuctionOriginDataExportManager(date)
+            big_orders_dict = __LowSuctionOriginDataExportManager.export_all_big_order_deal(200e4)
+            datas = big_orders_dict.get(code, [])
+            for x in datas:
+                x[2][3] = huaxin_util.convert_time(x[2][3], with_ms=False)
+                if len(x[2]) > 5:
+                    x[2][5] = huaxin_util.convert_time(x[2][5], with_ms=False)
+            order_ids = set()
+            datas.reverse()
+            fdatas = []
+            for d in datas:
+                if d[2][0] in order_ids:
+                    continue
+                fdatas.append(d)
+                order_ids.add(d[2][0])
+
+            response_data = json.dumps({"code": 0, "data": fdatas})
+        elif url.path == "/get_block_in_datas":
+            date = ps_dict.get("date")
+            time_str = ps_dict.get("time")
+            __LowSuctionOriginDataExportManager = LowSuctionOriginDataExportManager(date)
+            block_in_datas = __LowSuctionOriginDataExportManager.export_block_in_datas()
+            fdatas = []
+            for d in reversed(block_in_datas):
+                if d[0] <= time_str:
+                    fdatas = d[1]
+                    break
+            fdatas = [(x[0], output_util.money_desc(x[1])) for x in fdatas]
+            response_data = json.dumps({"code": 0, "data": fdatas})
+
+        elif url.path == "/get_codes_by_jx_plates":
+            # 鏍规嵁绮鹃�夋澘鍧楄幏鍙栦唬鐮�
+            plates = ps_dict.get("plates")
+            plates = set(json.loads(plates))
+            sql = " select code, jx_blocks  from kpl_code_blocks where  " + " and ".join(
+                [f"jx_blocks like '%{p}%'" for p in plates])
+            datas = Mysqldb().select_all(sql)
+            fdatas = [(x[0], "銆�".join([ f"<red>{dd}</red>" if dd in plates else dd for dd in json.loads(x[1])])) for x in datas if len(set(json.loads(x[1])) & plates) == len(plates)]
+            response_data = json.dumps({"code": 0, "data": fdatas})
+
+        print("GET璇锋眰")
+        self.send_response(200)
+        # 鍙戠粰璇锋眰瀹㈡埛绔殑鍝嶅簲鏁版嵁
+        self.send_header('Content-type', 'application/json')
+        self.end_headers()
+        self.wfile.write(response_data.encode())
+
+    def do_POST(self) -> None:
+        print("POST璇锋眰")
+
+
+if __name__ == '__main__':
+    server_address = ('', 8000)
+    httpd = HTTPServer(server_address, CORSRequestHandler)
+    print("Server running on http://localhost:8000")
+    httpd.serve_forever()
diff --git a/strategy/back_test.py b/strategy/back_test.py
index ee571d3..4b81a36 100644
--- a/strategy/back_test.py
+++ b/strategy/back_test.py
@@ -9,6 +9,7 @@
 
 from code_attribute import global_data_loader
 from log_module.log import logger_debug
+from strategy.data_analyzer import KTickLineAnalyzer
 from strategy.data_downloader import DataDownloader
 from strategy.low_suction_strategy import LowSuctionOriginDataExportManager
 from strategy.strategy_variable_factory import DataLoader, StrategyVariableFactory
@@ -368,4 +369,6 @@
 
 
 if __name__ == "__main__":
-    __back_test2()
+    data_loader = DataLoader("2025-06-10")
+    kline_1d_dict = data_loader.load_kline_data()
+    KTickLineAnalyzer.get_third_limit_up_days(kline_1d_dict.get("002907"), 10)
diff --git a/strategy/data_analyzer.py b/strategy/data_analyzer.py
index 5b7acde..882999f 100644
--- a/strategy/data_analyzer.py
+++ b/strategy/data_analyzer.py
@@ -272,6 +272,18 @@
         return count
 
     @classmethod
+    def __is_limit_up(cls, code, close, pre_close):
+        """
+        鏄惁娑ㄥ仠
+        @param code:
+        @param close:
+        @param pre_close:
+        @return:
+        """
+        return abs(close - cls.calculate_upper_limit_price(code,
+                                                        pre_close)) < 0.01
+
+    @classmethod
     def get_third_limit_up_days(cls, k_data, days):
         """
         鑾峰彇杩戝嚑涓氦鏄撴棩鐨勪笁鏉垮ぉ鏁�
@@ -280,18 +292,17 @@
         @return: 涓夋澘澶╂暟
         """
         count = 0
+        k_data = k_data[:days]
+        k_data = k_data[::-1]
         for i in range(days):
             if i + 3 >= len(k_data):
                 continue
             # 鍒ゆ柇杩炵画涓夋棩娑ㄥ仠涓旂鍥涙棩闈炴定鍋�
-            if (k_data[i]['close'] >= cls.calculate_upper_limit_price(k_data[i]["sec_id"], k_data[i]["pre_close"])) and \
-                    (k_data[i + 1]['close'] >= cls.calculate_upper_limit_price(k_data[i + 1]["sec_id"],
-                                                                               k_data[i + 1]["pre_close"])) and \
-                    (k_data[i + 2]['close'] >= cls.calculate_upper_limit_price(k_data[i + 2]["sec_id"],
-                                                                               k_data[i + 2]["pre_close"])) and \
-                    (k_data[i + 3]['close'] < cls.calculate_upper_limit_price(k_data[i + 3]["sec_id"],
-                                                                              k_data[i + 3]["pre_close"])):
-                count += 1
+            if cls.__is_limit_up(k_data[i]["sec_id"], k_data[i]['close'], k_data[i]["pre_close"]):
+                if cls.__is_limit_up(k_data[i+1]["sec_id"], k_data[i+1]['close'], k_data[i+1]["pre_close"]):
+                    if cls.__is_limit_up(k_data[i+2]["sec_id"], k_data[i+2]['close'], k_data[i+2]["pre_close"]):
+                        if not cls.__is_limit_up(k_data[i+3]["sec_id"], k_data[i+3]['close'], k_data[i+3]["pre_close"]):
+                            count += 1
         return count
 
     @classmethod
@@ -528,5 +539,5 @@
                         if reason not in block_days:
                             block_days[reason] = set()
                         block_days[reason].add(date)
-            return set([b for b in block_days if len(block_days[b])==len(days_list)])
+            return set([b for b in block_days if len(block_days[b]) == len(days_list)])
         return set()
diff --git a/strategy/env_info.py b/strategy/env_info.py
index b4129bd..439a7ea 100644
--- a/strategy/env_info.py
+++ b/strategy/env_info.py
@@ -5,6 +5,7 @@
 
 from strategy.strategy_variable_factory import DataLoader
 from third_data.history_k_data_manager import HistoryKDataManager
+from third_data.kpl_block_manager import KPLCodeJXBlocksManager
 from utils import tool
 
 
@@ -58,5 +59,15 @@
     return count
 
 
+def get_kpl_code_jx_blocks(day):
+    """
+    鑾峰彇寮�鐩樺暒浠g爜绮鹃�夋澘鍧楁暟閲�
+    @param day:
+    @return:
+    """
+    count = KPLCodeJXBlocksManager(day, set()).get_all_code_blocks_count()
+    return count
+
+
 if __name__ == "__main__":
     print(get_history_k_bars("2025-06-04"))
diff --git a/strategy/low_suction_strategy.py b/strategy/low_suction_strategy.py
index c6cd149..7ae9c54 100644
--- a/strategy/low_suction_strategy.py
+++ b/strategy/low_suction_strategy.py
@@ -5,6 +5,7 @@
 import os
 
 import constant
+from db.mysql_data_delegate import Mysqldb
 from strategy import strategy_variable
 
 
@@ -191,6 +192,25 @@
                 fdatas[data[0]].append(data[2])
         return fdatas
 
+    def export_all_big_order_deal(self, min_money=299e4):
+        """
+        鎵�鏈夊ぇ鍗曟垚浜わ紝鍖呭惈涔帮紝鍗�
+        @return: {"浠g爜":[浠g爜,鍗�/涔�, (涔板崟鍙�, 閲�, 閲戦, 鏃堕棿, 鏈�缁堟垚浜や环)]}
+        """
+
+        fdatas = {}
+        lines = self.__export_logs(f"logs/huaxin_local/l2/transaction_accurate_big_order.{self.day}.log")
+        if lines:
+            for line in lines:
+                line = line[line.find(" - ") + 3:].strip()
+                data = eval(line)
+                if data[2][2] < min_money:
+                    continue
+                if data[0] not in fdatas:
+                    fdatas[data[0]] = []
+                fdatas[data[0]].append(data)
+        return fdatas
+
     def export_big_sell_order_deal(self, min_money=299e4):
         """
         澶у崟鎴愪氦
@@ -267,6 +287,15 @@
                 data = eval(line)
         return data
 
+    def export_current_limit_up_records(self):
+        """
+        瀵煎嚭褰撴棩鍘嗗彶娑ㄥ仠
+        @return: [(浠g爜, 浠g爜鍚嶇О, 娑ㄥ仠鍘熷洜, 娑ㄥ仠鏃堕棿, 楂樺害淇℃伅, 鑷敱娴侀�氬競鍊硷紝鏄惁鐐告澘)]
+        """
+        results = Mysqldb().select_all(
+            f"select r.`_code`, r.`_code_name`, r.`_hot_block_name`, r.`_limit_up_time`, r.`_limit_up_high_info`, r.`_zylt_val`, r.`_open`  from kpl_limit_up_record r where r._day = '{self.day}'")
+        return results
+
 
 class LowSuctionDataManager:
     """
diff --git a/strategy/strategy_manager.py b/strategy/strategy_manager.py
index c2c8ca5..5aed98f 100644
--- a/strategy/strategy_manager.py
+++ b/strategy/strategy_manager.py
@@ -7,6 +7,8 @@
 from db import redis_manager_delegate as redis_manager
 from db.mysql_data_delegate import Mysqldb
 from db.redis_manager_delegate import RedisUtils
+from log_module import async_log_util
+from log_module.log import logger_trade
 from strategy.data_analyzer import KPLLimitUpDataAnalyzer
 from strategy.low_suction_strategy import LowSuctionOriginDataExportManager
 from strategy.strategy_params_settings import StrategyParamsSettingsManager
@@ -101,7 +103,9 @@
     """
     浣庡惛绛栫暐
     """
-    def __init__(self, day, script_name="strategy_script_v6.py", settings=StrategyParamsSettingsManager().get_settings()):
+
+    def __init__(self, day, script_name="strategy_script_v6.py",
+                 settings=StrategyParamsSettingsManager().get_settings()):
         self.now_day = day
         # 涔板ぇ鍗曪細{浠g爜:[澶у崟鏁版嵁]}
         self.big_order_buy = {}
@@ -135,7 +139,8 @@
         self.current_block_in_datas = []
 
         # 鍔犺浇绛栫暐鑴氭湰鏂囦欢
-        with open(script_name if constant.is_windows() else f'{constant.get_path_prefix()}/{script_name}', mode='r', encoding='utf-8') as f:
+        with open(script_name if constant.is_windows() else f'{constant.get_path_prefix()}/{script_name}', mode='r',
+                  encoding='utf-8') as f:
             lines = f.readlines()
             scripts = "\n".join(lines)
             # 娉ㄩ噴鎺夐噷闈㈢殑import涓庡彉閲�
@@ -225,7 +230,6 @@
         """
         if code_ in self.stock_variables_dict:
             return
-
         stock_variables = StrategyVariableFactory.create_from_history_data(
             self.kline_data.get(code_), None,
             self.limit_up_record_data.get(code_), self.data_loader.trade_days)
@@ -382,6 +386,8 @@
             # 鍒ゆ柇鏄惁鍙互涔�
             for b in compute_result[3]:
                 DealCodesManager().place_order(b, code)
+                async_log_util.info(logger_trade, f"{code}涓嬪崟锛屾澘鍧楋細{compute_result[3]}")
+
 
 # 褰撳墠鐨勪綆鍚哥瓥鐣ュ璞�
-low_suction_strtegy = None
\ No newline at end of file
+low_suction_strtegy = None
diff --git a/strategy/strategy_params_settings.py b/strategy/strategy_params_settings.py
index b987e71..a183bcc 100644
--- a/strategy/strategy_params_settings.py
+++ b/strategy/strategy_params_settings.py
@@ -31,7 +31,7 @@
         # 鏄ㄦ棩涓嶈兘璺屽仠
         self.cant_yesterday_limit_down = True
         # 鏄ㄦ棩涓嶈兘鐐告澘
-        self.cant_yesterday_open_limit_up = False
+        self.cant_yesterday_open_limit_up = True
         # 鏈夋定鍋滅殑浜ゆ槗鏃ユ暟閲�
         self.has_limit_up_days = 10
         # xx涓氦鏄撴棩鍐呬笉鑳芥湁xx娆℃定鍋�
diff --git a/strategy/strategy_script_v6.py b/strategy/strategy_script_v6.py
index 8f481a6..53cf2d5 100644
--- a/strategy/strategy_script_v6.py
+++ b/strategy/strategy_script_v6.py
@@ -91,6 +91,9 @@
     if sv.鍏釜浜ゆ槗鏃ユ定骞呰繃楂�:
         return False, f"6涓氦鏄撴棩娑ㄥ箙杩囬珮"
 
+    if sv.鏃ヤ笁鏉夸釜鏁癬10 >= 1:
+        return False, f"10涓氦鏄撴棩鏈�>=3杩炴澘"
+
     # if sv.褰撳墠浠� > sv.鏄ㄦ棩鏈�浣庝环 * 1.1:
     #     return False, f"涔板叆鏃剁殑浠锋牸蹇呴』鈮ゆ槰鏃ユ渶浣庝环*110%"
 
@@ -112,8 +115,8 @@
     # 鐩爣绁ㄦ澘鍧楁定鍋滀釜鏁�>=2
 
     # 鏉垮潡鍙兘涔板叆涓�涓唬鐮�
-    # if sv.鏉垮潡鎴愪氦浠g爜:
-    #     can_buy_plates -= set(sv.鏉垮潡鎴愪氦浠g爜.keys())
+    if sv.鏉垮潡鎴愪氦浠g爜:
+        can_buy_plates -= set(sv.鏉垮潡鎴愪氦浠g爜.keys())
 
     if not can_buy_plates:
         return False, f"娌℃湁娑ㄥ仠鐨勬澘鍧�: {[(plate, sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(plate)) for plate in sv.浠g爜鏉垮潡 if sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋淽}  杩炵画鑰侀鏉愶細{sv.杩炵画鑰侀鏉恾"
@@ -138,7 +141,7 @@
     if sv.浠婃棩澶у崟鏁版嵁:
         # print(sv.浠婃棩澶у崟鏁版嵁[-1][3], format_time(sv.浠婃棩澶у崟鏁版嵁[-1][3]))
         # filter_orders = [(o[0], o[2]) for o in sv.浠婃棩澶у崟鏁版嵁 if format_time(o[3]) >= sv.浠婃棩閲忓淇℃伅[0]]
-        filter_orders = [(o[0], o[2]) for o in sv.浠婃棩澶у崟鏁版嵁 if o[2] >= 200e4]
+        filter_orders = [(o[0], o[2]) for o in sv.浠婃棩澶у崟鏁版嵁]
         filter_orders.reverse()
         orderids = set()
         for o in filter_orders:
@@ -146,34 +149,20 @@
                 continue
             orderids.add(o[0])
             big_order_money += o[1]
-    big_sell_order_money = 0
-    if sv.浠婃棩鍗栧ぇ鍗曟暟鎹�:
-        filter_orders = [(o[0], o[2]) for o in sv.浠婃棩鍗栧ぇ鍗曟暟鎹� if o[2] >= 200e4]
-        filter_orders.reverse()
-        orderids = set()
-        for o in filter_orders:
-            if o[0] in orderids:
-                continue
-            orderids.add(o[0])
-            big_sell_order_money += o[1]
-
     threshold_money = max(sv.鑷敱娴侀�氬競鍊� // 1000, 200e4)
 
     limit_up_codes_count = max([(p, len(sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(p, []))) for p in can_buy_plates], key=lambda x: x[1])[1]
 
-    # threshold_money *= max(min(10 - limit_up_codes_count + 1, 10), 5) / 10
-    threshold_money *= 0.5
+    threshold_money *= max(10 - limit_up_codes_count + 3, 5) / 10
+    if big_order_money < threshold_money:
+        return False, f"({big_order_money}/{threshold_money})澶у崟閲戦涓嶈冻"
 
-    # print(target_code, sv.鑷敱娴侀�氬競鍊�, threshold_money, limit_up_codes_count)
+    big_sell_order_money = 0
 
-    # threshold_money = 200e4  # int(sv.鏄ㄦ棩鎴愪氦閲� * 0.2 * sv.浠婃棩娑ㄥ仠浠� * 0.05)
+    if big_order_money < threshold_money:
+        return False, f"({round(big_order_money / 1e4, 2)}涓�/{round(threshold_money / 1e4, 2)}涓�)澶у崟閲戦涓嶈冻"
 
-    final_big_order_money = big_order_money - big_sell_order_money
-
-    if final_big_order_money < threshold_money:
-        return False, f"({round(final_big_order_money / 1e4, 2)}涓�/{round(threshold_money / 1e4, 2)}涓�)澶у崟閲戦涓嶈冻"
-
-    return True, f" \n\t澶у崟淇℃伅锛歿round(final_big_order_money / 1e4, 2)}涓囷紙涔帮細{round(big_order_money / 1e4, 2)}涓� 鍗栵細{round(big_sell_order_money / 1e4, 2)}涓囷級/{round(threshold_money / 1e4, 2)}涓�  \n\t閲忓淇℃伅锛歿sv.浠婃棩閲忓淇℃伅}\n\t浠婃棩鏈�楂樹环:{sv.浠婃棩鏈�楂樹环淇℃伅} \n\t5鏃ユ渶楂樹环锛歿sv.鏃ユ渶楂樹环_5}", f"\n\t鏉垮潡淇℃伅锛歿[(p, sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(p)) for p in can_buy_plates]}", can_buy_plates
+    return True, f" \n\t澶у崟淇℃伅锛歿round(big_order_money / 1e4, 2)}涓囷紙涔帮細{round(big_order_money / 1e4, 2)}涓� 鍗栵細{round(big_sell_order_money / 1e4, 2)}涓囷級/{round(threshold_money / 1e4, 2)}涓�  \n\t閲忓淇℃伅锛歿sv.浠婃棩閲忓淇℃伅}\n\t浠婃棩鏈�楂樹环:{sv.浠婃棩鏈�楂樹环淇℃伅} \n\t5鏃ユ渶楂樹环锛歿sv.鏃ユ渶楂樹环_5}", f"\n\t鏉垮潡淇℃伅锛歿[(p, sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(p)) for p in can_buy_plates]}", can_buy_plates
 
 
 compute_result = can_buy()
diff --git a/strategy/strategy_script_v7.py b/strategy/strategy_script_v7.py
new file mode 100644
index 0000000..191dd45
--- /dev/null
+++ b/strategy/strategy_script_v7.py
@@ -0,0 +1,167 @@
+import logging
+
+from strategy.strategy_params_settings import StrategyParamsSettings
+from strategy.strategy_variable import StockVariables
+
+sv = StockVariables()
+settings = StrategyParamsSettings()
+target_code = ''
+
+
+def format_time(huaxin_timestamp):
+    huaxin_timestamp = str(huaxin_timestamp)
+    if huaxin_timestamp.find("9") == 0:
+        return f"0{huaxin_timestamp[0]}:{huaxin_timestamp[1: 3]}:{huaxin_timestamp[3: 5]}"
+    return f"{huaxin_timestamp[0:2]}:{huaxin_timestamp[2: 4]}:{huaxin_timestamp[4: 6]}"
+
+
+def can_buy():
+    """
+    @return: 鏄惁鍙拱, 涓嶈兘涔扮殑鍘熷洜/鍙拱鐨勬澘鍧�, 鏄惁閲忓
+    """
+    # print(f"{target_code}:鎵ц绛栫暐")
+    if not settings.can_buy_ge_code:
+        if target_code.find("60") != 0 and target_code.find("00") != 0:
+            return False, "鍒涗笟鏉�/绉戝垱鏉跨殑绁ㄤ笉涔�"
+    else:
+        if target_code.find("60") != 0 and target_code.find("00") != 0 and target_code.find("30") != 0:
+            return False, "绉戝垱鏉跨殑绁ㄤ笉涔�"
+
+    if sv.鏉垮潡鎴愪氦浠g爜:
+        deal_codes = set()
+        for p in sv.鏉垮潡鎴愪氦浠g爜:
+            deal_codes |= set(sv.鏉垮潡鎴愪氦浠g爜[p])
+        if len(deal_codes) >= settings.max_buy_codes_count:
+            return False, f"涔板叆浠g爜鏁拌秴闄�({len(deal_codes)}/{settings.max_buy_codes_count})"
+
+    # 鐩爣绁ㄦ澘鍧楁定鍋滀釜鏁�>=2
+    can_buy_plates = set()
+    for plate in sv.浠g爜鏉垮潡:
+        if not sv.璧勯噾娴佸叆鏉垮潡 or plate not in sv.璧勯噾娴佸叆鏉垮潡:
+            continue
+        if plate in sv.杩炵画鑰侀鏉�:
+            continue
+        if plate in sv.鏃ュ嚭鐜扮殑鏉垮潡_2:
+            # 鑰侀鏉�
+            threshold_count = settings.limit_up_count_of_old_plate
+        else:
+            # 鏂伴鏉�
+            threshold_count = settings.limit_up_count_of_new_plate
+        if len(sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(plate, [])) >= threshold_count:
+            can_buy_plates.add(plate)
+
+    if not sv.褰撳墠浠�:
+        return False, "鏃犲綋鍓嶄环"
+
+    # if getattr(sv, f"娑ㄥ仠鏁癬{settings.has_limit_up_days}") < 1 and getattr(sv, f"鐐告澘鏁癬{settings.has_limit_up_days}") < 1:
+    #     return False, f"杩憑settings.has_limit_up_days}涓氦鏄撴棩鏃犳定鍋�/鏃犵偢鏉�"
+
+    if settings.cant_yesterday_limit_down and not sv.鏄ㄦ棩闈炶穼鍋�:
+        return False, "鏄ㄦ棩璺屽仠"
+    if settings.cant_yesterday_limit_up and not sv.鏄ㄦ棩闈炴定鍋�:
+        return False, "鏄ㄦ棩娑ㄥ仠"
+    if settings.cant_yesterday_open_limit_up and not sv.鏄ㄦ棩闈炵偢鏉�:
+        return False, "鏄ㄦ棩鐐告澘"
+
+    if sv.浠婃棩娑ㄥ仠浠� > settings.price_range[1] or sv.浠婃棩娑ㄥ仠浠� < settings.price_range[0]:
+        return False, f"浠婃棩娑ㄥ仠浠烽珮浜巤settings.price_range[1]}/浣庝簬{settings.price_range[0]}"
+
+    if sv.鑷敱娴侀�氬競鍊� > settings.zyltgb_range[1] * 1e8 or sv.鑷敱娴侀�氬競鍊� < settings.zyltgb_range[0] * 1e8:
+        return False, f"鑷敱甯傚�硷紙{sv.鑷敱娴侀�氬競鍊紏锛変笉婊¤冻瑕佹眰"
+
+    if sv.鍏釜浜ゆ槗鏃ユ定骞呰繃楂�:
+        return False, f"6涓氦鏄撴棩娑ㄥ箙杩囬珮"
+
+    if sv.鏃ヤ笁鏉夸釜鏁癬10 >= 1:
+        return False, f"10涓氦鏄撴棩鏈�>=3杩炴澘"
+
+    # if sv.褰撳墠浠� > sv.鏄ㄦ棩鏈�浣庝环 * 1.1:
+    #     return False, f"涔板叆鏃剁殑浠锋牸蹇呴』鈮ゆ槰鏃ユ渶浣庝环*110%"
+
+    if (sv.褰撳墠浠� - sv.浠婃棩鏈�浣庝环) / sv.鏄ㄦ棩鏀剁洏浠� > 0.03:
+        return False, f"涔板叆鏃剁殑浠锋牸涓嶈兘楂樹簬浠婃棩鏈�浣庝环鐨�3%"
+
+    # if abs((sv.褰撳墠浠� - round(sv.浠婃棩鎴愪氦棰� / sv.浠婃棩鎴愪氦閲�, 2)) / sv.鏄ㄦ棩鏀剁洏浠�) >= settings.max_rate_than_average_price:
+    #     return False, f"涔板叆浠烽珮浜庡潎浠穥settings.max_rate_than_average_price}({abs((sv.褰撳墠浠� - round(sv.浠婃棩鎴愪氦棰� / sv.浠婃棩鎴愪氦閲�, 2)) / sv.鏄ㄦ棩鏀剁洏浠�)})"
+    #
+    # if (sv.浠婃棩鏈�楂樹环淇℃伅[0] - sv.褰撳墠浠�) / sv.鏄ㄦ棩鏀剁洏浠� > settings.min_rate_of_highest_and_price:
+    #     return False, f"浣庝簬鍒嗘椂楂樹环{settings.min_rate_of_highest_and_price}"
+
+    if not settings.can_buy_limited_up and abs(sv.浠婃棩鏈�楂樹环淇℃伅[0] - sv.浠婃棩娑ㄥ仠浠�) <= 0.001:
+        return False, f"浠婃棩鏈夋定鍋�"
+
+    # if sv.娑ㄥ仠鏁癬30 <= 0 and not sv.鏃ユ斁鍊嶉噺鏃ユ湡_15:
+    #     return False, "30涓氦鏄撴棩鏃犳定鍋滀笖15涓氦鏄撴棩鏃犲�嶉噺"
+
+    # 鐩爣绁ㄦ澘鍧楁定鍋滀釜鏁�>=2
+
+    # 鏉垮潡鍙兘涔板叆涓�涓唬鐮�
+    # if sv.鏉垮潡鎴愪氦浠g爜:
+    #     can_buy_plates -= set(sv.鏉垮潡鎴愪氦浠g爜.keys())
+
+    if not can_buy_plates:
+        return False, f"娌℃湁娑ㄥ仠鐨勬澘鍧�: {[(plate, sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(plate)) for plate in sv.浠g爜鏉垮潡 if sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋淽}  杩炵画鑰侀鏉愶細{sv.杩炵画鑰侀鏉恾"
+    # new_plates = set(can_buy_plates) - sv.鏃ュ嚭鐜扮殑鏉垮潡_2
+    # if new_plates:
+    #     # 鏈夋柊棰樻潗锛屽垽鏂槸鍚﹁繃鏄ㄦ棩鍓嶉珮
+    #     if sv.浠婃棩鏈�楂樹环淇℃伅[0] - sv.鏄ㄦ棩鏈�楂樹环 < 0.02:
+    #         return False, "浠婃棩鏈�楂樹环闇�澶т簬鏄ㄦ棩鏈�楂樹环"
+    # else:
+    #     if sv.浠婃棩鏈�楂樹环淇℃伅[0] - sv.鏃ユ渶楂樹环_5 < 0.02:
+    #         return False, "浠婃棩鏈�楂樹环闇�澶т簬5鏃ユ渶楂樹环"
+
+    if settings.trade_days_count_of_limit_up_price_over_high and sv.浠婃棩娑ㄥ仠浠� <= getattr(sv,
+                                                                                     f"鏃ユ渶楂樹环_{settings.trade_days_count_of_limit_up_price_over_high}"):
+        return False, f"浠婃棩娑ㄥ仠浠疯绐佺牬{settings.trade_days_count_of_limit_up_price_over_high}鏃ユ渶楂樹环"
+
+    # if sv.浠婃棩鎴愪氦閲� < sv.鏄ㄦ棩鎴愪氦閲� * 0.8:
+    #     return False, f"瀹炴椂鎴愪氦閲忓繀椤烩墺80%鏄ㄦ棩鎬绘垚浜ら噺"
+
+    # =======鎴愪氦澶у崟=====
+    big_order_money = 0
+    if sv.浠婃棩澶у崟鏁版嵁:
+        # print(sv.浠婃棩澶у崟鏁版嵁[-1][3], format_time(sv.浠婃棩澶у崟鏁版嵁[-1][3]))
+        # filter_orders = [(o[0], o[2]) for o in sv.浠婃棩澶у崟鏁版嵁 if format_time(o[3]) >= sv.浠婃棩閲忓淇℃伅[0]]
+        filter_orders = [(o[0], o[2]) for o in sv.浠婃棩澶у崟鏁版嵁 if o[2] >= 299e4 and o[4] > sv.鏄ㄦ棩鏀剁洏浠穄
+        if not filter_orders:
+            return False, "鏃犳定骞呭ぇ浜�0%鐨勫ぇ鍗�"
+        filter_orders = [(o[0], o[2]) for o in sv.浠婃棩澶у崟鏁版嵁 if o[2] >= 299e4]
+        filter_orders.reverse()
+        orderids = set()
+        for o in filter_orders:
+            if o[0] in orderids:
+                continue
+            orderids.add(o[0])
+            big_order_money += o[1]
+    big_sell_order_money = 0
+    if sv.浠婃棩鍗栧ぇ鍗曟暟鎹�:
+        filter_orders = [(o[0], o[2]) for o in sv.浠婃棩鍗栧ぇ鍗曟暟鎹� if o[2] >= 100e4]
+        filter_orders.reverse()
+        orderids = set()
+        for o in filter_orders:
+            if o[0] in orderids:
+                continue
+            orderids.add(o[0])
+            big_sell_order_money += o[1]
+
+    threshold_money = max(sv.鑷敱娴侀�氬競鍊� // 1000, 200e4)
+
+    limit_up_codes_count = max([(p, len(sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(p, []))) for p in can_buy_plates], key=lambda x: x[1])[1]
+
+    # threshold_money *= max(min(10 - limit_up_codes_count + 1, 10), 5) / 10
+    threshold_money *= 0.5
+
+    # print(target_code, sv.鑷敱娴侀�氬競鍊�, threshold_money, limit_up_codes_count)
+
+    # threshold_money = 200e4  # int(sv.鏄ㄦ棩鎴愪氦閲� * 0.2 * sv.浠婃棩娑ㄥ仠浠� * 0.05)
+
+    final_big_order_money = big_order_money - big_sell_order_money
+
+    if final_big_order_money <= 200e4:
+        # 澶у崟鍑�棰濊澶т簬200w
+        return False, f"({round(final_big_order_money / 1e4, 2)}涓�/{round(threshold_money / 1e4, 2)}涓�)澶у崟閲戦涓嶈冻"
+
+    return True, f" \n\t澶у崟淇℃伅锛歿round(final_big_order_money / 1e4, 2)}涓囷紙涔帮細{round(big_order_money / 1e4, 2)}涓� 鍗栵細{round(big_sell_order_money / 1e4, 2)}涓囷級/{round(threshold_money / 1e4, 2)}涓�  \n\t閲忓淇℃伅锛歿sv.浠婃棩閲忓淇℃伅}\n\t浠婃棩鏈�楂樹环:{sv.浠婃棩鏈�楂樹环淇℃伅} \n\t5鏃ユ渶楂樹环锛歿sv.鏃ユ渶楂樹环_5}", f"\n\t鏉垮潡淇℃伅锛歿[(p, sv.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(p)) for p in can_buy_plates]}", can_buy_plates
+
+
+compute_result = can_buy()
diff --git a/strategy/strategy_variable_factory.py b/strategy/strategy_variable_factory.py
index 97b9e28..c79673b 100644
--- a/strategy/strategy_variable_factory.py
+++ b/strategy/strategy_variable_factory.py
@@ -7,7 +7,7 @@
 import re
 
 import constant
-from code_attribute import global_data_loader
+from code_attribute import global_data_loader, gpcode_manager
 from db import mysql_data_delegate
 from strategy.data_analyzer import KTickLineAnalyzer, KPLLimitUpDataAnalyzer, K60SLineAnalyzer
 from strategy.strategy_variable import StockVariables
@@ -235,7 +235,7 @@
                 results = [x for x in results if
                            (tool.is_can_buy_code(x[0]) and x[0] in valid_codes and x[0] not in exclude_codes)]
                 # 鍙栧墠1/3涓旀定鍋滄暟鏄墠10
-                max_count = len(results) // 2 if len(results) % 2 == 0 else len(results) // 2 + 1
+                max_count = len(results) // 3 if len(results) % 3 == 0 else len(results) // 3 + 1
                 results = results[:max_count]
                 # 鍙栧墠10
                 results = results[:10]
@@ -636,7 +636,41 @@
             print(code, code_blocks[code])
 
 
+def __load_target_codes_v1():
+    """
+    50浜夸互涓嬬殑
+    @return:
+    """
+
+    def get_zylt(code):
+        zylt_volume_map = global_util.zylt_volume_map
+        last_trade_day = __DataLoader.trade_days[0]
+        volume = zylt_volume_map.get(code)
+        # 浠婃棩娑ㄥ仠浠疯绐佺牬鏄ㄦ棩鏈�楂樹环
+        k_bars = HistoryKDataManager().get_history_bars(code, last_trade_day)
+        return k_bars[0]["close"] * volume * tool.get_limit_up_rate(code)
+
+    __DataLoader = DataLoader('2025-06-13')
+    global_data_loader.load_zyltgb_volume_from_db()
+    results = __DataLoader.load_target_plate_and_codes()
+    # for k in results:
+    #     print(k, results[k])
+    plates = ["澶╃劧姘�", "鍐涘伐"]
+    print("==========鏂伴鏉�=======")
+    for p in plates:
+        codes = [x for x in results.get(p) ] # if get_zylt(x) < 31e8
+        print("======", p)
+        for code in codes:
+            print("\t\t", code, gpcode_manager.CodesNameManager().get_code_name(code))
+
+
+
+
+
 if __name__ == "__main__":
+
+    __load_target_codes_v1()
+
     __DataLoader = DataLoader("2025-06-12")
     # __test_jx_blocks(__DataLoader)
 
@@ -655,7 +689,7 @@
     results = __DataLoader.load_target_plate_and_codes()
     # for k in results:
     #     print(k, results[k])
-    plates = ["姹借溅闆堕儴浠�", "绋�鍦熸案纾�", "鍖栧伐", "鍖昏嵂", "鍏変紡"]
+    plates = ["姹借溅闆堕儴浠�", "鏂囧寲浼犲獟", "璋峰瓙缁忔祹"]
     print("==========鏂伴鏉�=======")
     for p in plates:
         print(p, results.get(p))
diff --git a/strategy/test.py b/strategy/test.py
index 2b50ce9..da567f2 100644
--- a/strategy/test.py
+++ b/strategy/test.py
@@ -1,8 +1,11 @@
+from huaxin_client import l1_subscript_codes_manager
 from strategy import strategy_manager
 from strategy.strategy_variable import StockVariables
 
-
 # 缁熻褰撴棩鐨勫钩鍧囨孩浠风巼
+from third_data.kpl_block_manager import KPLCodeJXBlocksManager
+
+
 def statistic_average(path):
     rate_list = []
     with open(path, mode='r', encoding='utf-8') as f:
@@ -23,6 +26,13 @@
     # statistic_average(r"C:\Users\Administrator\Desktop\3涓エ娑ㄥ仠涔嬪悗涔�.txt")
     # print("======3涓エ娑ㄥ仠涔嬪悗涔�+涓嶉檺寮�鐩樻定骞�+3涓定鍋滀箣鍚庡ぇ鍗曟墦鎶�")
     # statistic_average(r"C:\Users\Administrator\Desktop\3涓エ娑ㄥ仠涔嬪悗涔癬涓嶉檺寮�鐩樻定骞�.txt")
-    strategy_manager.low_suction_strtegy
-
-
+    codes = set()
+    codes_sh, codes_sz = l1_subscript_codes_manager.get_codes()
+    codes |= set([x.decode() for x in codes_sh])
+    codes |= set([x.decode() for x in codes_sz])
+    KPLCodeJXBlocksManager('2025-06-17', codes).start_download_blocks()
+    # target_block = {"鐭虫补鐭冲寲", "澶╃劧姘�", "鍖栧伐"}
+    # for code in code_blocks:
+    #     blocks = code_blocks.get(code)
+    #     if len(blocks & target_block) == len(target_block):
+    #         print(code, blocks)
diff --git a/strategy/time_series_backtest.py b/strategy/time_series_backtest.py
index a8196a5..b5128c2 100644
--- a/strategy/time_series_backtest.py
+++ b/strategy/time_series_backtest.py
@@ -298,6 +298,9 @@
         if code_ in self.stock_variables_dict:
             return
 
+        if code_ == '002907':
+            print("")
+
         stock_variables = StrategyVariableFactory.create_from_history_data(
             timeline_data["kline_data"].get(code_), timeline_data["minute_data"].get(code_),
             timeline_data["limit_up_record_data"].get(code_), timeline_data["trade_days"])
@@ -583,6 +586,19 @@
                                 most_real_kpl_plate_limit_up_codes_info[p] = []
                             most_real_kpl_plate_limit_up_codes_info[p].append(code)
 
+                # ---------娴嬭瘯--------
+                # test_plate = "鍖栧伐"
+                # if len(most_real_kpl_plate_limit_up_codes_info.get(test_plate, [])) >= 3:
+                #     print("娴嬭瘯寮�濮�=========")
+                #     code_plates_for_buy = self.current_data["code_plates_for_buy"]
+                #     plate_codes = [c for c in code_plates_for_buy if test_plate in code_plates_for_buy[c]]
+                #     print(f"{test_plate}婊¤冻", time_str, plate_codes)
+                #     for c in plate_codes:
+                #         sv: StockVariables = self.stock_variables_dict.get(c)
+                #         if sv and sv.褰撳墠浠� > sv.鏄ㄦ棩鏀剁洏浠�:
+                #             print(c)
+                #     print("娴嬭瘯瀹屾瘯=========")
+
             if ticks:
                 for tick in ticks:
                     code = tick["symbol"][-6:]
@@ -650,6 +666,7 @@
                         stock_variables.浠婃棩鏈�浣庝环 = tick["price"]
                     if most_real_kpl_plate_limit_up_codes_info:
                         stock_variables.寮�鐩樺暒鏈�姝f澘鍧楁定鍋� = most_real_kpl_plate_limit_up_codes_info
+
                     # if time_str >= '09:30:00':
                     #     if stock_variables.浠婃棩澶у崟鏁版嵁 and stock_variables.寮�鐩樺暒鏈�姝f澘鍧楁定鍋� and max(
                     #             [len(stock_variables.寮�鐩樺暒鏈�姝f澘鍧楁定鍋�.get(x, [])) for x in stock_variables.浠g爜鏉垮潡]) >= 3:
@@ -768,7 +785,7 @@
             stock_variables.鏉垮潡鎴愪氦浠g爜 = self.deal_block_codes
 
 
-# DEBUG_CODES =  ['603040', '603758', '603286', '603586', '605255', '002048', '605208', '002806', '603266', '603788']
+# DEBUG_CODES = ['600727']
 DEBUG_CODES = []
 
 VOLUME_LOG_ENABLE = False
@@ -777,7 +794,7 @@
 
 DEBUG_BLOCKS = []
 
-BIG_ORDER_MONEY_THRESHOLD = 100e4
+BIG_ORDER_MONEY_THRESHOLD = 200e4
 
 if __name__ == "__main__":
     back_test_dict = {}
@@ -786,9 +803,9 @@
     days = ["2025-05-12", "2025-05-13", "2025-05-14", "2025-05-15", "2025-05-16", "2025-05-19", "2025-05-20",
             "2025-05-21", "2025-05-22", "2025-05-23", "2025-05-26", "2025-05-27", "2025-05-28", "2025-05-29",
             "2025-05-30", "2025-06-03", "2025-06-04", "2025-06-05", "2025-06-06", "2025-06-09", "2025-06-10",
-            "2025-06-11",  "2025-06-12"]
+            "2025-06-11", "2025-06-12", "2025-06-13", "2025-06-16"]
 
-    # days = ["2025-06-09"]
+    # days = ["2025-06-13"]
 
     days.reverse()
     for day in days:
diff --git a/third_data/kpl_api.py b/third_data/kpl_api.py
index 552e7fc..af721f9 100644
--- a/third_data/kpl_api.py
+++ b/third_data/kpl_api.py
@@ -361,7 +361,7 @@
     #     print(d)
     #
     # print(result)
-    print(getCodeJingXuanBlocks("002519"))
+    print(getCodeJingXuanBlocks("002878"))
     # results = getHistoryCodesByPlateOrderByLZCS("801199", "2025-05-16", "0930", 3)
     # results = json.loads(results)["list"]
     # for result in results:
diff --git a/third_data/kpl_block_manager.py b/third_data/kpl_block_manager.py
new file mode 100644
index 0000000..8d48f9a
--- /dev/null
+++ b/third_data/kpl_block_manager.py
@@ -0,0 +1,55 @@
+"""
+寮�鐩樺暒鏉垮潡绠$悊
+"""
+import json
+
+import constant
+
+from db.mysql_data_delegate import Mysqldb
+from third_data import kpl_api, kpl_util
+from utils import tool
+
+
+class KPLCodeJXBlocksManager:
+    """
+    寮�鐩樺暒绮鹃�夋澘鍧楃鐞�
+    """
+
+    def __init__(self, day, target_codes):
+        self.day = day
+        self.mysql_db = Mysqldb()
+        self.target_codes = target_codes
+
+    def __download_blocks(self, code):
+        datas = kpl_api.getCodeJingXuanBlocks(code)
+        blocks = json.dumps([kpl_util.filter_block(x[1]) for x in datas], ensure_ascii=False)
+        block_ids = json.dumps([x[0] for x in datas], ensure_ascii=False)
+        block_details = json.dumps(datas, ensure_ascii=False)
+        id = f"{self.day}_{code}"
+        self.mysql_db.execute(
+            f"insert into kpl_code_blocks(id,code, day,jx_blocks, jx_block_ids, jx_blocks_detail, create_time) values('{id}','{code}','{self.day}','{blocks}', '{block_ids}','{block_details}', now())")
+
+    def start_download_blocks(self):
+        codes = self.mysql_db.select_all(f"select code from kpl_code_blocks where day='{self.day}'")
+        codes = set([x[0] for x in codes])
+        need_update_codes = set(self.target_codes) - codes
+        for code in need_update_codes:
+            self.__download_blocks(code)
+
+    def get_all_code_blocks(self):
+        """
+        鑾峰彇鎵�鏈変唬鐮佺殑鏉垮潡
+        @return:
+        """
+        sql = f"select code, jx_blocks from kpl_code_blocks where day = '{self.day}'"
+        results = self.mysql_db.select_all(sql)
+        return {x[0]: set(json.loads(x[1])) - constant.KPL_INVALID_BLOCKS for x in results}
+
+    def get_all_code_blocks_count(self):
+        """
+        鑾峰彇鎵�鏈変唬鐮佺殑鏉垮潡鐨勬暟閲�
+        @return:
+        """
+        sql = f"select count(*) from kpl_code_blocks where day = '{self.day}'"
+        results = self.mysql_db.select_one(sql)
+        return int(results[0])

--
Gitblit v1.8.0