def check_market_calendar(ts): cld = utils.gen_calendars_coll() exist = cld.find({"code": "SH000001"}).count() market_limit_date = MARKET_LIMIT_DATE logger.info(f"同步的截止时间是 {market_limit_date}") start = utils.market_first_day() logger.info(f"同步的开始时间是 {start}") sus = gen_sh000001(start, market_limit_date, ts) sh0001_sus = sorted(list(set(sus))) if not exist: logger.info("market first sync.") utils.bulk_insert(cld, "SH000001", sh0001_sus, start=start, end=market_limit_date) else: already_dates = cld.find({ "code": "SH000001", "ok": False }).distinct("date") int_already_dates = set( [utils.yyyymmdd_date(date) for date in already_dates]) int_sh0001_sus = set([utils.yyyymmdd_date(d) for d in sh0001_sus]) if int_sh0001_sus == int_already_dates: logger.info("无需更新 .") else: logger.info("市场交易日历需要重新插入.")
def check_mongo_diff(code, single_sus, ALREADYCHECK=False, DEL=False): """ DEL 是个标识位 表示是否根据 singe_sus 来调整删除原有数据 默认是只增加 不删除 ALREADYCHECK 也是个标志位 表示在插入新数据时,是否对数据库已经有该数据进行检查 默认是增量更新 数据都是原来没有插入过的 不检查 :param code: :param single_sus: :param ALREADYCHECK: :param DEL: :return: """ logger.info(f"股票代码是:{code} ") already_sus = list() if ALREADYCHECK: # 需要对已经有的数据进行插入重复检查 coll = utils.gen_calendars_coll() f_code = utils.code_convert(code) cursor = coll.find({ "code": f_code, "ok": False }, { "date": 1, "_id": 0 }) already_sus = [r.get("date") for r in cursor] add_sus = set(single_sus) - set(already_sus) # 需要插入的 # logger.info(f"需要新插入的数据: {add_sus} \n 插入数量是: {len(add_sus)}") else: add_sus = single_sus if DEL: # 需要检测后面可能又被删除数据 del_sus = set(already_sus) - set(single_sus) # 需要删除的 else: del_sus = set() return add_sus, del_sus
def bulk_delete(code, sus): logger.info(f"{code} 进入删除流程") coll = utils.gen_calendars_coll() f_code = utils.code_convert(code) try: ret = coll.delete_many({"code": f_code, "date": {"$in": list(sus)}}) except Exception as e: logger.info(f'批量删除有误,错误的原因是 {e}')
def bulk_insert(code, sus): logger.info(f"{code} 进入增加流程") coll = utils.gen_calendars_coll() bulks = list() # 将 code 转换为 带前缀的格式 f_code = utils.code_convert(code) for s in sus: bulks.append({ "code": f_code, "date": s, "date_int": utils.yyyymmdd_date(s), "ok": False }) try: ret = coll.insert_many(bulks) except Exception as e: # 批量插入出错的话 logger.warning(f"批量插入有误,错误的原因是 {e}")
def check_and_update(codes, timestamp): cld = utils.gen_calendars_coll() limit_date = datetime.datetime.combine( datetime.date.today(), datetime.time.min) + datetime.timedelta(days=1) codes_map = utils.convert_front_map(codes) market_start = utils.market_first_day() market_sus = gen_sh000001(market_start, limit_date, timestamp) for code in codes: logger.info("") logger.info(f"code: {code}") # 前缀模式 f_code = codes_map.get(code) logger.info("市场停牌: ") # market_sus = gen_sh000001(market_start, limit_date, timestamp) logger.info(f"market_sus_0: {market_sus[0]}") logger.info(f"market_sus_-1: {market_sus[-1]}") logger.info("个股停牌: ") code_sus = gen_inc_code_sus(code, market_start, limit_date, timestamp) if code_sus: logger.info(f"code_sus_0: {code_sus[0]}") logger.info(f"code_sus_-1: {code_sus[-1]}") else: logger.info(f"{code} no suspended days") logger.info("个股退市: ") infos = gen_delisted_info(code, timestamp) delisted = gen_delisted_days(infos, limit_date) if delisted == "no_records": error_code.append(code) continue if delisted: logger.info(f"delisted_0: {delisted[0]}") logger.info(f"delisted_-1: {delisted[-1]}") else: logger.info(f"{code} no delisted") # 在最新的 mysql 数据库中查询出的 all_sus all_sus = sorted(list(set(market_sus + code_sus + delisted))) single_sus = sorted(list(set(all_sus) - set(market_sus))) single_sus = [utils.yyyymmdd_date(dt) for dt in single_sus] # 生成 mongo 数据进行核对 cursor = cld.find({ "code": f_code, "ok": False }, { "date_int": 1, "_id": 0 }) mongo_sus = [j.get("date_int") for j in cursor] if sorted(single_sus) == sorted(mongo_sus): logger.info(f"check right!") else: logger.info("check wrong!") logger.warning(f"{sorted(single_sus)}") logger.warning(f"{sorted(mongo_sus)}") # update real_sus_dates = set(single_sus) - set(mongo_sus) logger.info(f"real_sus_dates: {real_sus_dates}") # FIXME 在没有的情况下进行更新 在有的情况下进行插入 # 但是如果将detection 的时间设置在 inc_sync 之后, 就不会出现 没有某天的数据 的情况 for sus in real_sus_dates: if list(cld.find({"code": f_code, "date_int": sus})): res = cld.update_one({ "code": f_code, "date_int": sus }, {"$set": { "ok": False }}) else: yyyy = int(str(sus)[:4]) mm = int(str(sus)[4:6]) dd = int(str(sus)[6:]) _date = datetime.datetime(yyyy, mm, dd) cld.insert_one({ "code": f_code, "date_int": sus, "date": _date, "ok": False }) real_trading_dates = set(mongo_sus) - set(single_sus) logger.info(f"real_trading_dates: {real_trading_dates}") # 将其从 mongo 中删除 cld.delete_many({ "code": f_code, "date_int": { "$in": list(real_trading_dates) } })