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
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