From e1788016750ad6ec1dfc28a4e6948ecaf5b326e4 Mon Sep 17 00:00:00 2001 From: Administrator <admin@example.com> Date: 星期四, 22 二月 2024 16:03:30 +0800 Subject: [PATCH] 影子单价格修改/消息日志添加/成交太快撤单 --- huaxin_client/l2_client.py | 8 +- trade/current_price_process_manager.py | 7 + code_attribute/code_nature_analyse.py | 2 l2/l2_transaction_data_processor.py | 3 trade/huaxin/huaxin_trade_server.py | 55 ++++++++----- huaxin_client/trade_client.py | 2 utils/tool.py | 9 +- huaxin_client/l2_data_manager.py | 15 +-- msg/buy_order_msg_manager.py | 15 +++ l2/cancel_buy_strategy.py | 64 +++++++++++++-- l2/l2_data_manager_new.py | 2 trade/huaxin/huaxin_trade_api_server.py | 5 12 files changed, 133 insertions(+), 54 deletions(-) diff --git a/code_attribute/code_nature_analyse.py b/code_attribute/code_nature_analyse.py index a0a3c5f..dc6e69f 100644 --- a/code_attribute/code_nature_analyse.py +++ b/code_attribute/code_nature_analyse.py @@ -400,7 +400,7 @@ # return False rate = (float(limit_up_price) - min_price_info[1]["close"]) / min_price_info[1]["close"] print(rate) - if rate >= 0.28: + if rate >= 0.319: return True, rate return False, rate diff --git a/huaxin_client/l2_client.py b/huaxin_client/l2_client.py index e2c757b..4672fcd 100644 --- a/huaxin_client/l2_client.py +++ b/huaxin_client/l2_client.py @@ -134,8 +134,8 @@ for d in codes_data: code = d[0] codes.add(code) - self.codes_volume_and_price_dict[code] = (d[1], d[2]) - self.l2_data_upload_manager.set_order_fileter_condition(code, d[1], float(d[2])) + self.codes_volume_and_price_dict[code] = (d[1], d[2], d[3]) + self.l2_data_upload_manager.set_order_fileter_condition(code, d[1], float(d[2]), d[3]) add_codes = codes - self.subscripted_codes del_codes = self.subscripted_codes - codes print("add del codes", add_codes, del_codes) @@ -191,8 +191,8 @@ # self.special_code_volume_for_order_dict[code] = (volume, time.time() + 3) d = self.codes_volume_and_price_dict.get(code) if d: - min_volume, limit_up_price = d[0], d[1] - self.l2_data_upload_manager.set_order_fileter_condition(code, min_volume, limit_up_price, + min_volume, limit_up_price, special_price = d[0], d[1], d[2] + self.l2_data_upload_manager.set_order_fileter_condition(code, min_volume, limit_up_price,special_price, {volume, constant.SHADOW_ORDER_VOLUME}, time.time() + 3) huaxin_l2_log.info(logger_local_huaxin_l2_subscript, f"璁剧疆涓嬪崟閲忕洃鍚細{code}-{volume}") diff --git a/huaxin_client/l2_data_manager.py b/huaxin_client/l2_data_manager.py index 862f347..b8c91e3 100644 --- a/huaxin_client/l2_data_manager.py +++ b/huaxin_client/l2_data_manager.py @@ -43,29 +43,30 @@ self.l2_transaction_codes = set() # 璁剧疆璁㈠崟杩囨护鏉′欢 - def set_order_fileter_condition(self, code, min_volume, limit_up_price, special_volumes=None, + # special_price:杩囨护鐨�1鎵嬬殑浠锋牸 + def set_order_fileter_condition(self, code, min_volume, limit_up_price, special_price, special_volumes=None, special_volumes_expire_time=None): if special_volumes is None: special_volumes = set() if code in self.filter_order_condition_dict and not special_volumes and not special_volumes_expire_time: - self.filter_order_condition_dict[code][0] = (min_volume, limit_up_price) + self.filter_order_condition_dict[code][0] = (min_volume, limit_up_price, special_price) huaxin_l2_log.info(logger_local_huaxin_l2_subscript, f"({code})甯歌杩囨护鏉′欢璁剧疆锛歿self.filter_order_condition_dict[code]}") else: - self.filter_order_condition_dict[code] = [(min_volume, limit_up_price), special_volumes, + self.filter_order_condition_dict[code] = [(min_volume, limit_up_price, special_price), special_volumes, special_volumes_expire_time] huaxin_l2_log.info(logger_local_huaxin_l2_subscript, f"({code})涓嬪崟鍚庤繃婊ゆ潯浠惰缃細{self.filter_order_condition_dict[code]}") # 杩囨护璁㈠崟 def __filter_order(self, item): - # if item[2] == 100 and item[3] == '1': - # # 涓嶈繃婊や拱1鎵� - # return item filter_condition = self.filter_order_condition_dict.get(item[0]) if filter_condition: # item[2]涓洪噺 if item[2] >= filter_condition[0][0]: + return item + # 1鎵嬬殑涔板崟婊¤冻浠锋牸 + if item[2] == 100 and item[3] == '1' and abs(filter_condition[0][2] - item[1]) < 0.001: return item if filter_condition[1] and item[2] in filter_condition[1]: if filter_condition[2] and time.time() > filter_condition[2]: @@ -73,8 +74,6 @@ filter_condition[1] = set() filter_condition[2] = None return None - return item - elif item[2] == 100 and item[3] == '1': return item return None return item diff --git a/huaxin_client/trade_client.py b/huaxin_client/trade_client.py index f0946de..08b4443 100644 --- a/huaxin_client/trade_client.py +++ b/huaxin_client/trade_client.py @@ -892,7 +892,7 @@ def OnTrade(self, client_id, request_id, sk, type_, data): if type_ == 1: async_log_util.info(logger_local_huaxin_trade_debug, - f"\n---------------------\n璇锋眰涓嬪崟锛歝lient_id-{client_id} request_id-{request_id}") + f"\n---------------------\n璇锋眰涓嬪崟锛歝lient_id-{client_id} request_id-{request_id} data:{data}") # 涓嬪崟 # 1-涔� 2-鍗� direction = data["direction"] diff --git a/l2/cancel_buy_strategy.py b/l2/cancel_buy_strategy.py index a839801..5adaf81 100644 --- a/l2/cancel_buy_strategy.py +++ b/l2/cancel_buy_strategy.py @@ -39,7 +39,7 @@ is_default=is_default) HourCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index) GCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index, is_default) - FCancelBigNumComputer().set_real_order_index(code, index) + FCancelBigNumComputer().set_real_order_index(code, index, is_default) class SecondCancelBigNumComputer: @@ -1629,7 +1629,8 @@ for k in keys: code = k.split("-")[-1] val = RedisUtils.get(__redis, k) - CodeDataCacheUtil.set_cache(cls.__real_order_index_cache, code, int(val)) + val = json.loads(val) + CodeDataCacheUtil.set_cache(cls.__real_order_index_cache, code, val) finally: RedisUtils.realse(__redis) @@ -1637,9 +1638,9 @@ def __get_redis(cls): return cls.__redis_manager.getRedis() - def __set_real_order_index(self, code, index): - CodeDataCacheUtil.set_cache(self.__real_order_index_cache, code, index) - RedisUtils.setex_async(self.__db, f"f_cancel_real_order_index-{code}", tool.get_expire(), f"{index}") + def __set_real_order_index(self, code, index, is_default): + CodeDataCacheUtil.set_cache(self.__real_order_index_cache, code, (index, is_default)) + RedisUtils.setex_async(self.__db, f"f_cancel_real_order_index-{code}", tool.get_expire(), json.dumps((index, is_default))) def __del_real_order_index(self, code): CodeDataCacheUtil.clear_cache(self.__real_order_index_cache, code) @@ -1648,7 +1649,8 @@ def __get_real_order_index(self, code): val = RedisUtils.get(self.__db, f"f_cancel_real_order_index-{code}") if val: - return int(val) + val = json.loads(val) + return val[0] return None def __get_real_order_index_cache(self, code): @@ -1702,9 +1704,9 @@ else: return False, "蹇�熸垚浜や簡50%浠ヤ笅" - # 璁剧疆鐪熷疄鐨勪笅鍗曚綅缃�,杩斿洖鏄惁闇�瑕佹挙鍗� - def set_real_order_index(self, code, index): - self.__set_real_order_index(code, index) + # 璁剧疆鐪熷疄鐨勪笅鍗曚綅缃� + def set_real_order_index(self, code, index, is_default): + self.__set_real_order_index(code, index, is_default) def place_order_success(self, code): self.clear(code) @@ -1712,6 +1714,50 @@ def cancel_success(self, code): self.clear(code) + # 鏄惁鎴愪氦澶揩闇�瑕佹挙鍗� + def need_cancel_for_deal_fast(self, code, trade_index): + # 鍒ゆ柇鏄惁鍏锋湁鐪熷疄鐨勪笅鍗曚綅缃� + real_order_index_info = self.__get_real_order_index_cache(code) + if not real_order_index_info: + return False, "娌℃壘鍒扮湡瀹炰笅鍗曚綅" + if real_order_index_info[1]: + return False, "鐪熷疄涓嬪崟浣嶄负榛樿" + if real_order_index_info[0] <= trade_index: + return False, "鐪熷疄涓嬪崟浣嶅湪鎴愪氦浣嶄箣鍓�" + real_order_index = real_order_index_info[0] + # 缁熻鏈挙璁㈠崟鐨勬暟閲忎笌閲戦 + total_datas = local_today_datas.get(code) + # 鏄惁鏄笅鍗�5鍒嗛挓鍐� + if tool.trade_time_sub(tool.get_now_time_str(),total_datas[real_order_index]['val']['time']) > 5*60: + return False, "涓嬪崟瓒呰繃5鍒嗛挓" + + total_left_count = 0 + total_left_num = 0 + for i in range(trade_index + 1, real_order_index_info[0]): + data = total_datas[i] + val = data["val"] + if not L2DataUtil.is_limit_up_price_buy(val): + continue + if val["num"] * float(val["price"]) < 5000: + continue + left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, + i, + total_datas, + local_today_canceled_buyno_map.get( + code)) + if left_count > 0: + total_left_count += left_count + total_left_num += val["num"] * left_count + if total_left_count < 10: + return True, f"鍓╀綑绗旀暟涓嶈冻({total_left_count})锛屾垚浜よ繘搴︼細{trade_index},鐪熷疄涓嬪崟浣嶇疆锛歿real_order_index}" + limit_up_price = gpcode_manager.get_limit_up_price(code) + if limit_up_price and total_left_num * float(limit_up_price) < 1000*100: + return True, f"鍓╀綑閲戦涓嶈冻({round(total_left_num * float(limit_up_price)*100)})锛屾垚浜よ繘搴︼細{trade_index},鐪熷疄涓嬪崟浣嶇疆锛歿real_order_index}" + return False, "涓嶆弧瓒虫挙鍗曟潯浠�" + + + + # ---------------------------------G鎾�------------------------------- class GCancelBigNumComputer: diff --git a/l2/l2_data_manager_new.py b/l2/l2_data_manager_new.py index c8fc40c..8f1ec10 100644 --- a/l2/l2_data_manager_new.py +++ b/l2/l2_data_manager_new.py @@ -510,6 +510,8 @@ except Exception as e: if constant.TEST: logging.exception(e) + # TODO 鍙兘鑰楁椂 + logger_l2_error.exception(e) async_log_util.error(logger_l2_error, f"H鎾ゅ嚭閿� 鍙傛暟锛歜uy_single_index-{_buy_single_index} buy_exec_index-{_buy_exec_index} {str(e)}") async_log_util.exception(logger_l2_error, e) diff --git a/l2/l2_transaction_data_processor.py b/l2/l2_transaction_data_processor.py index 836c138..f3a4928 100644 --- a/l2/l2_transaction_data_processor.py +++ b/l2/l2_transaction_data_processor.py @@ -109,6 +109,9 @@ if order_begin_pos and order_begin_pos.buy_exec_index and order_begin_pos.buy_exec_index > -1: HourCancelBigNumComputer().set_transaction_index(code, order_begin_pos.buy_single_index, buy_progress_index) + cresult = FCancelBigNumComputer().need_cancel_for_deal_fast(code,buy_progress_index) + if cresult[0]: + L2TradeDataProcessor.cancel_buy(code, f"涓嬪崟5鍒嗛挓鍐呮帓鍗曚笉瓒�:{cresult[1]}") # ---------------------------------鍒ゆ柇鏉垮潡鏄惁璺熶笂鏉ヤ簡------------------------------- try: pass diff --git a/msg/buy_order_msg_manager.py b/msg/buy_order_msg_manager.py index 993b854..319e288 100644 --- a/msg/buy_order_msg_manager.py +++ b/msg/buy_order_msg_manager.py @@ -2,12 +2,16 @@ from code_attribute import gpcode_manager from l2 import l2_data_source_util, l2_data_util from l2.l2_data_util import L2DataUtil +from log_module import async_log_util +from log_module.log import logger_kp_msg from msg import push_msg_manager from utils import output_util, tool # 鍗冲皢鎴愪氦 def almost_deal(code, real_order_index, trade_index, total_datas): + if trade_index > real_order_index: + return # 涓嬪崟3s杩囧悗鍐嶆彁閱� if tool.trade_time_sub(total_datas[-1]["val"]["time"], total_datas[real_order_index]["val"]["time"]) <= 3: return @@ -32,13 +36,19 @@ if total_left_count <= 10: push_msg_manager.push_order_almost_deal(code, code_name, real_order_index, f"鍓╀綑锛歿total_left_count}绗�", ctype="count") + async_log_util.info(logger_kp_msg, f"{code}鍗冲皢鎴愪氦锛歵rade_index-{trade_index}锛宺eal_order_index-{real_order_index}锛屽墿浣欙細{total_left_count}绗�") + elif total_left_money < 1500 * 10000: push_msg_manager.push_order_almost_deal(code, code_name, real_order_index, f"鍓╀綑锛歿output_util.money_desc(total_left_money)}", ctype="money") + async_log_util.info(logger_kp_msg, + f"{code}鍗冲皢鎴愪氦锛歵rade_index-{trade_index}锛宺eal_order_index-{real_order_index}锛屽墿浣欙細{total_left_money}鍏�") # 鐪熷疄涓嬪崟浣嶅悗闈㈣窡鍗曚笉瓒� def follow_not_enough(code, buy_exec_index, real_order_index, total_datas): + if buy_exec_index > real_order_index: + return # 涓嬪崟3s杩囧悗鍐嶆彁閱� if tool.trade_time_sub(total_datas[-1]["val"]["time"], total_datas[buy_exec_index]["val"]["time"]) <= 3: return @@ -69,7 +79,12 @@ push_msg_manager.push_delegate_order_danger(code, code_name, buy_exec_index, f"鍓╀綑锛歿real_place_order_after_count}绗�", ctype="count") + async_log_util.info(logger_kp_msg, + f"{code}灏佸崟涓嶈冻锛歜uy_exec_index-{buy_exec_index}锛宺eal_order_index-{real_order_index}锛屽墿浣欙細{real_place_order_after_count}鍏�") + if real_place_order_after_money <= 1500 * 10000: push_msg_manager.push_delegate_order_danger(code, code_name, buy_exec_index, f"鍓╀綑锛歿output_util.money_desc(real_place_order_after_money)}", ctype="money") + async_log_util.info(logger_kp_msg, + f"{code}灏佸崟涓嶈冻锛歜uy_exec_index-{buy_exec_index}锛宺eal_order_index-{real_order_index}锛屽墿浣欙細{real_place_order_after_money}鍏�") diff --git a/trade/current_price_process_manager.py b/trade/current_price_process_manager.py index 1540179..2055869 100644 --- a/trade/current_price_process_manager.py +++ b/trade/current_price_process_manager.py @@ -136,14 +136,17 @@ if True: print("璁剧疆L2浠g爜鏁伴噺锛�", len(add_code_set)) global latest_add_codes - async_log_util.info(logger_l2_codes_subscript, f"({request_id})棰勫鐞嗘柊澧炶闃呬唬鐮侊細{add_code_set - latest_add_codes}") + async_log_util.info(logger_l2_codes_subscript, + f"({request_id})棰勫鐞嗘柊澧炶闃呬唬鐮侊細{add_code_set - latest_add_codes}") latest_add_codes = add_code_set add_datas = [] for d in add_code_list: limit_up_price = gpcode_manager.get_limit_up_price(d) limit_up_price = round(float(limit_up_price), 2) min_volume = int(round(50 * 10000 / limit_up_price)) - add_datas.append((d, min_volume, limit_up_price)) + # 浼犻�掔瀛愪环 + add_datas.append( + (d, min_volume, limit_up_price, round(tool.get_shadow_price(limit_up_price), 2))) huaxin_target_codes_manager.HuaXinL2SubscriptCodesManager.push(add_datas, request_id) except Exception as e: logging.exception(e) diff --git a/trade/huaxin/huaxin_trade_api_server.py b/trade/huaxin/huaxin_trade_api_server.py index b3e9def..005f0b0 100644 --- a/trade/huaxin/huaxin_trade_api_server.py +++ b/trade/huaxin/huaxin_trade_api_server.py @@ -460,7 +460,7 @@ limit_up_price = gpcode_manager.get_limit_up_price(d[0]) if limit_up_price: # 榛樿璁剧疆娑ㄥ仠锛岄噺涓�0 - datas.append((code, float(limit_up_price), 10, 0, time.time())) + datas.append((code, 0, float(limit_up_price), tool.get_shadow_price(float(limit_up_price)))) except Exception as e: logger_l2_codes_subscript.exception(e) if not datas: @@ -478,7 +478,8 @@ # 濡傛灉鍦�9:24-9:30 闇�瑕佸姞杞芥澘鍧� if int("092400") < int(tool.get_now_time_str().replace(":", "")) < int("093000"): for d in datas: - KPLCodeJXBlockManager().load_jx_blocks(d[0], gpcode_manager.get_price(d[0]), float(d[2]), KPLLimitUpDataRecordManager.get_current_reasons()) + KPLCodeJXBlockManager().load_jx_blocks(d[0], gpcode_manager.get_price(d[0]), float(d[2]), + KPLLimitUpDataRecordManager.get_current_reasons()) time.sleep(1) logger_l2_codes_subscript.info("({})鍙戦�佸埌鍗庨懌L2浠g爜澶勭悊闃熷垪锛氭暟閲�-{}", request_id, len(datas)) except Exception as e: diff --git a/trade/huaxin/huaxin_trade_server.py b/trade/huaxin/huaxin_trade_server.py index dbbd577..1720f14 100644 --- a/trade/huaxin/huaxin_trade_server.py +++ b/trade/huaxin/huaxin_trade_server.py @@ -641,7 +641,7 @@ def __cancel_not_deal_order(self, code, order_ref, timeout=2): time.sleep(timeout) # 鎾や拱鍗� - huaxin_trade_api.cancel_order(1, code, "", orderRef = order_ref) + huaxin_trade_api.cancel_order(1, code, "", orderRef=order_ref) # 浜ゆ槗 def OnTrade(self, client_id, request_id, data): @@ -684,6 +684,9 @@ if buy1_info and buy1_info[0] * buy1_info[1] > 50 * 10000: # 濡傛灉涔�1鍦�50w浠ヤ笂灏卞姞涓�妗� price += 0.01 + limit_up_price = gpcode_manager.get_limit_up_price(code) + if limit_up_price and price > float(limit_up_price): + price = round(float(limit_up_price), 2) order_ref = huaxin_util.create_order_ref() result = huaxin_trade_api.order(direction, code, volume, price, price_type=price_type, sinfo=sinfo, order_ref=order_ref, @@ -1364,11 +1367,12 @@ continue if val["num"] * float(val["price"]) < 5000: continue - left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, - i, - total_datas, - l2_data_util.local_today_canceled_buyno_map.get( - code)) + left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2( + code, + i, + total_datas, + l2_data_util.local_today_canceled_buyno_map.get( + code)) if left_count > 0: total_left_count += left_count total_left_num += val["num"] * left_count @@ -1393,11 +1397,12 @@ if not l2_data_util.is_big_money(val): continue - canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(code, - i, - total_datas, - l2_data_util.local_today_canceled_buyno_map.get( - code)) + canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2( + code, + i, + total_datas, + l2_data_util.local_today_canceled_buyno_map.get( + code)) if not canceled_data: total_big_count += 1 else: @@ -1414,11 +1419,12 @@ if not l2_data_util.is_big_money(val): continue - canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(code, - i, - total_datas, - l2_data_util.local_today_canceled_buyno_map.get( - code)) + canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2( + code, + i, + total_datas, + l2_data_util.local_today_canceled_buyno_map.get( + code)) if not canceled_data: not_deal_total_big_count += 1 else: @@ -1437,11 +1443,12 @@ if not l2_data_util.is_big_money(val): continue - canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(code, - i, - total_datas, - l2_data_util.local_today_canceled_buyno_map.get( - code)) + canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2( + code, + i, + total_datas, + l2_data_util.local_today_canceled_buyno_map.get( + code)) if not canceled_data: real_place_order_after_count += 1 real_place_order_after_num += val["num"] @@ -1454,10 +1461,12 @@ limit_up_price) * 100 < 1500 * 10000) and ( real_place_order_after_count <= 10 or real_place_order_after_num * float( limit_up_price) * 100 < 1500 * 10000) - fdata = {"code_info": (code, code_name), "total_num": total_nums, "finish_num": deal_or_cancel_num, + fdata = {"code_info": (code, code_name), "total_num": total_nums, + "finish_num": deal_or_cancel_num, "buy1_money": output_util.money_desc(buy1_money), "big_num_count": total_big_count, - "big_num_money": output_util.money_desc(total_big_num * float(limit_up_price) * 100), + "big_num_money": output_util.money_desc( + total_big_num * float(limit_up_price) * 100), "not_deal_big_num_count": not_deal_total_big_count, "not_deal_big_num_money": output_util.money_desc( not_deal_total_big_num * float(limit_up_price) * 100), diff --git a/utils/tool.py b/utils/tool.py index b540cdf..a3b0d0a 100644 --- a/utils/tool.py +++ b/utils/tool.py @@ -228,10 +228,11 @@ # 鑾峰彇涔板叆浠锋牸绗煎瓙鐨勬渶浣庝环 def get_shadow_price(price): - fprice = round((100 - random.randint(2, 10)) * price / 100, 2) - if price - 0.1 < fprice: - fprice = price - 0.1 - return round(fprice, 2) + # fprice = round((100 - random.randint(2, 10)) * price / 100, 2) + # if price - 0.1 < fprice: + # fprice = price - 0.1 + # return round(fprice, 2) + return round(get_buy_min_price(price), 2) if __name__ == "__main__": -- Gitblit v1.8.0