Exemple #1
0
    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
Exemple #2
0
    def v_correlation(self, end=yesterdayobj(), vopts=None):
        """
        各基金净值的相关程度热力图可视化

        :param end: string or object of date, the end date of the line
        :returns: pyecharts.charts.Heatmap.render_notebook object
        """
        ctable = self.correlation_table(end)
        x_axis = list(ctable.columns)
        data = [[i, j, ctable.iloc[i, j]] for i in range(len(ctable))
                for j in range(len(ctable))]
        heatmap = HeatMap()
        heatmap.add_xaxis(x_axis)
        heatmap.add_yaxis(series_name="相关性", yaxis_data=x_axis, value=data)
        if vopts is None:
            vopts = heatmap_opts
        heatmap.set_global_opts(**vopts)

        return heatmap.render_notebook()
Exemple #3
0
    def sellout(self, date=yesterdayobj(), ratio=1):
        '''
        Sell all the funds in the same ratio on certain day, it is a virtual process,
        so it can happen before the last action exsiting in the cftable, by sell out earlier,
        it means all actions behind vanish. The status table in self.status would be directly changed.

        :param date: string or datetime obj of the selling date
        :param ratio: float between 0 to 1, the ratio of selling for each funds
        '''
        date = convert_date(date)
        s = self.status[self.status['date'] <= date]
        row = []
        ratio = ratio * 0.005
        for term in s.columns:
            if term != 'date':
                row.append(-ratio)
            else:
                row.append(date)
        s = s.append(pd.DataFrame([row], columns=s.columns), ignore_index=True)
        self.status = s
Exemple #4
0
 def update(self):
     lastdate = self.price.iloc[-1].date
     lastdatestr = lastdate.strftime('%Y%m%d')
     weight = self.price.iloc[1].totvalue
     self._updateurl = 'http://quotes.money.163.com/service/chddata.html?code=' + \
                       self.code + '&start=' + lastdatestr + '&end=' + yesterday() + '&fields=TCLOSE'
     df = pd.read_csv(self._updateurl, encoding='gb2312')
     self.name = df.iloc[0].loc['名称']
     if len(df) > 1:
         df = df.rename(columns={'收盘价': 'totvalue'})
         df['date'] = pd.to_datetime(df.日期)
         df = df.drop(['股票代码', '名称', '日期'], axis=1)
         df['netvalue'] = df.totvalue / weight
         df['comment'] = [0 for _ in range(len(df))]
         df = df.iloc[::-1].iloc[1:]
         df = df[df['date'].isin(opendate)]
         df = df.reset_index(drop=True)
         df = df[df['date'] <= yesterdayobj()]
         self.price = self.price.append(df, ignore_index=True, sort=True)
         return df
Exemple #5
0
    def v_techindex(self, end=yesterdayobj(), col=None, **vkwds):
        '''
        visualization on netvalue curve and specified indicators

        :param end: date string or obj, the end date of the figure
        :param col: list, list of strings for price col name, eg.['MA5','BBI']
            remember generate these indicators before the visualization
        :param vkwds: keywords option for pyecharts.Line().add(). eg, you may need is_symbol_show=False
            to hide the symbols on lines
        '''
        partprice = self.price[self.price['date'] <= end]
        xdata = [1 for _ in range(len(partprice))]
        netvaldata = [[row['date'], row['netvalue']] for _, row in partprice.iterrows()]
        line = Line()
        line.add('netvalue', xdata, netvaldata, is_datazoom_show=True, xaxis_type="time", **vkwds)
        if col is not None:
            for ind in col:
                inddata = [[row['date'], row[ind]] for _, row in partprice.iterrows()]
                line.add(ind, xdata, inddata, is_datazoom_show=True, xaxis_type="time", **vkwds)
        return line
Exemple #6
0
    def v_totvalue(self, end=yesterdayobj(), vopts=None):
        """
        visualization on the total values daily change of the aim
        """
        partp = self.aim.price[self.aim.price["date"] >= self.cftable.iloc[0].date]
        partp = partp[partp["date"] <= end]

        date = [d.date() for d in partp.date]
        valuedata = [
            self.briefdailyreport(d).get("currentvalue", 0) for d in partp.date
        ]

        line = Line()
        if vopts is None:
            vopts = line_opts

        line.add_xaxis(date)
        line.add_yaxis(series_name="持仓总值", y_axis=valuedata, is_symbol_show=False)
        line.set_global_opts(**vopts)

        return line.render_notebook()
