def compute(self, begin_date=None, end_date=None): """ 计算指定时间段内所有股票的该因子的值,并保存到数据库中 :param begin_date: 开始时间 :param end_date: 结束时间 """ dm = DataModule() # 如果没有指定日期范围,则默认为计算当前交易日的数据 if begin_date is None: begin_date = datetime.now().strftime('%Y-%m-%d') if end_date is None: end_date = datetime.now().strftime('%Y-%m-%d') dates = get_trading_dates(begin_date, end_date) for date in dates: # 查询出股票在某一交易日的总股本 df_basics = dm.get_stock_basic_at(date) if df_basics.index.size == 0: continue # 将索引改为code df_basics.set_index(['code'], 1, inplace=True) # 查询出股票在某一个交易日的收盘价 df_dailies = dm.get_one_day_k_data(autype=None, date=date) if df_dailies.index.size == 0: continue # 将索引设为code df_dailies.set_index(['code'], 1, inplace=True) update_requests = [] for code in df_dailies.index: try: # 股价 close = df_dailies.loc[code]['close'] # 总股本 total_shares = df_basics.loc[code]['totals'] # 总市值 = 股价 * 总股本 total_capital = round(close * total_shares, 2) print('%s, %s, mkt_cap: %15.2f' % (code, date, total_capital), flush=True) update_requests.append( UpdateOne( {'code': code, 'date': date}, {'$set': {'code': code, 'date': date, self.name: total_capital}}, upsert=True)) except: print('计算规模因子时发生异常,股票代码:%s,日期:%s' % (code, date), flush=True) if len(update_requests) > 0: save_result = self.collection.bulk_write(update_requests, ordered=False) print('股票代码: %s, 因子: %s, 插入:%4d, 更新: %4d' % (code, self.name, save_result.upserted_count, save_result.modified_count), flush=True)
def analyze(self): # 初始化对数据管理子系统接口的调用 dm = DataModule() # 初始化对因子管理子系统接口的调用 fm = FactorModule() # 获取分析周期内的 all_dates = get_trading_dates(self.begin_date, self.end_date) # 首档和末档,股票代码和后复权价格的Dictionary top_dailies = dict() bottom_dailies = dict() # 暂存上一个调整 last_adjust_date = None # 设置沪深300的首日值 hs300_k = dm.get_k_data('000300', index=True, begin_date=all_dates[0], end_date=all_dates[0]) self.hs300_first_value = hs300_k.loc[0]['close'] # 计算每日收益 for index in range(0, len(all_dates), self.interval): adjust_date = all_dates[index] # 获取因子值,按照指定的顺序排序 df_factor = fm.get_single_date_factors(self.factor, adjust_date) if df_factor.index.size == 0: continue df_factor.sort_values(self.factor, ascending=self.ascending, inplace=True) # 将股票代码设为index df_factor.set_index(['code'], inplace=True) # 获取当日所有股票的行情 df_dailies = dm.get_one_day_k_data(autype='hfq', date=adjust_date) # 将code设为index df_dailies.set_index(['code'], inplace=True) # 计算收益 self.compute_profit(last_adjust_date, df_dailies, top_dailies, bottom_dailies, adjust_date) # 删除停牌股票 df_dailies = df_dailies[df_dailies['is_trading']] # 计算每当包含的股票数 total_size = df_dailies.index.size single_position_count = int(total_size / self.position) # 调整首档组合 self.adjust_top_position(top_dailies, df_factor, df_dailies, single_position_count) # 调整末档组合 self.adjust_bottom_position(bottom_dailies, df_factor, df_dailies, single_position_count) # 保存上一个调整日 last_adjust_date = adjust_date # 生成零投资组合的组合收益 self.profit_df[ 'portfolio'] = self.profit_df['top'] - self.profit_df['bottom'] self.draw()