def v_category_positions(self, date=yesterdayobj(), rendered=True): """ 资产分类扇形图,按大类资产求和绘制 :param date: :param rendered: bool. default true for notebook, for plain pyechart obj to return, set rendered=False :return: """ d = {} for f in self.fundtradeobj: if isinstance(f, itrade): t = f.get_type() if t == "场内基金": t = get_fund_type(f.code[2:]) elif f.code == "mf": t = "货币基金" else: t = get_fund_type(f.code) if t == "其他": logger.warning( "%s has category others which should be double checked" % f.code ) d[t] = d.get(t, 0) + f.briefdailyreport(date).get("currentvalue", 0) sdata = sorted([(k, round(v, 2)) for k, v in d.items()]) pie = Pie() pie.add( series_name="总值占比", data_pair=sdata, label_opts=opts.LabelOpts(is_show=False, position="center"), ).set_global_opts( legend_opts=opts.LegendOpts( pos_left="left", type_="scroll", orient="vertical" ) ).set_series_opts( tooltip_opts=opts.TooltipOpts( trigger="item", formatter="{a} <br/>{b}: {c} ({d}%)" ), ) if rendered: return pie.render_notebook() else: return pie
def get_industry(self, date=yesterdayobj()): """ 获取基金组合持仓的行业占比信息,底层为非 A 股持仓的暂不支持 :param date: :return: Dict """ # TODO: hard coded 一个字典来合并一些二级行业 d = {} date = convert_date(date) rd = date - pd.Timedelta(days=120) year = rd.year season = int((rd.month - 0.1) / 3) + 1 for f in self.fundtradeobj: value = f.briefdailyreport(date).get("currentvalue", 0) if value > 0: if isinstance(f, itrade): if f.get_type() == "股票": industry = get_industry_fromxq(f.code).get( "industryname", "") if industry.strip(): d[industry] = d.get(industry, 0) + value continue elif f.get_type() in ["可转债", "债券", "货币基金"]: # 现在简化实现可转债暂时不按正股记行业 continue elif f.get_type() == "场内基金": code = f.code[2:] else: continue else: code = f.code if code == "mf": continue if get_fund_type(code) == "货币基金": continue ## 以下为持有股票的基金处理 ## fundinfo 有点浪费,不过简化实现暂时如此 fobj = fundinfo(code) industry_dict = fobj.get_industry_holdings(year=year, season=season) if industry_dict is None: continue ## 这里行业占比需要做个 scaling sv = sum([v for _, v in industry_dict.items()]) if sv < 1.0: # 只有极少数持仓存在行业信息 continue stock_ratio = fobj.get_portfolio_holdings( date.strftime("%Y%m%d"))["stock_ratio"] scale = stock_ratio / sv print(scale) for k, v in industry_dict.items(): if k.strip(): d[k] = d.get(k, 0) + value * v / 100 * scale return d
def get_portfolio(self, date=yesterdayobj()): """ 获取基金组合底层资产大类配置的具体值 :param date: :return: Dict[str, float]. stock,bond,cash 对应总值的字典 """ d = {"stock": 0, "bond": 0, "cash": 0} date = convert_date(date) for f in self.fundtradeobj: value = f.briefdailyreport(date).get("currentvalue", 0) if value > 0: if isinstance(f, itrade): if f.get_type() == "股票": d["stock"] += value continue elif f.get_type() in ["可转债", "债券"]: d["bond"] += value continue elif f.get_type() == "货币基金": d["cash"] += value continue elif f.get_type() == "场内基金": code = f.code[2:] else: continue else: code = f.code if code == "mf": d["cash"] += value continue if get_fund_type(code) == "货币基金": d["cash"] += value continue df = xu.get_daily("pt-F" + code, end=date.strftime("%Y%m%d")) if df is None or len(df) == 0: logger.warning("empty portfolio info for %s" % code) row = df.iloc[-1] if row["bond_ratio"] + row["stock_ratio"] < 10: # 联接基金 d["stock"] += ( (100 - row["bond_ratio"] - row["cash_ratio"]) * value / 100 ) d["bond"] += row["bond_ratio"] * value / 100 d["cash"] += row["cash_ratio"] * value / 100 else: d["stock"] += row["stock_ratio"] * value / 100 d["bond"] += row["bond_ratio"] * value / 100 d["cash"] += row["cash_ratio"] * value / 100 return d