def genContinuousContractPrice(id_map,
                               price,
                               adj_direction="前复权",
                               adj_type="收益率不变",
                               rollover_ahead=False):
    IDIndex = dict(zip(price.columns.tolist(), np.arange(price.shape[1])))
    AdjPrice = price.values[
        np.arange(id_map.shape[0]),
        list(map(lambda x: IDIndex.get(x, 0), id_map.tolist()))]
    AdjPrice[pd.isnull(id_map)] = np.nan
    if adj_type == "收益率不变":
        if adj_direction == "前复权":
            for i in range(id_map.shape[0] - 1, 0, -1):
                iID, iPreID = id_map.iloc[i], id_map.iloc[i - 1]
                if pd.isnull(iID) or pd.isnull(iPreID) or (iID == iPreID):
                    continue
                iAdj = price[iID].iloc[
                    i - rollover_ahead] / price[iPreID].iloc[i -
                                                             rollover_ahead]
                if pd.isnull(iAdj):
                    iAdj = price[iID].iloc[i] / price[iPreID].iloc[i - 1]
                AdjPrice[:i] = AdjPrice[:i] * iAdj
        elif adj_direction == "后复权":
            for i in range(1, id_map.shape[0]):
                iID, iPreID = id_map.iloc[i], id_map.iloc[i - 1]
                if pd.isnull(iID) or pd.isnull(iPreID) or (iID == iPreID):
                    continue
                iAdj = price[iPreID].iloc[
                    i - rollover_ahead] / price[iID].iloc[i - rollover_ahead]
                if pd.isnull(iAdj):
                    iAdj = price[iPreID].iloc[i - 1] / price[iID].iloc[i]
                AdjPrice[i:] = AdjPrice[i:] * iAdj
        else:
            raise __QS_Error__("不支持的调整方向: '%s'" % adj_direction)
    elif adj_type == "价差不变":
        if adj_direction == "前复权":
            for i in range(id_map.shape[0] - 1, 0, -1):
                iID, iPreID = id_map.iloc[i], id_map.iloc[i - 1]
                if pd.isnull(iID) or pd.isnull(iPreID) or (iID == iPreID):
                    continue
                iAdj = price[iPreID].iloc[
                    i - rollover_ahead] - price[iID].iloc[i - rollover_ahead]
                if pd.isnull(iAdj):
                    iAdj = price[iPreID].iloc[i - 1] - price[iID].iloc[i]
                AdjPrice[:i] = AdjPrice[:i] - iAdj
        elif adj_direction == "后复权":
            for i in range(1, id_map.shape[0]):
                iID, iPreID = id_map.iloc[i], id_map.iloc[i - 1]
                if pd.isnull(iID) or pd.isnull(iPreID) or (iID == iPreID):
                    continue
                iAdj = price[iPreID].iloc[
                    i - rollover_ahead] - price[iID].iloc[i - rollover_ahead]
                if pd.isnull(iAdj):
                    iAdj = price[iPreID].iloc[i - 1] - price[iID].iloc[i]
                AdjPrice[i:] = AdjPrice[i:] + iAdj
        else:
            raise __QS_Error__("不支持的调整方向: '%s'" % adj_direction)
    elif adj_type != "价格不变":
        raise __QS_Error__("不支持的调整方式: '%s'" % adj_type)
    return pd.Series(AdjPrice, index=id_map.index)
Exemple #2
0
 def getDBTable(self, table_format=None):
     try:
         if self.DBType == "SQL Server":
             SQLStr = "SELECT Name FROM SysObjects Where XType='U'"
             TableField = "Name"
         elif self.DBType == "MySQL":
             SQLStr = "SELECT table_name FROM information_schema.tables WHERE table_schema='" + self.DBName + "' AND table_type='base table'"
             TableField = "table_name"
         elif self.DBType == "Oracle":
             SQLStr = "SELECT table_name FROM user_tables WHERE TABLESPACE_NAME IS NOT NULL AND user='******'"
             TableField = "table_name"
         elif self.DBType == "sqlite3":
             SQLStr = "SELECT name FROM sqlite_master WHERE type='table'"
             TableField = "name"
         else:
             raise __QS_Error__("不支持的数据库类型 '%s'" % self.DBType)
         if isinstance(table_format, str) and table_format:
             SQLStr += (" WHERE %s LIKE '%s' " % (TableField, table_format))
         AllTables = self.fetchall(SQLStr)
     except Exception as e:
         Msg = ("'%s' 调用方法 getAllDBTable 时错误: %s" % (self.Name, str(e)))
         self._QS_Logger.error(Msg)
         raise __QS_Error__(Msg)
     else:
         return [rslt[0] for rslt in AllTables]
