Esempio n. 1
0
 def get_weights(self):
     code_list = list_jq2wind(self.code_list)
     code_weights = {}
     w.start()
     weight_data = np.array(
         w.wss(code_list, "mkt_cap_float",
               "unit=1;tradeDate=" + self.date + ";currencyType=").Data[0])
     weight_data = weight_data / np.sum(weight_data)
     for i in range(len(code_list)):
         code = code_list[i]
         code_weights[list_wind2jq([code])[0]] = weight_data[i]
     return code_weights
Esempio n. 2
0
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):
    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+'日回测程序执行中...')
        # 根据指数获取股票候选池的代码
        select_code_list = list_wind2jq(INCLUDED_INDEX)
        if len(select_code_list) > 0:  # 有可选股票时选取合适的股票
            stock_now = WEIGHTS(select_code_list, date_previous).get_weights()
            stock_dict[date_now] = stock_now
        else:
            stock_dict[date_now] = {}
 def get_weights(self):
     code_list = list_jq2wind(self.code_list)
     w.start()
     return_value = np.array(
         w.wsd(code_list, "pct_chg", "ED-" + str(self.N - 1) + "TD",
               self.date, "").Data)
     return_value = return_value.transpose()
     return_value = pd.DataFrame(return_value, columns=code_list)
     optimizer = HRPOpt(return_value)
     hrp_portfolio = optimizer.hrp_portfolio()
     hrp_portfolio = dict(
         zip(list_wind2jq(list(hrp_portfolio.keys())),
             hrp_portfolio.values()))
     return hrp_portfolio
Esempio n. 5
0
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+'日回测程序执行中...')
        # 根据指数获取股票候选池的代码
        code_list = SelectedStockPoolFromListV1(INCLUDED_INDEX, EXCLUDED_INDEX, date_previous).get_stock_pool()
        # 按照选股策略选股,与选股策略接口保持一致
        strategy = STRATEGY(code_list, date_previous)
        select_code_list = list_wind2jq(strategy.select_code())
        if len(select_code_list) > 0:  # 有可选股票时选取合适的股票
            stock_now = WEIGHTS(select_code_list, date_previous).get_weights()
            stock_dict[date_now] = stock_now
        else:
            stock_dict[date_now] = {}
 def get_weights(self):
     code_list = list_jq2wind(self.code_list)
     SW1_code_list = [t[0] for t in SW1_INDEX]
     weight_value = self._calc_weights(SW1_code_list)  # 提取行业权重
     industry_list = w.wss(code_list, "indexcode_sw", "tradeDate="+self.date+";industryType=1").Data[0]
     weight_value_temp = []
     for i in range(len(code_list)):
         industry_temp = industry_list[i]
         if industry_temp is None:  # 个股无行业分类数据的处理
             weight_value_temp.append(0.0)
         else:
             industry_index = SW1_code_list.index(industry_temp)
             weight_value_temp.append(weight_value[industry_index])
     weight_value_temp = np.array(weight_value_temp)
     weight_value_temp = weight_value_temp / np.sum(weight_value_temp)  # 权重归一化
     code_weights = dict([[list_wind2jq([code_list[i]])[0], weight_value_temp[i]] for i in range(len(code_list))])
     return code_weights
def algo(context):
    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]  # 择时信号计算
    select_time_dict[date_now] = select_time_value
    print(date_now + ('日回测程序执行中...,择时值:%.2f' % select_time_value))

    if date_now not in trading_date_list:  # 非调仓日
        pass
    else:  # 调仓日执行算法
        # 根据指数获取股票候选池的代码
        code_list = SelectedStockPoolFromListV1(
            INCLUDED_INDEX, EXCLUDED_INDEX, date_previous).get_stock_pool()
        strategy = STRATEGY(code_list, date_previous, 0.9)
        select_code_list = list_wind2jq(strategy.select_code())
        if len(select_code_list) > 0:  # 有可选股票时选取合适的股票
            stock_now = WEIGHTS(select_code_list, date_previous).get_weights()
        else:
            stock_dict[date_now] = {}
