| | |
| | | global_util.max60_volumn[code] = (max60, max60_day) |
| | | global_util.yesterday_volumn[code] = yesterday |
| | | try: |
| | | RedisUtils.setex(redis, "volumn_max60-{}".format(code), tool.get_expire(), json.dumps((max60, max60_day)), |
| | | auto_free=False) |
| | | RedisUtils.setex(redis, "volumn_yes-{}".format(code), tool.get_expire(), yesterday, auto_free=False) |
| | | RedisUtils.setex_async(0, "volumn_max60-{}".format(code), tool.get_expire(), json.dumps((max60, max60_day)), |
| | | auto_free=False) |
| | | RedisUtils.setex_async(0, "volumn_yes-{}".format(code), tool.get_expire(), yesterday, auto_free=False) |
| | | finally: |
| | | RedisUtils.realse(redis) |
| | | |
| | |
| | | |
| | | # ---保存未筛选的首板代码 |
| | | new_add_codes = gpcode_first_screen_manager.set_target_no_screen_codes(codes) |
| | | # 保存自由流通股本 |
| | | if dataList: |
| | | zyltgb_list = [] |
| | | for data in dataList: |
| | | code = data["code"] |
| | | if code in global_util.zyltgb_map: |
| | | continue |
| | | zyltgb_list.append( |
| | | {"code": code, "zyltgb": data["zyltgb"], "zyltgb_unit": data["zyltgbUnit"]}) |
| | | if zyltgb_list: |
| | | ZYLTGBUtil.save_list(zyltgb_list) |
| | | global_data_loader.load_zyltgb() |
| | | # 保存自由流通股本,暂时不保存 |
| | | # if dataList: |
| | | # zyltgb_list = [] |
| | | # for data in dataList: |
| | | # code = data["code"] |
| | | # if code in global_util.zyltgb_map: |
| | | # continue |
| | | # zyltgb_list.append( |
| | | # {"code": code, "zyltgb": data["zyltgb"], "zyltgb_unit": data["zyltgbUnit"]}) |
| | | # if zyltgb_list: |
| | | # ZYLTGBUtil.save_list(zyltgb_list) |
| | | # global_data_loader.load_zyltgb() |
| | | |
| | | # 获取昨日收盘价 |
| | | for code in codes: |
| | |
| | | if gpcode_manager.get_limit_up_price(code) is None: |
| | | inited_data.re_set_price_pres([code], True) |
| | | |
| | | # 板块关键字准备 |
| | | for code in codes: |
| | | if __CodesPlateKeysManager.get_history_limit_up_reason(code) is None: |
| | | # 从数据库加载历史涨停原因 |
| | | __CodesPlateKeysManager.set_history_limit_up_reason(code, |
| | | KPLLimitUpDataRecordManager.get_latest_blocks_set( |
| | | code)) |
| | | if __CodesPlateKeysManager.get_blocks(code) is None: |
| | | try: |
| | | results = kpl_api.getStockIDPlate(code) |
| | | bs = [r[1] for r in results] |
| | | __CodesPlateKeysManager.set_blocks(code, bs) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | pass |
| | | # 板块关键字准备 暂时删除 |
| | | # for code in codes: |
| | | # if __CodesPlateKeysManager.get_history_limit_up_reason(code) is None: |
| | | # # 从数据库加载历史涨停原因 |
| | | # __CodesPlateKeysManager.set_history_limit_up_reason(code, |
| | | # KPLLimitUpDataRecordManager.get_latest_blocks_set( |
| | | # code)) |
| | | # if __CodesPlateKeysManager.get_blocks(code) is None: |
| | | # try: |
| | | # results = kpl_api.getStockIDPlate(code) |
| | | # bs = [r[1] for r in results] |
| | | # __CodesPlateKeysManager.set_blocks(code, bs) |
| | | # except Exception as e: |
| | | # logging.exception(e) |
| | | # pass |
| | | |
| | | # 获取60天最大记录 |
| | | for code in codes: |
| | | need_get_volumn = False |
| | | if code not in global_util.max60_volumn or global_util.max60_volumn.get(code) is None: |
| | | need_get_volumn = True |
| | | if not need_get_volumn and code_nature_analyse.CodeNatureRecordManager.get_nature_cache( |
| | | code) is None: |
| | | need_get_volumn = True |
| | | # if not need_get_volumn and code_nature_analyse.CodeNatureRecordManager.get_nature_cache( |
| | | # code) is None: |
| | | # need_get_volumn = True |
| | | if need_get_volumn: |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | if limit_up_price is None: |
| | |
| | | # bad_codes.add(code) |
| | | # # 加入禁止交易代码 |
| | | # l2_trade_util.forbidden_trade(code) |
| | | code_nature_analyse.set_record_datas(code, |
| | | gpcode_manager.get_limit_up_price(code), |
| | | volumes_data) |
| | | # 暂时不保存K线形态 |
| | | # code_nature_analyse.set_record_datas(code, |
| | | # gpcode_manager.get_limit_up_price(code), |
| | | # volumes_data) |
| | | except Exception as e: |
| | | logger_first_code_record.error(f"{code}:{str(e)}") |
| | | gpcode_manager.FirstCodeManager().add_record(codes) |
| | | # 初始化板块信息 |
| | | for code in codes: |
| | | block_info.init_code(code) |
| | | # 初始化板块信息,暂时删除 |
| | | # for code in codes: |
| | | # block_info.init_code(code) |
| | | |
| | | if new_add_codes: |
| | | gpcode_manager.FirstGPCodesManager().set_first_gp_codes_with_data(HistoryKDatasUtils.get_gp_latest_info(codes, |
| | |
| | | from db import redis_manager_delegate as redis_manager |
| | | from third_data import block_info |
| | | |
| | | __redisManager = redis_manager.RedisManager(0) |
| | | |
| | | class FirstCodeDataManager: |
| | | __instance = None |
| | | __redisManager = redis_manager.RedisManager(0) |
| | | __db = 0 |
| | | __first_code_data_cache = {} |
| | | |
| | | def __get_redis(): |
| | | return __redisManager.getRedis() |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(FirstCodeDataManager, cls).__new__(cls, *args, **kwargs) |
| | | cls.__load_data() |
| | | return cls.__instance |
| | | |
| | | # 加载数据 |
| | | @classmethod |
| | | def __load_data(cls): |
| | | keys = RedisUtils.keys(cls.__get_redis(), "first_code_data-*") |
| | | for k in keys: |
| | | val = RedisUtils.get(cls.__get_redis(), k) |
| | | code = k.split("-")[-1] |
| | | if val: |
| | | cls.__first_code_data_cache[code] = json.loads(val) |
| | | |
| | | __first_code_data_cache = {} |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.__redisManager.getRedis() |
| | | |
| | | # 保存首板票的数据 |
| | | # 1.首次涨停时间 |
| | | # 2.最近涨停时间 |
| | | # 3.首次炸开时间 |
| | | # 4.最近炸开时间 |
| | | # 5.是否已经涨停 |
| | | def save_first_code_data(self, code, data): |
| | | tool.CodeDataCacheUtil.set_cache(self.__first_code_data_cache, code, data) |
| | | RedisUtils.setex_async(self.__db, f"first_code_data-{code}", tool.get_expire(), json.dumps(data)) |
| | | |
| | | # 保存首板票的数据 |
| | | # 1.首次涨停时间 |
| | | # 2.最近涨停时间 |
| | | # 3.首次炸开时间 |
| | | # 4.最近炸开时间 |
| | | # 5.是否已经涨停 |
| | | def __save_first_code_data(code, data): |
| | | tool.CodeDataCacheUtil.set_cache(__first_code_data_cache, code, data) |
| | | RedisUtils.setex(__redisManager.getRedis(), f"first_code_data-{code}", tool.get_expire(), json.dumps(data)) |
| | | def get_first_code_data(self, code): |
| | | val = RedisUtils.get(self.__get_redis(), f"first_code_data-{code}") |
| | | if val is None: |
| | | return None |
| | | return json.loads(val) |
| | | |
| | | |
| | | def __get_first_code_data(code): |
| | | val = RedisUtils.get(__get_redis(), f"first_code_data-{code}") |
| | | if val is None: |
| | | def get_first_code_data_cache(self, code): |
| | | cache_result = tool.CodeDataCacheUtil.get_cache(self.__first_code_data_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | return None |
| | | return json.loads(val) |
| | | |
| | | |
| | | def __get_first_code_data_cache(code): |
| | | cache_result = tool.CodeDataCacheUtil.get_cache(__first_code_data_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | val = __get_first_code_data(code) |
| | | tool.CodeDataCacheUtil.set_cache(__first_code_data_cache, code, val) |
| | | return val |
| | | class FirstNoScreenCodesManager: |
| | | __instance = None |
| | | __redisManager = redis_manager.RedisManager(0) |
| | | __db = 0 |
| | | __first_no_screen_codes_cache = set() |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(FirstNoScreenCodesManager, cls).__new__(cls, *args, **kwargs) |
| | | cls.__load_data() |
| | | return cls.__instance |
| | | |
| | | # 添加进首板未筛选票 |
| | | def __add_first_no_screen_codes(codes): |
| | | redis = __redisManager.getRedis() |
| | | try: |
| | | # 加载数据 |
| | | @classmethod |
| | | def __load_data(cls): |
| | | codes = RedisUtils.smembers(cls.__get_redis(), "first_no_screen_codes") |
| | | cls.__first_no_screen_codes_cache = codes |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.__redisManager.getRedis() |
| | | |
| | | # 添加进首板未筛选票 |
| | | def add_first_no_screen_codes(self, codes): |
| | | redis = self.__get_redis() |
| | | if codes: |
| | | for code in codes: |
| | | RedisUtils.sadd(redis, "first_no_screen_codes", code, auto_free=False) |
| | | RedisUtils.expire(redis, "first_no_screen_codes", tool.get_expire(), auto_free=False) |
| | | finally: |
| | | RedisUtils.realse(redis) |
| | | self.__first_no_screen_codes_cache.add(code) |
| | | RedisUtils.sadd_async(self.__db, "first_no_screen_codes", code, auto_free=False) |
| | | RedisUtils.expire_async(self.__db, "first_no_screen_codes", tool.get_expire(), auto_free=False) |
| | | |
| | | def clear_first_no_screen_codes(self): |
| | | self.__first_no_screen_codes_cache.clear() |
| | | RedisUtils.delete(self.__get_redis(), "first_no_screen_codes") |
| | | |
| | | def clear_first_no_screen_codes(): |
| | | RedisUtils.delete(__redisManager.getRedis(), "first_no_screen_codes") |
| | | |
| | | |
| | | def __remove_first_no_screen_codes(codes): |
| | | redis = __redisManager.getRedis() |
| | | try: |
| | | def remove_first_no_screen_codes(self, codes): |
| | | if codes: |
| | | for code in codes: |
| | | RedisUtils.srem(redis, "first_no_screen_codes", code, auto_free= False) |
| | | finally: |
| | | RedisUtils.realse(redis) |
| | | self.__first_no_screen_codes_cache.discard(code) |
| | | RedisUtils.srem_async(self.__db, "first_no_screen_codes", code, auto_free=False) |
| | | |
| | | def __get_first_no_screen_codes(self): |
| | | codes = RedisUtils.smembers(self.__get_redis(), "first_no_screen_codes") |
| | | if not codes: |
| | | return set() |
| | | return codes |
| | | |
| | | def __get_first_no_screen_codes(): |
| | | codes = RedisUtils.smembers(__get_redis(), "first_no_screen_codes") |
| | | if not codes: |
| | | return set() |
| | | return codes |
| | | def get_first_no_screen_codes_cache(self): |
| | | return self.__first_no_screen_codes_cache |
| | | |
| | | |
| | | # 处理ticks数据 |
| | |
| | | for price in prices: |
| | | code = price["code"] |
| | | time_ = price["time"] |
| | | old_data = __get_first_code_data_cache(code) |
| | | old_data = FirstCodeDataManager().get_first_code_data_cache(code) |
| | | if old_data is None: |
| | | continue |
| | | limit_up = price["limit_up"] |
| | |
| | | old_data[2] = time_ |
| | | old_data[3] = time_ |
| | | old_data[4] = limit_up |
| | | __save_first_code_data(code, old_data) |
| | | FirstCodeDataManager().save_first_code_data(code, old_data) |
| | | |
| | | |
| | | def set_target_no_screen_codes(codes): |
| | |
| | | del_codes = old_codes - codes_set |
| | | add_codes = codes_set - old_codes |
| | | if del_codes: |
| | | __remove_first_no_screen_codes(del_codes) |
| | | FirstNoScreenCodesManager().remove_first_no_screen_codes(del_codes) |
| | | if add_codes: |
| | | # 添加进首板未选票 |
| | | __add_first_no_screen_codes(add_codes) |
| | | FirstNoScreenCodesManager().add_first_no_screen_codes(add_codes) |
| | | return add_codes |
| | | |
| | | |
| | | # 获取首板未筛选的目标票 |
| | | def get_target_no_screen_codes(): |
| | | return __get_first_no_screen_codes() |
| | | return FirstNoScreenCodesManager().get_first_no_screen_codes_cache() |
| | | |
| | | |
| | | # 是否需要加入首板 |
| | |
| | | return True, "炸板后,60分钟内都未回封" |
| | | if now_rate <= 6: |
| | | return True, "炸板后,涨幅小于6%" |
| | | blocks = block_info.get_code_blocks(code) |
| | | if blocks and len(blocks) == 1: |
| | | codes = block_info.get_block_codes(blocks[0]) |
| | | |
| | | if codes: |
| | | pass |
| | | |
| | | return False, "首板炸开后,涨幅≤6%" |
| | |
| | | |
| | | |
| | | class CodesNameManager: |
| | | __db = 0 |
| | | redisManager = redis_manager.RedisManager(0) |
| | | __gp_list_names_first_cache = [] |
| | | |
| | |
| | | # 设置首板代码名称 |
| | | @classmethod |
| | | def set_first_code_names(cls, datas): |
| | | RedisUtils.set(cls.__get_redis(), "gp_list_names_first", json.dumps(datas)) |
| | | RedisUtils.set_async(cls.__db, "gp_list_names_first", json.dumps(datas)) |
| | | |
| | | # 删除首板代码名称 |
| | | @classmethod |
| | |
| | | # 首板代码管理 |
| | | class FirstCodeManager: |
| | | __instance = None |
| | | __db = 0 |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | |
| | | hasChanged = False |
| | | for code in codes: |
| | | if code not in self.__first_code_record_cache: |
| | | RedisUtils.sadd(self.__get_redis(), "first_code_record", code) |
| | | RedisUtils.sadd_async(self.__db, "first_code_record", code) |
| | | hasChanged = True |
| | | self.__first_code_record_cache.add(code) |
| | | if hasChanged: |
| | | RedisUtils.expire(self.__get_redis(), "first_code_record", tool.get_expire()) |
| | | RedisUtils.expire_async(self.__db, "first_code_record", tool.get_expire()) |
| | | |
| | | def is_in_first_record(self, code): |
| | | if RedisUtils.sismember(self.__get_redis(), "first_code_record", code): |
| | |
| | | hasChanged = False |
| | | for code in codes: |
| | | if code not in self.__first_code_limited_up_record_cache: |
| | | RedisUtils.sadd(self.__get_redis(), "first_code_limited_up_record", code) |
| | | RedisUtils.sadd_async(self.__get_redis(), "first_code_limited_up_record", code) |
| | | hasChanged = True |
| | | self.__first_code_limited_up_record_cache.add(code) |
| | | if hasChanged: |
| | | RedisUtils.expire(self.__get_redis(), "first_code_limited_up_record", tool.get_expire()) |
| | | RedisUtils.expire_async(self.__get_redis(), "first_code_limited_up_record", tool.get_expire()) |
| | | |
| | | # 是否涨停过 |
| | | def is_limited_up(self, code): |
| | |
| | | del_set = old_codes_set - codes_set |
| | | add_codes = codes_set - old_codes_set |
| | | for code in add_codes: |
| | | RedisUtils.sadd(redis_instance, "gp_list_first", code, auto_free=False) |
| | | RedisUtils.sadd_async(self.__db, "gp_list_first", code, auto_free=False) |
| | | for code in del_set: |
| | | RedisUtils.srem(redis_instance, "gp_list_first", code, auto_free=False) |
| | | RedisUtils.srem_async(self.__db, "gp_list_first", code, auto_free=False) |
| | | if add_codes or del_set: |
| | | RedisUtils.expire(redis_instance, "gp_list_first", tool.get_expire(), auto_free=False) |
| | | RedisUtils.expire_async(self.__db, "gp_list_first", tool.get_expire(), auto_free=False) |
| | | # 更新缓存 |
| | | self.__gp_list_first_codes_cache.clear() |
| | | self.__gp_list_first_codes_cache |= codes_set |
| | |
| | | return cls.exec("set", key, lambda: cls.__request(cls.__get_db(redis_), "set", key, val)) |
| | | |
| | | @classmethod |
| | | def set_async(cls, db, key, val, auto_free=True): |
| | | cls.add_async_task(db, "set", (key, val)) |
| | | # logger_redis_debug.info("setex_async({}):{}", 0, key) |
| | | |
| | | @classmethod |
| | | def setex(cls, redis_, key, expire, val, auto_free=True, _async=False): |
| | | return cls.exec("setex", key, lambda: cls.__request(cls.__get_db(redis_), "setex", key, [expire, val])) |
| | | |
| | |
| | | # 删除首板代码 |
| | | gpcode_manager.clear_first_codes() |
| | | # 删除首板未筛选代码 |
| | | gpcode_first_screen_manager.clear_first_no_screen_codes() |
| | | gpcode_first_screen_manager.FirstNoScreenCodesManager().clear_first_no_screen_codes() |
| | | # 删除禁止代码 |
| | | l2_trade_util.init_forbidden_trade_codes() |
| | | # 清空白名单 |