Exemple #3
0
 def renameFactor(self, table_name, old_factor_name, new_factor_name):
     if table_name not in self._Arctic.list_libraries():
         raise __QS_Error__("表: '%s' 不存在!" % table_name)
     Lib = self._Arctic[table_name]
     FactorInfo = Lib.read(symbol="_FactorInfo").set_index(["FactorName"])
     if old_factor_name not in FactorInfo.index:
         raise __QS_Error__("因子: '%s' 不存在!" % old_factor_name)
     if new_factor_name in FactorInfo.index:
         raise __QS_Error__("因子: '%s' 已经存在!" % new_factor_name)
     FactorNames = FactorInfo.index.tolist()
     FactorNames[FactorNames.index(old_factor_name)] = new_factor_name
     FactorInfo.index = FactorNames
     FactorInfo.index.name = "FactorName"
     Lib.write(
         "_FactorInfo",
         FactorInfo.reset_index(),
         chunker=arctic.chunkstore.passthrough_chunker.PassthroughChunker())
     IDs = Lib.list_symbols()
     IDs.remove("_FactorInfo")
     for iID in IDs:
         iMetaData = Lib.read_metadata(iID)
         if old_factor_name in iMetaData["FactorNames"]:
             iMetaData["FactorNames"][iMetaData["FactorNames"].index(
                 old_factor_name)] = new_factor_name
             Lib.write_metadata(iID, iMetaData)
     return 0
Exemple #4
0
def loadCSVFactorData(csv_path):
    with open(csv_path,mode='rb') as File:
        if File.readline().split(b',')[0]==b'':
            Horizon = True
        else:
            Horizon = False
    if Horizon:
        try:
            CSVFactor = readCSV2Pandas(csv_path, index_col=0, header=0, encoding="utf-8", parse_dates=True, infer_datetime_format=True)
        except:
            CSVFactor = readCSV2Pandas(csv_path, detect_file_encoding=True, index_col=0, header=0, parse_dates=True, infer_datetime_format=True)
    else:
        try:
            CSVFactor = readCSV2Pandas(csv_path, header=0, index_col=[0,1], encoding="utf-8", parse_dates=True, infer_datetime_format=True)
        except:
            CSVFactor = readCSV2Pandas(csv_path, detect_file_encoding=True, header=0, index_col=[0,1], parse_dates=True, infer_datetime_format=True)
        #Columns = list(CSVFactor.columns)
        #CSVFactor = CSVFactor.set_index(Columns[:2])[Columns[2]]
        CSVFactor = Series2DataFrame(CSVFactor.iloc[:, 0])
    try:
        if CSVFactor.index.dtype==np.dtype("O"):
            CSVDT = [dt.datetime.strptime(iDT, "%Y-%m-%D") for iDT in CSVFactor.index]
        elif CSVFactor.index.is_all_dates:
            CSVDT = [iDT.to_pydatetime() for iDT in CSVFactor.index]
        else:
            raise __QS_Error__("时间序列解析失败!")
    except:
        raise __QS_Error__("时间序列解析失败!")
    CSVID = [str(iID) for iID in CSVFactor.columns]
    CSVFactor = pd.DataFrame(CSVFactor.values, index=CSVDT, columns=CSVID)
    return CSVFactor
