import logging from py_jftech import autowired, component, get_config from api import AssetOptimize, PortfoliosChecker, Datum, Navs, DatumType logger = logging.getLogger(__name__) @component(bean_name='checker') class DefaultPortfoliosChecker(PortfoliosChecker): @autowired def __init__(self, asset: AssetOptimize = None, navs: Navs = None, datum: Datum = None): self._asset = asset self._navs = navs self._datum = datum self._config = get_config(__name__) def check(self, day=None, portfolios: dict = None): if not self._config.get('switch'): return portfolios funds = self._datum.get_datums(type=DatumType.FUND) company = {f"{fund['id']}": fund['companyType'] for fund in funds} customType = {f"{fund['id']}": fund['customType'] for fund in funds} companies = set(company[key] for key in portfolios.keys()) # 同时出现全部是ft或美盛基金的情况 if len(companies) == 1: # step1: 检查原始投组的customType。检查顺序用列表呈现,依序进行 priority = self._config.get('custom-type-priority') for p in priority: # 找出对应优先级序列的基金列表 keys = [key for key in portfolios.keys() if customType[key] == p] # 若存在匹配值则执行后跳出循环 if len(keys) > 0: # 选取非同公司的、风险等级小于等于原基金的 基金 min_risk = min(fund['risk'] for fund in funds if str(fund['id']) in keys) ids = [fund['id'] for fund in funds if fund['companyType'] != list(companies)[0] and fund['risk'] <= min_risk] if len(ids) == 0: continue best = self.find_highest_score(ids, day) # 若刚好有一个匹配,直接替换 if len(keys) == 1: portfolios[best] = portfolios[keys[0]] # 删除原始键 del portfolios[keys[0]] else: # 算分,把分低的替换掉 scores = self.do_score(keys, day) weight_scores = {key: scores[key] * portfolios[key] for key in keys} lowest = min(scores, key=lambda k: weight_scores[k]) portfolios[best] = portfolios[lowest] # 删除原始键 del portfolios[lowest] break return portfolios def do_score(self, ids, day): optimize = self._asset.find_optimize(fund_ids=ids, day=day) scores = optimize[1].to_dict() id_score = {} for k, v in scores.items(): id_score[f'{ids[k]}'] = v return id_score def find_highest_score(self, ids, day): optimize = self._asset.find_optimize(fund_ids=ids, day=day) return optimize[0][0]