From a846b46f15ad309a62fe400cf78dd7fc888155d7 Mon Sep 17 00:00:00 2001 From: Administrator <admin@example.com> Date: 星期一, 26 五月 2025 16:39:19 +0800 Subject: [PATCH] 完善大单够了加白机制 --- l2/l2_data_manager_new.py | 406 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 351 insertions(+), 55 deletions(-) diff --git a/l2/l2_data_manager_new.py b/l2/l2_data_manager_new.py index 15c035a..c1b0e7f 100644 --- a/l2/l2_data_manager_new.py +++ b/l2/l2_data_manager_new.py @@ -19,6 +19,7 @@ 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 @@ -27,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, \ @@ -180,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( @@ -189,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 @@ -216,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: @@ -325,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) # 鑾峰彇鐪熷疄涓嬪崟浣嶇疆涔嬪悗闇�瑕佸垽鏂璅鎾� @@ -391,7 +462,7 @@ 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): @@ -401,24 +472,25 @@ 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: @@ -489,7 +561,7 @@ 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) + 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, @@ -812,15 +884,20 @@ if not cls.__WantBuyCodesManager.is_in_cache( code) and not gpcode_manager.GreenListCodeManager().is_in_cache(code): 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.1: - return False, True, f"鍧囦环娑ㄥ箙({average_rate})灏忎簬10%", True - else: - if average_rate <= 0.05: - return False, True, f"鍧囦环娑ㄥ箙({average_rate})灏忎簬5%", 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 @classmethod @@ -877,7 +954,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( @@ -919,7 +996,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]: - l2_log.debug(code, "涓嶅彲浠ヤ笅鍗曪紝鍘熷洜锛歿}", pre_result[2]) + async_log_util.info(logger_l2_not_buy_reasons, f"{code}#{pre_result[2]}") return False # 娣诲姞涔板叆閿� if code not in cls.__buy_lock_dict: @@ -962,12 +1039,22 @@ 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) 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) @@ -1307,13 +1394,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_P}: + 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_P}: + trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_RD, + trade_constant.CANCEL_TYPE_P}: l2_log.cancel_debug(code, "鎾ゅ崟涓柇锛屽師鍥狅細{}", "鍔犵豢涓嶆槸L鎾�") return False @@ -1375,7 +1464,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") @@ -1433,9 +1522,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"][ @@ -1455,7 +1571,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]) @@ -1464,7 +1582,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 @@ -1869,6 +2016,7 @@ return False, -1, "鏈幏鍙栧埌绉瀬涔扮殑璧峰淇″彿", '', OrderBeginPosInfo.MODE_NORMAL # 璁$畻婵�杩涗拱鐨勪笅鍗曚俊鍙� + # 璁$畻婵�杩涗拱鐨勪笅鍗曚俊鍙� @classmethod def __compute_radical_order_begin_pos(cls, code, start_index, end_index): """ @@ -1878,32 +2026,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, - for_buy=True) + 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: # 姣忔涓嬪崟閮介渶瑕佸ぇ鍗� @@ -1914,10 +2066,14 @@ # 60s浠ヤ笂灏变笉涓嬪崟浜� return False, None, "璺濈涓婃缁熻澶у崟鏃堕棿杩囧幓60s", set() - if lack_money == 0: - if not tool.is_sh_code(code): - # 闈炰笂璇佺殑绁ㄧ湅50w - 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() # 鎬诲鎵樺ぇ鍗曢噾棰� @@ -1933,8 +2089,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, @@ -1949,23 +2103,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, f"澶у崟涓嶈冻锛歿trade_index}-{end_index} 缂哄皯鐨勫ぇ鍗�-{lack_money}", 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() @@ -1986,7 +2157,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: @@ -2009,8 +2180,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): @@ -2084,6 +2381,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"] @@ -2119,10 +2417,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) @@ -2223,6 +2519,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"] @@ -2261,8 +2558,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