Exemple #5
0
 def getFutureID(self, future_code="IF", date=None, is_current=True):
     if date is None: date = dt.date.today()
     if is_current: CodeStr = "EndT:= {Date}T;return GetFuturesID('{FutureID}', EndT);"
     else: raise __QS_Error__("目前不支持提取历史 ID")
     CodeStr = CodeStr.format(FutureID="".join(future_code.split(".")), Date=date.strftime("%Y%m%d"))
     ErrorCode, Data, Msg = self._TSLPy.RemoteExecute(CodeStr, {})
     if ErrorCode!=0: raise __QS_Error__("TinySoft 执行错误: "+Msg.decode("gbk"))
     return [iID.decode("gbk") for iID in Data]
 def _initInfo(self):
     if self.RiskESTDTs==[]: raise __QS_Error__("没有设置计算风险数据的时点序列!")
     FactorNames = set(self.Config.ModelArgs["所有因子"])
     if not set(self.FT.FactorNames).issuperset(FactorNames): raise __QS_Error__("因子表必须包含如下因子: %s" % FactorNames)
     self._genRegressDateTime()
     self._adjustRiskESTDateTime()
     if self.RiskESTDTs==[]: raise __QS_Error__("可以计算风险数据的时点序列为空!")
     return 0
 def renameFactor(self, table_name, old_factor_name, new_factor_name):
     if old_factor_name==new_factor_name: return 0
     OldPath = self.MainDir+os.sep+table_name+os.sep+old_factor_name+"."+self._Suffix
     NewPath = self.MainDir+os.sep+table_name+os.sep+new_factor_name+"."+self._Suffix
     with self._DataLock:
         if not os.path.isfile(OldPath): raise __QS_Error__("HDF5DB.renameFactor: 表 ’%s' 中不存在因子 '%s'!" % (table_name, old_factor_name))
         if os.path.isfile(NewPath): raise __QS_Error__("HDF5DB.renameFactor: 表 ’%s' 中的因子 '%s' 已存在!" % (table_name, new_factor_name))
         os.rename(OldPath, NewPath)
     return 0
 def renameTable(self, old_table_name, new_table_name):
     if old_table_name==new_table_name: return 0
     OldPath = self.MainDir+os.sep+old_table_name
     NewPath = self.MainDir+os.sep+new_table_name
     with self._DataLock:
         if not os.path.isdir(OldPath): raise __QS_Error__("HDF5DB.renameTable: 表: '%s' 不存在!" % old_table_name)
         if os.path.isdir(NewPath): raise __QS_Error__("HDF5DB.renameTable: 表 '"+new_table_name+"' 已存在!")
         os.rename(OldPath, NewPath)
     return 0
Exemple #9
0
 def getTradeDay(self, start_date=None, end_date=None, exchange="SSE", **kwargs):
     if exchange not in ("SSE", "SZSE"): raise __QS_Error__("不支持交易所: '%s' 的交易日序列!" % exchange)
     if start_date is None: start_date = dt.date(1900, 1, 1)
     if end_date is None: end_date = dt.date.today()
     CodeStr = "SetSysParam(pn_cycle(), cy_day());return MarketTradeDayQk(inttodate({StartDate}), inttodate({EndDate}));"
     CodeStr = CodeStr.format(StartDate=start_date.strftime("%Y%m%d"), EndDate=end_date.strftime("%Y%m%d"))
     ErrorCode, Data, Msg = self._TSLPy.RemoteExecute(CodeStr,{})
     if ErrorCode!=0: raise __QS_Error__("TinySoft 执行错误: "+Msg.decode("gbk"))
     return list(map(lambda x: dt.date(*self._TSLPy.DecodeDate(x)), Data))
Exemple #10
0
 def renameTable(self, old_table_name, new_table_name):
     if old_table_name not in self._TableFactorDict: raise __QS_Error__("表: '%s' 不存在!" % old_table_name)
     if (new_table_name!=old_table_name) and (new_table_name in self._TableFactorDict): raise __QS_Error__("表: '"+new_table_name+"' 已存在!")
     OldPath = self.MainDir+os.sep+old_table_name
     NewPath = self.MainDir+os.sep+new_table_name
     if OldPath==NewPath: pass
     elif os.path.isdir(NewPath): raise __QS_Error__("目录: '%s' 被占用!" % NewPath)
     with self._DataLock:
         os.rename(OldPath, NewPath)
     self._TableFactorDict[new_table_name] = self._TableFactorDict.pop(old_table_name)
     return 0
 def _QS_initOperation(self, start_dt, dt_dict, prepare_ids, id_dict):
     if len(self._Descriptors) > len(self.LookBack):
         raise __QS_Error__("面板运算因子 : '%s' 的参数'回溯期数'序列长度小于描述子个数!" %
                            self.Name)
     OldStartDT = dt_dict.get(self.Name, None)
     DTRuler = self._OperationMode.DTRuler
     if (OldStartDT is None) or (start_dt < OldStartDT):
         StartDT = dt_dict[self.Name] = start_dt
         StartInd, EndInd = DTRuler.index(StartDT), DTRuler.index(
             self._OperationMode.DateTimes[-1])
         if (self.iLookBackMode
                 == "扩张窗口") and (self.iInitData is not None) and (
                     self.iInitData.shape[0] > 0):
             if self.iInitData.index[-1] not in self._OperationMode.DTRuler:
                 self._QS_Logger.warning(
                     "注意: 因子 '%s' 的初始值不在时点标尺的范围内, 初始值和时点标尺之间的时间间隔将被忽略!" %
                     (self.Name, ))
             else:
                 StartInd = min(
                     StartInd,
                     self._OperationMode.DTRuler.index(
                         self.iInitData.index[-1]) + 1)
         DTs = DTRuler[StartInd:EndInd + 1]
         if self.iLookBackMode == "扩张窗口":
             DTPartition = [DTs
                            ] + [[]] * (len(self._OperationMode._PIDs) - 1)
         else:
             DTPartition = partitionList(DTs,
                                         len(self._OperationMode._PIDs))
         self._PID_DTs = {
             iPID: DTPartition[i]
             for i, iPID in enumerate(self._OperationMode._PIDs)
         }
     else:
         StartInd = DTRuler.index(OldStartDT)
     PrepareIDs = id_dict.setdefault(self.Name, prepare_ids)
     if prepare_ids != PrepareIDs:
         raise __QS_Error__("因子 %s 指定了不同的截面!" % self.Name)
     for i, iDescriptor in enumerate(self._Descriptors):
         iStartInd = StartInd - self.LookBack[i]
         if iStartInd < 0:
             self._QS_Logger.warning("注意: 对于因子 '%s' 的描述子 '%s', 时点标尺长度不足!" %
                                     (self.Name, iDescriptor.Name))
         iStartDT = DTRuler[max(0, iStartInd)]
         if self.DescriptorSection[i] is None:
             iDescriptor._QS_initOperation(iStartDT, dt_dict, prepare_ids,
                                           id_dict)
         else:
             iDescriptor._QS_initOperation(iStartDT, dt_dict,
                                           self.DescriptorSection[i],
                                           id_dict)
     if (self._OperationMode.SubProcessNum >
             0) and (self.Name not in self._OperationMode._Event):
         self._OperationMode._Event[self.Name] = (Queue(), Event())
