Esempio n. 1
0
 def __QS_move__(self, idt, **kwargs):
     IDs = self.DSs[args["数据源"]].getID(idt=self.CurDate, is_filtered=True)
     self._Output["优化器"].FactorData = self.DSs[args["数据源"]].getDateTimeData(
         idt=self.CurDate,
         ids=IDs,
         factor_names=[args["测试因子"]] + args["中性因子"])
     self._Output["优化器"].CovMatrix = args["风险数据源"].getDateCov(self.CurDate,
                                                              drop_na=True)
     self._Output["优化器"].TargetIDs = IDs
     self._Output["优化器"].preprocessData()
     Error, Portfolio = self._Output["优化器"].solve()
     Signal = Signal[Signal > 0]
     Signal = Signal / Signal.sum()
     Signal.sort(ascending=False)
     Signal = Signal[Signal.cumsum() > 0.9999]
     Signal = Signal / Signal.sum()
     Signal = dict(Signal)
     RetRate = self.DSs[args["数据源"]].readData(dts=[idt],
                                              ids=None,
                                              factor_names=[args["收益率因子"]])
     RetRate = RetRate.loc[self.CurDate]
     self._Output["投资组合"].append(dict(Portfolio))
     if self.CurInd >= 1:
         self._Output["换手率"].append(
             calcTurnover(self._Output["投资组合"][-2],
                          self._Output["投资组合"][-1]))
         self._Output["收益率"].append(
             calcPortfolioReturn(self._Output["投资组合"][-2], RetRate))
     else:
         self._Output["换手率"].append(1)
         self._Output["收益率"].append(0)
     return self._Output
Esempio n. 2
0
 def __QS_move__(self, idt, **kwargs):
     if self._iDT == idt: return 0
     self._iDT = idt
     Price = self._FactorTable.readData(
         dts=[idt],
         ids=self._FactorTable.getID(ifactor_name=self.PriceFactor),
         factor_names=[self.PriceFactor]).iloc[0, 0, :]
     for i in range(self.GroupNum):
         if len(self._Output["QP_P_CurPos"][i]) == 0:
             self._Output["净值"][i].append(self._Output["净值"][i][-1])
         else:
             iWealth = (self._Output["QP_P_CurPos"][i] * Price).sum()
             if pd.notnull(iWealth):
                 self._Output["净值"][i].append(iWealth)
             else:
                 self._Output["净值"][i].append(0)
         self._Output["换手率"][i].append(0)
     if len(self._Output["QP_P_MarketPos"]) == 0:
         self._Output["市场净值"].append(self._Output["市场净值"][-1])
     else:
         self._Output["市场净值"].append(
             (self._Output["QP_P_MarketPos"] * Price).sum())
     if self.CalcDTs:
         if idt not in self.CalcDTs[self._CurCalcInd:]: return 0
         self._CurCalcInd = self.CalcDTs[self._CurCalcInd:].index(
             idt) + self._CurCalcInd
     IDs = self._FactorTable.getFilteredID(idt=idt,
                                           id_filter_str=self.IDFilter)
     FactorData = self._FactorTable.readData(dts=[idt],
                                             ids=IDs,
                                             factor_names=[self.TestFactor
                                                           ]).iloc[0, 0, :]
     FactorData = FactorData[pd.notnull(FactorData)
                             & pd.notnull(Price[IDs])].copy()
     nID = FactorData.shape[0]
     if self.Perturbation and (nID > 0):
         FactorData = FactorData.astype("float")
         MinDiff = np.min(np.abs(np.diff(FactorData.unique())))
         FactorData += np.random.rand(nID) * MinDiff * 0.01
     FactorData = FactorData.sort_values(
         ascending=(self.FactorOrder == "升序"), inplace=False)
     IDs = list(FactorData.index)
     if self.WeightFactor != "等权":
         WeightData = self._FactorTable.readData(
             dts=[idt],
             ids=self._FactorTable.getID(ifactor_name=self.WeightFactor),
             factor_names=[self.WeightFactor]).iloc[0, 0, :]
     else:
         WeightData = pd.Series(1.0, index=self._FactorTable.getID())
     if self.IndustryFactor == "无":
         nSubID = distributeEqual(nID,
                                  self.GroupNum,
                                  remainder_pos="middle")
         for i in range(self.GroupNum):
             iWealth = self._Output["净值"][i][-1]
             iSubIDs = IDs[sum(nSubID[:i]):sum(nSubID[:i + 1])]
             iPortfolio = WeightData[iSubIDs]
             iPortfolio = iPortfolio / iPortfolio.sum()
             iPortfolio = iPortfolio[pd.notnull(iPortfolio)]
             self._Output["投资组合"][i].append(iPortfolio)
             self._Output["QP_P_CurPos"][i] = iPortfolio * iWealth / Price
             self._Output["QP_P_CurPos"][i] = self._Output["QP_P_CurPos"][
                 i][pd.notnull(self._Output["QP_P_CurPos"][i])]
             nPortfolio = len(self._Output["投资组合"][i])
             if nPortfolio > 1:
                 self._Output["换手率"][i][-1] = calcTurnover(
                     self._Output["投资组合"][i][-2],
                     self._Output["投资组合"][i][-1])
             elif nPortfolio == 1:
                 self._Output["换手率"][i][-1] = 1
     else:
         Portfolio = [{} for i in range(self.GroupNum)]
         IndustryData = self._FactorTable.readData(dts=[idt],
                                                   ids=IDs,
                                                   factor_names=[
                                                       self.IndustryFactor
                                                   ]).iloc[0, 0, :]
         AllIndustry = IndustryData.unique()
         for iIndustry in AllIndustry:
             iMask = (IndustryData == iIndustry)
             iIDIndex = IndustryData[iMask].index
             iIDDistribution = distributeEqual(iIDIndex.shape[0],
                                               self.GroupNum,
                                               remainder_pos="middle")
             for j in range(self.GroupNum):
                 jSubID = iIDIndex[sum(iIDDistribution[:j]
                                       ):sum(iIDDistribution[:j + 1])]
                 Portfolio[j].update(
                     {kID: WeightData[kID]
                      for kID in jSubID})
         for i in range(self.GroupNum):
             iWealth = self._Output["净值"][i][-1]
             iPortfolio = pd.Series(Portfolio[i])
             iPortfolio = iPortfolio / iPortfolio.sum()
             iPortfolio = iPortfolio[pd.notnull(iPortfolio)]
             self._Output["投资组合"][i].append(iPortfolio)
             self._Output["QP_P_CurPos"][i] = iPortfolio * iWealth / Price
             self._Output["QP_P_CurPos"][i] = self._Output["QP_P_CurPos"][
                 i][pd.notnull(self._Output["QP_P_CurPos"][i])]
             nPortfolio = len(self._Output["投资组合"][i])
             if nPortfolio > 1:
                 self._Output["换手率"][i][-1] = calcTurnover(
                     self._Output["投资组合"][i][-2],
                     self._Output["投资组合"][i][-1])
             elif nPortfolio == 1:
                 self._Output["换手率"][i][-1] = 1
     if self.MarketIDFilter:
         IDs = self._FactorTable.getFilteredID(
             idt=idt, id_filter_str=self.MarketIDFilter)
     WeightData = WeightData[IDs]
     Price = Price[IDs]
     WeightData = WeightData[pd.notnull(WeightData) & pd.notnull(Price)]
     WeightData = WeightData / WeightData.sum()
     self._Output[
         "QP_P_MarketPos"] = WeightData * self._Output["市场净值"][-1] / Price
     self._Output["QP_P_MarketPos"] = self._Output["QP_P_MarketPos"][
         pd.notnull(self._Output["QP_P_MarketPos"])]
     self._Output["调仓日"].append(idt)
     return 0