Exemple #7
0
    def v_totvalue(self, end=yesterdayobj(), **vkwds):
        '''
        visualization on the total values daily change of the aim
        '''
        valuedata = []
        partp = self.aim.price[
            self.aim.price['date'] >= self.cftable.iloc[0].date]
        partp = partp[partp['date'] <= end]
        for i, row in partp.iterrows():
            date = row['date']
            valuedata.append(
                [date,
                 self.briefdailyreport(date).get('currentvalue', 0)])

        line = Line()
        line.add('totvalue', [1 for _ in range(len(valuedata))],
                 valuedata,
                 is_datazoom_show=True,
                 xaxis_type="time",
                 **vkwds)

        return line
Exemple #8
0
 def update(self):
     lastdate = self.price.iloc[-1].date
     lastdatestr = lastdate.strftime("%Y%m%d")
     weight = self.price.iloc[1].totvalue
     self._updateurl = (
         "http://quotes.money.163.com/service/chddata.html?code=" +
         self.code + "&start=" + lastdatestr + "&end=" + yesterday() +
         "&fields=TCLOSE")
     df = pd.read_csv(self._updateurl, encoding="gb2312")
     self.name = df.iloc[0].loc["名称"]
     if len(df) > 1:
         df = df.rename(columns={"收盘价": "totvalue"})
         df["date"] = pd.to_datetime(df.日期)
         df = df.drop(["股票代码", "名称", "日期"], axis=1)
         df["netvalue"] = df.totvalue / weight
         df["comment"] = [0 for _ in range(len(df))]
         df = df.iloc[::-1].iloc[1:]
         df = df[df["date"].isin(opendate)]
         df = df.reset_index(drop=True)
         df = df[df["date"] <= yesterdayobj()]
         self.price = self.price.append(df, ignore_index=True, sort=True)
         return df
Exemple #9
0
    def briefdailyreport(self, date=yesterdayobj()):
        """
        quick summary of highly used attrs for trade

        :param date: string or object of datetime
        :returns: dict with several attrs: date, unitvalue, currentshare, currentvalue
        """
        date = convert_date(date)
        partcftb = self.cftable[self.cftable["date"] <= date]
        if len(partcftb) == 0:
            return {}

        unitvalue = self.get_netvalue(date)
        currentshare = myround(sum(partcftb.loc[:, "share"]))
        currentvalue = myround(currentshare * unitvalue)

        return {
            "date": date,
            "unitvalue": unitvalue,
            "currentshare": currentshare,
            "currentvalue": currentvalue,
        }
Exemple #10
0
    def v_positions(self, date=yesterdayobj(), rendered=True, vopts=None):
        """
        pie chart visualization of positions ratio in combination
        """
        sdata = sorted(
            [
                (fob.name, fob.briefdailyreport(date).get("currentvalue", 0))
                for fob in self.fundtradeobj
            ],
            key=lambda x: x[1],
            reverse=True,
        )

        pie = Pie()
        if vopts is None:
            vopts = pie_opts
        pie.add(series_name="总值占比", data_pair=sdata)
        pie.set_global_opts(**vopts)
        if rendered:
            return pie.render_notebook()
        else:
            return pie
Exemple #11
0
    def v_correlation(self, end=yesterdayobj(), **vkwds):
        '''
        各基金净值的相关程度热力图可视化

        :param end: string or object of date, the end date of the line
        :returns: pyecharts.Heatmap object
        '''
        ctable = self.correlation_table(end)
        x_axis = list(ctable.columns)
        data = [[i, j, ctable.iloc[i, j]] for i in range(len(ctable))
                for j in range(len(ctable))]
        heatmap = HeatMap()
        heatmap.add("",
                    x_axis,
                    x_axis,
                    data,
                    is_visualmap=True,
                    visual_pos='center',
                    visual_text_color="#000",
                    visual_range=[-1, 1],
                    visual_orient='horizontal',
                    **vkwds)
        return heatmap