Exemple #12
0
 def renameTable(self, old_table_name, new_table_name):
     if old_table_name not in self._TableFactorDict:
         raise __QS_Error__("表: '%s' 不存在!" % old_table_name)
     if (new_table_name != old_table_name) and (new_table_name
                                                in self._TableFactorDict):
         raise __QS_Error__("表: '" + new_table_name + "' 已存在!")
     SQLStr = "ALTER TABLE " + self.TablePrefix + self._Prefix + old_table_name + " RENAME TO " + self.TablePrefix + self._Prefix + new_table_name
     self.execute(SQLStr)
     self._TableFactorDict[new_table_name] = self._TableFactorDict.pop(
         old_table_name)
     return 0
Exemple #13
0
def _adjustData(data, data_type, order="C"):
    if data_type=="string": return data.where(pd.notnull(data), None).values
    elif data_type=="double": return data.astype("float").values
    elif data_type=="object":
        if order=="C":
            return np.ascontiguousarray(data.applymap(lambda x: np.frombuffer(pickle.dumps(x), dtype=np.uint8)).values)
        elif order=="F":
            return np.asfortranarray(data.applymap(lambda x: np.frombuffer(pickle.dumps(x), dtype=np.uint8)).values)
        else:
            raise __QS_Error__("不支持的参数 order 值: %s" % order)
    else: raise __QS_Error__("不支持的数据类型: %s" % data_type)
Exemple #14
0
 def renameTable(self, old_table_name, new_table_name):
     if old_table_name not in self._TableDT:
         raise __QS_Error__("表: '%s' 不存在!" % old_table_name)
     if (new_table_name != old_table_name) and (new_table_name
                                                in self._TableDT):
         raise __QS_Error__("表: '%s' 已存在!" % new_table_name)
     with self._DataLock:
         os.rename(
             self.MainDir + os.sep + old_table_name + "." + self._Suffix,
             self.MainDir + os.sep + new_table_name + "." + self._Suffix)
     self._TableDT[new_table_name] = self._TableDT.pop(old_table_name)
     return 0
Exemple #15
0
 def renameFactor(self, table_name, old_factor_name, new_factor_name):
     if old_factor_name not in self._TableFactorDict[table_name]:
         raise __QS_Error__("因子: '%s' 不存在!" % old_factor_name)
     if (new_factor_name != old_factor_name) and (
             new_factor_name in self._TableFactorDict[table_name]):
         raise __QS_Error__("表中的因子: '%s' 已存在!" % new_factor_name)
     SQLStr = "ALTER TABLE " + self.TablePrefix + self._Prefix + table_name
     SQLStr += " CHANGE COLUMN `" + old_factor_name + "` `" + new_factor_name + "`"
     self.execute(SQLStr)
     self._TableFactorDict[table_name][
         new_factor_name] = self._TableFactorDict[table_name].pop(
             old_factor_name)
     return 0