def algo(context):
    date_now = context.now.strftime('%Y-%m-%d')
    print(date_now + '日回测程序执行中...')
    if date_now not in context.trading_date_list:  # 非调仓日
        pass  # 预留非调仓日的微调空间
    else:  # 调仓日执行算法
        date_previous = get_trading_date_from_now(
            date_now, -1, ql.Days)  # 前一个交易日,用于获取因子数据的日期
        code_list = SelectedStockPoolFromListExcluded(
            context.INCLUDED_INDEX, context.EXCLUDED_INDEX,
            date_previous).get_stock_pool()
        factor = context.FACTOR(date_previous, code_list)  # 读取单因子的代码
        df = factor.get_factor().dropna()
        quantiles = df.quantile(context.QUANTILE).values  # 取对应的分位数值
        stock_codes = list(
            df[(df[factor.factor_name] >= quantiles[0][0])
               & (df[factor.factor_name] < quantiles[1][0])].index.values)
        stock_codes = list_wind2jq(stock_codes)  # 仓位配置前转换为聚宽代码
        stock_now = context.WEIGHTS_FUNCTION(stock_codes,
                                             date_previous).get_weights()
        stock_dict[date_now] = stock_now
Esempio n. 9
0
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]  # 择时信号计算

    if date_now not in trading_date_list:  # 非调仓日
        pass
    else:  # 调仓日执行算法,更新position_target
        position_now = False  # 虚拟上,调仓日需要提前清仓
        stock_dict[date_now] = {}
        # 根据指数获取股票候选池的代码
        all_code_set = set()
        for index in INDEX:
            code_set = set(
                w.wset("sectorconstituent",
                       "date=" + date_previous + ";windcode=" + index).Data[1])
            all_code_set = all_code_set | code_set
        code_list = list(all_code_set)  # 股票候选池
        strategy = STRATEGY(code_list, date_previous, 0.9)
        select_code_list = list_wind2jq(strategy.select_code())
        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

    # 打印择时信号和仓位配置信息
    print(date_now + ('日回测程序执行中...,择时值:%.2f' % select_time_value))
    print(date_now + '日回测程序执行中...,选股:')
    print(position_target)
Esempio n. 10
0
    def get_weights(self):
        code_list = list_jq2wind(self.code_list)
        code_weights = {}
        return_value = self._get_return(code_list)

        def optimization_target(weight_temp):
            weight_temp = weight_temp[:, np.newaxis]
            portfolio_return_value = np.matmul(weight_temp.transpose(),
                                               return_value)[0, :]  # 组合的投资回报序列
            mean = np.mean(portfolio_return_value)
            var = np.var(portfolio_return_value)
            skew = scipy.stats.skew(portfolio_return_value)
            kurtosis = scipy.stats.kurtosis(portfolio_return_value)
            loss = self.w2 * var + self.w3 * skew + self.w4 * kurtosis  # 对方差、偏度、丰度进行优化,期望值最小越好
            return loss

        def constraint(weight_temp):
            return np.sum(weight_temp) - 1.0

        n = len(self.code_list)  # 资产个数
        x_0 = np.ones((n, )) * 1.0 / n
        bounds = n * ((0.0, None), )  # 权重非负约束条件
        res = scipy.optimize.minimize(optimization_target,
                                      x_0,
                                      method='SLSQP',
                                      bounds=bounds,
                                      constraints={
                                          'type': 'eq',
                                          'fun': constraint
                                      })
        # print(res)
        if res.success:  # 优化成功
            x = res.x
        else:  # 优化失败,用等权
            x = x_0
        for i in range(len(code_list)):
            code = code_list[i]
            code_weights[list_wind2jq([code])[0]] = x[i]
        return code_weights
 def get_weights(self):
     code_list = list_jq2wind(self.code_list)
     stock_ZX1_industry_code_list = w.wss(
         code_list, "indexcode_citic",
         "industryType=1;tradeDate=" + self.date).Data[0]
     ZX1_industry_code_list = list(set(stock_ZX1_industry_code_list))
     weight_value = self._calc_weights(list(
         set(ZX1_industry_code_list)))  # 计算股票涉及到的行业权重
     # industry_list = w.wss(code_list, "indexcode_sw", "tradeDate="+self.date+";industryType=1").Data[0]
     weight_value_temp = []
     for i in range(len(code_list)):
         industry_temp = stock_ZX1_industry_code_list[i]
         if industry_temp is None:  # 个股无行业分类数据的处理
             weight_value_temp.append(0.0)
         else:
             industry_index = ZX1_industry_code_list.index(industry_temp)
             weight_value_temp.append(weight_value[industry_index])
     weight_value_temp = np.array(weight_value_temp)
     weight_value_temp = weight_value_temp / np.sum(
         weight_value_temp)  # 权重归一化
     code_weights = dict(
         [[list_wind2jq([code_list[i]])[0], weight_value_temp[i]]
          for i in range(len(code_list))])
     return code_weights
                risk_budget.append(value_ratio)
                risk_bounds.append([0.4, 0.85])  # 权重约束设置
            elif value_code in [
                    '513050.SH', '513100.SH', '513500.SH', '518880.SH'
            ]:  # 外盘黄金类
                stock_pool.append(value_code)
                risk_budget.append(value_ratio)
                risk_bounds.append([0.0, 0.2])  # 权重约束设置
            else:  # 国内股票类
                stock_pool.append(value_code)
                risk_budget.append(value_ratio)
                risk_bounds.append([0.0, 1.0])  # 权重约束设置
    S_result.append([stock_pool, risk_budget, np.array(risk_bounds)])