Exemple #12
0
    def v_netvalue(self, end=yesterdayobj(), vopts=None):
        """
        起点对齐归一的,各参考基金或指数的净值比较可视化

        :param end: string or object of date, the end date of the line
        :param vkwds: pyechart line.add() options
        :param vopts: dict, options for pyecharts instead of builtin settings
        :returns: pyecharts.charts.Line.render_notebook()
        """
        partprice = self.totprice[self.totprice["date"] <= end]

        line = Line()
        if vopts is None:
            vopts = line_opts
        line.set_global_opts(**vopts)
        line.add_xaxis([d.date() for d in list(partprice.date)])
        for fund in self.fundobjs:
            line.add_yaxis(
                series_name=fund.name,
                y_axis=list(partprice[fund.code]),
                is_symbol_show=False,
            )
        return line.render_notebook()
Exemple #13
0
    def briefdailyreport(self, date=yesterdayobj()):
        '''
        quick summary of highly used attrs for trade

        :param date: string or object of datetime
        :returns: dict with several attrs: date, unitvalue, currentshare, currentvalue
        '''
        date = convert_date(date)
        partcftb = self.cftable[self.cftable['date'] <= date]
        if len(partcftb) == 0:
            return {}

        unitvalue = self.aim.price[
            self.aim.price['date'] <= date].iloc[-1].netvalue
        currentshare = myround(sum(partcftb.loc[:, 'share']))
        currentvalue = myround(currentshare * unitvalue)

        return {
            'date': date,
            'unitvalue': unitvalue,
            'currentshare': currentshare,
            'currentvalue': currentvalue
        }
Exemple #14
0
    def v_positions(self, date=yesterdayobj(), rendered=True):
        """
        pie chart visualization of positions ratio in combination
        """
        sdata = sorted(
            [(fob.name, fob.briefdailyreport(date).get("currentvalue", 0))
             for fob in self.fundtradeobj],
            key=lambda x: x[1],
            reverse=True,
        )
        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
Exemple #15
0
    def v_netvalue(self, end=yesterdayobj(), **vkwds):
        '''
        起点对齐归一的,各参考基金或指数的净值比较可视化

        :param end: string or object of date, the end date of the line
        :param vkwds: pyechart line.add() options
        :returns: pyecharts.Line object
        '''
        partprice = self.totprice[self.totprice['date'] <= end]
        xdata = [1 for _ in range(len(partprice))]
        ydatas = []
        for fund in self.fundobjs:
            ydata = [[row['date'], row[fund.code]]
                     for _, row in partprice.iterrows()]
            ydatas.append(ydata)
        line = Line()
        for i, fund in enumerate(self.fundobjs):
            line.add(fund.name,
                     xdata,
                     ydatas[i],
                     is_datazoom_show=True,
                     xaxis_type="time",
                     **vkwds)
        return line
Exemple #16
0
    def v_techindex(self, end=yesterdayobj(), col=None, vopts=None):
        """
        visualization on netvalue curve and specified indicators

        :param end: date string or obj, the end date of the figure
        :param col: list, list of strings for price col name, eg.['MA5','BBI']
            remember generate these indicators before the visualization,
            these cols don't automatically generate for visualization
        :param vopts: dict, options for pyecharts instead of builtin settings
        """
        partprice = self.price[self.price["date"] <= end]
        xdata = [d.date() for d in list(partprice.date)]
        netvaldata = list(partprice.netvalue)
        if vopts is None:
            vopts = line_opts
        line = Line()
        line.add_xaxis(xdata)
        line.add_yaxis(series_name="netvalue", y_axis=netvaldata, is_symbol_show=False)
        line.set_global_opts(**vopts)
        if col is not None:
            for ind in col:
                inddata = list(partprice[ind])
                line.add_yaxis(series_name=ind, y_axis=inddata, is_symbol_show=False)
        return line.render_notebook()