Exemple #16
0
 def renameFactor(self, table_name, old_factor_name, new_factor_name):
     if old_factor_name not in self._TableFactorDict[table_name]:
         raise __QS_Error__("因子: '%s' 不存在!" % old_factor_name)
     if (new_factor_name != old_factor_name) and (
             new_factor_name in self._TableFactorDict[table_name]):
         raise __QS_Error__("表中的因子: '%s' 已存在!" % new_factor_name)
     TablePath = self.MainDir + os.sep + table_name
     with self._DataLock:
         iZTable = zarr.open(self.MainDir + os.sep + table_name, mode="w")
         iZTable[new_factor_name] = iZTable.pop(old_factor_name)
     self._TableFactorDict[table_name][
         new_factor_name] = self._TableFactorDict[table_name].pop(
             old_factor_name)
     return 0
Exemple #17
0
 def renameFactor(self, table_name, old_factor_name, new_factor_name):
     if old_factor_name not in self._TableFactorDict[table_name]:
         raise __QS_Error__("因子: '%s' 不存在!" % old_factor_name)
     if (new_factor_name != old_factor_name) and (
             new_factor_name in self._TableFactorDict[table_name]):
         raise __QS_Error__("表中的因子: '%s' 已存在!" % new_factor_name)
     TablePath = self.MainDir + os.sep + table_name
     with self._DataLock:
         os.rename(
             TablePath + os.sep + old_factor_name + "." + self._Suffix,
             TablePath + os.sep + new_factor_name + "." + self._Suffix)
     self._TableFactorDict[table_name][
         new_factor_name] = self._TableFactorDict[table_name].pop(
             old_factor_name)
     return 0
 def _QS_initOperation(self, start_dt, dt_dict, prepare_ids, id_dict):
     super()._QS_initOperation(start_dt, dt_dict, prepare_ids, id_dict)
     if len(self._Descriptors) > len(self.LookBack):
         raise __QS_Error__("时间序列运算因子 : '%s' 的参数'回溯期数'序列长度小于描述子个数!" %
                            self.Name)
     StartDT = dt_dict[self.Name]
     StartInd = self._OperationMode.DTRuler.index(StartDT)
     if (self.iLookBackMode
             == "扩张窗口") and (self.iInitData
                             is not None) and (self.iInitData.shape[0] > 0):
         if self.iInitData.index[-1] not in self._OperationMode.DTRuler:
             self._QS_Logger.warning(
                 "注意: 因子 '%s' 的初始值不在时点标尺的范围内, 初始值和时点标尺之间的时间间隔将被忽略!" %
                 (self.Name, ))
         else:
             StartInd = min(
                 StartInd,
                 self._OperationMode.DTRuler.index(self.iInitData.index[-1])
                 + 1)
     for i, iDescriptor in enumerate(self._Descriptors):
         iStartInd = StartInd - self.LookBack[i]
         if iStartInd < 0:
             self._QS_Logger.warning(
                 "注意: 对于因子 '%s' 的描述子 '%s', 时点标尺长度不足, 不足的部分将填充 nan!" %
                 (self.Name, iDescriptor.Name))
         iStartDT = self._OperationMode.DTRuler[max(0, iStartInd)]
         iDescriptor._QS_initOperation(iStartDT, dt_dict, prepare_ids,
                                       id_dict)
Exemple #19
0
 def renameFactor(self, table_name, old_factor_name, new_factor_name):
     if old_factor_name == new_factor_name: return 0
     with self._DataLock:
         iZTable = zarr.open(self.MainDir + os.sep + table_name, mode="a")
         if old_factor_name not in iZTable:
             raise __QS_Error__("ZarrDB.renameFactor: 表 ’%s' 中不存在因子 '%s'!" %
                                (table_name, old_factor_name))
         if new_factor_name in iZTable:
             raise __QS_Error__(
                 "ZarrDB.renameFactor: 表 ’%s' 中的因子 '%s' 已存在!" %
                 (table_name, new_factor_name))
         iZTable[new_factor_name] = iZTable.pop(old_factor_name)
         DataType = iZTable.attrs.get("DataType", {})
         DataType[new_factor_name] = DataType.pop(old_factor_name)
         iZTable.attrs["DataType"] = DataType
     return 0
