Ejemplo n.º 1
0
def xirrcal(cftable, trades, date, guess=0.1):
    """
    calculate the xirr rate

    :param cftable: cftable (pd.Dateframe) with date and cash column
    :param trades: list [trade1, ...], every item is an trade object,
        whose shares would be sold out virtually
    :param date: string of date or datetime object,
        the date when virtually all holding positions being sold
    :param guess: floating number, a guess at the xirr rate solution to be used
        as a starting point for the numerical solution
    :returns: the IRR as a single floating number
    """
    date = convert_date(date)
    partcftb = cftable[cftable["date"] <= date]
    if len(partcftb) == 0:
        return 0
    cashflow = [(row["date"], row["cash"]) for i, row in partcftb.iterrows()]
    rede = 0
    for fund in trades:
        if not isinstance(fund, itrade):
            rede += fund.aim.shuhui(
                fund.briefdailyreport(date).get("currentshare", 0),
                date,
                fund.remtable[fund.remtable["date"] <= date].iloc[-1].rem,
            )[1]
        else:  # 场内交易
            pricedf = get_daily(fund.code, end=date.strftime("%Y%m%d"), prev=20)
            price = pricedf[pricedf.date <= date].iloc[-1]["close"]
            rede += fund.cftable.share.sum() * price
    cashflow.append((date, rede))
    return xirr(cashflow, guess)
Ejemplo n.º 2
0
def xirrcal(cftable, trades, date, guess):
    '''
    calculate the xirr rate

    :param cftable: cftable (pd.Dateframe) with date and cash column
    :param trades: list [trade1, ...], every item is an trade object,
        whose shares would be sold out virtually
    :param date: string of date or datetime object,
        the date when virtually all holding positions being sold
    :param guess: floating number, a guess at the xirr rate solution to be used
        as a starting point for the numerical solution
    :returns: the IRR as a single floating number
    '''
    date = convert_date(date)
    partcftb = cftable[cftable['date'] <= date]
    if len(partcftb) == 0:
        return 0
    cashflow = [(row['date'], row['cash']) for i, row in partcftb.iterrows()]
    rede = 0
    for fund in trades:
        rede += fund.aim.shuhui(
            fund.briefdailyreport(date).get('currentshare', 0), date,
            fund.remtable[fund.remtable['date'] <= date].iloc[-1].rem)[1]
    cashflow.append((date, rede))
    return xirr(cashflow, guess)
Ejemplo n.º 3
0
def xirrcal(cftable, trades, date, startdate=None, guess=0.01):
    """
    calculate the xirr rate

    :param cftable: cftable (pd.Dateframe) with date and cash column
    :param trades: list [trade1, ...], every item is an trade object,
        whose shares would be sold out virtually
    :param date: string of date or datetime object,
        the date when virtually all holding positions being sold
    :param guess: floating number, a guess at the xirr rate solution to be used
        as a starting point for the numerical solution
    :returns: the IRR as a single floating number
    """
    date = convert_date(date)
    partcftb = cftable[cftable["date"] <= date]
    if len(partcftb) == 0:
        return 0
    if not startdate:
        cashflow = [(row["date"], row["cash"])
                    for i, row in partcftb.iterrows()]
    else:
        if not isinstance(startdate, dt.datetime):
            startdate = dt.datetime.strptime(
                startdate.replace("-", "").replace("/", ""), "%Y%m%d")
        start_cash = 0
        for fund in trades:
            start_cash += fund.briefdailyreport(startdate).get(
                "currentvalue", 0)
        cashflow = [(startdate, -start_cash)]
        partcftb = partcftb[partcftb["date"] > startdate]
        cashflow.extend([(row["date"], row["cash"])
                         for i, row in partcftb.iterrows()])
    rede = 0
    for fund in trades:
        if not isinstance(fund, itrade):
            partremtb = fund.remtable[fund.remtable["date"] <= date]
            if len(partremtb) > 0:
                rem = partremtb.iloc[-1]["rem"]
            else:
                rem = []
            rede += fund.aim.shuhui(
                fund.briefdailyreport(date).get("currentshare", 0), date,
                rem)[1]
        else:  # 场内交易
            rede += fund.briefdailyreport(date).get("currentvalue", 0)
    cashflow.append((date, rede))
    return xirr(cashflow, guess)
Ejemplo n.º 4
0
def cb_ytm(issue_date, rlist, cp, date=None, tax=1.0, guess=0.01):
    """
    可转债到期收益率计算器

    :param issue_date: 发行日期
    :param rlist: 计息及赎回列表
    :param cp: 可转债现价
    :param date: 参考日期
    :param tax: 计税 1 vs 0.8 税后 YTM
    :param guess: YTM 估计初始值
    :return:
    """

    if rlist[-1] < 100:
        logger.warning(
            "the format of rlist must contain the final return more than 100 without interest of that year"
        )
    issue_date = issue_date.replace("-", "").replace("/", "")
    issue_date_obj = dt.datetime.strptime(issue_date, "%Y%m%d")
    if date is None:
        date_obj = dt.datetime.today()
    else:
        date = date.replace("-", "").replace("/", "")
        date_obj = dt.datetime.strptime(date, "%Y%m%d")
    cf = [(date_obj, -cp)]
    passed = (date_obj - issue_date_obj).days // 365
    for i, r in enumerate(rlist[:-1]):
        if i >= passed:
            cf.append(
                (issue_date_obj + dt.timedelta(days=(i + 1) * 365), r * tax))
    # 关于赎回利息计算: https://www.jisilu.cn/?/question/339
    # https://www.jisilu.cn/question/5807
    # 富投网的算法:将最后一年超出100的部分,全部按照20%计税,
    cf.append((issue_date_obj + dt.timedelta(days=(len(rlist) - 1) * 365),
               rlist[-1]))
    #     print(cf)
    return xirr(cf, guess=guess)