From 8bfdc52b40b4456a5a29e4502cce5865be8ef439 Mon Sep 17 00:00:00 2001
From: admin <admin@example.com>
Date: 星期五, 05 九月 2025 18:17:15 +0800
Subject: [PATCH] bug修复

---
 main.py |  269 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 229 insertions(+), 40 deletions(-)

diff --git a/main.py b/main.py
index b378382..ac7057e 100644
--- a/main.py
+++ b/main.py
@@ -1,27 +1,33 @@
 # coding=utf-8
 from __future__ import print_function, absolute_import, unicode_literals
 import logging
-import json
-import os.path
-# from log import logger
+import multiprocessing
 import threading
 import time
+import schedule
 
 import constant
 # 寮曞叆鎺橀噾妗ユAPI
 import utils.juejin_api
-from log_module.log import logger_common, logger_kpl_jingxuan_in, logger_system
+from db.redis_manager_delegate import RedisUtils
+from huaxin_client.l2_data_transform_protocol import L2DataCallBack
+from log_module.log import logger_common, logger_kpl_jingxuan_in, logger_system, logger_debug
 # 寮曞叆寮�鐩樺暒API妯″潡
 # 寮曞叆鍏ㄥ眬鍙橀噺妯″潡
 # 寮曞叆瀹氭椂鍣ㄦā鍧�
 # 寮曞叆鍘嗗彶K绾挎柟娉曟ā鍧�
 # 寮曞叆鐬椂鍒嗘椂琛屾儏妯″潡
 # 寮曞叆璐︽埛绠$悊妯″潡銆愯繘琛岃祫閲戝拰浠撲綅绠$悊銆�
-from strategy import kpl_api, data_cache, check_timer, all_K_line, instant_time_market, account_management, order_methods
-from huaxin_client import l2_market_client
-from log_module import async_log_util
-from trade import huaxin_trade_data_update
-from utils import hx_qc_value_util
+from strategy import kpl_api, data_cache, check_timer, all_K_line, instant_time_market, account_management, \
+    order_methods, local_data_management, kpl_data_manager, market_sentiment_analysis, plate_strength_analysis, \
+    selling_strategy
+from huaxin_client import l2_market_client, l2_client, trade_client
+from log_module import async_log_util, log
+from strategy.order_methods import TodayBuyCodeManager
+from strategy.trade_setting import BuyMoneyPerCodeManager, OpeningQuantityManager
+from strategy.trading_dates_manager import TradingDatesManager
+from trade import huaxin_trade_data_update, huaxin_trade_api
+from utils import hx_qc_value_util, huaxin_util, juejin_api, tool
 
 # 寮曞叆琛屾儏璁㈤槄妯″潡
 # import subscribe_market
