| | |
| | | # ---------------------------------板上卖----------------------------- |
| | | # 涨停卖统计 |
| | | class L2LimitUpSellStatisticUtil: |
| | | _redisManager = redis_manager.RedisManager(0) |
| | | __db = 0 |
| | | __redisManager = redis_manager.RedisManager(0) |
| | | __limit_up_sell_num_cache = {} |
| | | __limit_up_sell_index_cache = {} |
| | | __instance = None |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(L2LimitUpSellStatisticUtil, cls).__new__(cls, *args, **kwargs) |
| | | # 初始化 |
| | | cls.load_data() |
| | | return cls.__instance |
| | | |
| | | @classmethod |
| | | def load_data(cls): |
| | | redis_ = cls.__get_redis() |
| | | try: |
| | | keys = RedisUtils.keys(redis_, "limit_up_sell_num-*") |
| | | for k in keys: |
| | | code = k.split["-"][-1] |
| | | cls.__limit_up_sell_num_cache[code] = RedisUtils.get(redis_, k) |
| | | keys = RedisUtils.keys(redis_, "limit_up_sell_index-*") |
| | | for k in keys: |
| | | code = k.split["-"][-1] |
| | | cls.__limit_up_sell_index_cache[code] = RedisUtils.get(redis_, k) |
| | | finally: |
| | | RedisUtils.realse(redis_) |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls._redisManager.getRedis() |
| | | return cls.__redisManager.getRedis() |
| | | |
| | | # 新增卖数据 |
| | | @classmethod |
| | | def __incre_sell_data(cls, code, num): |
| | | def __incre_sell_data(self, code, num): |
| | | if code not in self.__limit_up_sell_num_cache: |
| | | self.__limit_up_sell_num_cache[code] = 0 |
| | | self.__limit_up_sell_num_cache[code] += num |
| | | key = "limit_up_sell_num-{}".format(code) |
| | | RedisUtils.incrby(cls.__get_redis(), key, num) |
| | | RedisUtils.incrby_async(self.__db, key, num) |
| | | RedisUtils.expire_async(self.__db, key, tool.get_expire()) |
| | | |
| | | @classmethod |
| | | def __get_sell_data(cls, code): |
| | | def __get_sell_data(self, code): |
| | | key = "limit_up_sell_num-{}".format(code) |
| | | val = RedisUtils.get(cls.__get_redis(), key) |
| | | val = RedisUtils.get(self.__get_redis(), key) |
| | | if val is None: |
| | | return 0 |
| | | return int(val) |
| | | |
| | | @classmethod |
| | | def __save_process_index(cls, code, index): |
| | | key = "limit_up_sell_index-{}".format(code) |
| | | RedisUtils.setex(cls.__get_redis(), key, tool.get_expire(), index) |
| | | def __get_sell_data_cache(self, code): |
| | | if code in self.__limit_up_sell_num_cache: |
| | | return int(self.__limit_up_sell_num_cache[code]) |
| | | return 0 |
| | | |
| | | @classmethod |
| | | def __get_process_index(cls, code): |
| | | def __save_process_index(self, code, index): |
| | | tool.CodeDataCacheUtil.set_cache(self.__limit_up_sell_index_cache, code, index) |
| | | key = "limit_up_sell_index-{}".format(code) |
| | | val = RedisUtils.get(cls.__get_redis(), key) |
| | | RedisUtils.setex_async(self.__db, key, tool.get_expire(), index) |
| | | |
| | | def __get_process_index(self, code): |
| | | key = "limit_up_sell_index-{}".format(code) |
| | | val = RedisUtils.get(self.__get_redis(), key) |
| | | if val is None: |
| | | return -1 |
| | | return int(val) |
| | | |
| | | # 清除数据,当取消成功与买入之前需要清除数据 |
| | | @classmethod |
| | | def delete(cls, code): |
| | | key = "limit_up_sell_num-{}".format(code) |
| | | RedisUtils.delete(cls.__get_redis(), key) |
| | | key = "limit_up_sell_index-{}".format(code) |
| | | RedisUtils.delete(cls.__get_redis(), key) |
| | | def __get_process_index_cache(self, code): |
| | | cache_result = tool.CodeDataCacheUtil.get_cache(self.__limit_up_sell_index_cache, code) |
| | | if cache_result[0]: |
| | | return int(cache_result[1]) |
| | | return -1 |
| | | |
| | | @classmethod |
| | | def clear(cls): |
| | | keys = RedisUtils.keys(cls.__get_redis(), "limit_up_sell_num-*") |
| | | # 清除数据,当取消成功与买入之前需要清除数据 |
| | | |
| | | def delete(self, code): |
| | | tool.CodeDataCacheUtil.clear_cache(self.__limit_up_sell_index_cache, code) |
| | | tool.CodeDataCacheUtil.clear_cache(self.__limit_up_sell_num_cache, code) |
| | | key = "limit_up_sell_num-{}".format(code) |
| | | RedisUtils.delete_async(self.__db, key) |
| | | key = "limit_up_sell_index-{}".format(code) |
| | | RedisUtils.delete_async(self.__db, key) |
| | | |
| | | def clear(self): |
| | | keys = RedisUtils.keys(self.__get_redis(), "limit_up_sell_num-*") |
| | | for k in keys: |
| | | RedisUtils.delete(cls.__get_redis(), k) |
| | | code = k.split("-")[-1] |
| | | self.delete(code) |
| | | |
| | | # 处理数据,返回是否需要撤单 |
| | | # 处理范围:买入执行位-当前最新位置 |
| | | @classmethod |
| | | def process(cls, code, start_index, end_index, buy_exec_index): |
| | | |
| | | def process(self, code, start_index, end_index, buy_exec_index): |
| | | # 获取涨停卖的阈值 |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | zyltgb = l2_trade_factor.L2TradeFactorUtil.get_zyltgb(code) |
| | | # 大于自由流通市值的4.8% |
| | | threshold_num = int(zyltgb * 0.048) // (limit_up_price * 100) |
| | | total_num = cls.__get_sell_data(code) |
| | | total_num = self.__get_sell_data_cache(code) |
| | | cancel_index = None |
| | | process_index = cls.__get_process_index(code) |
| | | process_index = self.__get_process_index_cache(code) |
| | | total_datas = local_today_datas.get(code) |
| | | for i in range(start_index, end_index + 1): |
| | | if i < buy_exec_index: |
| | |
| | | continue |
| | | if L2DataUtil.is_limit_up_price_sell(total_datas[i]["val"]) or L2DataUtil.is_sell(total_datas[i]["val"]): |
| | | num = int(total_datas[i]["val"]["num"]) |
| | | cls.__incre_sell_data(code, num) |
| | | self.__incre_sell_data(code, num) |
| | | total_num += num |
| | | if total_num > threshold_num: |
| | | cancel_index = i |
| | |
| | | l2_log.cancel_debug(code, "板上卖信息:计算位置:{}-{} 板上卖数据{}/{}", start_index, end_index, total_num, |
| | | threshold_num) |
| | | |
| | | cls.__save_process_index(code, process_index) |
| | | self.__save_process_index(code, process_index) |
| | | if cancel_index is not None: |
| | | return total_datas[cancel_index], "板上卖的手数{} 超过{}".format(total_num, threshold_num) |
| | | return None, "" |