From 45b79f58ec7e8aa82bc086f636d89a5ec253b0e7 Mon Sep 17 00:00:00 2001 From: Administrator <admin@example.com> Date: 星期五, 25 八月 2023 12:53:15 +0800 Subject: [PATCH] S撤改进 --- trade/huaxin/trade_server.py | 10 + l2/cancel_buy_strategy.py | 251 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 170 insertions(+), 91 deletions(-) diff --git a/l2/cancel_buy_strategy.py b/l2/cancel_buy_strategy.py index 6c92609..6edd8e4 100644 --- a/l2/cancel_buy_strategy.py +++ b/l2/cancel_buy_strategy.py @@ -33,6 +33,8 @@ __s_cancel_real_place_order_index_cache = {} # 鎴愪氦浣嶇疆 __s_cancel_transaction_index_cache = {} + # H鎾ゆ槸鍚﹀垵濮嬪寲鏁版嵁锛屽綋鐪熷疄涓嬪崟浣嶇疆涓庢垚浜や綅鍒版潵鏃舵墠杩涜璧嬪�� + __s_cancel_inited_data = {} __instance = None @@ -88,6 +90,11 @@ return cache_result[1] return -1, 0, 0 + def __del_compute_data_cache(self, code): + CodeDataCacheUtil.clear_cache(self.__s_big_num_cancel_compute_data_cache, code) + key = "s_big_num_cancel_compute_data-{}".format(code) + RedisUtils.delete_async(self.__db, key) + # 璁剧疆鐪熷疄涓嬪崟浣嶇疆 def __save_real_place_order_index(self, code, index): CodeDataCacheUtil.set_cache(self.__s_cancel_real_place_order_index_cache, code, index) @@ -117,6 +124,7 @@ CodeDataCacheUtil.clear_cache(self.__s_big_num_cancel_compute_data_cache, code) CodeDataCacheUtil.clear_cache(self.__s_cancel_real_place_order_index_cache, code) CodeDataCacheUtil.clear_cache(self.__s_cancel_transaction_index_cache, code) + CodeDataCacheUtil.clear_cache(self.__s_cancel_inited_data, code) ks = ["s_big_num_cancel_compute_data-{}".format(code), "s_cancel_real_place_order_index-{}".format(code)] for key in ks: RedisUtils.delete_async(self.__db, key) @@ -124,6 +132,10 @@ # 璁剧疆鐪熷疄涓嬪崟浣嶇疆 def set_real_place_order_index(self, code, index): self.__save_real_place_order_index(code, index) + + # 璁剧疆鎴愪氦杩涘害浣� + def set_transaction_index(self, code, index): + self.__s_cancel_transaction_index_cache[code] = index def clear_data(self): ks = ["s_big_num_cancel_compute_data-*", "s_cancel_real_place_order_index-*"] @@ -191,105 +203,165 @@ return False, None l2_log.cancel_debug(code, "S绾ф槸鍚﹂渶瑕佹挙鍗曪紝鏁版嵁鑼冨洿锛歿}-{} ", start_index, end_index) l2_log.s_cancel_debug(code, "S绾ф槸鍚﹂渶瑕佹挙鍗曪紝鏁版嵁鑼冨洿锛歿}-{} ", start_index, end_index) + real_place_order_index = self.__s_cancel_real_place_order_index_cache.get(code) + transaction_index = self.__s_cancel_transaction_index_cache.get(code) - if tool.trade_time_sub(total_data[end_index]["val"]["time"], - total_data[buy_exec_index]["val"]["time"]) > constant.S_CANCEL_EXPIRE_TIME: - # 缁撴潫浣嶇疆瓒呰繃浜嗘墽琛屼綅缃�30s锛岄渶瑕侀噸鏂扮‘璁ょ粨鏉熶綅缃� - for i in range(end_index, start_index - 1, -1): - if total_data[end_index]["val"]["time"] != total_data[i]["val"]["time"]: - end_index = i - break - - # 鑾峰彇澶勭悊杩涘害 - process_index_old, buy_num, cancel_num = self.__get_compute_data_cache(code) - - # 濡傛灉start_index涓巄uy_single_index鐩稿悓锛屽嵆鏄笅鍗曞悗鐨勭涓�娆¤绠� - # 闇�瑕佹煡璇拱鍏ヤ俊鍙蜂箣鍓嶇殑鍚�1s鏄惁鏈夋定鍋滄挙鐨勬暟鎹� - process_index = process_index_old - - if process_index_old == -1: - # 绗�1娆¤绠楅渶瑕佽绠椾拱鍏ヤ俊鍙�-鎵ц浣嶇殑鍑�鍊� - left_big_num = self.__compute_left_big_num(code, buy_single_index, buy_single_index, buy_exec_index, - total_data, volume_rate_index) - buy_num += left_big_num - # 璁剧疆涔板叆淇″彿-涔板叆鎵ц浣嶇殑鏁版嵁涓嶉渶瑕佸鐞� - process_index = buy_exec_index - # 寮哄埗鍥哄畾涓�1s - range_seconds = 1 # self.__sCancelParamsManager.get_buy_time_range(buy_volume_rate_index) - # 鑾峰彇鐪熷疄涓嬪崟浣嶇疆 - place_order_index = self.__get_real_place_order_index_cache(code) - - cancel_rate_threshold = self.__sCancelParamsManager.get_cancel_rate(volume_rate_index) - try: - for i in range(start_index, end_index + 1): - data = total_data[i] - val = data["val"] - process_index = i - if process_index_old >= i: - # 宸茬粡澶勭悊杩囩殑鏁版嵁涓嶉渶瑕佸鐞� - continue - if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100: - continue - - if L2DataUtil.is_limit_up_price_buy(val): - - if place_order_index is not None and place_order_index < data["index"]: - # 涓嶈兘姣斾笅鍗曚綅缃悗 + if real_place_order_index and transaction_index: + # S鎾よ绠楄寖鍥达細鎴愪氦浣�-鐪熷疄涓嬪崟浣� + if not self.__s_cancel_inited_data.get(code): + l2_log.s_cancel_debug(code, "S鎾ゅ垵濮嬪寲锛屾垚浜や綅锛歿} 涓嬪崟浣嶏細{}", transaction_index, real_place_order_index) + # 娓呴櫎涔嬪墠鐨勮绠楁暟鎹� + self.__s_cancel_inited_data[code] = True + self.__del_compute_data_cache(code) + # 璁$畻鏈挙鍗曠殑璁㈠崟鎵嬫暟 + left_big_num = 0 + for i in range(transaction_index + 1, real_place_order_index): + data = total_data[code] + val = data["val"] + if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100: continue - # 濡傛灉鍦ㄥ泭鎷椂闂磋寖鍥村唴灏卞彲浠ヨ绠椾拱 - if tool.trade_time_sub(val["time"], buy_exec_time) <= range_seconds: - buy_num += data["re"] * int(val["num"]) - elif L2DataUtil.is_limit_up_price_buy_cancel(val): - # 鏌ヨ涔板叆浣嶇疆 - buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data(code, data, - local_today_num_operate_map.get( - code)) - if buy_index is not None and buy_single_index <= buy_index: - if place_order_index and place_order_index >= buy_index: + # 鑾峰彇 + if L2DataUtil.is_limit_up_price_buy(val): + left_big_num += val["num"] * data["re"] + elif L2DataUtil.is_limit_up_price_buy_cancel(val): + # 鏌ヨ涔板叆浣嶇疆 + buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data(code, data, + local_today_num_operate_map.get( + code)) + if buy_index is not None and transaction_index + 1 <= buy_index <= real_place_order_index and i < start_index: + left_big_num -= val["num"] * data["re"] + l2_log.s_cancel_debug(code, "S鎾ゅ垵濮嬪寲缁撴灉锛宭eft_big_num锛歿}", left_big_num) + self.__save_compute_data(code, real_place_order_index, left_big_num, 0) + # 淇濆瓨淇℃伅 + process_index_old, buy_num, cancel_num = self.__get_compute_data_cache(code) + process_index = process_index_old + cancel_rate_threshold = self.__sCancelParamsManager.get_cancel_rate(volume_rate_index) + try: + for i in range(start_index, end_index + 1): + data = total_data[i] + val = data["val"] + process_index = i + if process_index_old >= i: + # 宸茬粡澶勭悊杩囩殑鏁版嵁涓嶉渶瑕佸鐞� + continue + if L2DataUtil.is_limit_up_price_buy_cancel(val): + if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100: + continue + # 鏌ヨ涔板叆浣嶇疆 + buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data(code, data, + local_today_num_operate_map.get( + code)) + if buy_index is not None and transaction_index < buy_index < real_place_order_index: cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"]) - # 涔板叆鏃堕棿鍦ㄥ泭鎷寖鍥村唴 - elif tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds), - total_data[buy_index]["val"]["time"]) >= 0: - cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"]) - elif buy_index is None: - # 鏈夐儴鍒嗘挙閿�浠庤�屽鑷寸殑鏃犳硶婧簮锛岃繖鏃跺氨闇�瑕佸垽鏂浼颁拱鍏ユ椂闂存槸鍚﹀湪a_start_index鍒癮_end_index鐨勬椂闂村尯闂� - min_space, max_space = l2_data_util.compute_time_space_as_second(val["cancelTime"], - val["cancelTimeUnit"]) - # 鍙垽鏂璖绾ф挙閿�,鍙湁s绾ф挙閿�鎵嶆湁鍙兘鐩哥瓑 - if max_space - min_space <= 1: - buy_time = tool.trade_time_add_second(val["time"], 0 - min_space) - if int(total_data[buy_single_index]["val"]["time"].replace(":", "")) <= int( - buy_time.replace(":", "")): - # 涔板叆鏃堕棿鍦ㄥ泭鎷寖鍥村唴 - if tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds), - buy_time) >= 0: - cancel_num += data["re"] * int(val["num"]) + if need_cancel: + rate__ = round(cancel_num / max(buy_num, 1), 2) + if rate__ > cancel_rate_threshold: + return True, total_data[i] + finally: + # 淇濆瓨澶勭悊杩涘害涓庢暟鎹� + self.__save_compute_data(code, process_index, buy_num, cancel_num) + else: + # S娴嬭绠椾綅缃负淇″彿璧峰浣嶇疆鎵ц浣�1s涔嬪悗 + if tool.trade_time_sub(total_data[end_index]["val"]["time"], + total_data[buy_exec_index]["val"]["time"]) > constant.S_CANCEL_EXPIRE_TIME: + # 缁撴潫浣嶇疆瓒呰繃浜嗘墽琛屼綅缃�60s锛岄渶瑕侀噸鏂扮‘璁ょ粨鏉熶綅缃� + for i in range(end_index, start_index - 1, -1): + if total_data[end_index]["val"]["time"] != total_data[i]["val"]["time"]: + end_index = i + break + # 鑾峰彇澶勭悊杩涘害 + process_index_old, buy_num, cancel_num = self.__get_compute_data_cache(code) - # 淇濆瓨鏁版嵁 - if need_cancel: - rate__ = round(cancel_num / max(buy_num, 1), 2) - if rate__ > cancel_rate_threshold: - l2_log.trade_record(code, "S鎾よ寖鍥�", "'start_index':{} , 'end_index':{} ,'range_seconds':{}", - buy_single_index, - i, - range_seconds) - l2_log.trade_record(code, "S鎾�", "'index':{} , 'rate':{} , 'target_rate':{}", i, rate__, - cancel_rate_threshold) - return True, total_data[i] - finally: + # 濡傛灉start_index涓巄uy_single_index鐩稿悓锛屽嵆鏄笅鍗曞悗鐨勭涓�娆¤绠� + # 闇�瑕佹煡璇拱鍏ヤ俊鍙蜂箣鍓嶇殑鍚�1s鏄惁鏈夋定鍋滄挙鐨勬暟鎹� + process_index = process_index_old - l2_log.cancel_debug(code, "S绾уぇ鍗� 鑼冨洿锛歿}-{} 鍙栨秷璁$畻缁撴灉:{}/{},姣斾緥锛歿} 鐩爣姣斾緥:{} 璁$畻鏃堕棿鑼冨洿锛歿}", start_index, end_index, - cancel_num, - buy_num, round(cancel_num / max(buy_num, 1), 2), cancel_rate_threshold, range_seconds) + if process_index_old == -1: + # 绗�1娆¤绠楅渶瑕佽绠椾拱鍏ヤ俊鍙�-鎵ц浣嶇殑鍑�鍊� + left_big_num = self.__compute_left_big_num(code, buy_single_index, buy_single_index, buy_exec_index, + total_data, volume_rate_index) + buy_num += left_big_num + # 璁剧疆涔板叆淇″彿-涔板叆鎵ц浣嶇殑鏁版嵁涓嶉渶瑕佸鐞� + process_index = buy_exec_index + # 寮哄埗鍥哄畾涓�1s + range_seconds = 1 # self.__sCancelParamsManager.get_buy_time_range(buy_volume_rate_index) + # 鑾峰彇鐪熷疄涓嬪崟浣嶇疆 + place_order_index = self.__get_real_place_order_index_cache(code) - # 淇濆瓨澶勭悊杩涘害涓庢暟鎹� - self.__save_compute_data(code, process_index, buy_num, cancel_num) + cancel_rate_threshold = self.__sCancelParamsManager.get_cancel_rate(volume_rate_index) + try: + for i in range(start_index, end_index + 1): + data = total_data[i] + val = data["val"] + process_index = i + if process_index_old >= i: + # 宸茬粡澶勭悊杩囩殑鏁版嵁涓嶉渶瑕佸鐞� + continue + if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100: + continue + + if L2DataUtil.is_limit_up_price_buy(val): + + if place_order_index is not None and place_order_index < data["index"]: + # 涓嶈兘姣斾笅鍗曚綅缃悗 + continue + # 濡傛灉鍦ㄥ泭鎷椂闂磋寖鍥村唴灏卞彲浠ヨ绠椾拱 + if tool.trade_time_sub(val["time"], buy_exec_time) <= range_seconds: + buy_num += data["re"] * int(val["num"]) + elif L2DataUtil.is_limit_up_price_buy_cancel(val): + # 鏌ヨ涔板叆浣嶇疆 + buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data(code, data, + local_today_num_operate_map.get( + code)) + if buy_index is not None and buy_single_index <= buy_index: + if place_order_index and place_order_index >= buy_index: + cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"]) + # 涔板叆鏃堕棿鍦ㄥ泭鎷寖鍥村唴 + elif tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds), + total_data[buy_index]["val"]["time"]) >= 0: + cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"]) + elif buy_index is None: + # 鏈夐儴鍒嗘挙閿�浠庤�屽鑷寸殑鏃犳硶婧簮锛岃繖鏃跺氨闇�瑕佸垽鏂浼颁拱鍏ユ椂闂存槸鍚﹀湪a_start_index鍒癮_end_index鐨勬椂闂村尯闂� + min_space, max_space = l2_data_util.compute_time_space_as_second(val["cancelTime"], + val["cancelTimeUnit"]) + # 鍙垽鏂璖绾ф挙閿�,鍙湁s绾ф挙閿�鎵嶆湁鍙兘鐩哥瓑 + if max_space - min_space <= 1: + buy_time = tool.trade_time_add_second(val["time"], 0 - min_space) + if int(total_data[buy_single_index]["val"]["time"].replace(":", "")) <= int( + buy_time.replace(":", "")): + # 涔板叆鏃堕棿鍦ㄥ泭鎷寖鍥村唴 + if tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds), + buy_time) >= 0: + cancel_num += data["re"] * int(val["num"]) + + # 淇濆瓨鏁版嵁 + if need_cancel: + rate__ = round(cancel_num / max(buy_num, 1), 2) + if rate__ > cancel_rate_threshold: + l2_log.trade_record(code, "S鎾よ寖鍥�", + "'start_index':{} , 'end_index':{} ,'range_seconds':{}", + buy_single_index, + i, + range_seconds) + l2_log.trade_record(code, "S鎾�", "'index':{} , 'rate':{} , 'target_rate':{}", i, rate__, + cancel_rate_threshold) + return True, total_data[i] + finally: + + l2_log.cancel_debug(code, "S绾уぇ鍗� 鑼冨洿锛歿}-{} 鍙栨秷璁$畻缁撴灉:{}/{},姣斾緥锛歿} 鐩爣姣斾緥:{} 璁$畻鏃堕棿鑼冨洿锛歿}", start_index, end_index, + cancel_num, + buy_num, round(cancel_num / max(buy_num, 1), 2), cancel_rate_threshold, + range_seconds) + + # 淇濆瓨澶勭悊杩涘害涓庢暟鎹� + self.__save_compute_data(code, process_index, buy_num, cancel_num) return False, None # 鎾ゅ崟鎴愬姛 def cancel_success(self, code): self.__clear_data(code) - #涓嬪崟鎴愬姛 + + # 涓嬪崟鎴愬姛 def place_order_success(self, code): self.__clear_data(code) @@ -1113,7 +1185,8 @@ data = total_datas[index] if L2DataUtil.is_limit_up_price_buy(data["val"]): # 鑾峰彇鏄惁鍦ㄤ拱鍏ユ墽琛屼俊鍙峰懆鍥�2s - left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count(code, index, total_datas, + left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count(code, index, + total_datas, local_operate_map) if left_count > 0: buy_nums += left_count * data["val"]["num"] diff --git a/trade/huaxin/trade_server.py b/trade/huaxin/trade_server.py index 728fecc..315e5a8 100644 --- a/trade/huaxin/trade_server.py +++ b/trade/huaxin/trade_server.py @@ -25,7 +25,7 @@ from huaxin_client.client_network import SendResponseSkManager from l2 import l2_data_manager_new, l2_log, code_price_manager, l2_data_util, l2_data_manager, transaction_progress from l2.cancel_buy_strategy import HourCancelBigNumComputer, LCancelBigNumComputer, DCancelBigNumComputer, \ - GCancelBigNumComputer + GCancelBigNumComputer, SecondCancelBigNumComputer from l2.huaxin import huaxin_target_codes_manager from l2.huaxin.huaxin_target_codes_manager import HuaXinL1TargetCodesManager from l2.l2_data_manager_new import L2TradeDataProcessor @@ -253,7 +253,13 @@ buy_progress_index, total_datas, num_operate_map) - dask.compute(f1, f2, f3) + + f4 = dask.delayed( + SecondCancelBigNumComputer().set_transaction_index)( + code, + buy_progress_index) + + dask.compute(f1, f2, f3, f4) except Exception as e: hx_logger_l2_transaction.exception(e) finally: -- Gitblit v1.8.0