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