# 策略0部分
stock_pool_0 = list_wind2jq(S_result[0][0])
risk_budget_0 = S_result[0][1]
risk_bounds_0 = S_result[0][2]
stock_weights_0 = 风险预算组合_模块求解基本版_带约束(stock_pool_0,
                                     DATE,
                                     risk_budget=risk_budget_0,
                                     bounds=risk_bounds_0).get_weights()
# 加入信用债品种,对国债配置比例进行修正
stock_weights_0 = adjust_weights(stock_weights_0, BOND_ADJUST, STOCK_ADJUST)
# 输出文字信息
string_output_0 = '策略0的风险预算权重为:\n'
string_output_0 += str(dict(zip(stock_pool_0, risk_budget_0))) + '\n'
string_output_0 += '策略0的选股结果(选股日为 ' + DATE + ' 收盘):\n'
string_output_0 += str(stock_weights_0) + '\n'
print(string_output_0)
stock_pool_bond = ['511010.SH']
risk_budget_bond = [1.0]  # 候选目标[0.2, 0.8, 0.8]
risk_bounds_bond = np.array([[0.0, 1.0]])
# 国内股票部分配置方案
stock_pool_stock = ['159949.SZ', '159928.SZ', '510050.SH', '510500.SH']
risk_budget_stock = [1.0, 1.0, 1.0, 1.0]  # 总权重固定为4个单位
risk_bounds_stock = np.array([[0.0, 1.0]] * len(stock_pool_stock))
# 国际部分配置方案
stock_pool_global = ['513100.SH', '513500.SH', '518880.SH']
risk_budget_global = [0.75, 0.75, 0.8]  # 在区间[0.75, 0.75, 0.8]-[1.0, 1.0, 1.0]之间灵活调整
risk_bounds_global = np.array([[0.0, 1.0]] * len(stock_pool_global))
# 合并为整体证券池
stock_pool = stock_pool_bond + stock_pool_stock + stock_pool_global
risk_budget = risk_budget_bond + risk_budget_stock + risk_budget_global
risk_bounds = np.concatenate([risk_bounds_bond, risk_bounds_stock, risk_bounds_global])
stock_pool = list_wind2jq(stock_pool)
EXCLUDED_INDEX = []  # 剔除的股票代码
TRADING_DATES_LIST = ['15']  # 每月的调仓日期,非交易日寻找下一个最近的交易日

# 用于记录调仓信息的字典
stock_dict = {}

