| | |
| | | ########华鑫配置######## |
| | | if not is_windows() or True: |
| | | # 下单1手 |
| | | BUY_MONEY_PER_CODE = 500 # 500 if constant.IS_A else 20000 |
| | | BUY_MONEY_PER_CODE = 500 if constant.IS_A else 20000 |
| | | L2_SOURCE_TYPE = L2_SOURCE_TYPE_HUAXIN |
| | | JUEJIN_LOCAL_API = False |
| | | TRADE_WAY = TRADE_WAY_HUAXIN |
| | |
| | | code = k.split("-")[1] |
| | | self.__del_real_order_index(code) |
| | | |
| | | # 是否需要撤单 |
| | | def need_cancel(self, transaction_data): |
| | | if not transaction_data: |
| | | return False, "成交数据为空" |
| | | if transaction_data[2] < 10000: |
| | | return False, "成交量小于10000" |
| | | # 成交100万以上才算 |
| | | if transaction_data[1] * transaction_data[2] < 1000000: |
| | | return False, "金额不满足要求" |
| | | code = transaction_data[0] |
| | | real_order_index = self.__real_order_index_cache.get(code) |
| | | if not real_order_index: |
| | | return False, "真实下单位置没找到" |
| | | # 守护15s |
| | | now_time = l2_huaxin_util.convert_time(transaction_data[3]) |
| | | total_datas = local_today_datas.get(code) |
| | | if not total_datas: |
| | | return False, "L2数据为空" |
| | | order_time = total_datas[real_order_index]["val"]["time"] |
| | | if tool.trade_time_sub(now_time, order_time) > 15: |
| | | return False, "只守护15s" |
| | | buyno_map = local_today_buyno_map.get(code) |
| | | if not buyno_map: |
| | | return False, "没找到买单字典" |
| | | buy_data = buyno_map.get(str(transaction_data[6])) |
| | | if not buy_data: |
| | | return False, f"没有找到对应买单({transaction_data[6]})" |
| | | if not l2_data_util.is_big_money(buy_data["val"]): |
| | | return False, f"不为大单" |
| | | # 计算成交比例 |
| | | if transaction_data[2] > buy_data["val"]["num"] * 100 * 0.5: |
| | | return True, "快速成交了50%以上" |
| | | else: |
| | | return False, "快速成交了50%以下" |
| | | |
| | | # 设置真实的下单位置 |
| | | def set_real_order_index(self, code, index, is_default): |
| | | self.__set_real_order_index(code, index, is_default) |
| | |
| | | def cancel_success(self, code): |
| | | self.clear(code) |
| | | |
| | | # 是否成交太快需要撤单 |
| | | def need_cancel_for_deal_fast(self, code, trade_index): |
| | | # 距离太近,封单不足,有大单50w大单砸下来就撤 |
| | | def need_cancel_for_p(self, code, big_sell_order_info, order_begin_pos): |
| | | if not order_begin_pos or not order_begin_pos.buy_exec_index or order_begin_pos.buy_exec_index < 0: |
| | | return False, "尚未下单" |
| | | |
| | | if big_sell_order_info[0] < 50 * 10000 or not big_sell_order_info[1]: |
| | | return False, "不为大单" |
| | | # 判断是否具有真实的下单位置 |
| | | real_order_index_info = self.__get_real_order_index_cache(code) |
| | | if not real_order_index_info: |
| | | return False, "没找到真实下单位" |
| | | if real_order_index_info[1]: |
| | | return False, "真实下单位为默认" |
| | | |
| | | trade_index, is_default = TradeBuyQueue().get_traded_index(code) |
| | | if trade_index is None: |
| | | trade_index = 0 |
| | | real_order_index = real_order_index_info[0] |
| | | if real_order_index_info[0] <= trade_index: |
| | | return False, "真实下单位在成交位之前" |
| | | real_order_index = real_order_index_info[0] |
| | | |
| | | start_order_no = big_sell_order_info[1][-1][4][1] |
| | | real_trade_index = trade_index |
| | | # 统计未撤订单的数量与金额 |
| | | total_datas = local_today_datas.get(code) |
| | | for i in range(trade_index, real_order_index): |
| | | data = total_datas[i] |
| | | val = data['val'] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | if int(val['orderNo']) < start_order_no: |
| | | continue |
| | | real_trade_index = i |
| | | break |
| | | |
| | | # 是否是下单5分钟内 |
| | | if tool.trade_time_sub(tool.get_now_time_str(), total_datas[real_order_index]['val']['time']) > 30: |
| | | return False, "下单超过30s" |
| | | if tool.trade_time_sub(total_datas[-1]['val']['time'], total_datas[real_order_index]['val']['time']) > 180: |
| | | return False, "下单超过180s" |
| | | |
| | | total_left_count = 0 |
| | | total_left_num = 0 |
| | | # 成交位到真实下单位剩余的未成交的单 |
| | | for i in range(trade_index + 1, real_order_index_info[0]): |
| | | for i in range(real_trade_index + 1, real_order_index_info[0]): |
| | | data = total_datas[i] |
| | | val = data["val"] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | |
| | | total_left_count += left_count |
| | | total_left_num += val["num"] * left_count |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | if total_left_count < 10 and limit_up_price and total_left_num * float(limit_up_price) < 1000 * 100: |
| | | return True, f"剩余笔数({total_left_count})/金额({round(total_left_num * float(limit_up_price) * 100)})不足,成交进度:{trade_index},真实下单位置:{real_order_index}" |
| | | return False, "不满足撤单条件" |
| | | |
| | | # 下单3s内如果成交达到了上板那一刻总卖额的1.5倍就自动撤单 |
| | | def need_cancel_for_deal_fast_with_total_sell(self, code, trade_index, order_position: OrderBeginPosInfo): |
| | | try: |
| | | total_datas = local_today_datas.get(code) |
| | | if tool.trade_time_sub(total_datas[-1]['val']['time'], |
| | | total_datas[order_position.buy_single_index]['val']['time']) > 3: |
| | | return False, "已经超过生效时间" |
| | | # 计算已经成交的数量 |
| | | total_deal_num = 0 |
| | | for i in range(order_position.buy_single_index, trade_index): |
| | | if total_left_count < 5 or total_left_num * float(limit_up_price) < 500 * 100: |
| | | # 距离成交进度位5笔以内或500万以内 |
| | | # 计算我们后面的大单与涨停纯买额 |
| | | total_left_num = 0 |
| | | total_big_num_count = 0 |
| | | 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 |
| | | if val["num"] * float(val["price"]) < 5000: |
| | | money = val["num"] * float(val["price"]) |
| | | if money < 5000: |
| | | continue |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, |
| | | i, |
| | |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if left_count > 0: |
| | | total_deal_num += val["num"] * left_count |
| | | dealing_info = HuaXinBuyOrderManager.get_dealing_order_info(code) |
| | | if dealing_info: |
| | | if str(total_datas[trade_index]["val"]["orderNo"]) == str(dealing_info[0]): |
| | | total_deal_num += (total_datas[trade_index]["val"]["num"] - dealing_info[1] // 100) |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | deal_money = int(total_deal_num * float(limit_up_price) * 100) |
| | | if deal_money >= order_position.sell_info[1] * 2 and order_position.sell_info[1] > 1000 * 10000: |
| | | return True, f"成交金额:{deal_money}/{order_position.sell_info[1] * 2}" |
| | | return False, "成交金额不满足" |
| | | except Exception as e: |
| | | l2_log.f_cancel_debug(code, "计算出错:{}", str(e)) |
| | | return False, "计算出错" |
| | | if money > 299 * 100: |
| | | total_big_num_count += 1 |
| | | total_left_num += val["num"] |
| | | left_money = total_left_num * float(limit_up_price) |
| | | if total_big_num_count == 0 or left_money < 1000 * 100: |
| | | # 实际下单位后方所有涨停纯买额≤1000万或没有任何大单(≥299万) |
| | | return True, f"P撤:封单纯买额-{round(left_money / 100, 1)}万 大单数量-{total_big_num_count} 下单位-{real_order_index} 成交位-{real_trade_index}" |
| | | return False, "不满足撤单条件" |
| | | |
| | | |
| | | # ---------------------------------G撤------------------------------- |
| | |
| | | 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) |
| | | async_log_util.info(logger_real_place_order_position, |
| | | f"真实下单位矫正:{code}-{real_order_index} 下单数据:{order_info}") |
| | | f"真实下单位置矫正:{code}-({real_order_index},1)") |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | |
| | |
| | | |
| | | order_begin_pos = l2_data_manager.TradePointManager().get_buy_compute_start_data_cache(code) |
| | | |
| | | if order_begin_pos and order_begin_pos.buy_exec_index and order_begin_pos.buy_exec_index > -1: |
| | | # 已经下单的需要统计F撤 |
| | | try: |
| | | for d in datas: |
| | | if FCancelBigNumComputer().need_cancel(d)[ |
| | | 0] and not DCancelBigNumComputer().has_auto_cancel_rules(code): |
| | | L2TradeDataProcessor.cancel_buy(code, f"F撤撤单:{d}") |
| | | order_begin_pos = None |
| | | break |
| | | except Exception as e: |
| | | async_log_util.error(hx_logger_l2_debug, str(e)) |
| | | # 暂时注释掉 |
| | | # try: |
| | | # # 下单2s后才开始生效 |
| | | # cresult = LCancelBigNumComputer().add_transaction_datas(code, datas) |
| | | # if cresult[0] and not DCancelBigNumComputer().has_auto_cancel_rules(code): |
| | | # L2TradeDataProcessor.cancel_buy(code, f"L后成交太快撤单:{cresult[1]}") |
| | | # order_begin_pos = None |
| | | # except Exception as e: |
| | | # async_log_util.error(hx_logger_l2_debug, str(e)) |
| | | big_sell_order_info = None |
| | | try: |
| | | # 统计卖单 |
| | |
| | | big_sell_order_info, |
| | | order_begin_pos) |
| | | if need_cancel: |
| | | # async_log_util.error(logger_debug, f"{code} S前撤单:{cancel_msg}") |
| | | L2TradeDataProcessor.cancel_buy(code, f"S撤:{cancel_msg}") |
| | | cancel_msg = f"S撤:{cancel_msg}" |
| | | |
| | | if not need_cancel: |
| | | need_cancel, cancel_msg = FCancelBigNumComputer().need_cancel_for_p(code, big_sell_order_info, |
| | | order_begin_pos) |
| | | |
| | | if need_cancel: |
| | | L2TradeDataProcessor.cancel_buy(code, cancel_msg) |
| | | |
| | | GCancelBigNumComputer().set_big_sell_order_info(code, big_sell_order_info) |
| | | except Exception as e: |
| | | async_log_util.error(logger_debug, f"卖单统计异常:{big_sell_order_info}") |
| | |
| | | if order_begin_pos and order_begin_pos.buy_exec_index and order_begin_pos.buy_exec_index > -1: |
| | | HourCancelBigNumComputer().set_transaction_index(code, order_begin_pos.buy_single_index, |
| | | buy_progress_index) |
| | | cresult = FCancelBigNumComputer().need_cancel_for_deal_fast_with_total_sell(code, |
| | | buy_progress_index, |
| | | order_begin_pos) |
| | | if cresult[0] and not DCancelBigNumComputer().has_auto_cancel_rules(code): |
| | | L2TradeDataProcessor.cancel_buy(code, f"3s内成交太多:{cresult[1]}") |
| | | else: |
| | | pass |
| | | if order_begin_pos and order_begin_pos.buy_exec_index and order_begin_pos.buy_exec_index > -1: |
| | |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from l2.huaxin import huaxin_delegate_postion_manager |
| | | from l2.l2_sell_manager import L2MarketSellManager |
| | | from l2.l2_transaction_data_manager import HuaXinSellOrderStatisticManager |
| | | from log_module import log, log_export, async_log_util |
| | | from trade.huaxin import huaxin_trade_api |
| | | from utils import tool |
| | |
| | | l2.l2_data_util.local_today_datas[code] = total_datas |
| | | l2.l2_data_util.load_num_operate_map(l2.l2_data_util.local_today_num_operate_map, code, total_datas, True) |
| | | |
| | | # @unittest.skip("跳过此单元测试") |
| | | @unittest.skip("跳过此单元测试") |
| | | def test_block(self): |
| | | code = "603778" |
| | | # KPLCodeJXBlockManager().load_jx_blocks(code, 23.52,23.62, |
| | |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.get_current_reason_codes_dict()) |
| | | # l2.l2_data_manager_new.L2TradeDataProcessor.can_buy_first(code, None) |
| | | |
| | | def test_transaction_orders(self): |
| | | code = "603359" |
| | | l2.l2_data_util.load_l2_data(code) |
| | | total_datas = l2.l2_data_util.local_today_datas.get(code) |
| | | total_datas = total_datas[:90] |
| | | l2.l2_data_util.local_today_datas[code] = total_datas |
| | | datas = [('603359', 5.85, 224224, 9320665, 6, 286791, 695423, 711926, 'N'), |
| | | ('603359', 5.85, 512600, 9320665, 6, 286792, 695424, 711926, 'N'), |
| | | ('603359', 5.85, 300, 9320665, 6, 286793, 695428, 711926, 'N'), |
| | | ('603359', 5.85, 142876, 9320665, 6, 286794, 695429, 711926, 'N')] |
| | | big_sell_order_info = HuaXinSellOrderStatisticManager.add_transaction_datas(code, datas) |
| | | order_begin_pos = l2.l2_data_manager.OrderBeginPosInfo(buy_single_index=4, buy_exec_index=11) |
| | | index = 77 |
| | | l2.cancel_buy_strategy.FCancelBigNumComputer().set_real_order_index(code, index, False) |
| | | TradeBuyQueue().set_traded_index(code, 4) |
| | | l2.cancel_buy_strategy.FCancelBigNumComputer().need_cancel_for_p(code, big_sell_order_info, order_begin_pos) |
| | | |
| | | @unittest.skip("跳过此单元测试") |
| | | def test_transaction(self): |
| | | threading.Thread(target=async_log_util.run_sync, daemon=True).start() |
| | |
| | | ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) |
| | | code = ps_dict['code'] |
| | | date = ps_dict.get('date') |
| | | logger_debug.info(f"get_l2_datas:{code} {date}") |
| | | total_datas = l2_data_util.local_today_datas.get(code) |
| | | if date: |
| | | total_datas = None |
| | |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | code = "600822" |
| | | records = code_info_output.load_trade_record_cancel_watch_indexes(code, date="2024-03-12") |
| | | code = "603359" |
| | | records = code_info_output.load_trade_record_cancel_watch_indexes(code, |
| | | trade_record_log_util.CancelWatchIndexesInfo.CANCEL_TYPE_H) |
| | | print(records) |
| | | |
| | | # data = code_info_output.get_output_params(code, self.__jingxuan_cache_dict, self.__industry_cache_dict, |
| | | # trade_record_date=date) |
| | |
| | | can_cancel_codes.append((code, rate)) |
| | | if can_cancel_codes: |
| | | can_cancel_codes.sort(key=lambda x: x[1], reverse=True) |
| | | l2_data_manager_new.L2TradeDataProcessor.cancel_buy(can_cancel_codes[0][0], "下单距离太远") |
| | | # 暂时取消 |
| | | # l2_data_manager_new.L2TradeDataProcessor.cancel_buy(can_cancel_codes[0][0], "下单距离太远") |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | finally: |