| | |
| | | import logging |
| | | import threading |
| | | import time as t |
| | | |
| | | from code_attribute import big_money_num_manager, code_volumn_manager, code_data_util, industry_codes_sort, \ |
| | |
| | | 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 |
| | | from l2 import l2_data_manager, l2_log, l2_data_source_util, code_price_manager, \ |
| | | transaction_progress, cancel_buy_strategy |
| | | transaction_progress, cancel_buy_strategy, place_order_single_data_manager |
| | | from l2.cancel_buy_strategy import SCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer, \ |
| | | LCancelBigNumComputer, LatestCancelIndexManager, LCancelRateManager, GCancelBigNumComputer |
| | | from l2.l2_data_manager import L2DataException, OrderBeginPosInfo |
| | |
| | | __MarketSituationManager = MarketSituationManager() |
| | | __re_compute_threading_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10) |
| | | |
| | | # 买入锁 |
| | | __buy_lock_dict = {} |
| | | |
| | | # 获取代码评分 |
| | | @classmethod |
| | | def get_code_scores(cls): |
| | |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | if limit_up_price: |
| | | 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 |
| | | # if trade_price_info and limit_up_price and trade_price_info[0] == limit_up_price: |
| | | # filter_limit_up_sell = True |
| | | datas = l2_huaxin_util.get_format_l2_datas(code, origin_datas, limit_up_price, _start_index, |
| | | filter_limit_up_sell) |
| | | __start_time = round(t.time() * 1000) |
| | |
| | | try: |
| | | for d in add_datas: |
| | | if L2DataUtil.is_limit_up_price_sell(d['val']): |
| | | L2TradeSingleDataProcessor.add_l2_delegate_limit_up_sell(code,d) |
| | | elif L2DataUtil.is_limit_up_price_sell_cancel(d['val']): |
| | | L2TradeSingleDataProcessor.add_l2_delegate_limit_up_sell_cancel(code,d['val']['orderNo']) |
| | | L2TradeSingleDataProcessor.add_l2_delegate_limit_up_sell(code, d) |
| | | elif L2DataUtil.is_limit_up_price_sell_cancel(d['val']): |
| | | L2TradeSingleDataProcessor.add_l2_delegate_limit_up_sell_cancel(code, |
| | | d['val']['orderNo']) |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | except: |
| | |
| | | pass |
| | | |
| | | @classmethod |
| | | def start_buy(cls, code, last_data, last_data_index, is_first_code): |
| | | cls.__buy(code, 0, last_data, last_data_index, is_first_code) |
| | | |
| | | @classmethod |
| | | def __buy(cls, code, capture_timestamp, last_data, last_data_index, is_first_code): |
| | | __start_time = tool.get_now_timestamp() |
| | | can, need_clear_data, reason = False, False, "" |
| | | if not is_first_code: |
| | | can, need_clear_data, reason = cls.__can_buy(code) |
| | | else: |
| | | can, need_clear_data, reason = cls.__can_buy_first(code) |
| | | # 添加买入锁 |
| | | if code not in cls.__buy_lock_dict: |
| | | cls.__buy_lock_dict[code] = threading.Lock() |
| | | |
| | | # __start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - __start_time, "最后判断是否能下单", force=True) |
| | | # 删除虚拟下单 |
| | | if code in cls.unreal_buy_dict: |
| | | cls.unreal_buy_dict.pop(code) |
| | | with cls.__buy_lock_dict[code]: |
| | | # 判断是否可以下单,不处于可下单状态需要返回 |
| | | state = cls.__CodesTradeStateManager.get_trade_state_cache(code) |
| | | if state == trade_manager.TRADE_STATE_BUY_DELEGATED or state == trade_manager.TRADE_STATE_BUY_PLACE_ORDER or state == trade_manager.TRADE_STATE_BUY_SUCCESS: |
| | | # 不处于可下单状态 |
| | | return False |
| | | __start_time = tool.get_now_timestamp() |
| | | can, need_clear_data, reason = False, False, "" |
| | | if not is_first_code: |
| | | can, need_clear_data, reason = cls.__can_buy(code) |
| | | else: |
| | | can, need_clear_data, reason = cls.__can_buy_first(code) |
| | | |
| | | order_begin_pos = cls.__get_order_begin_pos( |
| | | code) |
| | | if not can: |
| | | l2_log.debug(code, "不可以下单,原因:{}", reason) |
| | | trade_record_log_util.add_cant_place_order_log(code, reason) |
| | | if need_clear_data: |
| | | 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 |
| | | else: |
| | | l2_log.debug(code, "可以下单,原因:{}", reason) |
| | | try: |
| | | 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) |
| | | l2_log.debug(code, "执行买入成功") |
| | | ################下单成功处理################ |
| | | trade_result_manager.real_buy_success(code, cls.__TradePointManager) |
| | | l2_log.debug(code, "处理买入成功1") |
| | | cancel_buy_strategy.set_real_place_position(code, local_today_datas.get(code)[-1]["index"], |
| | | order_begin_pos.buy_single_index, is_default=True) |
| | | l2_log.debug(code, "处理买入成功2") |
| | | params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc() |
| | | l2_log.debug(code, params_desc) |
| | | ############记录下单时的数据############ |
| | | # __start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - __start_time, "最后判断是否能下单", force=True) |
| | | # 删除虚拟下单 |
| | | if code in cls.unreal_buy_dict: |
| | | cls.unreal_buy_dict.pop(code) |
| | | |
| | | order_begin_pos = cls.__get_order_begin_pos( |
| | | code) |
| | | if not can: |
| | | l2_log.debug(code, "不可以下单,原因:{}", reason) |
| | | trade_record_log_util.add_cant_place_order_log(code, reason) |
| | | if need_clear_data: |
| | | 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 |
| | | else: |
| | | l2_log.debug(code, "可以下单,原因:{}", reason) |
| | | try: |
| | | jx_blocks, jx_blocks_by = KPLCodeJXBlockManager().get_jx_blocks_cache( |
| | | code), KPLCodeJXBlockManager().get_jx_blocks_cache(code, by=True) |
| | | if jx_blocks: |
| | | jx_blocks = jx_blocks[0] |
| | | if jx_blocks_by: |
| | | jx_blocks_by = jx_blocks_by[0] |
| | | 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) |
| | | l2_log.debug(code, "执行买入成功") |
| | | ################下单成功处理################ |
| | | trade_result_manager.real_buy_success(code, cls.__TradePointManager) |
| | | l2_log.debug(code, "处理买入成功1") |
| | | cancel_buy_strategy.set_real_place_position(code, local_today_datas.get(code)[-1]["index"], |
| | | order_begin_pos.buy_single_index, is_default=True) |
| | | l2_log.debug(code, "处理买入成功2") |
| | | params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc() |
| | | l2_log.debug(code, params_desc) |
| | | ############记录下单时的数据############ |
| | | try: |
| | | jx_blocks, jx_blocks_by = KPLCodeJXBlockManager().get_jx_blocks_cache( |
| | | code), KPLCodeJXBlockManager().get_jx_blocks_cache(code, by=True) |
| | | if jx_blocks: |
| | | jx_blocks = jx_blocks[0] |
| | | if jx_blocks_by: |
| | | jx_blocks_by = jx_blocks_by[0] |
| | | |
| | | info = cls.__trade_log_placr_order_info_dict[code] |
| | | info.mode = order_begin_pos.mode |
| | | info.set_buy_index(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) |
| | | info.set_sell_info(order_begin_pos.sell_info) |
| | | if jx_blocks: |
| | | info.set_kpl_blocks(list(jx_blocks)) |
| | | elif jx_blocks_by: |
| | | info.set_kpl_blocks(list(jx_blocks_by)) |
| | | else: |
| | | info.set_kpl_blocks([]) |
| | | can_buy_result = CodePlateKeyBuyManager.can_buy(code) |
| | | if can_buy_result: |
| | | if not can_buy_result[0] and can_buy_result[1]: |
| | | info.set_kpl_match_blocks(["独苗"]) |
| | | elif not can_buy_result[0] and not can_buy_result[1]: |
| | | info.set_kpl_match_blocks(["非独苗不满足身位"]) |
| | | info = cls.__trade_log_placr_order_info_dict[code] |
| | | info.mode = order_begin_pos.mode |
| | | info.set_buy_index(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) |
| | | info.set_sell_info(order_begin_pos.sell_info) |
| | | if jx_blocks: |
| | | info.set_kpl_blocks(list(jx_blocks)) |
| | | elif jx_blocks_by: |
| | | info.set_kpl_blocks(list(jx_blocks_by)) |
| | | else: |
| | | temps = [] |
| | | temps.extend(can_buy_result[0]) |
| | | if can_buy_result[5]: |
| | | temps.append(f"激进买入:{can_buy_result[5]}") |
| | | info.set_kpl_match_blocks(temps) |
| | | trade_record_log_util.add_place_order_log(code, info) |
| | | info.set_kpl_blocks([]) |
| | | can_buy_result = CodePlateKeyBuyManager.can_buy(code) |
| | | if can_buy_result: |
| | | if not can_buy_result[0] and can_buy_result[1]: |
| | | info.set_kpl_match_blocks(["独苗"]) |
| | | elif not can_buy_result[0] and not can_buy_result[1]: |
| | | info.set_kpl_match_blocks(["非独苗不满足身位"]) |
| | | else: |
| | | temps = [] |
| | | temps.extend(can_buy_result[0]) |
| | | if can_buy_result[5]: |
| | | temps.append(f"激进买入:{can_buy_result[5]}") |
| | | info.set_kpl_match_blocks(temps) |
| | | trade_record_log_util.add_place_order_log(code, info) |
| | | except Exception as e: |
| | | async_log_util.error(logger_l2_error, f"加入买入记录日志出错:{str(e)}") |
| | | |
| | | |
| | | |
| | | except Exception as e: |
| | | async_log_util.error(logger_l2_error, f"加入买入记录日志出错:{str(e)}") |
| | | |
| | | |
| | | |
| | | except Exception as e: |
| | | async_log_util.exception(logger_l2_error, e) |
| | | l2_log.debug(code, "执行买入异常:{}", str(e)) |
| | | pass |
| | | finally: |
| | | # l2_log.debug(code, "m值影响因子:{}", l2_trade_factor.L2TradeFactorUtil.factors_to_string(code)) |
| | | pass |
| | | return True |
| | | async_log_util.exception(logger_l2_error, e) |
| | | l2_log.debug(code, "执行买入异常:{}", str(e)) |
| | | pass |
| | | finally: |
| | | # l2_log.debug(code, "m值影响因子:{}", l2_trade_factor.L2TradeFactorUtil.factors_to_string(code)) |
| | | pass |
| | | return True |
| | | |
| | | # 是否可以取消 |
| | | @classmethod |
| | |
| | | order_begin_pos.mode = OrderBeginPosInfo.MODE_ACTIVE |
| | | order_begin_pos.sell_info = sell_info |
| | | fast_msg = sell_info |
| | | # 用了信号就必须清除掉原有信号 |
| | | place_order_single_data_manager.L2TradeSingleDataManager.clear_data(code) |
| | | |
| | | # if not has_single: |
| | | # # 第二步:计算闪电下单信号 |
| | |
| | | if code.find("60") == 0: |
| | | threshold_money = 0 |
| | | else: |
| | | for i in range(start_index - 1, -1, -1): |
| | | val = total_datas[i]["val"] |
| | | if tool.compare_time(val["time"], refer_sell_data[0]) < 0: |
| | | # 将本s的计算上去 |
| | | break |
| | | if L2DataUtil.is_sell(val): |
| | | threshold_money += val["num"] * int(float(val["price"]) * 100) |
| | | elif L2DataUtil.is_sell_cancel(val): |
| | | threshold_money -= val["num"] * int(float(val["price"]) * 100) |
| | | elif L2DataUtil.is_buy(val): |
| | | # 判断价格(大于卖1) 被买吃掉 |
| | | if round(float(val["price"]), 2) - sell_1_price >= 0: |
| | | threshold_money -= val["num"] * int(float(val["price"]) * 100) |
| | | pass |
| | | # for i in range(start_index - 1, -1, -1): |
| | | # val = total_datas[i]["val"] |
| | | # if tool.compare_time(val["time"], refer_sell_data[0]) < 0: |
| | | # # 将本s的计算上去 |
| | | # break |
| | | # if L2DataUtil.is_sell(val): |
| | | # threshold_money += val["num"] * int(float(val["price"]) * 100) |
| | | # elif L2DataUtil.is_sell_cancel(val): |
| | | # threshold_money -= val["num"] * int(float(val["price"]) * 100) |
| | | # elif L2DataUtil.is_buy(val): |
| | | # # 判断价格(大于卖1) 被买吃掉 |
| | | # if round(float(val["price"]), 2) - sell_1_price >= 0: |
| | | # threshold_money -= val["num"] * int(float(val["price"]) * 100) |
| | | # 第二步:计算起始信号 |
| | | second_930 = 9 * 3600 + 30 * 60 + 0 |
| | | total_datas = local_today_datas.get(code) |
| | |
| | | if _val["num"] * float(_val["price"]) < 5000: |
| | | continue |
| | | if last_index is None or (total_datas[last_index]["val"]["time"] == total_datas[i]["val"]["time"]): |
| | | single = place_order_single_data_manager.L2TradeSingleDataManager.get_valid_trade_single(code, |
| | | tool.to_time_with_ms( |
| | | _val[ |
| | | 'time'], |
| | | _val[ |
| | | 'tms'])) |
| | | if not single: |
| | | continue |
| | | if start is None: |
| | | start = i |
| | | last_index = i |
| | |
| | | trigger_buy = True |
| | | # 间隔最大时间为3s |
| | | max_space_time_ms = 3 * 1000 |
| | | if code.find("00") == 0 and threshold_money > 0: |
| | | # 深证非板上放量 |
| | | max_space_time_ms = 1 * 1000 |
| | | threshold_num = 0 |
| | | |
| | | # 不下单的信息 |
| | | not_buy_msg = "" |
| | | max_buy_num_set = set(max_num_set) |
| | |
| | | for ii in range(buy_single_index + 1, compute_end_index + 1): |
| | | if total_datas[buy_single_index]["val"]["time"] != total_datas[ii]["val"]["time"]: |
| | | return None, buy_nums, buy_count, ii, threshold_money, max_buy_num_set, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms" |
| | | if L2DataUtil.is_sell(_val): |
| | | threshold_money += _val["num"] * int(float(_val["price"]) * 100) |
| | | threshold_num = round(threshold_money / (limit_up_price * 100)) |
| | | elif L2DataUtil.is_sell_cancel(_val): |
| | | threshold_money -= _val["num"] * int(float(_val["price"]) * 100) |
| | | threshold_num = round(threshold_money / (limit_up_price * 100)) |
| | | # if L2DataUtil.is_sell(_val): |
| | | # threshold_money += _val["num"] * int(float(_val["price"]) * 100) |
| | | # threshold_num = round(threshold_money / (limit_up_price * 100)) |
| | | # elif L2DataUtil.is_sell_cancel(_val): |
| | | # threshold_money -= _val["num"] * int(float(_val["price"]) * 100) |
| | | # threshold_num = round(threshold_money / (limit_up_price * 100)) |
| | | # 涨停买 |
| | | elif L2DataUtil.is_limit_up_price_buy(_val): |
| | | if l2_data_util.is_big_money(_val): |
| | |
| | | if threshold_money <= 0: |
| | | # 板上下单需要安全笔数3笔 |
| | | safe_count = 3 |
| | | elif code.find("00") == 0: |
| | | # 深证非板上放量 |
| | | safe_count = 2 |
| | | |
| | | if buy_count < safe_count: |
| | | not_buy_msg = f"【{i}】安全笔数不足,{buy_count}/{safe_count}" |