# 根据回测阶段选取好调仓日期
trading_date_list = []  # 记录调仓日期的列表


def init(context):
    # 调仓日期获取
    global trading_date_list
    trading_date_list = get_trading_date_list_by_day_monthly(BACKTEST_START_DATE, BACKTEST_END_DATE, TRADING_DATES_LIST)
    # 每天time_rule定时执行algo任务,time_rule处于09:00:00和15:00:00之间
Esempio n. 14
0
        views_vector.append(ws.cell(ws.nrows - 2, j).value)
        views_cov.append(ws.cell(ws.nrows - 1, j).value)
    views_matrix = np.array(views_matrix).transpose()
    views_vector = np.array(views_vector).reshape(-1, 1)
    views_cov = np.diag(np.array(views_cov)**2)
    return views_matrix, views_vector, views_cov


if __name__ == '__main__':
    # 输入数据
    date = '2019-11-04'
    file_path = '投资示例.xlsx'
    # 数据整理
    code_list = 品种获取(file_path)
    views_matrix, views_vector, views_cov = 观点信息获取(file_path)
    code_weights = WEIGHTS(list_wind2jq(code_list), date).get_weights()

    # 风险平价收益和历史数据估计协方差数据
    rp_weights = [code_weights[code] for code in code_weights]
    return_cov = 方差风险_历史数据(code_list, date, 60).return_cov * 240
    # 主观观点标准差与历史估计标准差的比较
    views_variance = get_variance_of_views_from_weights_covariances(
        return_cov, views_matrix)
    views_std = np.sqrt(views_variance)
    print('观点的历史数据估计标准差为:')
    print(views_std)
    print('观点的主观判断标准差为:')
    print(np.sqrt(np.diag(views_cov)))

    # BL模型的参数设定
    delta_value = 50.0
Esempio n. 15
0
def equal_transfer(code_list, date):
    # 按照date日的参数等权调仓
    stock_now = {}
    for code in code_list:
        stock_now[list_wind2jq([code])[0]] = 1. / len(code_list)
    return stock_now
# 国内债券部分配置方案
stock_pool_1_bond = ['511010.SH']
risk_budget_1_bond = [1.0]
risk_bounds_1_bond = np.array([[0.4, 1.0]])
# 国内股票部分配置方案
stock_pool_1_stock = [
    '159928.SZ', '159949.SZ', '510050.SH', '512660.SH', '512720.SH',
    '515000.SH'
]
risk_budget_1_stock = [0.7, 0.7, 0.7, 0.5, 0.8, 0.6]  # 总权重固定为4个单位
risk_bounds_1_stock = np.array([[0.0, 1.0]] * len(stock_pool_1_stock))
# 合并为整体证券池
stock_pool_1 = stock_pool_1_bond + stock_pool_1_stock
risk_budget_1 = risk_budget_1_bond + risk_budget_1_stock
risk_bounds_1 = np.concatenate([risk_bounds_1_bond, risk_bounds_1_stock])
stock_pool_1 = list_wind2jq(stock_pool_1)
stock_weights_1 = 风险预算组合_模块求解基本版_带约束(stock_pool_1,
                                     date_1,
                                     risk_budget=risk_budget_1,
                                     bounds=risk_bounds_1).get_weights()
# 加入信用债品种,对国债配置比例进行修正
stock_weights_1['160618.XSHE'] = 0.05
stock_weights_1['161713.XSHE'] = 0.03
stock_weights_1['161716.XSHE'] = 0.09
stock_weights_1['167501.XSHE'] = 0.05
stock_weights_1['511010.XSHG'] = stock_weights_1['511010.XSHG'] - 0.22
# 输出文字信息
string_output_1 = '策略一的风险预算权重为:\n'
string_output_1 += str(dict(zip(stock_pool_1, risk_budget_1))) + '\n'
string_output_1 += '策略一的选股结果(选股日为 ' + date_1 + ' 收盘):\n'
string_output_1 += str(stock_weights_1) + '\n'
Esempio n. 17
0
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