Exemple #1
0
    def set_t2(self, value, date=None):
        """
        手动设定 t2 净值

        :param value:
        :return:
        """
        if not date:
            date = last_onday(last_onday(self.today)).strftime("%Y-%m-%d")
        self.t2value_cache = (value, date)
Exemple #2
0
 def get_t0(self, return_date=True, percent=False):
     last_value, last_date = self.get_t1()
     last_date_obj = dt.datetime.strptime(last_date, "%Y-%m-%d")
     cday = last_onday(self.today)
     while last_date_obj < cday:  # 昨天净值数据还没更新
         # 是否存在部分部分基金可能有 gap?
         if cday.strftime("%Y-%m-%d") not in gap_info[self.fcode]:
             self.t1_type = "昨日未出"
             raise DateMismatch(
                 self.code,
                 reason="%s netvalue has not been updated to yesterday" %
                 self.code,
             )
         else:
             cday = last_onday(cday)
         # 经过这个没报错,就表示数据源是最新的
     if last_date_obj >= self.today:  # 今天数据已出,不需要再预测了
         print("no need to predict net value since it has been out for %s" %
               self.code)
         self.t1_type = "今日已出"
         if not return_date:
             return last_value
         else:
             return last_value, last_date
     t = 0
     n = 0
     today_str = self.today.strftime("%Y%m%d")
     for k, v in self.t0dict.items():
         w = v
         t += w
         r = get_rt(k)
         # k should support get_rt, investing pid doesn't support this!
         if percent:
             c = w / 100 * (1 + r["percent"] / 100)  # 直接取标的当日涨跌幅
         else:
             df = xu.get_daily(k)
             basev = df[df["date"] <= last_date].iloc[-1]["close"]
             c = w / 100 * r["current"] / basev
         currency_code = get_currency_code(k)
         if currency_code:
             c = c * daily_increment(currency_code, today_str)
         n += c
     n += (100 - t) / 100
     t0value = n * last_value
     self.t0_delta = n
     if not return_date:
         return t0value
     else:
         return t0value, self.today.strftime("%Y-%m-%d")
Exemple #3
0
 def set_position(self, value, date=None):
     if date is None:
         yesterday = last_onday(self.today)
         datekey = yesterday.strftime("%Y%m%d")
     else:
         datekey = date.replace("/", "").replace("-", "")
     self.position_cache[datekey] = value
Exemple #4
0
    def get_position(self, date=None, refresh=False, return_date=True, **kws):
        """
        基于 date 日之前的净值数据,对 date 预估需要的仓位进行计算。

        :param date: str. %Y-%m-%d
        :param refresh: bool, default False. 若为 True,则刷新缓存,重新计算仓位。
        :param return_date: bool, default True. return tuple, the second one is date in the format %Y%m%d
        :param kws: 一些预估仓位可能的超参。包括 window,预估所需的时间窗口,decay 加权平均的权重衰减,smooth 每日仓位处理的平滑函数。以上参数均可保持默认即可获得较好效果。
        :return: float. 0-100. 100 代表满仓。
        """
        if not date:
            date = last_onday(self.today).strftime("%Y%m%d")
        else:
            date = date.replace("/", "").replace("-", "")
        if date not in self.position_cache or refresh:

            fdict = scale_dict(self.t1dict.copy(), aim=100)
            l = kws.get("window", 4)
            q = kws.get("decay", 0.8)
            s = kws.get("smooth", _smooth_pos)
            d = dt.datetime.strptime(date, "%Y%m%d")
            posl = [sum([v for _, v in self.t1dict.items()]) / 100]
            for _ in range(l):
                d = last_onday(d)
            for _ in range(l - 1):
                d = next_onday(d)
                pred = evaluate_fluctuation(
                    fdict,
                    d.strftime("%Y-%m-%d"),
                    lastday=last_onday(d).strftime("%Y-%m-%d"),
                )
                real = evaluate_fluctuation(
                    {self.fcode: 100},
                    d.strftime("%Y-%m-%d"),
                    lastday=last_onday(d).strftime("%Y-%m-%d"),
                )
                posl.append(s(real, pred, posl[-1]))
            current_pos = sum([q**i * posl[l - i - 1] for i in range(l)
                               ]) / sum([q**i for i in range(l)])
            self.position_cache[date] = current_pos
        if not return_date:
            return self.position_cache[date]
        else:
            return (
                self.position_cache[date],
                date[:4] + "-" + date[4:6] + "-" + date[6:8],
            )
Exemple #5
0
 def _base_value(self, code, shift):
     if not shift:
         funddf = xu.get_daily(code)  ## 获取股指现货日线
         return funddf[funddf["date"] <= last_onday(self.today)].iloc[-1][
             "close"]  # 日期是按当地时间
     # TODO: check it is indeed date of last_on(today)
     else:
         if code not in self.bar_cache:
             funddf = get_bar(code, prev=168, interval="3600")  ## 获取小时线
             ## 注意对于国内超长假期,prev 可能还不够
             if self.now.hour > 6:  # 昨日美国市场收盘才正常,才缓存参考小时线
                 self.bar_cache[code] = funddf
         else:
             funddf = self.bar_cache[code]
         refdate = last_onday(self.today) + dt.timedelta(days=1)  # 按北京时间校准
         return funddf[funddf["date"] <= refdate +
                       dt.timedelta(hours=shift)].iloc[-1][
                           "close"]  # 时间是按北京时间, 小时线只能手动缓存,日线不需要是因为自带透明缓存器
