| | |
| | | "zyltgb": constant.RADICAL_BUY_ZYLTGB_AS_YI_RANGES, |
| | | "top_block_count_by_market_strong": constant.RADICAL_BUY_TOP_IN_COUNT_BY_MARKET_STRONG, |
| | | "special_codes_max_block_in_rank": constant.RADICAL_BUY_TOP_IN_INDEX_WITH_SPECIAL, |
| | | "ignore_block_in_money_market_strong": constant.IGNORE_BLOCK_IN_MONEY_MARKET_STRONG |
| | | "ignore_block_in_money_market_strong": constant.IGNORE_BLOCK_IN_MONEY_MARKET_STRONG, |
| | | "buy_first_limit_up": 1 if constant.CAN_BUY_FIRST_LIMIT_UP else 0 |
| | | }} |
| | | self.send_response({"code": 0, "data": data, "msg": f""}, |
| | | client_id, |
| | |
| | | if radical_buy.get('ignore_block_in_money_market_strong') is not None: |
| | | constant.IGNORE_BLOCK_IN_MONEY_MARKET_STRONG = radical_buy.get( |
| | | 'ignore_block_in_money_market_strong') |
| | | if radical_buy.get('buy_first_limit_up') is not None: |
| | | constant.CAN_BUY_FIRST_LIMIT_UP = True if radical_buy.get( |
| | | 'buy_first_limit_up') else False |
| | | |
| | | self.send_response({"code": 0, "data": {}, "msg": f""}, |
| | | client_id, |
| | | request_id) |
| | |
| | | canceled_num = 0 |
| | | # 记录撤单索引 |
| | | canceled_indexes = [] |
| | | |
| | | deal_order_nos = HuaXinBuyOrderManager().get_deal_buy_order_nos(code) |
| | | if deal_order_nos is None: |
| | | deal_order_nos = set() |
| | | trade_index, is_default = TradeBuyQueue().get_traded_index(code) |
| | | if is_default: |
| | | trade_index = None |
| | | canceled_buyno_map = local_today_canceled_buyno_map.get(code) |
| | | for wi in watch_indexes: |
| | | cancel_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(code, |
| | | wi, |
| | | total_data, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | cancel_data = L2DataComputeUtil.is_canceled(code, wi, total_data, canceled_buyno_map, trade_index, deal_order_nos) |
| | | if cancel_data: |
| | | if str(wi) in after_place_order_index_dict: |
| | | # 真实下单位置之后的按照权重比例来计算 |
| | |
| | | 10 - after_place_order_index_by_dict[str(wi)]) // 10 |
| | | else: |
| | | canceled_num += total_data[wi]["val"]["num"] |
| | | |
| | | canceled_indexes.append(cancel_data["index"]) |
| | | # if wi == watch_indexes_list[-1] and left_count == 0: |
| | | # # 离下单位置最近的一个撤单,必须触发撤单 |
| | |
| | | # 新版L2监听 |
| | | IS_L2_NEW = True |
| | | |
| | | # 是否可买首封 |
| | | CAN_BUY_FIRST_LIMIT_UP = True |
| | | |
| | | |
| | |
| | | |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | logger_local_huaxin_l2_error.exception(e) |
| | | finally: |
| | | temp_list.clear() |
| | | |
| | |
| | | max_info = (i, val["num"]) |
| | | return total_datas[max_info[0]] |
| | | |
| | | @classmethod |
| | | def is_canceled(cls, code, index, total_datas, canceled_buyno_map, trade_index, deal_order_nos): |
| | | """ |
| | | 是否已经撤单 |
| | | @param deal_order_nos: 成交大单集合 |
| | | @param trade_index: 成交进度位 |
| | | @param index: 索引 |
| | | @param code: 代码 |
| | | @param total_datas: |
| | | @param canceled_buyno_map:撤单的订单号 |
| | | @return: |
| | | """ |
| | | cancel_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(code, index, |
| | | total_datas, |
| | | canceled_buyno_map) |
| | | if cancel_data: |
| | | # 已经撤单 |
| | | return True |
| | | else: |
| | | if trade_index and trade_index > index: |
| | | # 成交进度大于索引位置,且还没成交 |
| | | if total_datas[index]["val"]["orderNo"] not in deal_order_nos: |
| | | return True |
| | | return False |
| | | |
| | | |
| | | # ---------------------------------D撤------------------------------- |
| | | # 计算 成交位->真实下单位置 总共还剩下多少手没有撤单 |
| | |
| | | def set_real_place_order_index(self, code, index, buy_single_index, is_default): |
| | | if is_default: |
| | | return |
| | | if code in self.__watch_indexes_cache and len(self.__watch_indexes_cache[code]) > 1: |
| | | if code in self.__watch_indexes_cache and len(self.__watch_indexes_cache[code]) > 1: |
| | | # 囊括的单大于1个 |
| | | return |
| | | # 从买入信号位开始囊括 |
| | |
| | | @param end_index: |
| | | @return: 是否需要撤单,撤单索引, 消息 |
| | | """ |
| | | buyno_map = local_today_buyno_map.get(code) |
| | | watch_indexes = self.__watch_indexes_cache.get(code) |
| | | if not watch_indexes: |
| | | return False, None, "无大单监听" |
| | |
| | | continue |
| | | if val["num"] * float(val["price"]) < 5000: |
| | | continue |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(data, |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(data, buyno_map) |
| | | if buy_index is None: |
| | | continue |
| | | if buy_index in watch_indexes: |
| | | need_compute = True |
| | | break |
| | | cancel_indexes = set() |
| | | if need_compute: |
| | | canceled_buyno_map = local_today_canceled_buyno_map.get(code) |
| | | if need_compute or True: |
| | | cancel_count = 0 |
| | | cancel_data = None |
| | | # 成交买单号 |
| | | deal_order_nos = HuaXinBuyOrderManager().get_deal_buy_order_nos(code) |
| | | if deal_order_nos is None: |
| | | deal_order_nos = set() |
| | | trade_index, is_default = TradeBuyQueue().get_traded_index(code) |
| | | if is_default: |
| | | trade_index = None |
| | | for index in watch_indexes: |
| | | cancel_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(code, index, |
| | | total_datas, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if cancel_data: |
| | | if L2DataComputeUtil.is_canceled(code, index, total_datas, canceled_buyno_map, trade_index, |
| | | deal_order_nos): |
| | | # 买单已撤单 |
| | | cancel_count += 1 |
| | | cancel_indexes.add(index) |
| | | rate = round(cancel_count / len(watch_indexes), 2) |
| | |
| | | if dealing_info and str(dealing_info[0]) == str(val["orderNo"]): |
| | | total_left_num -= dealing_info[1] // 100 |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | total_left_money = total_left_num * float(limit_up_price)*100 |
| | | total_left_money = total_left_num * float(limit_up_price) * 100 |
| | | if total_left_money < 1e8: |
| | | if total_left_count <= 1 or (total_left_count <= THRESHOLD_COUNT and limit_up_price and total_left_num * float( |
| | | if total_left_count <= 1 or ( |
| | | total_left_count <= THRESHOLD_COUNT and limit_up_price and total_left_num * float( |
| | | limit_up_price) < THRESHOLD_MONEY_W * 100): |
| | | return True, f"剩余笔数({total_left_count})/金额({round(total_left_num * float(limit_up_price) * 100)})不足,成交进度:{trade_index},真实下单位置:{real_order_index} 阈值:({THRESHOLD_MONEY_W},{THRESHOLD_COUNT}) " |
| | | return False, f"不满足撤单条件: 成交进度-{trade_index} 真实下单位置-{real_order_index} total_left_count-{total_left_count} total_left_num-{total_left_num}" |
| | |
| | | # 计算我们后面的大单与涨停纯买额 |
| | | total_left_num = 0 |
| | | total_big_num_count = 0 |
| | | canceled_buyno_map = local_today_canceled_buyno_map.get(code) |
| | | canceled_buyno_map = local_today_canceled_buyno_map.get(code) |
| | | for i in range(real_order_index + 1, len(total_datas)): |
| | | data = total_datas[i] |
| | | val = data["val"] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | money = val["num"] * float(val["price"])*100 |
| | | money = val["num"] * float(val["price"]) * 100 |
| | | if money < 500000: |
| | | continue |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, |
| | |
| | | if total_count >= max_count: |
| | | return i |
| | | return end_index |
| | | |
| | | @classmethod |
| | | def is_canceled(cls, code, index, total_datas, canceled_buyno_map, trade_index, deal_order_nos): |
| | | """ |
| | | 是否已经撤单 |
| | | @param deal_order_nos: 成交大单集合 |
| | | @param trade_index: 成交进度位 |
| | | @param index: 索引 |
| | | @param code: 代码 |
| | | @param total_datas: |
| | | @param canceled_buyno_map:撤单的订单号 |
| | | @return: |
| | | """ |
| | | cancel_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(code, index, |
| | | total_datas, |
| | | canceled_buyno_map) |
| | | if cancel_data: |
| | | # 已经撤单 |
| | | return cancel_data |
| | | else: |
| | | if trade_index and trade_index > index: |
| | | # 成交进度大于索引位置,且还没成交 |
| | | if total_datas[index]["val"]["orderNo"] not in deal_order_nos: |
| | | return total_datas[index] |
| | | return None |
| | |
| | | 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) |
| | |
| | | __dealing_active_buy_order_info_dict = {} |
| | | # 最近成交的订单{"code":(订单号,是否成交完成)} |
| | | __latest_deal_order_info_dict = {} |
| | | # 成交的买单号集合:{"代码":set()} |
| | | __deal_buy_order_nos_dict = {} |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | |
| | | @classmethod |
| | | def __load_datas(cls): |
| | | __redis = cls.__get_redis() |
| | | try: |
| | | keys = RedisUtils.keys(__redis, "dealing_order_info-*") |
| | | for k in keys: |
| | | code = k.split("-")[-1] |
| | | val = RedisUtils.get(__redis, k) |
| | | val = json.loads(val) |
| | | tool.CodeDataCacheUtil.set_cache(cls.__dealing_order_info_dict, code, val) |
| | | finally: |
| | | RedisUtils.realse(__redis) |
| | | |
| | | keys = RedisUtils.keys(__redis, "dealing_order_info-*") |
| | | for k in keys: |
| | | code = k.split("-")[-1] |
| | | val = RedisUtils.get(__redis, k) |
| | | val = json.loads(val) |
| | | tool.CodeDataCacheUtil.set_cache(cls.__dealing_order_info_dict, code, val) |
| | | # 读取已经成交的大单 |
| | | deal_data_list_dict = log_export.load_huaxin_deal_record_all() |
| | | for code in deal_data_list_dict: |
| | | cls.__deal_buy_order_nos_dict[code] = set([x[0] for x in deal_data_list_dict[code]]) |
| | | |
| | | # 将数据持久化到数据库 |
| | | def sync_dealing_data_to_db(self): |
| | |
| | | |
| | | dealing_order_info = cls.__dealing_order_info_dict.get(code) |
| | | |
| | | if code not in cls.__deal_buy_order_nos_dict: |
| | | cls.__deal_buy_order_nos_dict[code] = set() |
| | | deal_buy_order_nos = cls.__deal_buy_order_nos_dict[code] |
| | | |
| | | for data in fdatas: |
| | | # q.append((data['SecurityID'], data['TradePrice'], data['TradeVolume'], |
| | | # data['OrderTime'], data['MainSeq'], data['SubSeq'], data['BuyNo'], |
| | |
| | | # if abs(deal_info[5] - limit_up_price) < 0.0001: |
| | | big_buy_datas.append(deal_info) |
| | | if deal_info[2] >= 500000: |
| | | deal_buy_order_nos.add(deal_info[0]) |
| | | normal_buy_datas.append(deal_info) |
| | | # 初始化本条数据 |
| | | dealing_order_info = [current_order_info[6], current_order_info[2], money, |
| | |
| | | current_order_info[3], |
| | | current_order_info[3]] |
| | | return big_buy_datas, normal_buy_datas |
| | | |
| | | def get_deal_buy_order_nos(self, code): |
| | | """ |
| | | 获取成交大单集合 |
| | | @param code: |
| | | @return: |
| | | """ |
| | | return self.__deal_buy_order_nos_dict.get(code) |
| | | |
| | | |
| | | # 卖单统计数据 |
| | |
| | | cls.__latest_sell_order_dict[code] = latest_sell_order |
| | | if big_sell_order_ids: |
| | | cls.__big_sell_order_ids_dict[code] = big_sell_order_ids |
| | | if big_sell_order_info: |
| | | if big_sell_order_info: |
| | | cls.__big_sell_order_info_dict[code] = big_sell_order_info |
| | | if big_sell_order_info_list: |
| | | if big_sell_order_info_list: |
| | | cls.__big_sell_order_info_list_dict[code] = big_sell_order_info_list |
| | | if latest_all_sell_orders: |
| | | if latest_all_sell_orders: |
| | | cls.__latest_all_sell_orders_dict[code] = latest_all_sell_orders |
| | | |
| | | use_time = time.time() - __start_time |
| | |
| | | @classmethod |
| | | def get_latest_trade_price_info(cls, code): |
| | | return cls.__latest_trade_price_dict.get(code) |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | code = "603300" |
| | | order_nos = HuaXinBuyOrderManager().get_deal_buy_order_nos(code) |
| | | print(order_nos) |
| | |
| | | # 加载l2订单成交数据 |
| | | @cache_log |
| | | def load_huaxin_deal_record(code, date=tool.get_now_date_str()): |
| | | datas_dict = load_huaxin_deal_record_all(date) |
| | | return datas_dict.get(code) |
| | | |
| | | |
| | | @cache_log |
| | | def load_huaxin_deal_record_all(date=tool.get_now_date_str()): |
| | | path = f"{constant.get_path_prefix()}/logs/huaxin/l2/transaction_desc.{date}.log" |
| | | # 格式:[(订单号,手数,开始成交时间,成交结束时间,下单手数)] |
| | | fdatas = [] |
| | | fdatas = {} |
| | | lines = __load_file_content(path) |
| | | for line in lines: |
| | | data_index = line.find(f"{code}#") |
| | | data_index = line.find(f"#") |
| | | if data_index > 0: |
| | | time_str, data = __parse_content(line) |
| | | code = data.split("#")[0] |
| | | data = data.split("#")[1] |
| | | data = eval(data) |
| | | fdatas.append(data) |
| | | if code not in fdatas: |
| | | fdatas[code] = [] |
| | | fdatas[code].append(data) |
| | | return fdatas |
| | | |
| | | |