From 82f0d56e8e25f56bf109db6e5d3dcec7a507ad4e Mon Sep 17 00:00:00 2001 From: Administrator <admin@example.com> Date: 星期三, 02 七月 2025 15:33:24 +0800 Subject: [PATCH] 日志调整/bug修复 --- l2/l2_data_manager_new.py | 703 ++++++++++++++++++++++++++++++++++------------------------ 1 files changed, 409 insertions(+), 294 deletions(-) diff --git a/l2/l2_data_manager_new.py b/l2/l2_data_manager_new.py index b3485a5..b3234c6 100644 --- a/l2/l2_data_manager_new.py +++ b/l2/l2_data_manager_new.py @@ -1,6 +1,7 @@ import copy import logging import threading +import time import time as t from cancel_strategy.s_l_h_cancel_strategy import HourCancelBigNumComputer, LCancelRateManager @@ -17,6 +18,8 @@ from l2.place_order_single_data_manager import L2TradeSingleDataProcessor from log_module import async_log_util, log_export from third_data import kpl_data_manager, block_info +from third_data.kpl_data_constant import LimitUpDataConstant +from trade.buy_radical.block_special_codes_manager import BlockSpecialCodesManager from trade.buy_radical.radical_buy_data_manager import EveryLimitupBigDealOrderManager from utils import global_util, tool, buy_condition_util, buy_strategy_util, trade_util import l2_data_util @@ -25,7 +28,7 @@ from trade import trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \ trade_result_manager, current_price_process_manager, trade_data_manager, trade_huaxin, trade_record_log_util, \ trade_constant, buy_open_limit_up_strategy -from trade.buy_radical import radical_buy_data_manager +from trade.buy_radical import radical_buy_data_manager, radical_buy_strategy from l2 import l2_data_manager, l2_log, l2_data_source_util, code_price_manager, \ transaction_progress, cancel_buy_strategy, place_order_single_data_manager from l2.cancel_buy_strategy import DCancelBigNumComputer, \ @@ -178,6 +181,7 @@ num_splites = [round(5000 / limit_up_price), round(10000 / limit_up_price), round(20000 / limit_up_price), round(30000 / limit_up_price)] total_num = 0 + buyno_map = local_today_buyno_map.get(code) for i in range(max(start_index, processed_index), end_index + 1): data = total_datas[i] if not L2DataUtil.is_limit_up_price_buy_cancel(data["val"]) and not L2DataUtil.is_limit_up_price_buy( @@ -187,8 +191,7 @@ if L2DataUtil.is_limit_up_price_buy_cancel(data["val"]): # 鑾峰彇涔板叆淇″彿 buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i], - local_today_buyno_map.get( - code)) + buyno_map) if buy_index is not None and buy_index < begin_pos: continue @@ -214,6 +217,70 @@ # print("m鍊煎ぇ鍗曡绠楄寖鍥达細{}-{} 鏃堕棿锛歿}".format(max(start_index, processed_index), end_index, # round(t.time() * 1000) - start_time)) + + +class HumanRadicalBuySingleManager: + """ + 浜轰负涔板叆绠$悊 + """ + # 浜轰负涓嬪崟鏍囪:{"浠g爜":(淇″彿鏃堕棿, 闂撮殧鏃堕棿,淇″彿鎴嚦鏃堕棿, radical_result)} + __human_radical_buy_mark_info = {} + + @classmethod + def add_single(cls, code, latest_data, radical_result): + """ + 娣诲姞涔板叆淇″彿 + @param code: + @param latest_data: + @param radical_result: + @return: + """ + start_time_with_ms = L2DataUtil.get_time_with_ms(latest_data["val"]) + if tool.is_sh_code(code): + cls.__human_radical_buy_mark_info[code] = ( + start_time_with_ms, 400, tool.trade_time_add_millionsecond(start_time_with_ms, 3000), radical_result) + else: + cls.__human_radical_buy_mark_info[code] = ( + start_time_with_ms, 30, tool.trade_time_add_millionsecond(start_time_with_ms, 2000), radical_result) + + @classmethod + def remove_single(cls, code): + """ + 绉婚櫎淇″彿 + @param code: + @return: + """ + if code in cls.__human_radical_buy_mark_info: + cls.__human_radical_buy_mark_info.pop(code) + + @classmethod + def has_single(cls, code): + """ + 鏄惁鏈変俊鍙� + @param code: + @return: + """ + if code in cls.__human_radical_buy_mark_info: + return True + return False + + @classmethod + def is_valid(cls, code, data): + """ + 淇″彿鏄惁鏈夋晥 + @param code: + @return: 鏄惁鏈夋晥锛屾棤鏁堟秷鎭�/鏈夋晥瀵硅薄 + """ + if code not in cls.__human_radical_buy_mark_info: + return False, "娌℃湁浜轰拱鍏ヤ俊鍙�" + single_time_ms, space_time_ms, expire_time_ms, _ = cls.__human_radical_buy_mark_info[code] + now_time_ms = L2DataUtil.get_time_with_ms(data["val"]) + if tool.trade_time_sub_with_ms(now_time_ms, + expire_time_ms) > 0: + cls.__human_radical_buy_mark_info.pop(code) + async_log_util.info(logger_l2_not_buy_reasons, f"{code}#澶у崟瓒冲锛屼汉涓轰笅鍗曪細 瓒呰繃淇″彿鐢熸晥鏃堕棿-{now_time_ms}/{expire_time_ms}") + return False, "瓒呰繃淇″彿鐢熸晥鏃堕棿" + return True, cls.__human_radical_buy_mark_info[code] class L2TradeDataProcessor: @@ -297,7 +364,7 @@ if not is_normal: # print("鍘嗗彶鏁版嵁寮傚父:", code) # 鏁版嵁涓嶆甯搁渶瑕佺姝氦鏄� - l2_trade_util.forbidden_trade(code, msg="L2鍘嗗彶鏁版嵁寮傚父") + l2_trade_util.forbidden_trade(code, msg="L2鍘嗗彶鏁版嵁寮傚父", force=True) # 绾犳鏁版嵁 if constant.L2_SOURCE_TYPE == constant.L2_SOURCE_TYPE_THS: # 鍚岃姳椤洪渶瑕佺籂姝f暟鎹紝鍏朵粬娓犻亾涓嶉渶瑕� @@ -323,8 +390,14 @@ cls.unreal_buy_dict.pop(code) @classmethod - def set_real_place_order_index(cls, code, index, order_begin_pos: OrderBeginPosInfo): + def set_real_place_order_index(cls, code, index, order_begin_pos: OrderBeginPosInfo, last_data): trade_record_log_util.add_real_place_order_position_log(code, index, order_begin_pos.buy_single_index) + total_datas = local_today_datas.get(code) + use_time = tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(total_datas[index]["val"]), + L2DataUtil.get_time_with_ms( + total_datas[order_begin_pos.buy_exec_index]["val"])) + trade_record_log_util.add_place_order_use_time(code, + f"鎵ц浣嶆椂闂达細{L2DataUtil.get_time_with_ms(total_datas[order_begin_pos.buy_exec_index]['val'])} 鑰楁椂锛歿use_time}") l2_log.debug(code, "璁剧疆鐪熷疄涓嬪崟浣嶏細{}", index) cancel_buy_strategy.set_real_place_position(code, index, order_begin_pos.buy_single_index, is_default=False) # 鑾峰彇鐪熷疄涓嬪崟浣嶇疆涔嬪悗闇�瑕佸垽鏂璅鎾� @@ -358,7 +431,7 @@ is_normal = l2.l2_data_util.l2_data_is_normal(code) if not is_normal: # 鏁版嵁涓嶆甯搁渶瑕佺姝氦鏄� - l2_trade_util.forbidden_trade(code, msg="L2鍘嗗彶鏁版嵁寮傚父") + l2_trade_util.forbidden_trade(code, msg="L2鍘嗗彶鏁版嵁寮傚父", force=True) # 杞崲鏁版嵁鏍煎紡 _start_index = 0 total_datas = local_today_datas.get(code) @@ -375,9 +448,10 @@ limit_up_price = round(float(limit_up_price), 2) # if trade_price_info and limit_up_price and trade_price_info[0] == limit_up_price: # filter_limit_up_sell = True - L2LimitUpSellDataManager.add_l2_origin_data(code, origin_datas) + datas = l2_huaxin_util.get_format_l2_datas(code, origin_datas, limit_up_price, _start_index, filter_limit_up_sell) + L2LimitUpSellDataManager.add_l2_data(code, datas) __start_time = round(t.time() * 1000) if len(datas) > 0: cls.process_add_datas(code, datas, 0, __start_time) @@ -388,33 +462,35 @@ finally: if datas: l2.l2_data_util.save_l2_data(code, None, datas) - origin_datas.clear() + # origin_datas.clear() @classmethod def __recompute_real_order_index(cls, code, pre_real_order_index, order_info, compute_type): - # 鍥犱负鏁版嵁鎱㈢殑闂閲嶆柊璁$畻 - real_order_index = huaxin_delegate_postion_manager.recompute_for_slow_time(code, order_info, - pre_real_order_index, compute_type) - if real_order_index: + # 1s涔嬪悗閲嶆柊璁$畻 + time.sleep(1) + real_order_index = huaxin_delegate_postion_manager.RealDelegateOrderPositionManager().recompute_l2_place_order_position( + code, order_info, pre_real_order_index, compute_type) + if real_order_index and pre_real_order_index != real_order_index: try: - exec_index = order_info[6] + exec_index = order_info[3] order_begin_pos = cls.__get_order_begin_pos( code) async_log_util.info(logger_debug, f"涓嬪崟浣嶇煫姝o細鐪熷疄涓嬪崟浣�-{real_order_index} 璁㈠崟淇℃伅-{order_info} 涓嬪崟淇℃伅-{order_begin_pos.to_dict()}") if order_begin_pos and order_begin_pos.buy_exec_index == exec_index: - cls.set_real_place_order_index(code, real_order_index, order_begin_pos) + cls.set_real_place_order_index(code, real_order_index, order_begin_pos, order_info[1]) async_log_util.info(logger_real_place_order_position, f"鐪熷疄涓嬪崟浣嶇疆鐭锛歿code}-({real_order_index},1)") except Exception as e: logger_debug.exception(e) + async_log_util.error(logger_debug, f"閲嶆柊瀵绘壘鐪熷疄涓嬪崟浣嶅紓甯革細{code}-{order_info}") @classmethod def process_add_datas(cls, code, add_datas, capture_timestamp, __start_time): now_time_str = tool.get_now_time_str() # 灏嗘湰娆′腑鏂缃负 cls.__break_current_batch_data_for_buy_dict[code] = False - if len(add_datas) > 0: + if add_datas: # 璁板綍褰撳墠鎵规暟鎹殑绱㈠紩 cls.__processing_data_indexes[code] = (add_datas[0]["index"], add_datas[-1]["index"]) if code not in cls.__trade_log_placr_order_info_dict: @@ -471,22 +547,6 @@ logger_l2_error.exception(e) finally: buy_open_limit_up_strategy.BuyOpenLimitupDataManager().remove_place_order_info(code) - - # 鑾峰彇涓嬪崟浣嶇疆 - place_order_index, order_info, compute_type = huaxin_delegate_postion_manager.get_l2_place_order_position( - code, float( - gpcode_manager.get_limit_up_price(code)), add_datas) - if place_order_index: - order_begin_pos = cls.__get_order_begin_pos( - code) - cls.set_real_place_order_index(code, place_order_index, order_begin_pos) - try: - cls.__re_compute_threading_pool.submit( - cls.__recompute_real_order_index, code, place_order_index, order_info, compute_type) - except: - pass - async_log_util.info(logger_l2_process, f"code:{code} 鑾峰彇鍒颁笅鍗曠湡瀹炰綅缃細{place_order_index}") - # 澶勭悊娑ㄥ仠鍗栦笌娑ㄥ仠鍗栨挙 try: for d in add_datas: @@ -497,6 +557,28 @@ d['val']['orderNo']) except Exception as e: logger_debug.exception(e) + finally: + # 鎵ц鏈�鍚庡啀鑾峰彇鐪熷疄涓嬪崟浣嶇疆锛岄槻姝笅鍗曚綅缃偅鎵规暟鎹湁澶ф壒閲忕殑鎾ゅ崟 + # ======鑾峰彇涓嬪崟浣嶇疆 + if constant.IS_NEW_VERSION_PLACE_ORDER: + place_order_index, order_info, compute_type = huaxin_delegate_postion_manager.RealDelegateOrderPositionManager.compute_l2_place_order_position( + code, add_datas) + else: + place_order_index, order_info, compute_type = huaxin_delegate_postion_manager.get_l2_place_order_position( + code, float( + gpcode_manager.get_limit_up_price(code)), add_datas) + + if place_order_index: + order_begin_pos = cls.__get_order_begin_pos( + code) + cls.set_real_place_order_index(code, place_order_index, order_begin_pos, order_info[1]) + try: + cls.__re_compute_threading_pool.submit( + cls.__recompute_real_order_index, code, place_order_index, order_info, + compute_type) + except: + pass + async_log_util.info(logger_l2_process, f"code:{code} 鑾峰彇鍒颁笅鍗曠湡瀹炰綅缃細{place_order_index}") except: async_log_util.error(logger_l2_error, f"{code} 澶勭悊鐪熷疄涓嬪崟浣嶇疆鍑洪敊") # 绗�1鏉℃暟鎹槸鍚︿负09:30:00 @@ -709,7 +791,14 @@ b_need_cancel, b_cancel_data, extra_msg = RDCancelBigNumComputer().need_cancel(code, start_index, end_index) if b_need_cancel and b_cancel_data: - return b_cancel_data, f"RD鎾�({extra_msg})", trade_constant.CANCEL_TYPE_RD + l2_log.d_cancel_debug(code, f"鍑嗗RD鎾�({start_index}-{end_index}): {extra_msg}") + big_order_info = radical_buy_data_manager.get_total_deal_big_order_info(code, + gpcode_manager.get_limit_up_price_as_num( + code)) + if big_order_info[0] > 0: + return b_cancel_data, f"RD鎾�({extra_msg})", trade_constant.CANCEL_TYPE_RD + else: + l2_log.d_cancel_debug(code, f"瑙﹀彂RD鎾わ紝浣嗘槸澶у崟宸茬粡瓒冲锛歿big_order_info}") except Exception as e: async_log_util.error(logger_l2_error, f"RD鎾ゅ嚭閿� 鍙傛暟锛歜uy_single_index-{_buy_single_index} buy_exec_index-{_buy_exec_index} 閿欒鍘熷洜锛歿str(e)}") @@ -741,6 +830,9 @@ order_begin_pos.buy_exec_index) else: if not cancel_data: + cancel_data, cancel_msg, cancel_type = rd_cancel(order_begin_pos.buy_single_index, + order_begin_pos.buy_exec_index) + if not cancel_data: cancel_data, cancel_msg = g_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) cancel_type = trade_constant.CANCEL_TYPE_G # 渚濇澶勭悊 @@ -760,11 +852,14 @@ cancel_type = trade_constant.CANCEL_TYPE_J if cancel_data and not DCancelBigNumComputer().has_auto_cancel_rules(code): - l2_log.debug(code, "瑙﹀彂鎾ゅ崟锛屾挙鍗曚綅缃細{} 锛屾挙鍗曞師鍥狅細{}", cancel_data["index"], cancel_msg) - # 鎾ゅ崟 - cls.cancel_buy(code, cancel_msg, cancel_index=cancel_data["index"], cancel_type=cancel_type) - # 鎾ゅ崟鎴愬姛锛岀户缁绠椾笅鍗� - cls.__process_not_order(code, cancel_data["index"] + 1, end_index, capture_time, is_first_code) + try: + # 鎾ゅ崟 + cls.cancel_buy(code, cancel_msg, cancel_index=cancel_data["index"], cancel_type=cancel_type) + # 鎾ゅ崟鎴愬姛锛岀户缁绠椾笅鍗� + cls.__process_not_order(code, cancel_data["index"] + 1, end_index, capture_time, is_first_code) + finally: + l2_log.debug(code, "瑙﹀彂鎾ゅ崟锛屾挙鍗曚綅缃細{} 锛屾挙鍗曞師鍥狅細{}, 涓嬪崟妯″紡锛歿}", cancel_data["index"], cancel_msg, + f"{order_begin_pos.mode}") else: pass @@ -786,8 +881,8 @@ now_time_int = int(tool.get_now_time_str().replace(":", "")) if now_time_int >= 145700: return False, True, f"14:57鍚庝笉鑳戒氦鏄�", True - if now_time_int < 93100: - return False, True, f"09:31涔嬪墠涓嶈兘浜ゆ槗", True + # if now_time_int < 93100: + # return False, True, f"09:31涔嬪墠涓嶈兘浜ゆ槗", True # 浜屾澘浠ヤ笂鐨勭エ涓嶄拱 yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes() if yesterday_codes and code in yesterday_codes: @@ -797,6 +892,19 @@ if not cls.__WantBuyCodesManager.is_in_cache( code) and not gpcode_manager.GreenListCodeManager().is_in_cache(code): return False, True, f"鍙拱鎯充拱锛氭病鍦ㄦ兂涔板崟鍜岀豢鍗�", True + if cls.__TradeTargetCodeModeManager.get_mode_cache() == TradeTargetCodeModeManager.MODE_ONLY_BUY_SPECIAL_CODES: + special_blocks = BlockSpecialCodesManager().get_code_blocks(code) + if not special_blocks: + return False, True, f"鍙拱杈ㄨ瘑搴�", True + # if not cls.__WantBuyCodesManager.is_in_cache(code): + average_rate = cls.__Buy1PriceManager.get_average_rate(code) + if average_rate: + if tool.is_ge_code(code): + if average_rate < 0.08: + return False, True, f"鍧囦环娑ㄥ箙({average_rate})灏忎簬8%", True + else: + if average_rate < 0.04: + return False, True, f"鍧囦环娑ㄥ箙({average_rate})灏忎簬4%", True return True, False, f"", False @@ -854,7 +962,7 @@ params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc() l2_log.debug(code, params_desc) #################娓呴櫎鏈涓嬪崟鐨勫ぇ鍗曟暟鎹�############### - EveryLimitupBigDealOrderManager.clear(code) + EveryLimitupBigDealOrderManager.clear(code, "涓嬪崟鎴愬姛") ############璁板綍涓嬪崟鏃剁殑鏁版嵁############ try: jx_blocks, jx_blocks_by = KPLCodeJXBlockManager().get_jx_blocks_cache( @@ -896,6 +1004,7 @@ def __buy(cls, code, capture_timestamp, last_data, last_data_index, is_first_code, block_info=None): pre_result = cls.__is_pre_can_buy(code) if not pre_result[0]: + async_log_util.info(logger_l2_not_buy_reasons, f"{code}#{pre_result[2]}") return False # 娣诲姞涔板叆閿� if code not in cls.__buy_lock_dict: @@ -938,8 +1047,21 @@ local_today_datas.get(code)) return False else: - l2_log.debug(code, "鍙互涓嬪崟锛屽師鍥狅細{}锛� 涓嬪崟妯″紡锛歿}", reason, order_begin_pos.mode) + try: + # 鍒ゆ柇鏄惁涓洪灏佷笅鍗� + order_begin_pos.first_limit_up_buy = radical_buy_data_manager.is_first_limit_up_buy(code) + + if not constant.CAN_BUY_FIRST_LIMIT_UP and order_begin_pos.first_limit_up_buy: + reason = "棣栧皝涓嶄笅鍗�" + l2_log.debug(code, "涓嶅彲浠ヤ笅鍗曪紝鍘熷洜锛歿}", reason) + trade_record_log_util.add_cant_place_order_log(code, reason) + cls.__break_current_batch_data_for_buy_dict[code] = True + trade_result_manager.real_cancel_success(code, order_begin_pos.buy_single_index, + order_begin_pos.buy_exec_index, + local_today_datas.get(code)) + return False + l2_log.debug(code, "鍙互涓嬪崟锛屽師鍥狅細{}锛� 涓嬪崟妯″紡锛歿} 鏈�灏忚鍗曞彿锛歿}", reason, order_begin_pos.mode, order_begin_pos.min_order_no) l2_log.debug(code, "寮�濮嬫墽琛屼拱鍏�") trade_manager.start_buy(code, capture_timestamp, last_data, last_data_index, order_begin_pos.mode, order_begin_pos.buy_exec_index) @@ -1025,225 +1147,6 @@ is_limit_up_buy = False return is_limit_up_buy - @classmethod - def __is_big_order_deal_enough(cls, code): - """ - 澶у崟鎴愪氦鏄惁瓒冲 - @param code: - @param volume_rate: - @return: - """ - limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) - refer_volume = code_volumn_manager.CodeVolumeManager().get_max_volume_in_5days(code) - if refer_volume is None: - refer_volume = 0 - - money_y = int(refer_volume * limit_up_price / 1e8) - money_y = min(money_y, 50) - money_y = max(money_y, 5) - # 璁$畻澶у崟鍙傝�冩暟閲� - threshold_count = int(round(0.4 * money_y)) * 4 - threshold_money = threshold_count * 299 * 10000 - volume_rate_info = cls.volume_rate_info.get(code) - - deal_big_order_money = BigOrderDealManager().get_total_buy_money(code) - if deal_big_order_money >= threshold_money: - return True, f"閲忔瘮-{volume_rate_info}, 鎬诲ぇ鍗曟垚浜ら噾棰�({deal_big_order_money})>={threshold_money}" - else: - return False, f"閲忔瘮-{volume_rate_info}, 鎬诲ぇ鍗曟垚浜ら噾棰�({deal_big_order_money})<{threshold_money}" - - @classmethod - def __can_buy_first(cls, code): - """ - 鏄惁鍙互涓嬪崟 - @param code: - @return:(鏄惁鍙互涓嬪崟, 鏄惁娓呯悊淇″彿鏁版嵁, 涓嶈兘涓嬪崟娑堟伅, 鏄惁绠楁湁鏁堟墽琛�) - """ - - pre_result = cls.__is_pre_can_buy(code) - if not pre_result[0]: - return pre_result[0], pre_result[1], pre_result[2], pre_result[3] - - now_time_int = int(tool.get_now_time_str().replace(":", "")) - if 130100 >= now_time_int >= 112900 or now_time_int < 93100: - if now_time_int < 93100: - # 鍒ゆ柇杩�120澶╂槸鍚︽湁娑ㄥ仠 - k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code) - if k_format and len(k_format) >= 12 and not k_format[11]: - return False, True, f"09:31:00涔嬪墠涓嬪崟锛�90涓氦鏄撴棩鏃犳定鍋�", True - - # 鍒ゆ柇鎴愪氦鐨勫ぇ鍗曟暟閲� - data_list = BigOrderDealManager().get_total_buy_money_list(code) - bigger_money = 2990000 - fdatas = [] - for d in data_list: - if d < bigger_money: - continue - fdatas.append(d) - thresh_count = 3 if tool.is_sh_code(code) else 1 - if len(fdatas) < thresh_count: - return False, True, f"09:31:00涔嬪墠涓嬪崟锛屾垚浜ゅぇ鍗曟暟閲忥紙{len(fdatas)}锛変笉瓒硔thresh_count}涓�", True - else: - # 鍒ゆ柇鏁版嵁鏄惁鍗� - total_datas = local_today_datas.get(code) - if tool.trade_time_sub_with_ms(tool.get_now_time_with_ms_str(), - L2DataUtil.get_time_with_ms(total_datas[-1]["val"])) > 500: - return False, True, f"09:31:00涔嬪墠涓嬪崟锛孡2鏁版嵁鏃堕棿鐩稿樊500ms浠ヤ笂", True - else: - return False, True, f"09:31:00涔嬪墠锛�11:29:00-13:01:00涓嶈兘浜ゆ槗", True - - limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) - - if constant.MIN_CODE_PRICE < limit_up_price < constant.MAX_CODE_PRICE: - # 婊¤冻鏉′欢鐨勫崟浠� - pass - elif limit_up_price > constant.MAX_CODE_PRICE: - # HighIncreaseCodeManager().add_code(code) - # 灏忓競鍊奸珮鑲′环鍙拱 - zyltgb = global_util.zyltgb_map.get(code) - if zyltgb > 25e8 or limit_up_price > constant.MAX_SUBSCRIPT_CODE_PRICE: - return False, True, f"鑲′环澶т簬{constant.MAX_CODE_PRICE}鍧�/灏忎簬{constant.MIN_CODE_PRICE}鍧�", True - else: - return False, True, f"鑲′环灏忎簬{constant.MIN_CODE_PRICE}鍧�", True - - # place_order_count = cls.__PlaceOrderCountManager.get_place_order_count(code) - # if place_order_count and place_order_count >= 10: - # l2_trade_util.forbidden_trade(code, msg="褰撴棩涓嬪崟娆℃暟宸茶揪10娆�") - # return False, True, f"褰撴棩涓嬪崟娆℃暟宸茶揪10娆�" - - # ---------鍧囦环绾︽潫------------- - average_rate = cls.__Buy1PriceManager.get_average_rate(code) - if average_rate and average_rate <= 0.01 and tool.trade_time_sub(tool.get_now_time_str(), "10:30:00") >= 0: - return False, True, f"鍧囦环娑ㄥ箙({average_rate})灏忎簬1%", True - - total_data = local_today_datas.get(code) - - # 9:32涔嬪墠涓婅瘉寮�1鐨勭エ涓嶄拱 - if tool.is_sh_code(code) and int(total_data[-1]["val"]["time"].replace(":", "")) <= int("093100"): - # 鑾峰彇娑ㄥ仠鏃堕棿 - limit_up_data = kpl_data_manager.KPLLimitUpDataRecordManager.record_code_dict.get(code) - if limit_up_data: - limit_up_time = tool.to_time_str(limit_up_data[2]) - if int(limit_up_time.replace(":", "")) < int("093000"): - return False, True, f"涓婅瘉寮�涓�09:32涔嬪墠涓嶄笅鍗�", True - - # ------------鎸傚崟鏃堕棿绾︽潫---------- - order_begin_pos = cls.__get_order_begin_pos( - code) - if not trade_result_manager.can_place_order_for_cancel_time(code, total_data[ - order_begin_pos.buy_exec_index]) and not gpcode_manager.GreenListCodeManager().is_in_cache(code): - return False, True, f"璺濈涓婃鎸傚崟灏忎簬鏃堕棿闄愬埗", True - - # ------------鏉垮潡绾︽潫------------- - if not cls.__WantBuyCodesManager.is_in_cache(code): - # 鎯充拱鍗曟棤鏉垮潡绾︽潫 - block_buy_result = buy_strategy_util.is_block_can_buy(code, cls.__get_can_buy_block(code)) - if not block_buy_result[0]: - return block_buy_result[0], block_buy_result[1], block_buy_result[2], True - - if constant.L2_SOURCE_TYPE == constant.L2_SOURCE_TYPE_HUAXIN: - # ---------------------鍒ゆ柇鏄惁涓烘澘涓婃斁閲�---------------------- - trade_price = current_price_process_manager.get_trade_price(code) - if trade_price is None: - return False, True, f"灏氭湭鑾峰彇鍒板綋鍓嶆垚浜や环", True - # 鍒ゆ柇鏄惁涓烘澘涓婃斁閲忥細 - # 1.褰撳墠鎴愪氦浠蜂负娑ㄥ仠浠� - # 2.璺濈鏈�杩戠殑闈炴澘涓婃垚浜ょ殑鏃堕棿澶т簬涓�涓槇鍊� - if abs(limit_up_price - float(trade_price)) < 0.001: - is_limit_up_buy = cls.__is_at_limit_up_buy(code, order_begin_pos.buy_exec_index) - if is_limit_up_buy: - # 鏉夸笂涔颁笖闈炲姞缁� - # 鑾峰彇鏈�杩戠殑闈炴定鍋滀环鎴愪氦鏃堕棿 - not_limit_up_trade_time_with_ms = current_price_process_manager.get_trade_not_limit_up_time_with_ms( - code) - # 鍒ゆ柇鎴愪氦杩涘害鍒板綋鍓嶆暟鎹殑绗旀暟锛屽鏋滃皯浜�10绗斾笖杩樻湁鏈垚浜ょ殑澶у崟锛�>=299锛夊氨鍙互涓嬪崟 - trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code) - if trade_index is None: - trade_index = 0 - can_place_order, msg = buy_strategy_util.is_near_by_trade_index(code, trade_index) - if not can_place_order: - try: - # 涓嶈兘涓嬪崟锛屽垽鏂皬缇ゆ挙鏄惁鍙互涓� - if buy_strategy_util.is_has_small_batch_cancel(code, trade_index, - order_begin_pos.buy_single_index): - # 鍒ゆ柇鎾ゅ崟姣斾緥鏄惁瓒冲 - cancel_rate_reieved_info = buy_strategy_util.is_cancel_rate_reieved(code, 0.69, - trade_index, - order_begin_pos.buy_single_index) - if not cancel_rate_reieved_info[0]: - return False, True, f"鏉夸笂鏀鹃噺璺濈杩�({not_limit_up_trade_time_with_ms})锛屾湁灏忕兢鎾�, 鏁翠綋鎾ゅ崟姣斾緥涓嶈冻锛坽trade_index}-{order_begin_pos.buy_single_index}锛墈cancel_rate_reieved_info[1]}", False - else: - return False, True, f"鏉夸笂鏀鹃噺璺濈杩�({not_limit_up_trade_time_with_ms})锛屾病鏈夊皬缇ゆ挙锛坽trade_index}-{order_begin_pos.buy_single_index}锛�", False - except Exception as e: - l2_log.info(code, logger_l2_error, f"鏉夸笂鏀鹃噺({not_limit_up_trade_time_with_ms})涓嶈冻寮傚父锛歿str(e)}") - logger_l2_error.exception(e) - return False, True, f"鏉夸笂鏀鹃噺璁$畻寮傚父", False - - # -------鏄惁璺濈鎴愪氦杩涘害浣嶅お杩�-------- - buy1_money = code_price_manager.Buy1PriceManager().get_latest_buy1_money(code) - buy1_price = code_price_manager.Buy1PriceManager().get_buy1_price(code) - if buy1_price and abs(limit_up_price - buy1_price) > 0.0001: - # 涔�1鏈定鍋� - buy1_money = 0 - if not buy1_money: - buy1_money = 1 - if buy_strategy_util.is_far_away_from_trade_index(code, trade_index, buy1_money): - return False, True, f"璺濈鎴愪氦杩涘害浣嶅お杩滐細鎴愪氦杩涘害-{trade_index} 涔�1-{buy1_money}", False - - # ------------------涓婅瘉涓嬪崟闇�瑕佹湁鎴愪氦澶у崟锛堝寘鍚富鍔ㄤ拱涓庤鍔ㄤ拱锛夋垨鑰呮寕涔扮殑澶у崟----------------- - if tool.is_sh_code(code): - deal_big_order_count = BigOrderDealManager().get_total_buy_count(code) - if deal_big_order_count < 1: - # 缁熻鎸備拱澶у崟 - trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code) - if trade_index is None: - trade_index = 0 - limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) - # 浠庢垚浜よ繘搴︿綅鍒版埅鑷充綅缃绠楀ぇ鍗� - min_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) - left_count, left_money = cancel_buy_strategy.L2DataComputeUtil.compute_left_buy_order(code, - trade_index, - total_data[ - -1][ - "index"], - limit_up_price, - min_money=min_money) - if left_count < 1: - return False, False, f"娌℃湁宸叉寕鎴栬�呮垚浜ょ殑澶у崟", False - if not cls.__WantBuyCodesManager.is_in_cache(code): - # 鎯充拱鍗曚笉闇�瑕佸ぇ鍗曠害鏉� - big_deal_order_info = cls.__is_big_order_deal_enough(code) - if not big_deal_order_info[0]: - return False, False, big_deal_order_info[1], False - - place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code) - # ------------------绗竴鍜岀浜屾涓嬪崟閮藉繀椤昏鏈夎嚦灏戜竴绗旀湭鎴愪氦鐨勫ぇ鍗�-------------------------- - # 璁$畻澶у崟 - total_datas = local_today_datas.get(code) - if place_order_count < 2: - trade_index, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code) - if trade_index is None: - trade_index = 0 - min_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) - left_count, left_num = L2DataComputeUtil.compute_left_buy_order(code, trade_index, - total_datas[-1]["index"], - limit_up_price, min_money) - if left_count < 1: - return False, False, f"绗瑊place_order_count + 1}娆′笅鍗曟棤寰呮垚浜ょ殑澶у崟", False - - # -------鍒ゆ柇鏄惁鏄噺鍖栦笅鍗曪紝濡傛灉鏄氨涓嶈窡鍒颁笅鍗�-------- - # 閲嶈锛氶噺鍖栦笅鍗曚細澧炲姞涓嬪崟娆℃暟锛屾澘鍧椾笅鍗曚腑鏈変笅鍗曟鏁扮殑浣跨敤锛屾墍浠ユ澘鍧楅渶瑕佸湪閲忓寲鍒ゆ柇涔嬪墠 - # 鍙湁鏉垮潡婊¤冻涓嬪崟涔嬪悗鎵嶈兘鍒ゆ柇鍏跺畠鏉′欢 - range_indexes = cls.__processing_data_indexes.get(code) - if range_indexes: - # 鏄惁鏄噺鍖栧崟 - is_quantization_result = buy_strategy_util.is_quantization(code, range_indexes[0], range_indexes[1]) - if is_quantization_result[0] and not gpcode_manager.GreenListCodeManager().is_in_cache(code): - # 閲忓寲鍗曚笖娌℃湁鍔犵豢 - cls.__next_buy_time_dict[code] = is_quantization_result[1] - return False, True, is_quantization_result[2], True - return True, False, "婊¤冻涓嬪崟鏉′欢", True - # 鑾峰彇鍙互涔扮殑鏉垮潡 @classmethod def __get_can_buy_block(cls, code): @@ -1262,7 +1165,8 @@ kpl_data_manager.KPLLimitUpDataRecordManager.total_datas, latest_current_limit_up_records, block_info.get_before_blocks_dict(), - kpl_data_manager.KPLLimitUpDataRecordManager.get_current_limit_up_reason_codes_dict(), codes_delegate, codes_success) + kpl_data_manager.KPLLimitUpDataRecordManager.get_current_limit_up_reason_codes_dict(), + codes_delegate, codes_success) can_buy_result = CodePlateKeyBuyManager.can_buy(code) return can_buy_result @@ -1497,13 +1401,15 @@ # 鏄惁鏄氦鏄撻槦鍒楄Е鍙� # 鎵叆涓嬪崟鍙湁L鎾よ兘鎾ゅ崟 if order_begin_pos and order_begin_pos.mode == OrderBeginPosInfo.MODE_RADICAL and cancel_type not in { - trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_L, trade_constant.CANCEL_TYPE_RD}: + trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_L, trade_constant.CANCEL_TYPE_RD, + trade_constant.CANCEL_TYPE_P}: l2_log.cancel_debug(code, "鎾ゅ崟涓柇锛屽師鍥狅細{}", "鎵叆涓嬪崟涓嶆槸L鎾�") return False # 鍔犵豢鍙湁L鎾�/浜烘挙鐢熸晥 if gpcode_manager.GreenListCodeManager().is_in_cache(code): if cancel_type not in {trade_constant.CANCEL_TYPE_L, trade_constant.CANCEL_TYPE_L_UP, - trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_RD}: + trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_RD, + trade_constant.CANCEL_TYPE_P}: l2_log.cancel_debug(code, "鎾ゅ崟涓柇锛屽師鍥狅細{}", "鍔犵豢涓嶆槸L鎾�") return False @@ -1565,7 +1471,7 @@ order_begin_pos.threshold_money, order_begin_pos.num, order_begin_pos.count, order_begin_pos.at_limit_up, total_datas[order_begin_pos.buy_exec_index], - cls.volume_rate_info[code], order_begin_pos.mode) + cls.volume_rate_info[code], order_begin_pos.mode_desc) cls.__save_order_begin_data(code, order_begin_pos) cls.__LimitUpTimeManager.save_limit_up_time(code, total_datas[order_begin_pos.buy_exec_index]["val"]["time"]) l2_log.debug(code, "delete_buy_cancel_point") @@ -1623,9 +1529,36 @@ _start_time = tool.get_now_timestamp() total_datas = local_today_datas[code] - # ---------璁$畻婵�杩涗拱鍏ョ殑淇″彿--------- + # 涓嶉渶瑕佹牴鎹汉涓轰笅鍗曟潵涓嬪崟 + # if not HumanRadicalBuySingleManager.has_single(code): + # # ---------璁$畻婵�杩涗拱鍏ョ殑淇″彿--------- + # radical_result = cls.__compute_radical_order_begin_pos(code, compute_start_index, compute_end_index) + # else: + # human_radical_result = cls.__compute_human_radical_order_begin_pos(code, compute_start_index, + # compute_end_index) + # l2_log.debug(code, f"澶у崟瓒冲锛屼汉涓轰笅鍗曡绠楃粨鏋�({compute_start_index}-{compute_end_index}):{human_radical_result}") + # if human_radical_result[0]: + # radical_result = list(human_radical_result[2]) + # # 鏀瑰彉鎵ц浣嶇疆 + # radical_result[1] = human_radical_result[1]["index"] + # else: + # radical_result = None + radical_result = cls.__compute_radical_order_begin_pos(code, compute_start_index, compute_end_index) - if radical_result[0]: + if radical_result and radical_result[0]: + + # if not HumanRadicalBuySingleManager.has_single(code): + # big_order_deal_enough_result = radical_buy_data_manager.is_big_order_deal_enough(code, + # code_volumn_manager.CodeVolumeManager().get_volume_rate_refer_in_5days( + # code), 0) + # if big_order_deal_enough_result[6] <= 0: + # HumanRadicalBuySingleManager.add_single(code, total_datas[-1], radical_result) + # async_log_util.info(logger_l2_not_buy_reasons, f"{code}#澶у崟瓒冲锛岄渶瑕佹牴鎹汉涓轰笅鍗�({compute_start_index}-{compute_end_index})锛歿radical_result[1]}") + # return + # #涓嬪崟鍓嶄竴姝ワ紝绉婚櫎浜轰负涓嬪崟淇″彿 + # is_human_radical_buy = HumanRadicalBuySingleManager.has_single(code) + # HumanRadicalBuySingleManager.remove_single(code) + buy_single_index, buy_exec_index = radical_result[1], radical_result[1] buy_volume_rate = cls.volume_rate_info[code][0] refer_sell_data = cls.__L2MarketSellManager.get_refer_sell_data(code, total_datas[buy_single_index]["val"][ @@ -1645,7 +1578,9 @@ mode=OrderBeginPosInfo.MODE_RADICAL, mode_desc=f"澶у崟涓嶈冻鎵叆:{radical_result[2]}", sell_info=sell_info, - threshold_money=threshold_money) + threshold_money=threshold_money, + min_order_no=radical_result[5] + ) order_begin_pos_info.at_limit_up = cls.__is_at_limit_up_buy(code) ordered = cls.__process_with_find_exec_index(code, order_begin_pos_info, compute_end_index, block_info=radical_result[3]) @@ -1654,7 +1589,36 @@ # 鐩戝惉澶у崟 RDCancelBigNumComputer().set_watch_indexes(code, radical_result[4]) return + else: + radical_result = cls.__compute_radical_order_begin_pos_for_many_sell(code, compute_start_index, + compute_end_index) + if radical_result[0]: + buy_single_index, buy_exec_index = radical_result[0][0], radical_result[0][1] + buy_volume_rate = cls.volume_rate_info[code][0] + refer_sell_data = cls.__L2MarketSellManager.get_refer_sell_data(code, + total_datas[buy_single_index]["val"][ + "time"]) + if refer_sell_data: + sell_info = (refer_sell_data[0], refer_sell_data[1]) + else: + sell_info = (total_datas[buy_single_index]["val"]["time"], 0) + threshold_money = 0 + order_begin_pos_info = OrderBeginPosInfo(buy_single_index=buy_single_index, + buy_exec_index=buy_exec_index, + buy_compute_index=buy_exec_index, + num=total_datas[buy_single_index]["val"]["num"], count=1, + max_num_set=set(), + buy_volume_rate=buy_volume_rate, + mode=OrderBeginPosInfo.MODE_RADICAL, + mode_desc=f"鎬绘姏鍘嬪ぇ鎵叆:{radical_result[2]}", + sell_info=sell_info, + threshold_money=threshold_money) + order_begin_pos_info.at_limit_up = cls.__is_at_limit_up_buy(code) + ordered = cls.__process_with_find_exec_index(code, order_begin_pos_info, compute_end_index, + block_info=radical_result[2]) + if ordered: + radical_buy_data_manager.BlockPlaceOrderRecordManager().add_record(code, radical_result[2]) if RadicalBuyDealCodesManager().get_code_blocks(code): # 宸茬粡鎵叆涓嬭繃鍗� return @@ -2059,6 +2023,7 @@ return False, -1, "鏈幏鍙栧埌绉瀬涔扮殑璧峰淇″彿", '', OrderBeginPosInfo.MODE_NORMAL # 璁$畻婵�杩涗拱鐨勪笅鍗曚俊鍙� + # 璁$畻婵�杩涗拱鐨勪笅鍗曚俊鍙� @classmethod def __compute_radical_order_begin_pos(cls, code, start_index, end_index): """ @@ -2068,32 +2033,36 @@ @param code: @param start_index: @param end_index: - @return: (鏄惁鑾峰彇鍒颁俊鍙�, 淇″彿浣嶇疆, 鎵叆鏉垮潡/娑堟伅, 鎵叆鏉垮潡澶у崟娴佸叆淇℃伅, 闇�瑕佺洃鍚殑澶у崟) + @return: (鏄惁鑾峰彇鍒颁俊鍙�, 淇″彿浣嶇疆, 鎵叆鏉垮潡/娑堟伅, 鎵叆鏉垮潡澶у崟娴佸叆淇℃伅, 闇�瑕佺洃鍚殑澶у崟, 缁熻涓婃澘澶у崟鎴愪氦鐨勬渶灏忚鍗曞彿) """ # 婵�杩涗拱淇″彿鐨勬椂闂� - def __can_order(): # 鍒ゆ柇鏄惁鏄澘涓婃斁閲� - if cls.__is_at_limit_up_buy(code, start_index): - return False, None, "鏉夸笂鏀鹃噺", None + # if cls.__is_at_limit_up_buy(code, start_index): + # return False, None, "鏉夸笂鏀鹃噺", None total_datas = local_today_datas[code] limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) bigger_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) - min_num = int(bigger_money / limit_up_price / 100) + bigger_money_num, current_min_num, total_min_num = int(bigger_money / limit_up_price / 100), int( + bigger_money / limit_up_price / 100), int(5000 / limit_up_price) refer_sell_data = L2MarketSellManager().get_refer_sell_data(code, radical_data[3]) # 鍙傝�冩�诲崠棰� refer_sell_money = 0 if refer_sell_data: refer_sell_money = refer_sell_data[1] - # 澶у崟鍒ゆ柇缁撴灉 + # 鍒ゆ柇杩橀渶澶у崟鐨勯噾棰濓紙max(姣忔涓婃澘澶у崟,绱鎴愪氦澶у崟)锛� big_order_deal_enough_result = radical_buy_data_manager.is_big_order_deal_enough(code, code_volumn_manager.CodeVolumeManager().get_volume_rate_refer_in_5days( code), - refer_sell_money) + refer_sell_money, + for_buy=True, + is_almost_open_limit_up= + radical_data[5]) # 缂轰箯鐨勫ぇ鍗曢噾棰� - lack_money = big_order_deal_enough_result[3] + current_lack_money = int(big_order_deal_enough_result[5]) + total_lack_money = int(big_order_deal_enough_result[6]) # 濡傛灉鏈夊ぇ鍗曟垚浜ゅ氨涓嶉渶瑕佺湅澶у崟 if constant.CAN_RADICAL_BUY_NEED_BIG_ORDER_EVERYTIME: # 姣忔涓嬪崟閮介渶瑕佸ぇ鍗� @@ -2104,8 +2073,14 @@ # 60s浠ヤ笂灏变笉涓嬪崟浜� return False, None, "璺濈涓婃缁熻澶у崟鏃堕棿杩囧幓60s", set() - if lack_money == 0: - min_num = int(5000 / limit_up_price) + if max(current_lack_money, total_lack_money) <= 0: + # 宸茬粡涓嶇己灏戝ぇ鍗曚簡 + # if not tool.is_sh_code(code): + # 闈炰笂璇佺殑绁ㄧ湅50w + current_min_num = int(5000 / limit_up_price) + # 濡傛灉绱澶у崟鎴愪氦瓒冲锛屽彧闇�鐪�50w + # if big_order_deal_enough_result[4]: + # min_num = int(5000 / limit_up_price) # 闇�瑕佺洃鍚殑澶у崟 watch_indexes = set() # 鎬诲鎵樺ぇ鍗曢噾棰� @@ -2121,8 +2096,6 @@ 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, @@ -2137,23 +2110,40 @@ # 鍒ゆ柇鏄惁涓哄ぇ鍗� order_money = dealing_active_order_info[2] + round(val["price"], 2) * val["num"] * 100 if order_money >= bigger_money: - lack_money -= order_money - watch_indexes.add(i) - if lack_money < 0: + if val["num"] >= bigger_money_num: + watch_indexes.add(i) + if val["num"] >= current_min_num: + current_lack_money -= order_money + if val["num"] >= total_min_num: + total_lack_money -= order_money + if max(current_lack_money, total_lack_money) < 0: single_index = i break if int(val["orderNo"]) <= radical_data[1]: # 涓诲姩涔板崟鍚庣殑鏁版嵁涓嶇畻 continue - watch_indexes.add(i) - lack_money -= round(val["price"], 2) * val["num"] * 100 - if lack_money < 0: + + if val["num"] >= bigger_money_num: + watch_indexes.add(i) + + if val["num"] >= current_min_num: + current_lack_money -= round(val["price"], 2) * val["num"] * 100 + + if val["num"] >= total_min_num: + total_lack_money -= round(val["price"], 2) * val["num"] * 100 + + if max(current_lack_money, total_lack_money) < 0: single_index = i break if single_index is not None: - return True, single_index, "鏈夊ぇ鍗�", watch_indexes - return False, None, "鏃犲ぇ鍗�", watch_indexes + every_time_big_orders = EveryLimitupBigDealOrderManager.list_big_buy_deal_orders(code) + if every_time_big_orders: + min_order_no = min(min(every_time_big_orders, key=lambda e: e[0])[0], radical_data[1]) + else: + min_order_no = radical_data[1] + return True, single_index, f"鏈夊ぇ鍗�,澶у崟鎯呭喌锛歿big_order_deal_enough_result[1]}", watch_indexes, min_order_no + return False, None, f"澶у崟涓嶈冻锛歿trade_index}-{end_index} 缂哄皯鐨勫ぇ鍗�-{max(current_lack_money, total_lack_money)} 澶у崟鎯呭喌锛歿big_order_deal_enough_result[1]}", watch_indexes, None radical_data = RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.get(code) record_codes = radical_buy_data_manager.BlockPlaceOrderRecordManager().get_codes() @@ -2174,7 +2164,7 @@ return False, None, "瓒呰繃鐢熸晥鏃堕棿" result = __can_order() - l2_log.debug(code, f"L2鎵叆鍒ゆ柇锛歿result}") + l2_log.debug(code, f"L2鎵叆鍒ゆ柇({start_index}-{end_index})锛歿result}") if result[0]: # 宸茬粡鎵叆涓嬭繃鍗曚笖鍏佽鏉夸笂鏀鹃噺鎵叆鐨勫氨闇�瑕佸垽鏂澘涓婃斁閲忕殑璺濈 if is_radical_buy and constant.CAN_RADICAL_BUY_AT_LIMIT_UP: @@ -2197,8 +2187,134 @@ # 濡傛灉鏉夸笂鏀鹃噺涓嶅彲涔板叆灏遍渶瑕佸垹闄や俊鍙� if not constant.CAN_RADICAL_BUY_AT_LIMIT_UP and code in RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict: RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.pop(code) - return True, result[1], radical_data[2], radical_data[4], result[3] + return True, result[1], radical_data[2], radical_data[4], result[3], result[4] + else: + async_log_util.info(logger_l2_not_buy_reasons, f"{code}#{result[2]}") return result + + @classmethod + def __compute_human_radical_order_begin_pos(cls, code, start_index, end_index): + """ + 澶勭悊璺熶汉涔� + @param code: + @param start_index: + @param end_index: + @return: + """ + total_datas = local_today_datas.get(code) + result = HumanRadicalBuySingleManager.is_valid(code, total_datas[start_index]) + if not result[0]: + return False, None, result[1] + result = result[1] + single_time_ms, space_time_ms, expire_time_ms, radical_result = result[0], result[1], result[2], result[3] + + bigger_num = l2_data_util.get_big_money_val(gpcode_manager.get_limit_up_price_as_num(code), + tool.is_ge_code(code)) // ( + gpcode_manager.get_limit_up_price_as_num(code) * 100) + canceled_buyno_map = local_today_buyno_map.get(code) + for i in range(start_index, end_index + 1): + data = total_datas[i] + val = data["val"] + if not L2DataUtil.is_limit_up_price_buy(val): + continue + if val["num"] < bigger_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: + continue + + # 鍒ゆ柇鏄惁瓒呰繃鐢熸晥鏃堕棿 + if tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(total_datas[i]["val"]), + expire_time_ms) > 0: + HumanRadicalBuySingleManager.remove_single(code) + return False, None, "瓒呰繃淇″彿鐢熸晥鏃堕棿" + is_valid = False + # 鍒ゆ柇璺濈涓婁釜50w涔板崟鐨勬椂闂存槸鍚﹁秴杩囦簡space_time_ms + buy_exec_index = radical_result[1] + for ii in range(i - 1, buy_exec_index, -1): + data_child = total_datas[ii] + val_child = data_child["val"] + if not L2DataUtil.is_limit_up_price_buy(val_child): + continue + if val_child["num"] * float(val_child["price"]) < 5000: + continue + if tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(val), + L2DataUtil.get_time_with_ms(val_child)) > space_time_ms: + is_valid = True + break + if is_valid: + return True, data, radical_result + return False, None, "娌℃湁鏈夋晥淇″彿" + + # 鎬诲崠棰濆弬鑰冩椂闂翠娇鐢ㄨ褰� + __refer_sell_used_times = {} + + @classmethod + def __compute_radical_order_begin_pos_for_many_sell(cls, code, start_index, end_index): + """ + 璁$畻娣辫瘉楂樻姏鍘嬬殑鍗栫殑涔板叆淇″彿 + @param code: + @param start_index: + @param end_index: + @return: 淇″彿淇℃伅锛堜俊鍙蜂綅,鎵ц浣嶏級, 娑堟伅, 鍙拱鍏ョ殑鏉垮潡 + """ + if True: + return None, "姝ゆ潯涓嶇敓鏁�", None + if not tool.is_sz_code(code): + return None, "闈炴繁璇佺殑绁�", None + # 鍒ゆ柇鎶涘帇鏄惁澶т簬5000w + total_datas = local_today_datas.get(code) + refer_sell_data = cls.__L2MarketSellManager.get_refer_sell_data(code, total_datas[-1]["val"]["time"]) + if not refer_sell_data or refer_sell_data[1] < 5e7: + return None, "鎬诲崠棰濆皬浜�5000涓�", None + if code in cls.__refer_sell_used_times and refer_sell_data[0] in cls.__refer_sell_used_times: + return None, f"鏃堕棿宸茬粡琚娇鐢細{refer_sell_data[0]}", None + + deal_codes = RadicalBuyDealCodesManager().get_deal_codes() + if code in deal_codes: + return None, f"宸茬粡鎴愪氦", None + + f_buy_blocks, orgin_buy_blocks = radical_buy_strategy.compute_can_radical_buy_blocks(code, deal_codes) + if not f_buy_blocks: + return None, f"鏉垮潡涓嶅彲涔板叆", None + + # 鍒ゆ柇鏄惁鏈夋定鍋滀拱鐨勬暟鎹� + has_limit_up = False + for i in range(start_index, end_index + 1): + data = total_datas[i] + val = data["val"] + if L2DataUtil.is_limit_up_price_buy(val): + has_limit_up = True + break + if not has_limit_up: + return None, "鏃犳定鍋滀拱鏁版嵁", None + # 鏌ユ壘璁℃暟璧风偣 + refer_sell_time_int = int(refer_sell_data[0].replace(":", "")) + begin_index = start_index + for i in range(start_index - 1, -1, -1): + data = total_datas[i] + val = data["val"] + if int(val["time"].replace(":", "")) < refer_sell_time_int: + begin_index = i + 1 + break + threshold_num = int(round(refer_sell_data[1] / gpcode_manager.get_limit_up_price_as_num(code) / 100)) + total_num = 0 + for i in range(begin_index, end_index + 1): + data = total_datas[i] + val = data["val"] + if L2DataUtil.is_limit_up_price_buy(val): + total_num += val["num"] + elif L2DataUtil.is_limit_up_price_buy_cancel(val): + total_num -= val["num"] + if total_num > threshold_num: + if code not in cls.__refer_sell_used_times: + cls.__refer_sell_used_times[code] = set() + cls.__refer_sell_used_times[code].add(refer_sell_data[0]) + return (begin_index, end_index), "鍙互涓嬪崟", f_buy_blocks + return None, "鎬讳拱棰濅笉婊¤冻", None @classmethod def test__compute_active_order_begin_pos(cls, code, continue_count, start_index, end_index): @@ -2272,6 +2388,7 @@ if place_order_count is None: place_order_count = 0 is_ge_code = tool.is_ge_code(code) + buy_no_map = local_today_buyno_map.get(code) for i in range(compute_start_index, compute_end_index + 1): data = total_datas[i] _val = total_datas[i]["val"] @@ -2307,10 +2424,8 @@ elif L2DataUtil.is_limit_up_price_buy_cancel(_val): # 鍒ゆ柇涔板叆浣嶇疆鏄惁鍦ㄤ拱鍏ヤ俊鍙蜂箣鍓� buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i], - local_today_buyno_map.get( - code)) + buy_no_map) if buy_index is not None: - # 鎵惧埌涔版挙鏁版嵁鐨勪拱鍏ョ偣 if buy_index >= buy_single_index: max_buy_num_set.discard(buy_index) @@ -2411,6 +2526,7 @@ max_buy_num_set = set(max_num_set) active_buy_blocks = cls.get_active_buy_blocks(code) is_ge_code = tool.is_ge_code(code) + buyno_map = local_today_buyno_map.get(code) for i in range(compute_start_index, compute_end_index + 1): data = total_datas[i] _val = total_datas[i]["val"] @@ -2449,8 +2565,7 @@ elif L2DataUtil.is_limit_up_price_buy_cancel(_val): # 鍒ゆ柇涔板叆浣嶇疆鏄惁鍦ㄤ拱鍏ヤ俊鍙蜂箣鍓� buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i], - local_today_buyno_map.get( - code)) + buyno_map) if buy_index is not None: # 鎵惧埌涔版挙鏁版嵁鐨勪拱鍏ョ偣 -- Gitblit v1.8.0