示例#1
0
 def forcastStkReturn(self):
     '''
     给出下一期股票收益的预测
     :return:dataframe,纵轴:股票,横轴:e_ret,各因子暴露收益
     '''
     nextDate = fapi.TradingTimePoints(
         asset_code=None,
         starttime=self.timespan[1] + timedelta(days=1),
         endtime=self.timespan[1] + timedelta(days=10),
         freq=self.freq).index[0].to_pydatetime()
     FactorMatDict = {
         x.descriptorRefName(): get_feature(descriptor=x,
                                            starttime=nextDate,
                                            endtime=nextDate,
                                            freq=self.freq,
                                            check=False)
         for x in self.factors
     }
     matchDs = xr.Dataset(FactorMatDict)
     CalibratedFeats = {
         fename: matchDs[fename].values.flatten()
         for fename in matchDs
     }
     stocks = matchDs.indexes['StockCode']
     df_factorLoading = pd.DataFrame(index=stocks, data=CalibratedFeats)
     expFreturnLi = [
         self.expFreturn[f.descriptorRefName()] for f in self.factors
     ]
     df_ForcastReturns = df_factorLoading.mul(expFreturnLi, axis=1)
     df_ForcastReturns['e_ret'] = df_ForcastReturns.sum(axis=1)
     return df_ForcastReturns
示例#2
0
 def __init__(self,
              asset_code: str,
              factors: List[Union[Descriptor]],
              starttime: datetime,
              endtime: datetime,
              freq: str = 'd',
              forcast_period: int = 1):
     '''
     :param stockcode: 待预测标的
     :param factors: 特征列表
     :param starttime: 样本起始时间
     :param endtime: 样本结束时间
     :param freq: 学习频率 'm'(分)/'d'(日)/'w'(周)/'M'(月)
     :param forcast_period: 预测期
     '''
     #todo 如何预测同标的的期货合约(要考虑合约换月)?
     #     (丢给feature算法/get_return特殊处理,此处仅考虑可以由stockcode顺利获取特征及收益)
     ReturnSeries = fapi.getReturn(asset_code=asset_code,
                                   starttime=starttime,
                                   endtime=endtime,
                                   forcast_period=forcast_period,
                                   freq=freq)
     for factor in factors:
         factor.freq = freq
         feSeries = get_feature(factor, starttime, endtime, asset_code,
                                True)
示例#3
0
 def forcastStkReturn(self, check=True) -> pd.DataFrame:
     '''
     给出下一期股票收益的预测
     :param check: bool 是否检查更新特征数据
     :return:dataframe,纵轴:股票,横轴:e_ret,各因子暴露收益
     '''
     nextDate = fapi.TradingTimePoints(
         asset_code=None,
         starttime=self.timespan[1] + timedelta(days=1),
         endtime=self.timespan[1] + timedelta(days=10),
         freq=self.freq).index[0].to_pydatetime()
     FactorMatDict = {
         x.descriptorRefName(): get_feature(descriptor=x,
                                            starttime=nextDate,
                                            endtime=nextDate,
                                            freq=self.freq,
                                            checkLevel=2 if check else 0)
         for x in self.factors
     }
     matchDs = xr.Dataset(FactorMatDict)
     CalibratedFeats = {
         fename: matchDs[fename].values.flatten()
         for fename in matchDs
     }
     stocks = matchDs.indexes['StockCode']
     df_factorLoading = pd.DataFrame(index=stocks, data=CalibratedFeats)
     expFreturnLi = [
         self.expFreturn[f.descriptorRefName()] for f in self.factors
     ]
     df_ForcastReturns: pd.DataFrame = df_factorLoading.mul(expFreturnLi,
                                                            axis=1)
     df_ForcastReturns['e_ret'] = df_ForcastReturns.sum(axis=1)
     cashdict = {i: 0 for i in list(df_ForcastReturns.columns)}
     cash = pd.DataFrame(cashdict, index=['cash'])
     aa = df_ForcastReturns.append(cash)
     return aa
