| | |
| | | from l2.l2_data_util import L2DataUtil, local_today_num_operate_map, local_today_datas |
| | | from log_module.log import logger_buy_1_volumn, logger_l2_h_cancel, logger_l2_s_cancel, logger_l2_d_cancel, \ |
| | | logger_l2_l_cancel |
| | | from utils.tool import CodeDataCacheUtil |
| | | |
| | | |
| | | class SecondCancelBigNumComputer: |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __sCancelParamsManager = l2_trade_factor.SCancelParamsManager |
| | | __s_big_num_cancel_compute_data_cache = {} |
| | | |
| | | @classmethod |
| | | def __getRedis(cls): |
| | |
| | | # 保存结束位置 |
| | | @classmethod |
| | | def __save_compute_data(cls, code, process_index, buy_num, cancel_num): |
| | | CodeDataCacheUtil.set_cache(cls.__s_big_num_cancel_compute_data_cache, code, |
| | | (process_index, buy_num, cancel_num)) |
| | | key = "s_big_num_cancel_compute_data-{}".format(code) |
| | | cls.__getRedis().setex(key, tool.get_expire(), json.dumps((process_index, buy_num, cancel_num))) |
| | | |
| | |
| | | return val[0], val[1], val[2] |
| | | |
| | | @classmethod |
| | | def __get_compute_data_cache(cls, code): |
| | | cache_result = CodeDataCacheUtil.get_cache(cls.__s_big_num_cancel_compute_data_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = cls.__get_compute_data(code) |
| | | CodeDataCacheUtil.set_cache(cls.__s_big_num_cancel_compute_data_cache, code, val) |
| | | return val |
| | | |
| | | @classmethod |
| | | def __clear_data(cls, code): |
| | | CodeDataCacheUtil.clear_cache(cls.__s_big_num_cancel_compute_data_cache, code) |
| | | ks = ["s_big_num_cancel_compute_data-{}".format(code)] |
| | | for key in ks: |
| | | cls.__getRedis().delete(key) |
| | |
| | | for key in ks: |
| | | keys = cls.__getRedis().keys(key) |
| | | for k in keys: |
| | | cls.__getRedis().delete(k) |
| | | code = k.replace("s_big_num_cancel_compute_data-","") |
| | | cls.__clear_data(code) |
| | | |
| | | # 计算净大单 |
| | | @classmethod |
| | |
| | | break |
| | | |
| | | # 获取处理进度 |
| | | process_index_old, buy_num, cancel_num = cls.__get_compute_data(code) |
| | | process_index_old, buy_num, cancel_num = cls.__get_compute_data_cache(code) |
| | | |
| | | # 如果start_index与buy_single_index相同,即是下单后的第一次计算 |
| | | # 需要查询买入信号之前的同1s是否有涨停撤的数据 |
| | |
| | | __tradeBuyQueue = TradeBuyQueue() |
| | | __buyL2SafeCountManager = BuyL2SafeCountManager() |
| | | __hCancelParamsManager = l2_trade_factor.HCancelParamsManager() |
| | | # 缓存 |
| | | __cancel_watch_indexs_cache = {} |
| | | __cancel_watch_indexs_exec_cache = {} |
| | | __cancel_watch_canceled_indexs_cache = {} |
| | | __cancel_traded_progress_cache = {} |
| | | __cancel_compute_data_cache = {} |
| | | |
| | | @classmethod |
| | | def __getRedis(cls): |
| | |
| | | # 保存成交位置到执行位置的揽括范围数据 |
| | | @classmethod |
| | | def __save_watch_index_set(cls, code, datas, process_index, finish): |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_watch_indexs_cache, code, (list(datas), process_index, finish)) |
| | | key = f"h_cancel_watch_indexs-{code}" |
| | | cls.__getRedis().setex(key, tool.get_expire(), json.dumps((list(datas), process_index, finish))) |
| | | |
| | |
| | | val = json.loads(val) |
| | | return val[0], val[1], val[2] |
| | | |
| | | @classmethod |
| | | def __get_watch_index_set_cache(cls, code): |
| | | cache_result = CodeDataCacheUtil.get_cache(cls.__cancel_watch_indexs_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = cls.__get_watch_index_set(code) |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_watch_indexs_cache, code, val) |
| | | return val |
| | | |
| | | # 保存执行位置后面的守护数据 |
| | | @classmethod |
| | | def __save_watch_index_set_after_exec(cls, code, datas, process_index, total_count, big_num_count, finished): |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_watch_indexs_exec_cache, code, |
| | | (list(datas), process_index, total_count, big_num_count, finished)) |
| | | key = f"h_cancel_watch_indexs_exec-{code}" |
| | | cls.__getRedis().setex(key, tool.get_expire(), |
| | | json.dumps((list(datas), process_index, total_count, big_num_count, finished))) |
| | |
| | | val = json.loads(val) |
| | | return val[0], val[1], val[2], val[3], val[4] |
| | | |
| | | @classmethod |
| | | def __get_watch_index_set_after_exec_cache(cls, code): |
| | | cache_result = CodeDataCacheUtil.get_cache(cls.__cancel_watch_indexs_exec_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = cls.__get_watch_index_set_after_exec(code) |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_watch_indexs_exec_cache, code, val) |
| | | return val |
| | | |
| | | # 保存已经撤单的监听位置 |
| | | @classmethod |
| | | def __add_watch_canceled_index(cls, code, index): |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_watch_canceled_indexs_cache, code) |
| | | key = f"h_cancel_watch_canceled_indexs-{code}" |
| | | cls.__getRedis().sadd(key, index) |
| | | cls.__getRedis().expire(key, tool.get_expire()) |
| | |
| | | return cls.__getRedis().smembers(key) |
| | | |
| | | @classmethod |
| | | def __get_watch_canceled_index_cache(cls, code): |
| | | cache_result = CodeDataCacheUtil.get_cache(cls.__cancel_watch_canceled_indexs_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = cls.__get_watch_canceled_index(code) |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_watch_canceled_indexs_cache, code, val) |
| | | return val |
| | | |
| | | @classmethod |
| | | def __del_watch_canceled_index(cls, code): |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_watch_canceled_indexs_cache, code) |
| | | key = f"h_cancel_watch_canceled_indexs-{code}" |
| | | cls.__getRedis().delete(key) |
| | | |
| | | # 保存成交进度 |
| | | @classmethod |
| | | def __save_traded_progress(cls, code, origin_process_index, latest_process_index): |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_traded_progress_cache, code, |
| | | (origin_process_index, latest_process_index)) |
| | | key = "h_cancel_traded_progress-{}".format(code) |
| | | cls.__getRedis().setex(key, tool.get_expire(), json.dumps((origin_process_index, latest_process_index))) |
| | | |
| | |
| | | val = json.loads(val) |
| | | return val[0], val[1] |
| | | |
| | | @classmethod |
| | | def __get_traded_progress_cache(cls, code): |
| | | cache_result = CodeDataCacheUtil.get_cache(cls.__cancel_traded_progress_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = cls.__get_traded_progress(code) |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_traded_progress_cache, code, val) |
| | | return val |
| | | |
| | | # 保存结算位置 |
| | | @classmethod |
| | | def __save_compute_data(cls, code, process_index, cancel_num): |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_compute_data_cache, code, |
| | | (process_index, cancel_num)) |
| | | key = "h_cancel_compute_data-{}".format(code) |
| | | cls.__getRedis().setex(key, tool.get_expire(), json.dumps((process_index, cancel_num))) |
| | | |
| | |
| | | return val[0], val[1] |
| | | |
| | | @classmethod |
| | | def __get_compute_data_cache(cls, code): |
| | | cache_result = CodeDataCacheUtil.get_cache(cls.__cancel_compute_data_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = cls.__get_compute_data(code) |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_compute_data_cache, code, val) |
| | | return val |
| | | |
| | | @classmethod |
| | | def __del_compute_data(cls, code): |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_compute_data_cache, code) |
| | | key = "h_cancel_compute_data-{}".format(code) |
| | | cls.__getRedis().delete(key) |
| | | |
| | | @classmethod |
| | | def __clear_data(cls, code): |
| | | |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_watch_indexs_cache, code) |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_traded_progress_cache, code) |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_watch_canceled_indexs_cache, code) |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_watch_indexs_exec_cache, code) |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_compute_data_cache, code) |
| | | |
| | | ks = ["h_cancel_compute_data-{}".format(code), f"h_cancel_watch_indexs_exec-{code}", |
| | | f"h_cancel_watch_indexs-{code}", f"h_cancel_traded_progress-{code}", |
| | | f"h_cancel_watch_canceled_indexs-{code}"] |
| | |
| | | if time_space <= constant.S_CANCEL_EXPIRE_TIME: |
| | | return False, None |
| | | # 获取成交进度 |
| | | origin_progress_index, latest_progress_index = cls.__get_traded_progress(code) |
| | | origin_progress_index, latest_progress_index = cls.__get_traded_progress_cache(code) |
| | | if latest_progress_index is None: |
| | | latest_progress_index = -1 |
| | | # 监听的数据 |
| | |
| | | total_nums = 1 |
| | | if origin_progress_index is not None: |
| | | # 获取成交位置到执行位置的监控数据 |
| | | watch_indexs = cls.__get_watch_index_set(code)[0] |
| | | watch_indexs = cls.__get_watch_index_set_cache(code)[0] |
| | | # 监听的总数 |
| | | for indexs in watch_indexs: |
| | | index = indexs[0] |
| | |
| | | watch_indexs_dict[index] = indexs |
| | | total_nums += total_data[index]["val"]["num"] * indexs[2] |
| | | # 获取到执行位后的监听数据 |
| | | datas, process_index, total_count, big_num_count, finished = cls.__get_watch_index_set_after_exec(code) |
| | | datas, process_index, total_count, big_num_count, finished = cls.__get_watch_index_set_after_exec_cache(code) |
| | | if datas: |
| | | for indexs in datas: |
| | | index = indexs[0] |
| | |
| | | watch_indexs_dict[index] = indexs |
| | | total_nums += total_data[index]["val"]["num"] * indexs[2] |
| | | |
| | | processed_index, cancel_num = cls.__get_compute_data(code) |
| | | processed_index, cancel_num = cls.__get_compute_data_cache(code) |
| | | |
| | | l2_log.cancel_debug(code, "H级是否需要撤单,数据范围:{}-{} ", start_index, end_index) |
| | | # 获取下单次数 |
| | |
| | | # 是否有观测的数据撤单 |
| | | has_watch_canceled = False |
| | | # 获取之前已经撤单的数据 |
| | | old_canceld_indexs = cls.__get_watch_canceled_index(code) |
| | | old_canceld_indexs = cls.__get_watch_canceled_index_cache(code) |
| | | # 重新计算撤单 |
| | | cancel_num = 0 |
| | | if old_canceld_indexs: |
| | |
| | | logger_l2_h_cancel.info( |
| | | f"code-{code} H级撤单计算结果 范围:{start_index}-{end_index} 处理进度:{process_index} 目标比例:{cancel_rate_threshold} 取消计算结果:{cancel_num}/{total_nums}") |
| | | # H撤已撤订单 |
| | | logger_l2_h_cancel.info(f"code-{code} H撤已撤订单:{cls.__get_watch_canceled_index(code)}") |
| | | logger_l2_h_cancel.info(f"code-{code} H撤已撤订单:{cls.__get_watch_canceled_index_cache(code)}") |
| | | # 保存处理进度与数据 |
| | | cls.__save_compute_data(code, process_index, cancel_num) |
| | | # 有观测数据撤单 |
| | |
| | | "time"]) < constant.S_CANCEL_EXPIRE_TIME - 1: |
| | | return |
| | | # 保存成交进度 |
| | | origin_index, latest_index = cls.__get_traded_progress(code) |
| | | origin_index, latest_index = cls.__get_traded_progress_cache(code) |
| | | if origin_index is None: |
| | | cls.__save_traded_progress(code, index, index) |
| | | # 计算揽括范围 |
| | |
| | | @classmethod |
| | | def __compute_watch_indexs_after_single(cls, code, buy_single_index, buy_exec_index, total_data, |
| | | local_today_num_operate_map, buy_volume_index): |
| | | watch_list, process_index_old, total_count_old, big_num_count_old, finish = cls.__get_watch_index_set_after_exec( |
| | | watch_list, process_index_old, total_count_old, big_num_count_old, finish = cls.__get_watch_index_set_after_exec_cache( |
| | | code) |
| | | if watch_list and finish: |
| | | # 已经计算完了不需要再进行计算 |
| | |
| | | # 返回监听范围与已撤单索引 |
| | | @classmethod |
| | | def get_watch_index_dict(cls, code): |
| | | origin_progress_index, latest_progress_index = cls.__get_traded_progress(code) |
| | | origin_progress_index, latest_progress_index = cls.__get_traded_progress_cache(code) |
| | | # 监听的数据 |
| | | watch_indexs_dict = {} |
| | | total_nums = 0 |
| | | if origin_progress_index is not None: |
| | | # 获取成交位置到执行位置的监控数据 |
| | | watch_indexs = cls.__get_watch_index_set(code)[0] |
| | | watch_indexs = cls.__get_watch_index_set_cache(code)[0] |
| | | # 监听的总数 |
| | | for indexs in watch_indexs: |
| | | index = indexs[0] |
| | |
| | | # 只计算最近的执行位之后的数据 |
| | | watch_indexs_dict[index] = indexs |
| | | # 获取到执行位后的监听数据 |
| | | datas, process_index, total_count, big_num_count, finished = cls.__get_watch_index_set_after_exec(code) |
| | | datas, process_index, total_count, big_num_count, finished = cls.__get_watch_index_set_after_exec_cache(code) |
| | | if datas: |
| | | for indexs in datas: |
| | | index = indexs[0] |
| | | watch_indexs_dict[index] = indexs |
| | | return watch_indexs_dict, cls.__get_watch_canceled_index(code) |
| | | return watch_indexs_dict, cls.__get_watch_canceled_index_cache(code) |
| | | |
| | | |
| | | # ---------------------------------D撤------------------------------- |
| | |
| | | # 成交位变化之后重新计算 |
| | | class DCancelBigNumComputer: |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __cancel_real_order_index_cache = {} |
| | | |
| | | @classmethod |
| | | def __getRedis(cls): |
| | |
| | | |
| | | @classmethod |
| | | def __set_real_order_index(cls, code, index): |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_real_order_index_cache, code, index) |
| | | cls.__getRedis().setex(f"d_cancel_real_order_index-{code}", tool.get_expire(), f"{index}") |
| | | |
| | | @classmethod |
| | |
| | | return None |
| | | |
| | | @classmethod |
| | | def __get_real_order_index_cache(cls, code): |
| | | cache_result = CodeDataCacheUtil.get_cache(cls.__cancel_real_order_index_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = cls.__get_real_order_index(code) |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_real_order_index_cache, code, val) |
| | | return val |
| | | |
| | | @classmethod |
| | | def clear(cls, code=None): |
| | | if code: |
| | | cls.__getRedis().delete(f"d_cancel_real_order_index-{code}") |
| | |
| | | keys = cls.__getRedis().keys("d_cancel_real_order_index-*") |
| | | if keys: |
| | | for k in keys: |
| | | code = k.replace("d_cancel_real_order_index-", "") |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_real_order_index_cache, code) |
| | | cls.__getRedis().delete(k) |
| | | |
| | | # 设置成交位 |
| | |
| | | total_data[buy_exec_index]['val']['time']) > constant.D_CANCEL_EXPIRE_TIME: |
| | | return False, "超过D撤守护时间" |
| | | |
| | | real_order_index = cls.__get_real_order_index(code) |
| | | real_order_index = cls.__get_real_order_index_cache(code) |
| | | if not real_order_index: |
| | | return False, "尚未获取到真实下单位置" |
| | | |
| | |
| | | class LCancelBigNumComputer: |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __last_trade_progress_dict = {} |
| | | __cancel_watch_index_cache = {} |
| | | |
| | | @classmethod |
| | | def __getRedis(cls): |
| | |
| | | |
| | | @classmethod |
| | | def __add_watch_index(cls, code, index): |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_watch_index_cache, code) |
| | | cls.__getRedis().sadd(f"l_cancel_watch_index-{code}", index) |
| | | cls.__getRedis().expire(f"l_cancel_watch_index-{code}", tool.get_expire()) |
| | | |
| | | @classmethod |
| | | def __del_watch_index(cls, code, index): |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_watch_index_cache, code) |
| | | cls.__getRedis().srem(f"l_cancel_watch_index-{code}", index) |
| | | |
| | | @classmethod |
| | |
| | | return cls.__getRedis().smembers(f"l_cancel_watch_index-{code}") |
| | | |
| | | @classmethod |
| | | def __get_watch_indexes_cache(cls, code): |
| | | cache_result = CodeDataCacheUtil.get_cache(cls.__cancel_watch_index_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = cls.__get_watch_indexes(code) |
| | | cls.__cancel_watch_index_cache[code] = val |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_watch_index_cache, code, val) |
| | | return val |
| | | |
| | | @classmethod |
| | | def del_watch_index(cls, code): |
| | | CodeDataCacheUtil.clear_cache(cls.__cancel_watch_index_cache, code) |
| | | cls.__getRedis().delete(f"l_cancel_watch_index-{code}") |
| | | |
| | | @classmethod |
| | |
| | | else: |
| | | keys = cls.__getRedis().keys(f"l_cancel_watch_index-*") |
| | | for k in keys: |
| | | cls.__getRedis().delete(k) |
| | | code = k.replace("l_cancel_watch_index-", "") |
| | | cls.del_watch_index(code) |
| | | |
| | | # 设置成交位置,成交位置变化之后相应的监听数据也会发生变化 |
| | | @classmethod |
| | | def set_trade_progress(cls, code, index, total_data): |
| | | old_watch_indexes = cls.__get_watch_indexes(code) |
| | | old_watch_indexes = cls.__get_watch_indexes_cache(code) |
| | | if cls.__last_trade_progress_dict.get(code) == index and len( |
| | | old_watch_indexes) >= constant.L_CANCEL_MAX_WATCH_COUNT: |
| | | # 成交进度尚未发生变化且已经监听到了足够的数据 |
| | |
| | | # 守护S撤以外的数据 |
| | | if time_space <= constant.S_CANCEL_EXPIRE_TIME or int(tool.get_now_time_str().replace(":", "")) > int("145000"): |
| | | return False, None |
| | | watch_indexes = cls.__get_watch_indexes(code) |
| | | watch_indexes = cls.__get_watch_indexes_cache(code) |
| | | if not watch_indexes: |
| | | return False, None |
| | | watch_indexes = set([int(i) for i in watch_indexes]) |
| | |
| | | def cancel_success(cls, code): |
| | | cls.clear(code) |
| | | |
| | | |
| | | # --------------------------------封单额变化撤------------------------ |
| | | # 涨停封单额统计 |
| | | class L2LimitUpMoneyStatisticUtil: |