def get_field(self,
                  contract: str = 'main',
                  price: str = 'close',
                  rebalance_num: int = 1,
                  field: str = 'continuous_price') -> DataFrame:
        """
        获取连续合约指定字段的数据
        Parameters
        ----------
        contract: str
                合约种类,目前可选有main和active_near,main表示主力合约,active_near表示活跃近月
        rebalance_num: int, default = 1
                换仓天数,可选1,3,5
        field: str, default = 'close'
                字段,continuous_open或者continuous_close

        Returns
        -------
        df: DataFrame
            连续合约field字段数据,一般是开盘价或收盘价
        """
        data = self.get_continuous_contract_data(contract=contract,
                                                 price=price,
                                                 rebalance_num=rebalance_num)

        df = stack_dataframe_by_fields(data=data,
                                       index_field='datetime',
                                       column_field='underlying_symbol',
                                       data_field=field)
        return df
    def get_field(self, symbol: str, field: str) -> DataFrame:
        """
        获取单品种收盘价DataFrame

        Parameters
        ________
        symbol: string
                品种代码

        field:  string
                要获取的字段,如open, high, low, close

        Returns
        -------
        单品种不同合约的收盘价,index是交易日期,columns是合约代码,data是字段值

        Example:
        ________
        >>> self = DailyDataManager()
        >>> df = self.get_field("A", "close")
        >>>>print(df)

        contract     A0901   A0903   A0905   A0907  ...   A2105   A2107   A2109   A2111
        datetime                                    ...
        2009-01-05  3660.0  3598.0  3413.0  3308.0  ...     NaN     NaN     NaN     NaN
        2009-01-06  3679.0  3630.0  3459.0  3360.0  ...     NaN     NaN     NaN     NaN
        2009-01-07  3599.0  3610.0  3448.0  3360.0  ...     NaN     NaN     NaN     NaN
        2009-01-08  3600.0  3623.0  3420.0  3348.0  ...     NaN     NaN     NaN     NaN
        2009-01-09  3600.0  3623.0  3462.0  3407.0  ...     NaN     NaN     NaN     NaN
        ...
        """
        # 预先检查
        if field not in self.daily_data.columns.drop(['contract', 'datetime']):
            raise NameError(f"No field named {field}")
        if symbol not in self.daily_data.underlying_symbol.tolist():
            raise NameError(f"No symbol named {symbol}")

        # 如果已有数据,则直接返回
        if field in self.fields_dict:
            if symbol in self.fields_dict[field]:
                return self.fields_dict[field][symbol]

        daily_data = self.daily_data
        daily_data = daily_data[daily_data['underlying_symbol'] == symbol]
        data = stack_dataframe_by_fields(data=daily_data,
                                         index_field='datetime',
                                         column_field='contract',
                                         data_field=field)
        self.fields_dict[field][symbol] = data
        return data
Example #3
0
def get_near_contract_except_main(daily_data: DataFrame,
                                  main_contract_df: DataFrame) -> DataFrame:
    """
    获取单品种除主力合约以外的近月合约
    :param daily_data: 单品种日线行情数据
    :param main_contract_df: 单品种每日主力合约,注意是shift前的main_contract
    :type daily_data: DataFrame
    :type main_contract_df: DataFrame
    :return: 单品种每日近月合约,注意是shift前的近月合约,Series,index是时间,data是shift前的近月合约
    """
    try:
        close = stack_dataframe_by_fields(data=daily_data,
                                          index_field='datetime',
                                          column_field='contract',
                                          data_field='close')
    except KeyError:
        close = daily_data.copy()

    main_contract_list = main_contract_df['main_contract'].tolist()
    near_contract_list = []
    for i in range(len(close)):
        if i != len(close) - 1:
            # 可选合约池:今天有交易且排除掉主力合约
            if main_contract_list[i] in close.iloc[i].dropna().index:
                pool = close.iloc[i].dropna().index.drop(main_contract_list[i])
                # 如果没有可选合约,则返回缺失值
                if len(pool) == 0:
                    print(main_contract_list[i], close.index[i])
                    near_contract_list.append(np.nan)
                else:
                    near_contract_list.append(pool.min())
            else:
                near_contract_list.append(np.nan)
        else:
            pool = close.iloc[i].dropna().index.drop(main_contract_list[i])
            near_contract_list.append(pool.min())
    near_contract_df = pd.Series(near_contract_list,
                                 index=close.index).reset_index()
    near_contract_df.columns = ['datetime', 'near_contract']
    return near_contract_df
    def compute_factor(self) -> DataFrame:
        """
        计算因子,通过对compute_single_factor实现

        Returns
        -------
        因子值: DataFrame
                index为datetime, columns为underlying_symbol, data为factor
        """
        symbol_list = self.get_symbol_list()
        factor_list = []
        for symbol in tqdm(symbol_list):
            factor = self.compute_single_factor(symbol)
            factor_list.append(factor)
        factor = pd.concat(factor_list, axis=0)
        factor = stack_dataframe_by_fields(data=factor,
                                           index_field='datetime',
                                           column_field='underlying_symbol',
                                           data_field='factor')
        factor = factor.rolling(window=self.window, min_periods=1).mean()
        self.factor_value = factor
        return factor