From 892b50e242e3c59a738b92dfdfee1bf1ff8932f2 Mon Sep 17 00:00:00 2001
From: Administrator <admin@example.com>
Date: 星期五, 21 十月 2022 16:59:58 +0800
Subject: [PATCH] 新策略修改

---
 trade_gui.py |  504 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 464 insertions(+), 40 deletions(-)

diff --git a/trade_gui.py b/trade_gui.py
index bb64ef9..2d218d1 100644
--- a/trade_gui.py
+++ b/trade_gui.py
@@ -5,12 +5,16 @@
 import array
 import threading
 import time
+import random
 
 import win32gui
 import win32api
 import win32con
 
 import global_util
+import gpcode_manager
+import redis_manager
+import tool
 from log import *
 from threading import Thread
 
@@ -66,9 +70,9 @@
     @classmethod
     def checkEnv(cls):
         # 妫�娴嬩氦鏄撶獥鍙�
-        buy_wins = cls.get_buy_wins()
-        if len(buy_wins) < 3:
-            raise Exception("闂數涔板叆绐楀彛鏈�浣庨渶瑕�3涓�")
+        buy_wins = THSBuyWinManagerNew.get_buy_wins()
+        if len(buy_wins) < 10:
+            raise Exception("涓嬪崟绐楀彛鏈�浣庨渶瑕�10涓�")
 
         # 妫�娴嬫挙鍗曠獥鍙�
         cancel_trade_win = cls.getCancelBuyWin()
@@ -169,7 +173,8 @@
 
     def getLimitUpPrice(self, win):
         hwnd = win32gui.GetDlgItem(win, 0x000006C8)
-        return self.getText(hwnd)
+        text_ = self.getText(hwnd)
+        return text_.replace("娑ㄥ仠锛�", "")
 
     # 鑾峰彇浜ゆ槗缁撴灉
     def getTradeResultWin(self):
@@ -217,36 +222,40 @@
         try:
             logger_trade_gui.info("寮�濮嬩拱鍏ワ細code-{}".format(code))
             if win < 1:
-                win = self.get_available_buy_win()
-                if win < 1:
+                win = THSBuyWinManagerNew.get_distributed_code_win(code)  # self.get_available_buy_win()
+                if win is None or win < 1:
                     raise Exception("鏃犲彲鐢ㄧ殑浜ゆ槗绐楀彛")
             print("浣跨敤绐楀彛", win)
             t = time.time()
             print(t)
             start = int(round(t * 1000))
-            # 杈撳叆浠g爜
-            # 浠g爜杈撳叆妗嗙殑鎺т欢ID:0x00000408
-            hwnd1 = win32gui.GetDlgItem(win, 0x00000408)
-            # 鍚嶇О 鍚嶇О鐨勬帶浠禝D:0x0000040C
-            hwnd_name = win32gui.GetDlgItem(win, 0x0000040C)
-            self.input_number(hwnd1, code)
-            # 鏈�澶氱瓑寰�2s閽�
-            data_fill = False
-            for i in range(0, 500):
-                bufSize = win32gui.SendMessage(hwnd_name, win32con.WM_GETTEXTLENGTH, 0, 0) + 1
-                print(i, bufSize)
-                if bufSize > 1:
-                    data_fill = True
-                    break;
-                time.sleep(0.004)
-
-            if not data_fill:
-                raise Exception("浠g爜杈撳叆濉厖鍑洪敊")
-            time.sleep(0.001)
+            # # 杈撳叆浠g爜
+            # # 浠g爜杈撳叆妗嗙殑鎺т欢ID:0x00000408
+            # hwnd1 = win32gui.GetDlgItem(win, 0x00000408)
+            # # 鍚嶇О 鍚嶇О鐨勬帶浠禝D:0x0000040C
+            # hwnd_name = win32gui.GetDlgItem(win, 0x0000040C)
+            # self.input_number(hwnd1, code)
+            # # 鏈�澶氱瓑寰�2s閽�
+            # data_fill = False
+            # for i in range(0, 500):
+            #     bufSize = win32gui.SendMessage(hwnd_name, win32con.WM_GETTEXTLENGTH, 0, 0) + 1
+            #     print(i, bufSize)
+            #     if bufSize > 1:
+            #         data_fill = True
+            #         break;
+            #     time.sleep(0.004)
+            #
+            # if not data_fill:
+            #     raise Exception("浠g爜杈撳叆濉厖鍑洪敊")
+            # time.sleep(0.001)
             # 楠岃瘉娑ㄥ仠浠�
             limit_up_price_now = self.getLimitUpPrice(win)
