From ad3cc1a24c4b413bae3069cc6d1c2a1923540ce3 Mon Sep 17 00:00:00 2001 From: Administrator <admin@example.com> Date: 星期五, 25 七月 2025 15:51:48 +0800 Subject: [PATCH] 开盘啦TCP请求/委托数据持久化异步处理 --- utils/buy_strategy_util.py | 258 +++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 225 insertions(+), 33 deletions(-) diff --git a/utils/buy_strategy_util.py b/utils/buy_strategy_util.py index 10eeaf4..7d0960d 100644 --- a/utils/buy_strategy_util.py +++ b/utils/buy_strategy_util.py @@ -1,9 +1,17 @@ """ 涔板叆绛栫暐甯姪绫� """ -from code_attribute import gpcode_manager -from l2 import l2_data_util, l2_data_source_util -from utils import tool +import time + +from code_attribute import gpcode_manager, code_volumn_manager +from l2 import l2_data_util, l2_data_source_util, transaction_progress +from l2.l2_data_util import L2DataUtil +from l2.l2_transaction_data_manager import HuaXinSellOrderStatisticManager +from log_module import async_log_util +from log_module.log import logger_l2_error +from settings.trade_setting import MarketSituationManager, TradeBlockBuyModeManager +from trade import trade_data_manager +from utils import tool, buy_condition_util, global_util def is_has_small_batch_cancel(code, start_index, end_index): @@ -22,7 +30,7 @@ end_time_with_ms = l2_data_util.L2DataUtil.get_time_with_ms(total_datas[end_index]["val"]) buy_count = 0 cancel_count = 0 - for i in range(end_index - 1, start_index - 1, -1): + for i in range(end_index - 1, start_index, -1): data = total_datas[i] val = data["val"] if val["num"] < min_num: @@ -37,7 +45,7 @@ break continue # 涓庡綋鍓嶆椂闂寸浉宸�3s鐨勭粨鏉� - if tool.trade_time_sub_with_ms(end_time_with_ms, l2_data_util.L2DataUtil.get_time_with_ms(val)) > 3000: + if tool.trade_time_sub_with_ms(end_time_with_ms, l2_data_util.L2DataUtil.get_time_with_ms(val)) > 10000: break cancel_count += 1 @@ -49,6 +57,14 @@ def is_cancel_rate_reieved(code, threshhold_rate, start_index, end_index): + """ + 鎾ゅ崟姣斾緥鏄惁杈惧埌鏌愪竴涓槇鍊� + @param code: + @param threshhold_rate: + @param start_index: + @param end_index: + @return: + """ # 缁熻鎬诲叡鐨勬定鍋滀拱 limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) min_num = int(round(5000 / limit_up_price)) @@ -77,9 +93,46 @@ if buy_index and start_index <= buy_index: cancel_count += 1 if buy_count == 0: - return False + return False, "涔板叆鏁伴噺涓�0" if round(cancel_count / buy_count, 2) > threshhold_rate: - return True + return True, f"涔板叆鏁伴噺-{buy_count} 鎾ゅ崟鏁伴噺-{cancel_count}" + return False, f"涔板叆鏁伴噺-{buy_count} 鎾ゅ崟鏁伴噺-{cancel_count}" + + +def is_far_away_from_trade_index(code, trade_index, buy1_money): + """ + 鏄惁璺濈鎴愪氦杩涘害浣嶅お杩� + @param code: + @param trade_index: + @param buy1_money: + @return: + """ + if buy1_money < 1e7: + # 涔�1澶т簬1鍗冧竾鎵嶈兘璁$畻 + return False + limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) + min_num = int(round(5000 / limit_up_price)) + threshhold_num = int(round(buy1_money * 0.5 / 100 / limit_up_price)) + total_datas = l2_data_util.local_today_datas.get(code) + end_index = total_datas[-1]["index"] + total_num = 0 + canceled_buyno_map = l2_data_util.local_today_canceled_buyno_map.get( + code) + for i in range(trade_index, end_index + 1): + data = total_datas[i] + val = data["val"] + if not L2DataUtil.is_limit_up_price_buy(val): + continue + if val["num"] < min_num: + continue + left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2( + code, + i, + total_datas, canceled_buyno_map) + if left_count > 0: + total_num += val["num"] + if total_num > threshhold_num: + return True return False @@ -90,30 +143,169 @@ @param trade_index: @return: """ - total_data = l2_data_util.local_today_datas.get(code) - total_count = 0 - total_big_count = 0 - for i in range(trade_index + 1, total_data[-1]["index"] + 1): - data = total_data[i] - val = data["val"] - if not l2_data_util.L2DataUtil.is_limit_up_price_buy(val): - continue - money = val["num"] * float(val["price"]) - if money < 5000: - continue + # 鑾峰彇浠婃棩鎴愪氦閲忎笌鍙傝�冮噺 + # today = get_today_volumn(code) + # max60, yesterday = get_histry_volumn(code) + try: + today_volume = code_volumn_manager.CodeVolumeManager().get_today_volumn_cache(code) + histry_volumn = code_volumn_manager.CodeVolumeManager().get_histry_volumn(code) + if not today_volume or not histry_volumn: + return False, "灏氭湭鑾峰彇鍒伴噺" + threshhold_volume = (histry_volumn[0][0] - today_volume) // 3 + limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) + threshhold_volumes = threshhold_volume // 100, int(50000 / limit_up_price), int(200000 / limit_up_price) - left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2( - code, - i, - total_data, - l2_data_util.local_today_canceled_buyno_map.get( - code)) - if left_count > 0: - total_count += 1 - if money > 29900: - total_big_count += 1 - if total_count > 10: - break - if total_count > 10 or total_big_count < 1: - return False, f"鏈垚浜ゆ暟閲�-{total_count}锛屽ぇ鍗曟暟閲�-{total_big_count}" - return True, "" + total_data = l2_data_util.local_today_datas.get(code) + total_count = 0 + total_big_count = 0 + total_num = 0 + for i in range(trade_index + 1, total_data[-1]["index"] + 1): + data = total_data[i] + val = data["val"] + if not l2_data_util.L2DataUtil.is_limit_up_price_buy(val): + continue + money = val["num"] * float(val["price"]) + if money < 5000: + continue + + left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2( + code, + i, + total_data, + l2_data_util.local_today_canceled_buyno_map.get( + code)) + if left_count > 0: + total_num += val["num"] + total_count += 1 + if money > 29900: + total_big_count += 1 + if threshhold_volumes[2] < total_num: + break + if threshhold_volumes[1] <= total_num <= threshhold_volumes[2] and total_num < threshhold_volumes[ + 0] and total_big_count > 0: + # 鍓╀綑鐨勫�煎湪500w-2000w涔嬮棿鎵嶄細鍙備笌璁$畻 + return True, "" + return False, f"鏈垚浜ゆ墜鏁�-{total_num}锛岄槇鍊�-{threshhold_volumes[0]}锛屽ぇ鍗曟暟閲�-{total_big_count}" + except Exception as e: + async_log_util.error(logger_l2_error, f"璁$畻鏄惁璺濈鎴愪氦杩涘害浣嶇疆杩戯細{str(e)}") + return False, "璁$畻寮傚父" + + +def is_quantization(code, start_index, end_index): + """ + 鏄惁鏄噺鍖栧崟 + @param code: + @param satrt_index: + @param end_index: + @return:(鏄惁鏄噺鍖�, 涓嬫鍙互涓嬪崟鏃堕棿) + """ + + # 闃堝�肩殑鍙栧�艰寖鍥� + THRESHOLD_MONEY_RANGE = 1e5, 3e5 + today_volume = code_volumn_manager.CodeVolumeManager().get_today_volumn_cache(code) + histry_volumn = code_volumn_manager.CodeVolumeManager().get_histry_volumn(code) + if not today_volume or not histry_volumn: + return False, "灏氭湭鑾峰彇鍒伴噺" + threshhold_volume = (histry_volumn[0][0] - today_volume) // 6 // 100 + limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) + threshhold_volumes_range = int(THRESHOLD_MONEY_RANGE[0] / limit_up_price), int( + THRESHOLD_MONEY_RANGE[1] / limit_up_price) + if threshhold_volume < threshhold_volumes_range[0]: + threshhold_volume = threshhold_volumes_range[0] + if threshhold_volume > threshhold_volumes_range[1]: + threshhold_volume = threshhold_volumes_range[1] + total_datas = l2_data_util.local_today_datas.get(code) + + time_as_ms = tool.trade_time_sub_with_ms( + L2DataUtil.get_time_with_ms(total_datas[end_index]["val"]), + L2DataUtil.get_time_with_ms(total_datas[start_index]["val"])) + if time_as_ms > (10 if tool.is_sz_code(code) else 100): + return False, "闈為噺鍖�" + + limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) + + total_buy_nums = 0 + min_num = int(5000 / limit_up_price) + # 鑾峰彇鎴愪氦杩涘害浣� + for i in range(start_index, end_index + 1): + val = total_datas[i]["val"] + if not L2DataUtil.is_limit_up_price_buy(val): + continue + if val["num"] < min_num: + continue + total_buy_nums += val["num"] + if total_buy_nums > threshhold_volume: + break + if total_buy_nums > threshhold_volume: + # 鍒ゆ柇鏄惁涓洪噺鍖� + # 娣辫瘉10ms鍐咃紝涓婅瘉100ms鍐呭氨鍒ゅ畾涓洪噺鍖� + HuaXinSellOrderStatisticManager.clear_latest_deal_volume(code) + next_buy_time = time.time() + buy_condition_util.get_cancel_and_buy_space_time( + code) / 1000 + # 濡傛灉鏄娆′笅鍗曪紝澧炲姞涓�娆′笅鍗曟鏁� + place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code) + if place_order_count == 0: + trade_data_manager.PlaceOrderCountManager().place_order(code) + return True, next_buy_time, f"鎵ц浣嶆壒娆℃暟鎹噺({total_buy_nums})澶т簬{threshhold_volume} {start_index}-{end_index}" + else: + return False, None + + +def is_block_can_buy(code, can_buy_result): + """ + 鏉垮潡鏄惁鍙拱 + @param code: + @param can_buy_result: + @return: + """ + now_timestamp = int(tool.get_now_time_str().replace(":", "")) + # 鍒ゆ柇鏉垮潡 + # (鍙互涔扮殑鏉垮潡鍒楄〃, 鏄惁鏄嫭鑻�, 娑堟伅绠�浠�,鍙拱鐨勫己鍔夸富绾�, 鏉垮潡鍏抽敭璇�) + if can_buy_result is None: + return False, True, "灏氭湭鑾峰彇鍒版澘鍧椾俊鎭�" + + # 鏄惁鏄己鍔�30鍒嗛挓 + is_in_strong_time_30 = now_timestamp <= int("100000") + + # 鑾峰彇甯傚満琛屾儏 + situation = MarketSituationManager().get_situation_cache() + zylt_threshold_as_yi = buy_condition_util.get_zyltgb_threshold(situation) + zyltgb_as_yi = round(global_util.zyltgb_map.get(code) / 100000000, 2) + + if zyltgb_as_yi < zylt_threshold_as_yi[0]: + return False, True, f"{zylt_threshold_as_yi[0]}浜夸互涓嬬殑閮戒笉涔帮紙{zyltgb_as_yi}锛�" + # 娴嬭瘯鏃跺彲鍙栨秷娉ㄩ噴 + # if 1 > 0: + # return True, False, "涔版墍鏈�" + + if zyltgb_as_yi >= zylt_threshold_as_yi[1]: + return False, True, f"{zylt_threshold_as_yi[1]}浜夸互涓婄殑閮戒笉涔帮紙{zyltgb_as_yi}锛�" + + msg_list = [] + if is_in_strong_time_30: + msg_list.append("寮哄娍30鍒嗛挓") + # 鐙嫍 + if not can_buy_result[0] and can_buy_result[1]: + msg_list.append("鐙嫍") + return True, False, "寮哄娍30鍒嗛挓锛岀嫭鑻�" + elif not can_buy_result[0]: + return False, True, f"寮哄娍30鍒嗛挓锛岄潪鐙嫍涓嶆弧瓒宠韩浣嶏細{can_buy_result[2]}" + else: + msg_list.append("闈炵嫭鑻�") + # 鍚庢帓锛屾弧瓒宠嚜鐢辨祦閫氬競鍊奸渶瑕佷笅鍗� + return True, False, can_buy_result[2] + else: + place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code) + if place_order_count > 0: + return True, False, "涔嬪墠涓嬭繃鍗�" + if not can_buy_result[0]: + # 娌℃湁鏉垮潡 + if can_buy_result[1]: + # 鏄嫭鑻� + if not TradeBlockBuyModeManager().can_buy_unique_block(): + # 涓嶈兘涔扮嫭鑻� + return False, True, f"闈炲己鍔�30鍒嗛挓锛岀嫭鑻楋紝涓嶆弧瓒宠韩浣嶏細{can_buy_result[2]}" + else: + # 闈炵嫭鑻楋紝娌℃湁鍙互涔板叆鐨勬澘鍧� + return False, True, f"闈炲己鍔�30鍒嗛挓锛岄潪鐙嫍锛屼笉婊¤冻韬綅锛歿can_buy_result[2]}" + return True, False, can_buy_result[2] -- Gitblit v1.8.0