@@ -47,11 +53,19 @@
     鏃犻渶鎺橀噾鑰冭檻鐨勭嚎绋嬫垨杩涚▼鏂瑰紡瀹炵幇
     '''
     # 鍒濆鍖栬处鎴蜂粨浣嶇鐞嗘暟鎹�
-    account_management.finance_management()
+    try:
+        account_management.finance_management()
+    except:
+        pass
     # 鍒濆鍖栬处鎴蜂粨浣嶇鐞嗘暟鎹�
-    account_management.position_management()
+    try:
+        account_management.position_management()
+    except:
+        pass
     # 鍒濆鍖�.瀹炰緥鍖栫紦瀛樹腑鐨勫叏灞�鏁版嵁
     data_cache.DataCache()
+    # 璇诲彇鏈湴K绾挎暟鎹� 骞舵洿鏂板埌data_cache
+
     # 鍒濆鍖朅鑲℃墍鏈夌洰鏍囩エ鏍囩殑淇℃伅
     data_cache.all_stocks = utils.juejin_api.JueJinApi.get_target_codes()
     # 鑾峰彇鐩爣鏍囩殑K绾�---鍒濆鍖�
@@ -60,18 +74,53 @@
 
     # 鐩存帴璋冪敤鐩爣鏍囩殑鎸囨爣K绾垮啓鍏ユ湰鍦版枃浠�
     # all_K_line.all_stocks_all_k_line_dict_write()
+    local_data_management.read_local_K_line_data()
+    # 璇诲彇鏈湴涓偂鎵�灞炴澘鍧楁暟鎹� 骞舵洿鏂板埌data_cache
+    local_data_management.read_local_all_stocks_plate_data()
+    # 鍒濆鍖栨媺鍙栧綋鏃ヤ拱鍏ヤ唬鐮�
+    TodayBuyCodeManager()
+    # 寮�浠撻噾棰濆垵濮嬪寲
+    BuyMoneyPerCodeManager()
+    # 寮�浠撴暟閲�
+    OpeningQuantityManager()
 
-    # 鍏堜娇鐢╦son.load()鐩存帴浠庢枃浠朵腑璇诲彇銆愬凡缁忓瓨鍌ㄥ湪鏈湴鐨凨绾挎寚鏍囧睘鎬у瓧鍏搞�戝苟瑙f瀽JSON鏁版嵁
-    if os.path.exists(constant.K_BARS_PATH):
-        with open(constant.K_BARS_PATH, 'r', encoding='utf-8') as f:
-            data_cache.all_stocks_all_K_line_property_dict = json.load(f)
-            print(
-                f"data_cache.all_stocks_all_K_line_property_dict鐨勪釜鏁�==={len(data_cache.all_stocks_all_K_line_property_dict)}")
 
-    # # 鑾峰彇鐩爣鏍囩殑K绾�---鍒濆鍖�
-    # all_K_line.main_index_k_line_history.init(data_cache.DataCache().today_date, data_cache.DataCache().next_trading_day, data_cache.DataCache().main_index_stocks)
-    # # 鐩存帴璋冪敤涓昏鎸囨暟K绾垮啓鍏ユ湰鍦版枃浠�
-    # all_K_line.main_index_k_line_dict_write()
+def __run_pending():
+    def update_k_lines():
+        logger_debug.info("寮�濮嬫洿鏂癒绾�")
+        all_K_line.all_stocks_all_k_line_dict_write()
+        local_data_management.read_local_K_line_data()
+        logger_debug.info("缁撴潫鏇存柊K绾�")
+
+    def update_target_codes():
+        data_cache.target_codes_manager.update_today_codes_info()
+        time.sleep(2)
+        data_cache.target_codes_manager.load_data()
+
+    def update_all_stocks_plate():
+        plate_strength_analysis.get_all_stocks_plate_dict(data_cache.DataCache().filtered_stocks)
+        local_data_management.read_local_all_stocks_plate_data()
+
+    def update_trading_dates():
+        dates = TradingDatesManager().update_trading_dates()
+        TradingDatesManager().load_data()
+
+    schedule.every().day.at("17:00:00").do(lambda: threading.Thread(target=update_k_lines, daemon=True).start())
+    schedule.every().day.at("09:05:00").do(lambda: threading.Thread(target=update_k_lines, daemon=True).start())
+    schedule.every().day.at("09:05:00").do(lambda: huaxin_trade_data_update.add_money_list())
+    schedule.every().day.at("09:05:00").do(lambda: huaxin_trade_data_update.add_position_list())
+    schedule.every().day.at("17:10:00").do(lambda: threading.Thread(target=update_target_codes, daemon=True).start())
+    schedule.every().day.at("17:00:00").do(
+        lambda: threading.Thread(target=update_all_stocks_plate, daemon=True).start())
+    schedule.every().day.at("17:00:00").do(lambda: threading.Thread(target=update_trading_dates, daemon=True).start())
+
+    while True:
+        try:
+            schedule.run_pending()
+        except:
+            pass
+        finally:
+            time.sleep(1)
 
 
 # 绗竴姝ワ細鍒濆鍖朿ontext鍑芥暟锛屽苟寮�鍚幏鍙栧疄鏃舵暟鎹殑绾跨▼
@@ -81,35 +130,47 @@
     # 瀹炴椂杩愯瀹氭椂鍣ㄧ嚎绋嬨�愬畾鏃跺櫒鍑芥暟鐩墠 鍙鐞� 15:00 鍚庤繍琛屼竴娆� 鏁寸悊褰撴棩娑ㄥ仠淇℃伅 鍜� 鑾峰彇鎵�鏈変釜鑲$殑鏉垮潡姒傚康銆�
     threading.Thread(target=lambda: check_timer.check_time(), daemon=True).start()
     # 鑾峰彇瀹炴椂澶х洏琛屾儏鎯呯华缁煎悎寮哄害 [鍒嗘暟] 绾跨▼
-    threading.Thread(target=lambda: kpl_api.get_real_time_market_strong(), daemon=True).start()
+    threading.Thread(target=lambda: market_sentiment_analysis.set_plan_position_quantity(), daemon=True).start()
     # 瀹炴椂妫�娴嬫槸鍚︽媺鍙朘绾跨嚎绋�
-    threading.Thread(target=lambda: all_K_line.check_time_and_data_date(), daemon=True).start()
+    # threading.Thread(target=lambda: all_K_line.check_time_and_data_date(), daemon=True).start()
     # print(f"all_stocks_all_K_line_property_dict== {type(data_cache.all_stocks_all_K_line_property_dict)}")
     # 鑾峰彇瀹炴椂澶х洏鎸囨暟琛屾儏绾跨▼
     threading.Thread(target=lambda: instant_time_market.index_market_current(), daemon=True).start()
+    # 瀹氭椂浠诲姟
+    threading.Thread(target=lambda: __run_pending(), daemon=True).start()
+
     # instant_time_market.index_market_trend()
 
     #  寮�鐩樺暒鐨勬定鍋滄蹇电殑鍥炶皟鍑芥暟
     def kpl_limit_up_process(datas):
         # print(f"鍥炶皟鎴愬姛==={datas}")
-        data_cache.limit_up_block_names = datas
+        if datas is not None and len(datas) > 0:
+            data_cache.limit_up_block_names = datas
+        else:
+            data_cache.limit_up_block_names = []
 
     # # 璁$畻褰撳墠绾跨▼鏁伴噺
     # get_current_thread_count()
 
     # 寮�鍚紑鐩樺暒 娑ㄥ仠鍒楄〃 鍜� 鍏ㄧ洏涓偂姒傚康鏉垮潡 鎺ュ彛绾跨▼
     # 娑ㄥ仠姒傚康绾跨▼
-    # threading.Thread(target=kpl_api.kpl_limit_up_process, daemon=True).start()    #璇ヨ浠g爜涓哄彧杩愯鍗曚竴绾跨▼涓嶅洖璋冩暟鎹殑鏂瑰紡
-    threading.Thread(target=kpl_api.kpl_limit_up_process, args=(kpl_limit_up_process,), daemon=True).start()
+    # threading.Thread(target=plate_strength_analysis.kpl_limit_up_process, daemon=True).start()    #璇ヨ浠g爜涓哄彧杩愯鍗曚竴绾跨▼涓嶅洖璋冩暟鎹殑鏂瑰紡
+    threading.Thread(target=plate_strength_analysis.kpl_limit_up_process, args=(kpl_limit_up_process,),
+                     daemon=True).start()
 
     # # 寮�鐩樺暒鐨勬澘鍧楀己搴︿笅鐨勪釜鑲″己搴﹀洖璋冨嚱鏁�
-    def get_market_sift_plate_its_stock_power_process(market_sift_plate_stock_dict):
+    def get_market_sift_plate_its_stock_power_process(market_sift_plate_info):
         # print(f"鍥炶皟鎴愬姛===绮鹃�夋澘鍧楄偂绁ㄥ己搴︽暟鎹洿鏂�==={market_sift_plate_stock_dict}")
         # logger_kpl_jingxuan_in.info(f"{market_sift_plate_stock_dict}")
-        data_cache.market_sift_plate_stock_dict = market_sift_plate_stock_dict
+        if market_sift_plate_info is None:
+            return
+        market_sift_plate_stock_dict, market_sift_plates = market_sift_plate_info[0], market_sift_plate_info[1]
+        if market_sift_plate_stock_dict:
+            data_cache.market_sift_plate_stock_dict = market_sift_plate_stock_dict
+            data_cache.market_sift_plates = market_sift_plates
 
     # 鏉垮潡寮哄害涓嬩釜鑲″己搴︾嚎绋�
-    threading.Thread(target=kpl_api.get_market_sift_plate_its_stock_power_process,
+    threading.Thread(target=plate_strength_analysis.get_market_sift_plate_its_stock_power_process,
                      args=(get_market_sift_plate_its_stock_power_process,), daemon=True).start()
 
     # 鍒濆鍖杇et_current_data鏂规硶鍑芥暟锛屼笅鍗曚拱閫昏緫鎵嶄細杩愯涓�傘�傘�傘�愭牳蹇冧富绾跨▼锛岄殢鏃惰�冭檻鍏跺惎鍔ㄩ『搴忋��>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@@ -117,13 +178,13 @@
 
     try:
         # 璁$畻寮�鐩樺暒鏄ㄦ棩鎷夊彇鐨勬蹇垫暟鎹腑涓虹┖鐨勮偂绁ㄦ暟閲�
-        kpl_api.get_have_no_plate_num()
+        plate_strength_analysis.get_have_no_plate_num()
     except Exception as e:
         logger_system.exception(e)
 
     # 鑾峰彇鍘嗗彶娑ㄥ仠淇℃伅鏁版嵁骞舵暣鐞�
     try:
-        kpl_api.get_handling_limit_up_info()
+        plate_strength_analysis.get_handling_limit_up_info()
     except Exception as e:
         logger_system.exception(e)
 
@@ -133,42 +194,166 @@
     except Exception as e:
         logger_system.exception(e)
 
-    # # 鑾峰彇鎵�鏈変釜鑲$殑鏉垮潡姒傚康骞跺啓鍏ユ枃浠躲�愯�楁椂杈冮暱搴旇鏀惧湪 鏍稿績涓荤嚎绋� 鍜� 浠撲綅绠$悊 鍚庨潰銆�
-    # kpl_api.get_all_stocks_plate_dict(data_cache.min_stocks)
+
+# 鎸佷粨浠g爜鐨凩2鏁版嵁鍥炶皟
+class MyPositionsL2DataCallback(L2DataCallBack):
+    __last_price_dict = {}
+    __pre_close_price_dict = {}  # 鏄ㄦ棩鏀剁洏浠�
+
+    def OnL2Transaction(self, code, datas):
+        """
+        鏄ㄦ棩鎸佷粨L2閫愮瑪鎴愪氦鍥炶皟
+        :param code:
+        :param datas:
+        :return:
+        """
+        if datas:
+            start_time = time.time()
+            # logger_debug.debug(f"{code} - L2閫愮瑪鎴愪氦涓婃姤锛歿len(datas)}")
+            price, time_str = datas[-1][1], huaxin_util.convert_time(datas[-1][3])
+            try:
+                # 鑾峰彇鏈�杩戠殑鎴愪氦浠�
+                if code not in self.__pre_close_price_dict:
+                    # 鑾峰彇鏀剁洏浠锋牸
+                    results = juejin_api.JueJinApi.history_n(tool.get_symbol(code), "1d", 1, 1, "close")
+                    if results:
+                        self.__pre_close_price_dict[code] = results[0]["close"]
+                        logger_debug.debug(f"{code} - 鑾峰彇鍒版槰鏃ユ敹鐩樹环锛歿results[0]['close']}")
+                if self.__last_price_dict.get(code) == price:
+                    return
+                limit_up_price = tool.get_limit_up_price(code, self.__pre_close_price_dict[code])
+                if code in self.__last_price_dict:
+                    if abs(limit_up_price - self.__last_price_dict[code]) < 0.0001 < abs(limit_up_price - price):
+                        # 澶勭悊鐐告澘閫昏緫
+                        # 鐩戝惉浜嗙偢鏉夸簡瑕佸仛鐨勫嚱鏁�
+                        try:
+                            selling_strategy.explosion_strategy(code)
+                            # 鐐告澘s
+                        finally:
+                            logger_debug.info(f"鐐告澘:{code}-({price},{time_str})")
+            except Exception as e:
+                logger_debug.exception(e)
+            finally:
+                self.__last_price_dict[code] = price
+                data_cache.latest_deal_price_dict[code] = price
+                data_cache.latest_l2_transaction_info_dict[code] = (price, time_str)
+                use_time = time.time() - start_time
+                if use_time > 0.1:
+                    logger_debug.warning(f"L2閫愮瑪鎴愪氦澶勭悊鑰楁椂锛歿use_time} 鏈�鍚庝竴鏉℃暟鎹細{datas[-1]}")
+
+    def OnMarketData(self, code, datas):
+        # logger_debug.info(f"鏀跺埌L2Market鏁版嵁锛歿datas}")
+        for d in datas:
+            code = d["securityID"]
+            buy1 = d["buy"][0]
+
+    # 瀹炴椂L2涔�1鎴愪氦閲�
+    def OnRealTimeBuy1Info(self, code, buy1_info):
+        pass
+        # buy1_info: [涔�1鏃堕棿,涔�1浠锋牸, 鍘熷涔�1閲�, 瀹炴椂涔�1閲廬
+        # 鏈�缁堢殑涔�1涓猴細 鍘熷涔�1閲�+瀹炴椂涔�1閲�
+        # async_log_util.info(logger_debug, f"OnRealTimeBuy1Info锛歿code}-{buy1_info}")
+        # L1DataProcessor.excute_sell_rule(code, buy1_info[3], buy1_info[1], "l2-real")
+
+
+l2_data_callbacks = []
+
+
+# 璁㈤槄鎸佷粨L2鏁版嵁
+def __subscript_position_l2():
+    """
+    璁㈤槄鎸佷粨L2鏁版嵁
+    :return:
+    """
+    position_result = huaxin_trade_api.get_position_list(blocking=True)
+    logger_debug.info(f"鑾峰彇鎸佷粨缁撴灉锛歿position_result}")
+    if not position_result or position_result["code"] != 0 or not position_result["data"]:
+        return
+    positions = position_result["data"]
+    subscript_codes = set()
+    for p in positions:
+        if p["prePosition"] > 0:
+            subscript_codes.add(p["securityID"])
+    if not subscript_codes:
+        return
+
+    for i in range(len(subscript_codes)):
+        l2_data_callbacks.append(MyPositionsL2DataCallback())
+    l2_client.run(subscript_codes, l2_data_callbacks)
 
 
 # 绗笁姝ワ細鎵ц绛栫暐鐨勫垵濮嬭缃�
 if __name__ == '__main__':
+    log.close_print()
     class MyMarketDataCallback(l2_market_client.L2MarketDataCallback):
+
+        def __init__(self):
+            def push_ticks_of_position_codes():
+                """
+                鎺ㄩ�佹寔浠撲唬鐮佺殑tick鏁版嵁
+                :return:
+                """
+                while True:
+                    try:
+                        if data_cache.OPEN_BIDDING_TIME <= tool.get_now_time_str() <= data_cache.OPENING_TIME:
+                            logger_debug.info(f"09:25-09:30涓诲姩鎺ㄩ�佹暟鎹�")
+                            datas = [v for k, v in data_cache.current_l1_dict.items()]
+                            instant_time_market.set_current_info(datas)
+                        elif tool.get_now_time_str() > data_cache.OPENING_TIME:
+                            break
+                    except Exception as e:
+                        logger_debug.exception(e)
+                    finally:
+                        time.sleep(3)
+
+            threading.Thread(target=push_ticks_of_position_codes, daemon=True).start()
+
         def on_markets(self, datas):
             """
             L1鏁版嵁鍥炶皟
             :param datas:
             :return:
             """
-            data_cache.latest_code_market_info_dict = {x[0]: x for x in datas}
-            if datas:
-                print(datas[0])
+            for x in datas:
+                data_cache.latest_code_market_info_dict[x[0]] = x
             if constant.is_windows():
                 instant_time_market.get_current_info()
             else:
                 instant_time_market.set_current_info(datas)
 
 
+    # 鍔犺浇寮�鐩樺暒鏉垮潡鏃ュ織鏁版嵁
+    kpl_data_manager.KPLMarketsSiftPlateLogManager()
+    kpl_data_manager.KPLMarketStockHeatLogManager()
+
     # 鍚姩寮傛鏃ュ織
     threading.Thread(target=async_log_util.run_sync, daemon=True).start()
 
+    # redis 鏁版嵁鍚屾
+    threading.Thread(target=RedisUtils.run_loop, daemon=True).start()
+
+    # 绛栫暐涓庝氦鏄撻�氫俊闃熷垪
+    queue_strategy_r_trade_w, queue_strategy_w_trade_r, queue_strategy_w_trade_for_query_r = multiprocessing.Queue(), multiprocessing.Queue(), multiprocessing.Queue()
+
+    # 涓嶆槸妯℃嫙鐩樼殑鏃跺�欏惎鍔ㄤ氦鏄�
+    if not constant.IS_SIMULATED_TRADE:
+        multiprocessing.Process(target=trade_client.run, args=(
+            queue_strategy_r_trade_w, queue_strategy_w_trade_r, queue_strategy_w_trade_for_query_r,)).start()
+
     # 鍚姩浜ゆ槗
-    order_methods.run()
+    order_methods.run(queue_strategy_r_trade_w, queue_strategy_w_trade_r, queue_strategy_w_trade_for_query_r)
 
     # 杩愯鍗庨懌澧炲�兼湇鍔¤繘绋�,鐢ㄤ簬鑾峰彇K绾夸笌浜ゆ槗鏃ュ巻
     threading.Thread(target=hx_qc_value_util.run, daemon=True).start()
 
     # 杩愯浜ゆ槗鏁版嵁鏇存柊鏈嶅姟
-    huaxin_trade_data_update.run()
+    huaxin_trade_data_update.run(order_methods.trade_callback)
 
     # 绛夊緟5s锛岀瓑鍏朵粬绾跨▼/杩涚▼鍚姩瀹屾瘯
-    time.sleep(5)
+    time.sleep(15)
+
+    # 璁㈤槄鎸佷粨绁�
+    threading.Thread(target=__subscript_position_l2, daemon=True).start()
 
     try:
         # 鍒濆鍖栨暟鎹�
@@ -177,7 +362,11 @@
         logger_system.exception(e)
 
     # 闇�瑕佽闃呯殑鐩爣浠g爜
-    target_codes = [x["sec_id"] for x in data_cache.DataCache().all_stocks]
+    target_codes = [x[-6:] for x in data_cache.DataCache().min_stocks]
+    position_codes = [x[-6:] for x in data_cache.position_symbols_set]
+    logger_debug.info(f"浠婃棩鎸佷粨浠g爜锛歿position_codes}")
+    target_codes = set(target_codes) | set(position_codes)
+    logger_debug.info(f"浠婃棩瑕佽闃呯殑浠g爜锛歿len(target_codes)}-{target_codes}")
 
     # 璁㈤槄L2 market琛屾儏
     l2_market_client.run(target_codes, MyMarketDataCallback())

--
Gitblit v1.8.0