Exemple #17
0
    def v_netvalue(self, end=yesterdayobj(), benchmark=True, vopts=None):
        """
        visulaization on  netvalue curve

        :param end: dateobject for indicating the end date in the figure, default to yesterday
        :param benchmark: bool, whether include benchmark's netvalue curve, default true
        :param vopts: dict, options for pyecharts instead of builtin settings
        """
        a, b = self.comparison(end)
        if vopts is None:
            vopts = line_opts
        line = Line()
        line.add_xaxis([d.date() for d in list(a.date)])
        line.add_yaxis(
            y_axis=list(a.netvalue), series_name=self.name, is_symbol_show=False
        )
        line.set_global_opts(**vopts)
        if benchmark is True:
            line.add_yaxis(
                series_name=self.benchmark.name,
                y_axis=list(b.netvalue),
                is_symbol_show=False,
            )
        return line.render_notebook()
Exemple #18
0
 def total_annualized_returns(self, date=yesterdayobj()):
     return indicator.annualized_returns(self.price, self.start, date)
Exemple #19
0
 def sharpe(self, date=yesterdayobj()):
     rp = self.total_annualized_returns(date)
     return (rp - self.riskfree) / self.algorithm_volatility(date)
Exemple #20
0
 def algorithm_volatility(self, date=yesterdayobj()):
     return indicator.volatility(self.price, date)
Exemple #21
0
 def benchmark_volatility(self, date=yesterdayobj()):
     return indicator.volatility(self.bmprice, date)
Exemple #22
0
 def alpha(self, date=yesterdayobj()):
     rp = self.total_annualized_returns(date)
     rm = self.benchmark_annualized_returns(date)
     beta = self.beta(date)
     return rp - (self.riskfree + beta * (rm - self.riskfree))
Exemple #23
0
 def volatility(price, date=yesterdayobj()):
     df = pd.DataFrame(data={"rate": indicator.ratedaily(price, date)})
     return df.std().rate * 15.8144
Exemple #24
0
 def benchmark_annualized_returns(self, date=yesterdayobj()):
     return indicator.annualized_returns(self.bmprice, self.start, date)
Exemple #25
0
 def beta(self, date=yesterdayobj()):
     bcmk = indicator.ratedaily(self.bmprice, date)
     bt = indicator.ratedaily(self.price, date)
     df = pd.DataFrame(data={"bcmk": bcmk, "bt": bt})
     res = df.cov()
     return res.loc["bcmk", "bt"] / res.loc["bcmk", "bcmk"]