+            trade_win = THSBuyWinManagerNew.get_trade_win(win)
+            # if not trade_win:
+            #     error = "浜ゆ槗瀛愮獥鍙f煡鎵惧け璐� {}".format(code)
+            #     raise Exception(error)
 
-            # 娴嬭瘯锛屾殏鏃朵笉楠岃瘉娑ㄥ仠浠�
+            # TODO 鏆傛椂涓嶉獙璇佹定鍋滀环
             if not global_util.TEST:
                 if abs(float(limit_up_price_now) - float(limit_up_price)) >= 0.01:
                     error = "娑ㄥ仠浠烽獙璇佸嚭閿� {}-{}".format(limit_up_price, limit_up_price_now)
@@ -258,6 +267,7 @@
             # win32gui.SendMessage(buy_hwnd, win32con.WM_LBUTTONUP, 0, 0);
 
             # 涔板叆 蹇嵎閿瓸
+            # 鑾峰彇浜ゆ槗win
             win32gui.PostMessage(win, win32con.WM_KEYDOWN, 66, 0);
 
             logger_trade_gui.info("鎵ц涔板叆缁撴潫锛歝ode-{} 鑰楁椂:{}".format(code, int(round(time.time() * 1000)) - start))
@@ -380,18 +390,432 @@
             self.input_number(code_input, "")
 
 