Exemple #20
0
 def connect(self):
     if not os.path.isdir(self.MainDir):
         raise __QS_Error__("不存在主目录: %s!" % self.MainDir)
     AllTables = listDirDir(self.MainDir)
     _TableFactorDict = {}
     if not os.path.isfile(self.MainDir + os.sep + "LockFile"):
         open(self.MainDir + os.sep + "LockFile", mode="a").close()
     self._LockFile = self.MainDir + os.sep + "LockFile"
     self._DataLock = fasteners.InterProcessLock(self._LockFile)
     with self._DataLock:
         for iTable in AllTables:
             iTablePath = self.MainDir + os.sep + iTable
             iFactors = set(listDirFile(iTablePath, suffix=self._Suffix))
             if not iFactors: continue
             try:
                 iDataType = readNestedDictFromHDF5(
                     iTablePath + os.sep + "_TableInfo.h5", "/DataType")
             except:
                 iDataType = None
             if (iDataType is None) or (iFactors != set(iDataType.index)):
                 iDataType = {}
                 for ijFactor in iFactors:
                     with h5py.File(iTablePath + os.sep + ijFactor + "." +
                                    self._Suffix,
                                    mode="r") as ijDataFile:
                         iDataType[ijFactor] = ijDataFile.attrs["DataType"]
                 iDataType = pd.Series(iDataType)
                 writeNestedDict2HDF5(iDataType,
                                      iTablePath + os.sep + "_TableInfo.h5",
                                      "/DataType")
             _TableFactorDict[iTable] = iDataType
     self._TableFactorDict = _TableFactorDict
     self._isAvailable = True
     return 0
Exemple #21
0
def filterID(factor_data, id_filter_str):
    if not id_filter_str: return factor_data.index.tolist()
    CompiledIDFilterStr, IDFilterFactors = testIDFilterStr(
        id_filter_str, factor_names=factor_data.columns.tolist())
    if CompiledIDFilterStr is None: raise __QS_Error__("ID 过滤字符串有误!")
    temp = factor_data.loc[:, IDFilterFactors]
    return eval("temp[" + CompiledIDFilterStr + "].index.tolist()")
Exemple #22
0
 def renameFactor(self, table_name, old_factor_name, new_factor_name):
     if old_factor_name not in self._TableFactorDict[table_name]: raise __QS_Error__("因子: '%s' 不存在!" % old_factor_name)
     if (new_factor_name!=old_factor_name) and (new_factor_name in self._TableFactorDict[table_name]): raise __QS_Error__("表中的因子: '%s' 已存在!" % new_factor_name)
     if self.DBType!="sqlite3":
         SQLStr = "ALTER TABLE "+self.TablePrefix+self.InnerPrefix+table_name
         SQLStr += " CHANGE COLUMN `"+old_factor_name+"` `"+new_factor_name+"`"
         self.execute(SQLStr)
     else:
         # 将表名改为临时表
         SQLStr = "ALTER TABLE %s RENAME TO %s"
         TempTableName = genAvailableName("TempTable", self.TableNames)
         self.execute(SQLStr % (self.TablePrefix+self.InnerPrefix+table_name, self.TablePrefix+self.InnerPrefix+TempTableName))
         # 创建新表
         FieldTypes = OrderedDict()
         for iFactorName, iDataType in self._TableFactorDict[table_name].items():
             iDataType = ("text" if iDataType=="string" else "real")
             if iFactorName==old_factor_name: FieldTypes[new_factor_name] = iDataType
             else: FieldTypes[iFactorName] = iDataType
         self.createTable(table_name, field_types=FieldTypes)
         # 导入数据
         OldFactorNames = ", ".join(self._TableFactorDict[table_name].index)
         NewFactorNames = ", ".join(FieldTypes)
         SQLStr = "INSERT INTO %s (datetime, code, %s) SELECT datetime, code, %s FROM %s"
         Cursor = self.cursor(SQLStr % (self.TablePrefix+self.InnerPrefix+table_name, NewFactorNames, OldFactorNames, self.TablePrefix+self.InnerPrefix+TempTableName))
         self._Connection.commit()
         # 删除临时表
         Cursor.execute("DROP TABLE %s" % (self.TablePrefix+self.InnerPrefix+TempTableName, ))
         self._Connection.commit()
         Cursor.close()
     self._TableFactorDict[table_name][new_factor_name] = self._TableFactorDict[table_name].pop(old_factor_name)
     self._TableFieldDataType[table_name][new_factor_name] = self._TableFieldDataType[table_name].pop(old_factor_name)
     return 0