Exemple #26
0
    def _addrow(self):
        """
        Return cashflow table with one more line or raise an exception if there is no more line to add
        The same logic also applies to rem table
        关于对于一个基金多个操作存在于同一交易日的说明:无法处理历史买入第一笔同时是分红日的情形, 事实上也不存在这种情形。无法处理一日多笔买卖的情形。
        同一日既有卖也有买不现实,多笔买入只能在 csv 上合并记录,由此可能引起份额计算 0.01 的误差。可以处理分红日买入卖出的情形。
        分级份额折算日封闭无法买入,所以程序直接忽略当天的买卖。因此不会出现多个操作共存的情形。
        """
        # the design on data remtable is disaster, it is very dangerous though works now

        code = self.aim.code
        if len(self.cftable) == 0:
            if len(self.status[self.status[code] != 0]) == 0:
                raise Exception("no other info to be add into cashflow table")
            i = 0
            while self.status.iloc[i].loc[code] == 0:
                i += 1
            value = self.status.iloc[i].loc[code]
            date = self.status.iloc[i].date
            if value > 0:
                rdate, cash, share = self.aim.shengou(value, date)
                rem = rm.buy([], share, rdate)
            else:
                raise TradeBehaviorError("You cannot sell first when you never buy")
        elif len(self.cftable) > 0:
            recorddate = list(self.status.date)
            lastdate = self.cftable.iloc[-1].date + pd.Timedelta(1, unit="d")
            while (lastdate not in self.aim.specialdate) and (
                (lastdate not in recorddate)
                or (
                    (lastdate in recorddate)
                    and (
                        self.status[self.status["date"] == lastdate].loc[:, code].any()
                        == 0
                    )
                )
            ):
                lastdate += pd.Timedelta(1, unit="d")
                if (lastdate - yesterdayobj()).days >= 1:
                    raise Exception("no other info to be add into cashflow table")
            date = lastdate
            label = self.aim.dividend_label  # 现金分红 0, 红利再投 1
            cash = 0
            share = 0
            rem = self.remtable.iloc[-1].rem
            rdate = date

            if (date in recorddate) and (date not in self.aim.zhesuandate):
                # deal with buy and sell and label the fenhongzaitouru, namely one label a 0.05 in the original table to label fenhongzaitouru
                value = self.status[self.status["date"] == date].iloc[0].loc[code]
                fenhongmark = round(10 * value - int(10 * value), 1)
                if fenhongmark == 0.5 and label == 0:
                    label = 1  # fenhong reinvest
                    value = round(value, 1)
                elif fenhongmark == 0.5 and label == 1:
                    label = 0
                    value = round(value, 1)

                if value > 0:  # value stands for purchase money
                    rdate, dcash, dshare = self.aim.shengou(value, date)
                    rem = rm.buy(rem, dshare, rdate)

                elif value < -0.005:  # value stands for redemp share
                    rdate, dcash, dshare = self.aim.shuhui(
                        -value, date, self.remtable.iloc[-1].rem
                    )
                    _, rem = rm.sell(rem, -dshare, rdate)
                elif value >= -0.005 and value < 0:
                    # value now stands for the ratio to be sold in terms of remain positions, -0.005 stand for sell 100%
                    remainshare = sum(self.cftable.loc[:, "share"])
                    ratio = -value / 0.005
                    rdate, dcash, dshare = self.aim.shuhui(
                        remainshare * ratio, date, self.remtable.iloc[-1].rem
                    )
                    _, rem = rm.sell(rem, -dshare, rdate)
                else:  # in case value=0, when specialday is in record day
                    rdate, dcash, dshare = date, 0, 0

                cash += dcash
                share += dshare
            if date in self.aim.specialdate:  # deal with fenhong and xiazhe
                comment = (
                    self.aim.price[self.aim.price["date"] == date]
                    .iloc[0]
                    .loc["comment"]
                )
                if isinstance(comment, float):
                    if comment < 0:
                        dcash2, dshare2 = (
                            0,
                            sum([myround(sh * (-comment - 1)) for _, sh in rem]),
                        )  # xiazhe are seperately carried out based on different purchase date
                        rem = rm.trans(rem, -comment, date)
                        # myround(sum(cftable.loc[:,'share'])*(-comment-1))
                    elif comment > 0 and label == 0:
                        dcash2, dshare2 = (
                            myround(sum(self.cftable.loc[:, "share"]) * comment),
                            0,
                        )
                        rem = rm.copy(rem)

                    elif comment > 0 and label == 1:
                        dcash2, dshare2 = (
                            0,
                            myround(
                                sum(self.cftable.loc[:, "share"])
                                * (
                                    comment
                                    / self.aim.price[self.aim.price["date"] == date]
                                    .iloc[0]
                                    .netvalue
                                )
                            ),
                        )
                        rem = rm.buy(rem, dshare2, date)

                    cash += dcash2
                    share += dshare2
                else:
                    raise ParserFailure("comments not recoginized")

        self.cftable = self.cftable.append(
            pd.DataFrame([[rdate, cash, share]], columns=["date", "cash", "share"]),
            ignore_index=True,
        )
        self.remtable = self.remtable.append(
            pd.DataFrame([[rdate, rem]], columns=["date", "rem"]), ignore_index=True
        )
Exemple #27
0
 def get_netvalue(self, date=yesterdayobj()):
     return get_daily(self.code, end=date.strftime("%Y%m%d"), prev=20).iloc[-1].close
Exemple #28
0
 def v_tradecost(self, start=None, end=yesterdayobj(), vopts=None):
     raise NotImplementedError()
Exemple #29
0
 def v_totvalue(self, end=yesterdayobj(), vopts=None):
     raise NotImplementedError()
Exemple #30
0
 def get_netvalue(self, date=yesterdayobj()):
     return self.aim.price[self.aim.price["date"] <= date].iloc[-1].netvalue