Exemple #1
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 #2
0
def daily_increment(code, date, lastday=None, _check=False):
    """
    单一标的 date 日(若 date 日无数据则取之前的最晚有数据日,但该日必须大于 _check 对应的日期)较上一日或 lastday 的倍数,
    lastday 支持不完整,且不能离 date 太远

    :param code:
    :param date:
    :param lastday: 如果用默认 None,则表示和前一日的涨跌
    :param _check: 数据必须已更新到 date 日,除非之前每天都是节假日
    :return:
    """
    try:
        tds = xu.get_daily(code=code, end=date, prev=30)
    except Exception as e:  # 只能笼统 catch 了,因为抓取失败的异常是什么都能遇到。。。
        code = get_alt(code)
        if code:
            tds = xu.get_daily(code=code, end=date, prev=30)
        else:
            raise e
    tds = tds[tds["date"] <= date]
    if _check:
        date = date.replace("-", "").replace("/", "")
        date_obj = dt.datetime.strptime(date, "%Y%m%d")

        while tds.iloc[-1]["date"] < date_obj:
            # in case data is not up to date
            # 但是存在日本市场休市时间不一致的情况,估计美股也存在
            if not is_on(
                    date_obj.strftime("%Y%m%d"),
                    get_market(code),
                    no_trading_days=no_trading_days,
            ) or (date_obj.strftime("%Y-%m-%d") in gap_info.get(code, [])):
                print("%s is closed on %s" % (code, date))
                if not lastday:
                    return 1  # 当日没有涨跌,这里暂时为考虑 _check 和 lastday 相同的的情形
                date_obj -= dt.timedelta(days=1)
            else:
                raise DateMismatch(
                    code,
                    reason="%s has no data newer than %s" %
                    (code, date_obj.strftime("%Y-%m-%d")),
                )
    if not lastday:
        ratio = tds.iloc[-1]["close"] / tds.iloc[-2]["close"]
    else:
        tds2 = tds[tds["date"] <= lastday]
        # 未考虑连 lastday 的数据数据源都没更新的情形,这种可能极小
        ratio = tds.iloc[-1]["close"] / tds2.iloc[-1]["close"]
    return ratio
Exemple #3
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],
            )