Esempio n. 3
0
 def __QS_move__(self, idt, **kwargs):
     Price = self._FactorTable.readData(
         dates=[idt], ids=None, ifactor_name=self._SysArgs["价格因子"]).iloc[0]
     for i in range(self._SysArgs["分组数"]):
         if len(self._Output["QP_P_CurPos"][i]) == 0:
             self._Output["净值"][i].append(self._Output["净值"][i][-1])
         else:
             iWealth = (self._Output["QP_P_CurPos"][i] * Price).sum()
             if pd.notnull(iWealth):
                 self._Output["净值"][i].append(iWealth)
             else:
                 self._Output["净值"][i].append(0)
         self._Output["换手率"][i].append(0)
     if len(self._Output["QP_P_MarketPos"]) == 0:
         self._Output["市场净值"].append(self._Output["市场净值"][-1])
     else:
         self._Output["市场净值"].append(
             (self._Output["QP_P_MarketPos"] * Price).sum())
     if (self._CalcDateTimes is not None) and (idt
                                               not in self._CalcDateTimes):
         return 0
     IDs = self._FactorTable.getID(idt=idt,
                                   is_filtered=True,
                                   id_filter_str=self._SysArgs["筛选条件"])
     FactorData = self._FactorTable.readData(
         dts=[idt], ids=IDs,
         ifactor_name=self._SysArgs["测试因子"]).iloc[0].copy()
     FactorData = FactorData[pd.notnull(Price[IDs])]
     nID = FactorData.shape[0]
     if (self._SysArgs["随机微扰"]) and (nID > 0):
         FactorData = FactorData.astype("float")
         MinDiff = np.min(np.abs(np.diff(FactorData.unique())))
         FactorData = FactorData + np.random.rand(nID) * MinDiff * 0.01
     if self._SysArgs["划分方式"] == "定量":
         if (self._SysArgs["排序方向"] == "升序"):
             FactorData.sort(ascending=True)
         else:
             FactorData.sort(ascending=False)
         if self._SysArgs["缺失处理"] == "排在最前":
             FactorData = FactorData[pd.isnull(FactorData)].append(
                 FactorData[pd.notnull(FactorData)])
         elif self._SysArgs["缺失处理"] == "丢弃":
             FactorData = FactorData[pd.notnull(FactorData)]
     elif self._SysArgs["划分方式"] == "定比":
         if (self._SysArgs["排序方向"] == "降序"):
             FactorData = -FactorData
     # 构建投资组合
     if self._SysArgs["权重因子"] != "等权":
         WeightData = self._FactorTable.readData(
             dts=[idt], ids=IDs, ifactor_name=self._SysArgs["权重因子"]).iloc[0]
     else:
         WeightData = pd.Series(1.0, index=IDs)
     IDs = []
     for j in range(self._SysArgs["分组数"]):
         if self._SysArgs["划分方式"] == "定比":
             if (j > 0) and (j < self._SysArgs["分组数"] - 1):
                 jIDs = list(
                     FactorData[(FactorData >= FactorData.quantile(
                         self._SysArgs["分类节点"][j - 1]))
                                & (FactorData < FactorData.quantile(
                                    self._SysArgs["分类节点"][j]))].index)
             elif j == 0:
                 jIDs = list(FactorData[FactorData < FactorData.quantile(
                     self._SysArgs["分类节点"][j])].index)
                 if self._SysArgs["缺失处理"] == "排在最前":
                     jIDs += list(FactorData[pd.isnull(FactorData)].index)
             else:
                 jIDs = list(FactorData[FactorData >= FactorData.quantile(
                     self._SysArgs["分类节点"][-1])].index)
                 if self._SysArgs["缺失处理"] == "排在最后":
                     jIDs += list(FactorData[pd.isnull(FactorData)].index)
         elif self._SysArgs["划分方式"] == "定界":
             if (j > 0) and (j < self._SysArgs["分组数"] - 1):
                 jIDs = list(FactorData[
                     (FactorData >= self._SysArgs["分类节点"][j - 1])
                     & (FactorData < self._SysArgs["分类节点"][j])].index)
             elif j == 0:
                 jIDs = list(FactorData[
                     FactorData < self._SysArgs["分类节点"][j]].index)
                 if self._SysArgs["缺失处理"] == "排在最前":
                     jIDs += list(FactorData[pd.isnull(FactorData)].index)
             else:
                 jIDs = list(FactorData[
                     FactorData >= self._SysArgs["分类节点"][-1]].index)
                 if self._SysArgs["缺失处理"] == "排在最后":
                     jIDs += list(FactorData[pd.isnull(FactorData)].index)
         else:
             if (j > 0) and (j < self._SysArgs["分组数"] - 1):
                 jIDs = list(FactorData.iloc[self._SysArgs["分类节点"][j -
                                                                   1]:self.
                                             _SysArgs["分类节点"][j]].index)
             elif j == 0:
                 jIDs = list(
                     FactorData.iloc[:self._SysArgs["分类节点"][j]].index)
             else:
                 jIDs = list(
                     FactorData.iloc[self._SysArgs["分类节点"][-1]:].index)
         jWealth = self._Output["净值"][j][-1]
         jPortfolio = WeightData[jIDs]
         jPortfolio = jPortfolio[pd.notnull(jPortfolio)]
         jPortfolio = jPortfolio / jPortfolio.sum()
         self._Output["投资组合"][j].append(dict(jPortfolio))
         self._Output["QP_P_CurPos"][j] = jPortfolio * jWealth / Price
         self._Output["QP_P_CurPos"][j] = self._Output["QP_P_CurPos"][j][
             pd.notnull(self._Output["QP_P_CurPos"][j])]
         nPortfolio = len(self._Output["投资组合"][j])
         if nPortfolio > 1:
             self._Output["换手率"][j][-1] = calcTurnover(
                 self._Output["投资组合"][j][-2], self._Output["投资组合"][j][-1])
         elif nPortfolio == 1:
             self._Output["换手率"][j][-1] = 1
         IDs += jIDs
     if self._SysArgs["市场组合"] is not None:
         IDs = self._FactorTable.getID(idt=idt,
                                       is_filtered=True,
                                       id_filter_str=self._SysArgs["市场组合"])
     WeightData = WeightData[IDs]
     Price = Price[IDs]
     WeightData = WeightData[pd.notnull(WeightData) & pd.notnull(Price)]
     WeightData = WeightData / WeightData.sum()
     #self._Output["市场组合"].append(dict(WeightData))
     self._Output["调仓日"].append(idt)
     self._Output[
         "QP_P_MarketPos"] = WeightData * self._Output["市场净值"][-1] / Price
     self._Output["QP_P_MarketPos"] = self._Output["QP_P_MarketPos"][
         pd.notnull(self._Output["QP_P_MarketPos"])]
     return 0