+class THSGuiUtil:
+    @classmethod
+    def getText(cls, hwnd):
+        bufSize = win32gui.SendMessage(hwnd, win32con.WM_GETTEXTLENGTH, 0, 0) + 1
+        buffer = array.array('b', b'\x00\x00' * bufSize)
+        win32gui.SendMessage(hwnd, win32con.WM_GETTEXT, bufSize, buffer)
+        text = win32gui.PyGetString(buffer.buffer_info()[0], bufSize - 1)
+        return text.replace("\x00", "").strip();
+
+    # 娣诲姞涓嬪崟绐楀彛
+    @classmethod
+    def add_buy_win(cls):
+        buy_wins = THSGuiTrade().get_buy_wins()
+        if len(buy_wins) < 1:
+            raise Exception("娌℃湁涔板叆绐楀彛")
+        if len(buy_wins) >= 10:
+            raise Exception("鏈�澶氬彧鑳芥坊鍔�10涓笅鍗曟")
+        # 澧炲姞绐楀彛鎸夐挳鐨処D锛�00005ED
+        win = buy_wins[-1]
+        add_btn = win32gui.GetDlgItem(win, 0x000005ED)
+        if add_btn <= 0:
+            raise Exception("娌℃湁鎵惧埌娣诲姞鎸夐挳")
+        try:
+            win32gui.SetForegroundWindow(win)
+        except:
+            pass
+        cls.click(add_btn)
+        for i in range(0, 30):
+            new_buy_wins = THSGuiTrade().get_buy_wins()
+            if len(new_buy_wins) - len(buy_wins) >= 1:
+                # 姹傚樊闆�
+                list_ = list(set(new_buy_wins).difference(set(buy_wins)))
+                return list_[0]
+            else:
+                time.sleep(0.01)
+        raise Exception("鏈坊鍔犳垚鍔�")
+
+    # 绐楀彛鏄惁瀛樺湪
+    @classmethod
+    def is_win_exist(cls, win):
+        try:
+            result = win32gui.IsWindowVisible(win)
+            if result:
+                return True
+            else:
+                return False
+        except:
+            return False
+
+    # 绐楀彛鏄惁姝e湪灞曠ず
+    @classmethod
+    def is_win_show(cls, win):
+        try:
+            result = win32gui.GetWindowRect(win)
+            if result[2] - result[0] > 0 and result[3] - result[1] > 0:
+                return True
+            else:
+                return False
+        except:
+            return False
+
+    @classmethod
+    def click(cls, control):
+        win32gui.SendMessage(control, win32con.WM_LBUTTONDOWN, 0, 0)
+        win32gui.SendMessage(control, win32con.WM_LBUTTONUP, 0, 0)
+
+    # 娓呴櫎涔板叆绐楀彛浠g爜
+    @classmethod
+    def clear_buy_window_code(cls, win):
+        if not cls.is_win_exist(win):
+            raise Exception("绐楀彛涓嶅瓨鍦�")
+
+        hwnd1 = win32gui.GetDlgItem(win, 0x00000408)
+        if hwnd1 <= 0:
+            raise Exception("缂栬緫鎺т欢娌℃壘鍒�")
+        THSGuiTrade().input_number(hwnd1, "")
+
+    # 璁剧疆涔板叆绐楀彛浠g爜
+    @classmethod
+    def set_buy_window_code(cls, win, code):
+        if not cls.is_win_exist(win):
+            raise Exception("绐楀彛涓嶅瓨鍦�")
+        try:
+            win32gui.SetForegroundWindow(win)
+        except:
+            pass
+        hwnd1 = win32gui.GetDlgItem(win, 0x00000408)
+        if hwnd1 <= 0:
+            raise Exception("缂栬緫鎺т欢娌℃壘鍒�")
+        THSGuiTrade().input_number(hwnd1, code)
+
+
+# 杩囨椂 鍚岃姳椤轰拱鍏ョ獥鍙g鐞嗗櫒
+class __THSBuyWinManager:
+    redisManager = redis_manager.RedisManager(2)
+
+    @classmethod
+    def __get_redis(cls):
+        return cls.redisManager.getRedis()
+
+    # 淇濆瓨绐楀彛浠g爜鍒嗛厤
+    @classmethod
+    def __save_code_win(cls, code, win):
+        key = "buywin_distribute-{}".format(code)
+        cls.__get_redis().setex(key, tool.get_expire(), win)
+
+    # 鑾峰彇绐楀彛鍒嗛厤鐨勪唬鐮�
+    @classmethod
+    def __get_code_win(cls, code):
+        key = "buywin_distribute-{}".format(code)
+        win = cls.__get_redis().get(key)
+        if win is not None:
+            return int(win)
+        return None
+
+    # 鍒犻櫎浠g爜绐楀彛鍒嗛厤
+    @classmethod
+    def __del_code_win(cls, code):
+        key = "buywin_distribute-{}".format(code)
+        cls.__get_redis().delete(key)
+
+    # 鑾峰彇鎵�鏈夊凡缁忓垎閰嶇獥鍙g殑浠g爜
+    @classmethod
+    def __get_distributed_win_codes(cls):
+        key = "buywin_distribute-*"
+        keys = cls.__get_redis().keys(key)
+        codes = []
+        for k in keys:
+            codes.append(k.replace("buywin_distribute-", ""))
+        return codes
+
+    # 鑾峰彇鍙敤鐨勭獥鍙�
+    @classmethod
+    def __get_available_win(cls):
+        # 鏄惁鏈夊彲鐢ㄧ殑杩樻湭鍒嗛厤鐨勭獥鍙�
+        key = "buywin_distribute-*"
+        keys = cls.__get_redis().keys(key)
+        win_list = THSGuiTrade().get_buy_wins()
+        if len(win_list) < 1:
+            raise Exception("蹇呴』瑕佹湁涓�涓拱鍏ョ獥鍙�")
+        win_set = set(win_list)
+        for k in keys:
+            win = int(cls.__get_redis().get(k))
+            if win in win_set:
+                win_set.remove(win)
+        if len(win_set) > 0:
+            return win_set.pop()
+
+        # 娌℃湁鍓╀綑鐨勭獥鍙o紝鏂板鍔犵獥鍙�
+        win = THSGuiUtil.add_buy_win()
+        if win:
+            return win
+        else:
+            raise Exception("鏂板绐楀彛澶辫触")
+
+    # 涓轰唬鐮佸垎閰嶇獥鍙�
+    @classmethod
+    def distribute_win_for_code(cls, code):
+        # 鑾峰彇鏄惁宸茬粡鍒嗛厤
+        win = cls.__get_code_win(code)
+        if win is not None:
+            # 宸茬粡鍒嗛厤鐨勭獥鍙f槸鍚︽湁鏁�
+            if THSGuiUtil.is_win_exist(win):
+                # 濉厖浠g爜
+                THSGuiUtil.set_buy_window_code(win, code)
+                return win
+
+        # 鑾峰彇鍙敤鐨勭獥鍙�
+        win = cls.__get_available_win()
+        if win is None:
+            raise Exception("绐楀彛宸茬粡鍒嗛厤瀹屾瘯锛屾棤鍙敤绐楀彛")
+        # 淇濆瓨绐楀彛鍒嗛厤淇℃伅
+        cls.__save_code_win(code, win)
+        THSGuiUtil.set_buy_window_code(win, code)
+        return win
+
+    # 鍒犻櫎浠g爜绐楀彛鍒嗛厤
+    @classmethod
+    def cancel_distribute_win_for_code(cls, code):
+        win = cls.__get_code_win(code)
+        if win is not None:
+            # 娓呴櫎浠g爜
+            THSGuiUtil.clear_buy_window_code(win)
+        cls.__del_code_win(code)
+
+    # 鑾峰彇浠g爜宸茬粡鍒嗛厤鐨勭獥鍙�
+    @classmethod
+    def get_distributed_code_win(cls, code):
+        win = cls.__get_code_win(code)
+        if not THSGuiUtil.is_win_exist(win):
+            # 鍒犻櫎涓嶅瓨鍦ㄧ殑绐楀彛
+            cls.__del_code_win(code)
+            return None
+        return win
+
+    @classmethod
+    def fill_codes(cls, codes):
+        codes_ = gpcode_manager.get_gp_list()
+        # 鍏堝垹闄ゆ病鏈夌殑浠g爜
+        old_codes = cls.__get_distributed_win_codes()
+        for code in old_codes:
+            if code not in codes_:
+                cls.cancel_distribute_win_for_code(code)
+        add_codes = codes[0:10]
+        del_codes = codes[10:]
+
+        for code in del_codes:
+            cls.cancel_distribute_win_for_code(code)
+
+        for code in add_codes:
+            # 宸茬粡鍔犲叆杩涘幓鐨勪笉鍋氭搷浣�
+            if code in old_codes:
+                continue
+            win = cls.distribute_win_for_code(code)
+            print("鍒嗛厤鐨勭獥鍙�:", win, THSGuiUtil.is_win_exist(win))
+
+
+# 鍚岃姳椤轰拱鍏ョ獥鍙g鐞嗗櫒
+class THSBuyWinManagerNew:
+    redisManager = redis_manager.RedisManager(2)
+
+    @classmethod
+    def get_buy_wins(cls):
+        buy_win_list = []
+        hWndList = []
+        main_hwnd = None
+        win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWndList)
+        for hwnd in hWndList:
+            if THSGuiUtil.getText(hwnd) == "涓撲笟鐗堜笅鍗�":
+                main_hwnd = hwnd
+                break
+        if not main_hwnd:
+            raise Exception("涓撲笟鐗堜笅鍗曟湭鎵撳紑")
+        child_win = None
+        for i in range(0, 20):
+            child_win = win32gui.FindWindowEx(main_hwnd, child_win, "#32770", None)
+            if not child_win:
+                break
+            if not win32gui.IsWindowVisible(child_win):
+                continue
+            temp = win32gui.FindWindowEx(child_win, None, "Button", "鎾ゅ崟")
+            if temp:
+                buy_win_list.append(child_win)
+        return buy_win_list
+
+    @classmethod
+    def get_trade_win(cls, win):
+        # 鑾峰彇浜ゆ槗绐楀彛
+        child_child_win = None
+        for j in range(0, 10):
+            child_child_win = win32gui.FindWindowEx(win, child_child_win, "#32770", None)
+            if not child_child_win:
+                break
+            temp = win32gui.FindWindowEx(child_child_win, None, "Edit", None)
+            if temp:
+                return child_child_win
+        return None
+
+    @classmethod
+    def __get_redis(cls):
+        return cls.redisManager.getRedis()
+
+    # 淇濆瓨绐楀彛浠g爜鍒嗛厤
+    @classmethod
+    def __save_code_win(cls, code, win):
+        key = "buywin_distribute-{}".format(code)
+        cls.__get_redis().setex(key, tool.get_expire(), win)
+
+    # 鑾峰彇绐楀彛鍒嗛厤鐨勪唬鐮�
+    @classmethod
+    def __get_code_win(cls, code):
+        key = "buywin_distribute-{}".format(code)
+        win = cls.__get_redis().get(key)
+        if win is not None:
+            return int(win)
+        return None
+
+    # 鍒犻櫎浠g爜绐楀彛鍒嗛厤
+    @classmethod
+    def __del_code_win(cls, code):
+        key = "buywin_distribute-{}".format(code)
+        cls.__get_redis().delete(key)
+
+    # 鑾峰彇鎵�鏈夊凡缁忓垎閰嶇獥鍙g殑浠g爜
+    @classmethod
+    def __get_distributed_win_codes(cls):
+        key = "buywin_distribute-*"
+        keys = cls.__get_redis().keys(key)
+        codes = []
+        for k in keys:
+            codes.append(k.replace("buywin_distribute-", ""))
+        return codes
+
+    # 鑾峰彇鍙敤鐨勭獥鍙�
+    @classmethod
+    def __get_available_win(cls):
+        # 鏄惁鏈夊彲鐢ㄧ殑杩樻湭鍒嗛厤鐨勭獥鍙�
+        key = "buywin_distribute-*"
+        keys = cls.__get_redis().keys(key)
+        win_list = cls.get_buy_wins()
+        if len(win_list) < 1:
+            raise Exception("蹇呴』瑕佹湁涓�涓拱鍏ョ獥鍙�")
+        win_set = set(win_list)
+        for k in keys:
+            win = int(cls.__get_redis().get(k))
+            if win in win_set:
+                win_set.remove(win)
+        if len(win_set) > 0:
+            return win_set.pop()
+
+        # 娌℃湁鍓╀綑鐨勭獥鍙o紝鏂板鍔犵獥鍙�
+        raise Exception("娌℃湁鍓╀綑绐楀彛")
+
+    # 涓轰唬鐮佸垎閰嶇獥鍙�
+    @classmethod
+    def distribute_win_for_code(cls, code):
+        # 鑾峰彇鏄惁宸茬粡鍒嗛厤
+        win = cls.__get_code_win(code)
+        if win is not None:
+            # 宸茬粡鍒嗛厤鐨勭獥鍙f槸鍚︽湁鏁�
+            if THSGuiUtil.is_win_exist(win):
+                # 濉厖浠g爜
+                THSGuiUtil.set_buy_window_code(cls.get_trade_win(win), code)
+                return win
+
+        # 鑾峰彇鍙敤鐨勭獥鍙�
+        win = cls.__get_available_win()
+        if win is None:
+            raise Exception("绐楀彛宸茬粡鍒嗛厤瀹屾瘯锛屾棤鍙敤绐楀彛")
+        # 淇濆瓨绐楀彛鍒嗛厤淇℃伅
+        cls.__save_code_win(code, win)
+        THSGuiUtil.set_buy_window_code(cls.get_trade_win(win), code)
+        return win
+
+    # 鍒犻櫎浠g爜绐楀彛鍒嗛厤
+    @classmethod
+    def cancel_distribute_win_for_code(cls, code):
+        win = cls.__get_code_win(code)
+        if win is not None:
+            # 娓呴櫎浠g爜
+            try:
+                THSGuiUtil.clear_buy_window_code(win)
+            except:
+                pass
+        cls.__del_code_win(code)
+
+    # 鑾峰彇浠g爜宸茬粡鍒嗛厤鐨勭獥鍙�
+    @classmethod
+    def get_distributed_code_win(cls, code):
+        win = cls.__get_code_win(code)
+        if not THSGuiUtil.is_win_exist(win):
+            # 鍒犻櫎涓嶅瓨鍦ㄧ殑绐楀彛
+            cls.__del_code_win(code)
+            return None
+        return win
+
+    # 鑾峰彇浠g爜鍚嶇О
+    @classmethod
+    def __get_code_name(cls, win):
+        trade_win = cls.get_trade_win(win)
+        if trade_win is None:
+            return None
+        code_name_win = win32gui.GetDlgItem(trade_win, 0x000005C2)
+        return THSGuiUtil.getText(code_name_win)
+
+    @classmethod
+    def fill_codes(cls, codes):
+        name_codes = gpcode_manager.get_name_codes()
+        codes_ = gpcode_manager.get_gp_list()
+        # 鍏堝垹闄ゆ病鏈夌殑浠g爜
+        old_codes = cls.__get_distributed_win_codes()
+        for code in old_codes:
+            if code not in codes_:
+                cls.cancel_distribute_win_for_code(code)
+        add_codes = codes[0:10]
+        del_codes = codes[10:]
+
+        for code in del_codes:
+            cls.cancel_distribute_win_for_code(code)
+
+        for code in add_codes:
+            # 宸茬粡鍔犲叆杩涘幓鐨勪笉鍋氭搷浣�
+            if code in old_codes:
+                # 鏍¢獙浠g爜鏄惁濉厖瀵�
+                win = cls.__get_code_win(code)
+                if not THSGuiUtil.is_win_exist(win):
+                    cls.cancel_distribute_win_for_code(code)
+                else:
+                    code_name = cls.__get_code_name(win)
+                    if name_codes.get(code_name) != code:
+                        cls.cancel_distribute_win_for_code(code)
+                continue
+            win = cls.distribute_win_for_code(code)
+            print("鍒嗛厤鐨勭獥鍙�:", win, THSGuiUtil.is_win_exist(win))
+
+
+class GUITest:
+    def test_distribute(self):
+        codes = ["300396", "688656", "688029", "688787", "688016", "002659", "002777", "603318", "000333", "003004",
+                 "002882", "300014", "688981", "002531"]
+
+        for i in range(10, len(codes)):
+            THSBuyWinManagerNew.cancel_distribute_win_for_code(codes[i])
+
+        for i in range(0, 10):
+            win = THSBuyWinManagerNew.distribute_win_for_code(codes[i])
+            time.sleep(1)
+            print("鍒嗛厤鐨勭獥鍙�:", win, THSGuiUtil.is_win_exist(win))
+
+        random.shuffle(codes)
+        print(codes[0:10])
+        for i in range(10, len(codes)):
+            THSBuyWinManagerNew.cancel_distribute_win_for_code(codes[i])
+
+        for i in range(0, 10):
+            win = THSBuyWinManagerNew.distribute_win_for_code(codes[i])
+            time.sleep(1)
+            print("鍒嗛厤鐨勭獥鍙�:", win, THSGuiUtil.is_win_exist(win))
+
+        # THSBuyWinManager.cancel_distribute_win_for_code("600125")
+
+
 if __name__ == '__main__':
-    try:
-        # THSGuiTrade.checkEnv();
-        # print("鐜姝e父")
-        trade = THSGuiTrade();
-        print(id(trade))
-        # win = trade.get_available_buy_win()
-        # if win < 1:
-        #     raise Exception("鏃犲彲鐢ㄧ殑浜ゆ槗绐楀彛")
-        # result = trade.buy("002564", "7.26")
-        # # print("浜ゆ槗鎴愬姛")
-        # time.sleep(0.2)
-        trade.cancel_buy("000716")
-    except Exception as e:
-        print(e)
+    THSGuiTrade().buy("002853", "18.98", THSBuyWinManagerNew.get_buy_wins()[5])
+    # GUITest().test_distribute()
+    # try:
+    #     THSGuiUtil.set_buy_window_code(0x000112D0, "000333")
+    # except Exception as e:
+    #     print(e)

--
Gitblit v1.8.0