Exemple #6
0
    def set_t1(self, value, date=None):
        """
        设定 T-1 的基金净值,有时我们只想计算实时净值,这就不需要重复计算 t1,可以先行设定

        :param value:
        :param date:
        :return:
        """
        if date is None:
            yesterday = last_onday(self.today)
            datekey = yesterday.strftime("%Y%m%d")
        else:
            datekey = date.replace("/", "").replace("-", "")
        if datekey in self.t1value_cache:
            print("t-1 value already exists, rewriting...")
        self.t1value_cache[datekey] = value
        self.t1_type = "已计算"
Exemple #7
0
def get_bond_rates(rating, date=None):
    """
    获取各评级企业债的不同久期的预期利率

    :param rating: str. eg AAA, AA-, N for 中国国债
    :param date: %Y-%m-%d
    :return:
    """
    rating_uid = {
        "N": "2c9081e50a2f9606010a3068cae70001",
        "AAA": "2c9081e50a2f9606010a309f4af50111",
        "AAA-": "8a8b2ca045e879bf014607ebef677f8e",
        "AA+": "2c908188138b62cd01139a2ee6b51e25",
        "AA": "2c90818812b319130112c279222836c3",
        "AA-": "8a8b2ca045e879bf014607f9982c7fc0",
        "A+": "2c9081e91b55cc84011be40946ca0925",
        "A": "2c9081e91e6a3313011e6d438a58000d",
    }

    def _fetch(date):
        r = rpost(
            "https://yield.chinabond.com.cn/cbweb-mn/yc/searchYc?\
xyzSelect=txy&&workTimes={date}&&dxbj=0&&qxll=0,&&yqqxN=N&&yqqxK=K&&\
ycDefIds={uid}&&wrjxCBFlag=0&&locale=zh_CN".format(uid=rating_uid[rating],
                                                   date=date), )
        return r

    if not date:
        date = dt.datetime.today().strftime("%Y-%m-%d")

    r = _fetch(date)
    while len(r.text.strip()) < 20:  # 当天没有数据,非交易日
        date = last_onday(date).strftime("%Y-%m-%d")
        r = _fetch(date)
    l = r.json()[0]["seriesData"]
    l = [t for t in l if t[1]]
    df = pd.DataFrame(l, columns=["year", "rate"])
    return df
Exemple #8
0
    def get_t1(self, date=None, return_date=True):
        """
        预测 date 日的净值,基于 date-1 日的净值和 date 日的外盘数据,数据自动缓存,不会重复计算

        :param date: str. %Y-%m-%d. 注意若是 date 日为昨天,即今日预测昨日的净值,date 取默认值 None。
        :param return_date: bool, default True. return tuple, the second one is date in the format %Y%m%d
        :return: float, (str).
        :raises NonAccurate: 由于外盘数据还未及时更新,而 raise,可在调用程序中用 except 捕获再处理。
        """
        if date is None:
            yesterday = last_onday(self.today)
            datekey = yesterday.strftime("%Y%m%d")
        else:
            datekey = date.replace("/", "").replace("-", "")
        if datekey not in self.t1value_cache:

            if self.positions:
                current_pos = self.get_position(datekey, return_date=False)
                hdict = scale_dict(self.t1dict.copy(), aim=current_pos * 100)
            else:
                hdict = self.t1dict.copy()

            if date is None:  # 此时预测上个交易日净值
                yesterday_str = datekey
                last_value, last_date = self.get_t2()
                last_date_obj = dt.datetime.strptime(last_date, "%Y-%m-%d")
                cday = last_onday(last_onday(self.today))
                while last_date_obj < cday:  # 前天净值数据还没更新
                    # 是否存在部分 QDII 在 A 股交易日,美股休市日不更新净值的情形?
                    if (cday.strftime("%Y-%m-%d")
                            not in gap_info[self.fcode]) and is_on(
                                cday, "US", no_trading_days):
                        # 这里检查比较宽松,只要当天美股休市,就可以认为确实基金数据不存在而非未更新
                        self.t1_type = "前日未出"
                        raise DateMismatch(
                            self.code,
                            reason=
                            "%s netvalue has not been updated to the day before yesterday"
                            % self.code,
                        )
                    else:
                        cday = last_onday(cday)
                    # 经过这个没报错,就表示数据源是最新的
                if last_date_obj >= last_onday(self.today):  # 昨天数据已出,不需要再预测了
                    print(
                        "no need to predict t-1 value since it has been out for %s"
                        % self.code)
                    self.t1_type = "昨日已出"
                    self.t1value_cache = {
                        last_date.replace("-", ""): last_value
                    }
                    if not return_date:
                        return last_value
                    else:
                        return last_value, last_date
            else:
                yesterday_str = datekey
                fund_price = xu.get_daily(self.fcode)  # 获取国内基金净值
                fund_last = fund_price[fund_price["date"] < date].iloc[-1]
                # 注意实时更新应用 date=None 传入,否则此处无法保证此数据是前天的而不是大前天的,因为没做校验
                # 事实上这里计算的预测是针对 date 之前的最晚数据和之前一日的预测
                last_value = fund_last["close"]
                last_date = fund_last["date"].strftime("%Y-%m-%d")
            self.t1_delta = (1 + evaluate_fluctuation(
                hdict, yesterday_str, lastday=last_date, _check=True) / 100)
            net = last_value * self.t1_delta
            self.t1value_cache[datekey] = net
            self.t1_type = "已计算"
        if not return_date:
            return self.t1value_cache[datekey]
        else:
            return (
                self.t1value_cache[datekey],
                datekey[:4] + "-" + datekey[4:6] + "-" + datekey[6:8],
            )