Exemple #23
0
 def __QS_move__(self, idt, **kwargs):
     if self._iDT == idt: return 0
     iTradingRecord = {
         iAccount.Name: iAccount.__QS_move__(idt, **kwargs)
         for iAccount in self.Accounts
     }
     Signal = None
     if (not self.SignalDTs) or (idt in self.SignalDTs):
         Signal = self.genSignal(idt, iTradingRecord)
     if Signal is not None:
         if not isinstance(Signal, pd.Series):
             raise __QS_Error__("信号格式有误, 必须是 Series 类型!")
         if self.LongWeightAlloction.ReAllocWeight or self.ShortWeightAlloction.ReAllocWeight:
             LongSignal, ShortSignal = Signal[Signal > 0], Signal[
                 Signal < 0]
             if (LongSignal.shape[0] >
                     0) and self.LongWeightAlloction.ReAllocWeight:
                 LongSignal = self._allocateWeight(
                     idt, LongSignal.index.tolist(), self.TargetAccount.IDs,
                     self.LongWeightAlloction) * LongSignal.sum()
             if (ShortSignal.shape[0] >
                     0) and self.ShortWeightAlloction.ReAllocWeight:
                 ShortSignal = self._allocateWeight(
                     idt, ShortSignal.index.tolist(),
                     self.TargetAccount.IDs,
                     self.ShortWeightAlloction) * ShortSignal.sum()
             Signal = LongSignal.add(ShortSignal, fill_value=0.0)
         self._AllSignals[idt] = Signal
     Signal = self._bufferSignal(Signal)
     self.trade(idt, iTradingRecord, Signal)
     for iAccount in self.Accounts:
         iAccount.__QS_after_move__(idt, **kwargs)
     return 0
 def _QS_initOperation(self, start_dt, dt_dict, prepare_ids, id_dict):
     OldStartDT = dt_dict.get(self.Name, None)
     if (OldStartDT is None) or (start_dt < OldStartDT):
         dt_dict[self.Name] = start_dt
         StartInd, EndInd = self._OperationMode.DTRuler.index(
             dt_dict[self.Name]), self._OperationMode.DTRuler.index(
                 self._OperationMode.DateTimes[-1])
         DTs = self._OperationMode.DTRuler[StartInd:EndInd + 1]
         DTPartition = partitionList(DTs, len(self._OperationMode._PIDs))
         self._PID_DTs = {
             iPID: DTPartition[i]
             for i, iPID in enumerate(self._OperationMode._PIDs)
         }
     PrepareIDs = id_dict.setdefault(self.Name, prepare_ids)
     if prepare_ids != PrepareIDs:
         raise __QS_Error__("因子 %s 指定了不同的截面!" % self.Name)
     for i, iDescriptor in enumerate(self._Descriptors):
         if self.DescriptorSection[i] is None:
             iDescriptor._QS_initOperation(start_dt, dt_dict, prepare_ids,
                                           id_dict)
         else:
             iDescriptor._QS_initOperation(start_dt, dt_dict,
                                           self.DescriptorSection[i],
                                           id_dict)
     if (self._OperationMode.SubProcessNum >
             0) and (self.Name not in self._OperationMode._Event):
         self._OperationMode._Event[self.Name] = (Queue(), Event())
Exemple #25
0
 def getTable(self, table_name, args={}):
     if not os.path.isdir(self.MainDir + os.sep + table_name):
         raise __QS_Error__("ZarrDB.getTable: 表 '%s' 不存在!" % table_name)
     return _FactorTable(name=table_name,
                         fdb=self,
                         sys_args=args,
                         logger=self._QS_Logger)
Exemple #26
0
 def getDateTime(self,
                 ifactor_name=None,
                 iid=None,
                 start_dt=None,
                 end_dt=None,
                 args={}):
     if iid is None: iid = "000001.SH"
     CycleStr = self._genCycleStr(args.get("周期", self.Cycle),
                                  args.get("周期单位", self.CycleUnit))
     if start_dt is None: start_dt = dt.datetime(1970, 1, 1)
     if end_dt is None: end_dt = dt.datetime.now()
     CodeStr = "SetSysParam(pn_cycle()," + CycleStr + ");"
     CodeStr += "return select " + "['date'] "
     CodeStr += "from markettable datekey inttodate(" + start_dt.strftime(
         "%Y%m%d") + ") "
     CodeStr += "to (inttodate(" + end_dt.strftime(
         "%Y%m%d") + ")+0.9999) of '{ID}' end;"
     ErrorCode, Data, Msg = self._FactorDB._TSLPy.RemoteExecute(
         CodeStr.format(ID="".join(reversed(iid.split(".")))), {})
     if ErrorCode != 0:
         raise __QS_Error__("TinySoft 执行错误: " + Msg.decode("gbk"))
     DTs = np.array([
         dt.datetime(*self._FactorDB._TSLPy.DecodeDateTime(iData[b"date"]))
         for iData in Data
     ],
                    dtype="O")
     return DTs[(DTs >= start_dt) & (DTs <= end_dt)].tolist()
