def backtest(self): """ run the whole backtest :return: """ self.prepare() dates = pd.bdate_range(self.start, self.end) for d in dates: # 考虑到暂时只支持基金,只在国内交易日运行 if d not in opendate_set: d = next_onday(d) self.run(d)
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], )