def algo(context): date_now = context.now.strftime('%Y-%m-%d') date_previous = get_trading_date_from_now(date_now, -1, ql.Days) # 前一个交易日,用于获取因子数据的日期 if date_now not in trading_date_list: # 非调仓日 pass # 预留非调仓日的微调空间 else: # 调仓日执行算法 print(date_now + '日回测程序执行中...') try: code_list = list_gm2wind( list( get_history_constituents( INDEX, start_date=date_previous, end_date=date_previous)[0]['constituents'].keys())) except IndexError: code_list = w.wset("sectorconstituent", "date=" + date_previous + ";windcode=" + INDEX).Data[1] I = trading_date_list.index(date_now) trading_dates = trading_date_list[I - HISTORY_LENGTH:I + 1] data_dfs = [] for i in range(len(trading_dates) - 1): date_start = get_trading_date_from_now( trading_dates[i], -1, ql.Days) # 计算因子值的日子,买入前一日的因子值 date_end = get_trading_date_from_now(trading_dates[i + 1], -1, ql.Days) # 计算收益率到期的日子-收盘 factors_df = get_factor_from_wind(code_list, FACTOR_LIST, date_start) # 获取因子 return_df = get_return_from_wind(code_list, date_start, date_end) factors_df_and_return_df = pd.concat( [factors_df, return_df], axis=1).dropna() # 去掉因子或者回报有空缺值的样本 factors_df_and_return_df = sort_data( factors_df_and_return_df) # 使用排序数据作为输入 data_dfs.append(factors_df_and_return_df) factors_return_df = pd.concat(data_dfs, axis=0) # 获取的最终训练数据拼接,return为目标 # 根据data_df训练模型 model = OrdinaryLinearRegression() model.fit(factors_return_df) # 根据factor_date_previous选取股票 factor_date_previous_df = get_factor_from_wind(code_list, FACTOR_LIST, date_previous).dropna() sorted_codes = model.predict( factor_date_previous_df) # 获取预测收益率从小到大排序的股票列表 sorted_codes = list_wind2jq(sorted_codes) # 根据股票列表下单 stock_codes = sorted_codes[-STOCK_NUMBER:] stock_now = {} for stock_code in stock_codes: # 平均持仓持股 stock_now[stock_code] = 1. / STOCK_NUMBER stock_dict[date_now] = stock_now
def algo(context): global position_now, position_target date_now = context.now.strftime('%Y-%m-%d') date_previous = get_trading_date_from_now(date_now, -1, ql.Days) # 前一个交易日,用于获取因子数据的日期 select_time_value = select_time_model[date_now] # 择时信号计算 print(date_now + ('日回测程序执行中...,择时值:%.2f' % select_time_value)) if date_now not in trading_date_list: # 非调仓日 pass # 预留非调仓日的微调空间 else: # 调仓日执行算法 position_now = False # 虚拟上,调仓日需要提前清仓 # 根据指数获取股票候选池的代码 code_list = SelectedStockPoolFromListV1( INCLUDED_INDEX, EXCLUDED_INDEX, date_previous).get_stock_pool() I = trading_date_list.index(date_now) trading_dates = trading_date_list[I - HISTORY_LENGTH:I + 1] # 提取训练数据并训练模型 data_dfs = [] for i in range(len(trading_dates) - 1): date_start = get_trading_date_from_now( trading_dates[i], -1, ql.Days) # 计算因子值的日子,买入前一日的因子值 date_end = get_trading_date_from_now(trading_dates[i + 1], -1, ql.Days) # 计算收益率到期的日子-收盘 # 提取因子和收益数据 factors_df = get_factor_from_wind(code_list, FACTOR_LIST, date_start) # 获取因子 return_df = get_return_from_wind(code_list, date_start, date_end) factors_df_and_return_df = pd.concat( [factors_df, return_df], axis=1).dropna() # 去掉因子或者回报有空缺值的样本 factors_df_and_return_df = factor_and_return_process( factors_df_and_return_df) # 对因子和回报进行预处理# 使用排序数据作为输入 data_dfs.append(factors_df_and_return_df) factors_return_df = pd.concat(data_dfs, axis=0) # 获取的最终训练数据拼接,return为目标 # 根据data_df训练模型 model = OrdinaryLinearRegression(select_number=SELECT_NUMBER) model.fit(factors_return_df) # 根据factor_date_previous选取股票,使用模型 factor_date_previous_df = get_factor_from_wind(code_list, FACTOR_LIST, date_previous).dropna() factor_date_previous_df = factor_process( factor_date_previous_df) # 对因子进行预处理 select_code_list = model.predict( factor_date_previous_df) # 返回选取的股票代码,Wind格式 # 行业轮动部分 sw1_industry = get_SW1_industry(date_now, select_code_list) industry_wm_result = industry_wheel_movement[date_now] select_code_list = [ stock for stock in select_code_list if sw1_industry[stock] is not None and industry_wm_result[sw1_industry[stock]] == 1 ] # 忽略无行业信息的股票并根据行业择时信号选择候选股票 # 转化为聚宽代码格式 select_code_list = list_wind2jq(select_code_list) # 根据股票列表下单 if len(select_code_list) > 0: # 有可选股票时记录下可选股票 stock_now = WEIGHTS(select_code_list, date_previous).get_weights() position_target = stock_now else: position_target = {} # 择时判定 if select_time_value >= 0 and not position_now and position_target != {}: # LLT择时信号为正,空仓且有目标持仓状态 stock_dict[date_now] = position_target position_now = True elif select_time_value < 0 and position_now and position_target != {}: # LLT择时信号为负且持仓状态: stock_dict[date_now] = {} position_now = False