def loadCSVFilePortfolioSignal(csv_path):
    FileSignals = {}
    if not os.path.isfile(csv_path):
        raise __QS_Error__("文件: '%s' 不存在" % csv_path)
    with open(csv_path) as CSVFile:
        FirstLine = CSVFile.readline()
    if len(FirstLine.split(",")) != 3:  # 横向排列
        CSVDF = readCSV2Pandas(csv_path, detect_file_encoding=True)
        temp = list(CSVDF.columns)
        nCol = len(temp)
        AllSignalDates = [str(int(temp[i])) for i in range(0, nCol, 2)]
        for i in range(int(nCol / 2)):
            iDT = CSVDF.columns[i * 2]
            iSignal = CSVDF.iloc[:, i * 2:i * 2 + 2]
            iSignal = iSignal[pd.notnull(iSignal.iloc[:, 1])].set_index(
                [iDT]).iloc[:, 0]
            FileSignals[AllSignalDates[i]] = iSignal
    else:  # 纵向排列
        CSVDF = readCSV2Pandas(csv_path, detect_file_encoding=True, header=0)
        AllSignalDates = pd.unique(CSVDF.iloc[:, 0])
        AllColumns = list(CSVDF.columns)
        for iDT in AllSignalDates:
            iSignal = CSVDF.iloc[:, 1:][CSVDF.iloc[:, 0] == iDT]
            iSignal = iSignal.set_index(AllColumns[1:2])
            iSignal = iSignal[AllColumns[2]]
            FileSignals[str(iDT)] = iSignal
    return FileSignals
Exemple #28
0
 def cursor(self, sql_str=None):
     if self._Connection is None:
         raise __QS_Error__("%s尚未连接!" % self.__doc__)
     Cursor = self._Connection.cursor()
     if sql_str is None: return Cursor
     Cursor.execute(sql_str)
     return Cursor
Exemple #29
0
 def __QS_prepareRawData__(self, factor_names, ids, dts, args={}):
     CycleStr = self._genCycleStr(args.get("周期", self.Cycle),
                                  args.get("周期单位", self.CycleUnit))
     Fields = self._FactorDB._FactorInfo["DBFieldName"].loc[
         self.Name].loc[factor_names].tolist()
     CodeStr = "SetSysParam(pn_cycle()," + CycleStr + ");"
     CodeStr += "return select " + "['date'],['" + "'],['".join(
         Fields) + "'] "
     CodeStr += "from markettable datekey inttodate(" + dts[0].strftime(
         "%Y%m%d") + ") "
     CodeStr += "to (inttodate(" + dts[-1].strftime(
         "%Y%m%d") + ")+0.9999) of '{ID}' end;"
     Data = {}
     for iID in ids:
         iCodeStr = CodeStr.format(ID="".join(reversed(iID.split("."))))
         ErrorCode, iData, Msg = self._FactorDB._TSLPy.RemoteExecute(
             iCodeStr, {})
         if ErrorCode != 0:
             raise __QS_Error__("TinySoft 执行错误: " + Msg.decode("gbk"))
         if iData: Data[iID] = pd.DataFrame(iData).set_index([b"date"])
     if not Data: return pd.Panel(Data)
     Data = pd.Panel(Data).swapaxes(0, 2)
     Data.major_axis = [
         dt.datetime(*self._FactorDB._TSLPy.DecodeDateTime(iDT))
         for iDT in Data.major_axis
     ]
     Data.items = [(iCol.decode("gbk") if isinstance(iCol, bytes) else iCol)
                   for i, iCol in enumerate(Data.items)]
     Data = Data.loc[Fields]
     Data.items = factor_names
     return Data
Exemple #30
0
 def getTable(self, table_name, args={}):
     if table_name not in self._TableFactorDict:
         raise __QS_Error__("表 '%s' 不存在!" % table_name)
     return _FactorTable(name=table_name,
                         fdb=self,
                         data_type=self._TableFactorDict[table_name],
                         sys_args=args)