示例#4
0
    def __getfundamental(self, timespan):
        '''
        计算并返回指定时间段内的交易日、描述子数据、收益数据以及横截面回归结果.
        :param timespan: 指定的时间段
        :return: (out_dateIndex,out_endogs,out_exogs,out_dateIndex)
            out_dateIndex:时间段内的交易时点序列
            out_endogs:时间段内的股票收益数据
            out_exogs:时间段内的描述子数据
            out_rst:时间段内的横截面回归结果
        '''
        ReturnMat = fapi.getReturn(asset_code=None,
                                   starttime=timespan[0],
                                   endtime=timespan[1],
                                   forcast_period=self.forcast_period,
                                   freq=self.freq,
                                   asset_type='stock')
        #取因子矩阵
        FactorMatDict = {
            'feat_' + x.descriptorRefName(): get_feature(descriptor=x,
                                                         starttime=timespan[0],
                                                         endtime=timespan[1],
                                                         freq=self.freq,
                                                         check=False)
            for x in self.factors
        }
        ControlMatDict = {
            'ctrl_' + x.descriptorRefName(): get_feature(descriptor=x,
                                                         starttime=timespan[0],
                                                         endtime=timespan[1],
                                                         freq=self.freq,
                                                         check=False)
            for x in self.controls
        }
        #FMB回归
        matchDict = {'return': ReturnMat}
        matchDict.update(FactorMatDict)
        matchDict.update(ControlMatDict)
        matchDs = xr.Dataset(matchDict)

        def ProdTrue(*args):
            for obj in args:
                if (args is True):
                    continue
                else:
                    return False
            return True

        CalibratedCtrls = [
            matchDs[fe_name].values for fe_name in matchDs
            if fe_name[0:4] == 'ctrl'
        ]
        CalibratedFeats = [
            matchDs[fe_name].values for fe_name in matchDs
            if fe_name[0:4] == 'feat'
        ]
        if (CalibratedCtrls.__len__() > 0):
            ArrayProdTrue = np.frompyfunc(ProdTrue, CalibratedCtrls.__len__(),
                                          1)
            AssembledControlMat = ArrayProdTrue(
                *CalibratedCtrls).astype('bool')
            MaskedReturn = np.ma.MaskedArray(matchDs['return'].values,
                                             mask=~AssembledControlMat,
                                             fill_value=np.nan)
        else:
            MaskedReturn = matchDs['return'].values
        l = MaskedReturn.shape[0]
        out_rst = []
        exogs = np.stack(CalibratedFeats)
        noneCount = 0
        for i in tqdm(range(l), desc='正在截面回归...'):
            try:
                out_rst.append(
                    sm.OLS(endog=MaskedReturn[i],
                           exog=exogs[:, i, :].T,
                           missing='drop').fit())
            except:
                out_rst.append(None)
                noneCount += 1
        if (noneCount == l):
            raise Exception("所选时间区间内无有效回归样本,请检查基础数据!")
        out_dateIndex = matchDs['return'].indexes['Time']
        return (out_dateIndex, out_rst)
示例#5
0
'''
择时模型:
根据选择的资产、特征,在样本时间区间内训练择时模型,并进行样本外回测.
输入:资产代码、特征对象列表、样本时间区间;
输出:一个可给出回测报告(输入时间区间即可)的对象。

对其它api的假定:
get_feature(descriptor:Descriptor,starttime:datetime, endtime:datetime,stock_name:list=None,check:bool=True)
descriptor的频率交由get_feature来指定,并在对象初始化中被剔除。

todo:现在回头补写一些基础数据和因子特征算法,用multifactor模型研究一下因子收益的持续性;
     加入残差动量因子:将因子横街面回归残差
'''
from typing import List, Union
from datetime import datetime
from core.features.Descriptor import Descriptor
from core.fundamentals.getfundamentals import fundamentalApi as fapi
from core.features.getfeature import get_feature


class TSmodel:
    def __init__(self,
                 asset_code: str,
                 factors: List[Union[Descriptor]],
                 starttime: datetime,
                 endtime: datetime,
                 freq: str = 'd',
                 forcast_period: int = 1):
        '''
        :param stockcode: 待预测标的