| | |
| | | import big_money_num_manager |
| | | import constant |
| | | import gpcode_manager |
| | | import l2_data_log |
| | | import l2_data_util |
| | | from db import redis_manager |
| | | import tool |
| | | from l2.transaction_progress import TradeBuyQueue |
| | | from trade import trade_data_manager, trade_queue_manager, l2_trade_factor |
| | | from l2 import l2_log |
| | | from l2 import l2_log, l2_data_log |
| | | from l2.l2_data_util import L2DataUtil, local_today_num_operate_map, local_today_datas |
| | | from log import logger_buy_1_volumn |
| | | |
| | |
| | | |
| | | # 计算净大单 |
| | | @classmethod |
| | | def __compute_left_big_num(cls, code, start_index, end_index, total_data): |
| | | def __compute_left_big_num(cls, code, buy_single_index, start_index, end_index, total_data, place_order_count): |
| | | # 获取大单的最小手数 |
| | | left_big_num = 0 |
| | | # 点火大单数量 |
| | | fire_count = 5 |
| | | if place_order_count <= 4: |
| | | fire_count = 6 - place_order_count |
| | | else: |
| | | fire_count = 2 |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_data[i] |
| | | val = data["val"] |
| | |
| | | continue |
| | | |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | | left_big_num += val["num"] * data["re"] |
| | | if i - buy_single_index < fire_count: |
| | | # 点火大单不算 |
| | | left_big_num += 0 |
| | | else: |
| | | left_big_num += val["num"] * data["re"] |
| | | elif L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | # 查询买入位置 |
| | | buy_index, buy_data = l2_data_util.get_buy_data_with_cancel_data(data, |
| | | local_today_num_operate_map.get( |
| | | code)) |
| | | if buy_index is not None and start_index <= buy_index <= end_index: |
| | | left_big_num -= val["num"] * data["re"] |
| | | if buy_index - buy_single_index < fire_count: |
| | | left_big_num -= 0 |
| | | else: |
| | | left_big_num -= val["num"] * data["re"] |
| | | elif buy_index is None: |
| | | # 有部分撤销从而导致的无法溯源,这时就需要判断预估买入时间是否在a_start_index到a_end_index的时间区间 |
| | | min_space, max_space = l2_data_util.compute_time_space_as_second(val["cancelTime"], |
| | |
| | | |
| | | # 如果start_index与buy_single_index相同,即是下单后的第一次计算 |
| | | # 需要查询买入信号之前的同1s是否有涨停撤的数据 |
| | | process_index = -1 |
| | | process_index = process_index_old |
| | | # 下单次数 |
| | | place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code) |
| | | |
| | | if buy_single_index == start_index: |
| | | # 第1次计算需要计算买入信号-执行位的净值 |
| | | left_big_num = cls.__compute_left_big_num(code, buy_single_index, buy_exec_index, total_data) |
| | | left_big_num = cls.__compute_left_big_num(code, buy_single_index, buy_single_index, buy_exec_index, |
| | | total_data, place_order_count) |
| | | buy_num += left_big_num |
| | | # 设置买入信号-买入执行位的数据不需要处理 |
| | | start_index = end_index + 1 |
| | |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_data[i] |
| | | val = data["val"] |
| | | process_index = i |
| | | if process_index_old >= i: |
| | | # 已经处理过的数据不需要处理 |
| | | continue |
| | | if not l2_data_util.is_big_money(val): |
| | | continue |
| | | process_index = i |
| | | if L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | | buy_num += data["re"] * int(val["num"]) |
| | | elif L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | # 查询买入位置 |
| | | buy_index, buy_data = l2_data_util.get_buy_data_with_cancel_data(data, |
| | | local_today_num_operate_map.get( |
| | |
| | | buy_time = tool.trade_time_add_second(val["time"], 0 - min_space) |
| | | if int(total_data[buy_single_index]["val"]["time"].replace(":", "")) <= int( |
| | | buy_time.replace(":", "")): |
| | | cancel_num += buy_data["re"] * int(buy_data["val"]["num"]) |
| | | cancel_num += data["re"] * int(val["num"]) |
| | | |
| | | # 保存数据 |
| | | |
| | | if need_cancel: |
| | | cancel_rate_threshold = constant.S_CANCEL_FIRST_RATE |
| | | place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code) |
| | | |
| | | if place_order_count <= 1: |
| | | cancel_rate_threshold = constant.S_CANCEL_FIRST_RATE |
| | | elif place_order_count <= 2: |
| | | cancel_rate_threshold = constant.S_CANCEL_SECOND_RATE |
| | | else: |
| | | cancel_rate_threshold = constant.S_CANCEL_THIRD_RATE |
| | | if cancel_num / buy_num > cancel_rate_threshold: |
| | | if cancel_num / max(buy_num, 1) > cancel_rate_threshold: |
| | | return True, total_data[i] |
| | | finally: |
| | | l2_log.cancel_debug(threadId, code, "S级大单 范围:{}-{} 取消计算结果:{}/{}", start_index, end_index, cancel_num, |
| | | buy_num) |
| | | l2_log.cancel_debug(threadId, code, "S级大单 范围:{}-{} 取消计算结果:{}/{},比例:{}", start_index, end_index, cancel_num, |
| | | buy_num, round(cancel_num / buy_num, 2)) |
| | | # 保存处理进度与数据 |
| | | cls.__save_compute_data(code, process_index, buy_num, cancel_num) |
| | | return False, None |
| | | |
| | | # 下单成功 |
| | | @classmethod |
| | | def place_order_success(cls, code, buy_single_index, buy_exec_index): |
| | | def cancel_success(cls, code): |
| | | cls.__clear_data(code) |
| | | |
| | | |
| | | # --------------------------------H撤------------------------------- |
| | | class HourCancelBigNumComputer: |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __tradeBuyQueue = TradeBuyQueue() |
| | | |
| | | @classmethod |
| | | def __getRedis(cls): |
| | | return cls.__redis_manager.getRedis() |
| | | |
| | | # 保存成交进度 |
| | | @classmethod |
| | | def __save_trade_progress(cls, code, index): |
| | | key = f"trade_progress_index-{code}" |
| | | cls.__getRedis().setex(key, tool.get_expire(), index) |
| | | |
| | | # 保存成交进度 |
| | | @classmethod |
| | | def __get_trade_progress(cls, code): |
| | | key = f"trade_progress_index-{code}" |
| | | val = cls.__getRedis().get(key) |
| | | if val is None: |
| | | return None |
| | | return int(val) |
| | | |
| | | @classmethod |
| | | def __save_watch_index_set(cls, code, datas): |
| | |
| | | @classmethod |
| | | def place_order_success(cls, code, buy_single_index, buy_exec_index, total_data, local_today_num_operate_map): |
| | | cls.__clear_data(code) |
| | | cls.set_trade_progress(code, buy_exec_index, total_data, local_today_num_operate_map) |
| | | cls.set_trade_progress(code, buy_exec_index, total_data, local_today_num_operate_map, True) |
| | | |
| | | # 设置成交进度 |
| | | @classmethod |
| | | def set_trade_progress(cls, code, index, total_data, local_today_num_operate_map): |
| | | def set_trade_progress(cls, code, index, total_data, local_today_num_operate_map, is_default=False): |
| | | l2_log.cancel_debug(0, code, "成交进度:{}", index) |
| | | last_index, is_default = cls.__tradeBuyQueue.get_traded_index(code) |
| | | # 成交进度 |
| | | cls.__save_trade_progress(code, index) |
| | | cls.compute_watch_end_index(code, total_data, local_today_num_operate_map) |
| | | if is_default: |
| | | cls.__tradeBuyQueue.set_default_traded_index(code, index) |
| | | if last_index is None or last_index != index: |
| | | cls.compute_watch_end_index(code, total_data, local_today_num_operate_map) |
| | | |
| | | @classmethod |
| | | def compute_watch_end_index(cls, code, total_data, local_today_num_operate_map): |
| | | trade_progress_index = cls.__get_trade_progress(code) |
| | | threshold_money = l2_trade_factor.L2TradeFactorUtil.compute_m_value(code) * 2 |
| | | # 最小值1500万 |
| | | if threshold_money < 15000000: |
| | | threshold_money = 15000000 |
| | | trade_progress_index, is_default = cls.__tradeBuyQueue.get_traded_index(code) |
| | | threshold_money, msg = l2_trade_factor.L2TradeFactorUtil.compute_m_value(code) |
| | | if threshold_money < constant.H_CANCEL_MIN_MONEY: |
| | | threshold_money = constant.H_CANCEL_MIN_MONEY |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | threshold_num = round(threshold_money / (limit_up_price * 100)) |
| | | if trade_progress_index is None: |
| | | raise Exception("尚未获取到成交进度") |
| | | total_num = 0 |
| | | watch_set = set() |
| | | for i in range(trade_progress_index + 1, total_data[-1]["index"] + 1): |
| | | total_count = 0 |
| | | for i in range(trade_progress_index, total_data[-1]["index"] + 1): |
| | | data = total_data[i] |
| | | val = data["val"] |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | |
| | | # 已经买撤 |
| | | total_num -= buy_data["val"]["num"] * cancel_data["re"] |
| | | canceled = True |
| | | if data["re"] - cancel_data["re"] > 0: |
| | | watch_set.add((i, data["re"] - cancel_data["re"])) |
| | | count = data["re"] - cancel_data["re"] |
| | | if count > 0: |
| | | total_count += count |
| | | watch_set.add((i, count)) |
| | | break |
| | | if not canceled: |
| | | watch_set.add((i, data["re"])) |
| | | count = data["re"] |
| | | total_count += count |
| | | watch_set.add((i, count)) |
| | | |
| | | # 判断是否达到阈值 |
| | | if total_num >= threshold_num: |
| | | l2_log.cancel_debug(0, code, "获取到H撤监听数据:{}", json.dumps(watch_set)) |
| | | if total_num >= threshold_num and total_count >= constant.H_CANCEL_MIN_COUNT: |
| | | # 最小8笔 |
| | | l2_log.cancel_debug(0, code, "获取到H撤监听数据:{}", json.dumps(list(watch_set))) |
| | | break |
| | | # 保存计算范围 |
| | | cls.__save_watch_index_set(code, watch_set) |