Ejemplo n.º 1
0
def period_return_maker_(chooseday_r, factor_value, indicator):
    date_r2 = month(chooseday_r, change_month=-12)
    date = chooseday_r
    if len(date) <= 8:
        date_r = date[0:4] + '-' + date[4:6] + '-' + date[6:8]
    else:
        date_r = date

    # 创建某时刻截面指标df
    df_values = pd.DataFrame(columns=['date', 'code', 'factor_value'],
                             index=range(len(factor_value)))

    df_values['date'] = date
    df_values['code'] = factor_value['code']
    df_values['factor_value'] = factor_value[indicator]  # 指标选择

    # 对指标进行标准化
    df_values['factor_value'] = (df_values['factor_value'] -
                                 df_values['factor_value'].min()) \
                                / (df_values['factor_value'].max() -
                                   df_values['factor_value'].min())  # 标准化

    # 创建该段时间所有股票的收益率pool
    returns = get_data_panel("huangwei",
                             "huangwei",
                             list(df_values['code']),
                             date_r2,
                             date_r,
                             collection='stock_daily')

    df_price = pd.DataFrame(columns=['date', 'code'],
                            index=range(len(df_values)))
    df_price['date'] = date
    df_price['code'] = df_values['code']
    df_price['cum_return'] = 0

    # 计算每只股票在这段时间的累计收益,并填入cum_return中
    def caculate_cum_return(code):
        one_stock = returns[returns['code'] == code].reset_index(drop=True)
        unique_index = list(one_stock['date'].drop_duplicates(
            keep='first', inplace=False).index)
        one_stock = one_stock.iloc[unique_index].sort_values(by='date')
        one_stock['rtn'] += 1
        one_stock['c_rtn'] = one_stock['rtn'].cumprod()
        return one_stock['c_rtn'].iloc[-1] - one_stock['c_rtn'].iloc[0]

    df_price['cum_return'] = df_price['code'].apply(caculate_cum_return)

    # 合并收盘价以及指标值数据,计算两者截面相关性
    df_all = df_price.merge(df_values[['code', 'factor_value']],
                            how='inner',
                            on='code')

    # 剔除不匹配的股票
    df_all = df_all.dropna(axis=0, how='any').reset_index(drop=True)
    ic, p = spearman_cor(df_all['cum_return'].values,
                         df_all['factor_value'].values)

    print('IC值计算完毕')
    return ic, p
Ejemplo n.º 2
0
    def _open_convert_database(self):
        all_data = get_data_panel("huangwei",
                                  "huangwei",
                                  self.symbol_list,
                                  '2017-03-01',
                                  '2019-08-01',
                                  collection='stock_daily')
        comb_index = None
        for s in self.symbol_list:
            one_stock = all_data[all_data['code'] == s][[
                'date', 'open', 'high', 'low', 'close', 'vol', 'rtn'
            ]]
            one_stock = one_stock.rename(columns={
                "date": "datetime",
                "vol": "volume"
            })
            one_stock['adj_close'] = 0

            one_stock_arr = one_stock.values

            for i in range(len(one_stock_arr)):
                if i == 0:
                    one_stock_arr[i, 7] = one_stock_arr[i, 4] \
                                                     * (1 + one_stock_arr[i, 6])
                else:
                    one_stock_arr[i, 7] = one_stock_arr[i - 1, 7] \
                                                     * (1 + one_stock_arr[i, 6])

            one_stock = pd.DataFrame(one_stock_arr,
                                     columns=one_stock.columns,
                                     index=range(len(one_stock)))
            del one_stock['rtn']

            # 将datatime作为index,并改为datatime格式
            one_stock['datetime'] = pd.to_datetime(one_stock['datetime'])
            one_stock.set_index(["datetime"], inplace=True)
            one_stock = one_stock.fillna(method='ffill')
            # ffill:用前一个非缺失值去填充该缺失值(向后填充)
            # bfill:用下一个非缺失值填充该缺失值(向前填充)

            self.symbol_data[s] = one_stock.sort_values(by="datetime",
                                                        ascending=True)

            # Combine the index to pad forward values
            if comb_index is None:
                comb_index = self.symbol_data[s].index
            else:
                comb_index.union(self.symbol_data[s].index)
                # 这里对于不同股票的日期会不断叠加,直到得到一列所有股票里面最长的

            # Set the latest symbol_data to None
            self.latest_symbol_data[s] = []

        # Reindex the dataframes
        for s in self.symbol_list:
            self.symbol_data[s] = self.symbol_data[s].reindex(
                index=comb_index, method='pad').iterrows()
Ejemplo n.º 3
0
def get_data_(cal_day, indicator):
    # 读取所有股票信息表
    stock_info = pd.read_excel(
        'C:/Users/Lenovo/PycharmProjects/my_project/frjj_codes/stock_info_20190801.xlsx'
    )
    stock_info = stock_info.dropna(axis=0, how='any').reset_index(drop=True)

    # 与指数成分股取交集
    index_content_now = index_content[index_content['date'] == list(
        index_content['date'][index_content['date'] >= cal_day])
                                      [0]].reset_index(drop=True)

    index_content_now.rename(columns={'stock_code': '证券代码'}, inplace=True)
    stock_info = stock_info.merge(index_content_now['证券代码'],
                                  on='证券代码',
                                  how='inner')

    # 读取申万一级行业划分
    sw1 = sw_info_(cal_day, "sw1")
    sw1.rename(columns={'sw_name': 'sw1_name'}, inplace=True)

    # 读取申万三级行业划分
    sw3 = sw_info_(cal_day, "sw3")
    sw3.rename(columns={'sw_name': 'sw3_name'}, inplace=True)

    all = pd.DataFrame(columns=['code', 'code_name'],
                       index=range(len(stock_info)))
    all['code'] = stock_info['证券代码']
    all['code_name'] = stock_info['证券简称']
    all = all.merge(sw1[['code', 'sw1_code', 'sw1_name']],
                    on='code',
                    how='left')
    all = all.merge(sw3[['code', 'sw3_code', 'sw3_name']],
                    on='code',
                    how='left')

    # 使cal_day适应api
    if len(cal_day) == 8:
        cal_day = cal_day[0:4] + '-' + cal_day[4:6] + '-' + cal_day[6:8]
    else:
        pass

    # 直接从数据库收集股票的流通市值(或总市值)
    data = get_data_panel("huangwei",
                          "huangwei",
                          list(all['code']),
                          forwardchangeday2(cal_day),
                          forwardchangeday2(cal_day),
                          collection='stock_indicator')

    # 用total_mv替换原表的cir_mv
    all = all.merge(data[['code', indicator]], on='code', how='left')
    all['cir_mv'] = all[indicator]
    del all[indicator]

    return all
Ejemplo n.º 4
0
def weight_maker_(chooseday_r, weight_origin, how=0):
    user = "******"
    passwd = "huangwei"
    weight = weight_origin

    if how == 0:  # 等权
        weight['weight_adj_sw1'] = 1 / len(weight_origin)
        print('持仓赋权方式为:等权')

    elif how == 1:  # 按市值加权,取出这天股票组合的市值信息
        if 'total_mv' not in weight.columns:

            info_all = get_data_panel(user,
                                      passwd,
                                      list(weight['code']),
                                      chooseday_r,
                                      chooseday_r,
                                      collection='stock_indicator')
            weight = weight.merge(info_all[['code', 'total_mv']],
                                  how='inner',
                                  on='code')
        else:
            pass

        weight_sum = sum(weight['total_mv'])
        weight['weight_adj_sw1'] = weight['total_mv'] / weight_sum
        del weight['total_mv']
        print('持仓赋权方式为:市值加权')

    elif how == 2:  # 按过去一年收益率波动率倒数
        # 获取当下日期过去一年的收益率数据
        info_all = get_data_panel_backwards(user,
                                            passwd,
                                            list(weight['code']),
                                            chooseday_r,
                                            back_years=0,
                                            back_months=12,
                                            collection='stock_daily')
        info_all = info_all.rename(columns={'code': 'codes'})
        # 分组统计标准差
        grouped = info_all.groupby(by=info_all['codes']).std()
        grouped['code'] = grouped.index
        weight = weight.merge(grouped[['code', 'rtn']], how='inner', on='code')
        weight['rtn'] = 1 / weight['rtn']
        weight['rtn'] = weight['rtn'].ffill()  # 缺失值延续前值
        weight['weight_sum'] = sum(weight['rtn'])
        weight['weight_adj_sw1'] = weight['rtn'] / weight['weight_sum']
        print('持仓赋权方式为:波动率倒数加权')

    return weight
Ejemplo n.º 5
0
def get_data_(cal_day, indicator):
    # 与指数成分股取交集
    index_content_now = index_content[index_content['date'] == list(
        index_content['date'][index_content['date'] >= cal_day])
                                      [0]].reset_index(drop=True)

    index_content_now.rename(columns={'stock_code': '证券代码'}, inplace=True)

    stock_info_ = stock_info.merge(index_content_now['证券代码'],
                                   on='证券代码',
                                   how='inner')

    # 取当天的申万行业划分
    sw_ = sw[sw['date'] == cal_day].reset_index(drop=True)

    all = pd.DataFrame(columns=['code', 'code_name'],
                       index=range(len(stock_info_)))
    all['code'] = stock_info_['证券代码']
    all['code_name'] = stock_info_['证券简称']
    all = all.merge(sw_[[
        'code', 'sw1_code', 'sw1_name', 'sw2_code', 'sw2_name', 'sw3_code',
        'sw3_name'
    ]],
                    on='code',
                    how='left')

    # 使cal_day适应api
    if len(cal_day) == 8:
        cal_day = cal_day[0:4] + '-' + cal_day[4:6] + '-' + cal_day[6:8]
    else:
        pass

    # 直接从数据库收集股票的流通市值(或总市值)
    data = get_data_panel("huangwei",
                          "huangwei",
                          list(all['code']),
                          forwardchangeday2(cal_day),
                          forwardchangeday2(cal_day),
                          collection='stock_indicator')

    # 用total_mv替换原表的cir_mv
    all = all.merge(data[['code', indicator]], on='code', how='left')
    all['cir_mv'] = all[indicator]
    del all[indicator]

    return all
Ejemplo n.º 6
0
def position_init_(stock_pool, changeday, total_capitals):
    # 持仓矩阵初始化
    position = pd.DataFrame(columns=['date', 'code', 'weight', 'account',
                                     'open_price',
                                     'lots', 'account_surplus', 'close_price'],
                            index=range(len(stock_pool)))
    position['code'] = stock_pool['code']
    position['weight'] = stock_pool['weight_adj_sw1']
    position['date'] = changeday
    position['account'] = total_capitals[-1] * position['weight']
    # 计算每个股票的应买手数
    price = get_data_panel("huangwei", "huangwei", list(position['code']),
                           changeday, changeday,
                           collection='stock_daily').drop_duplicates(['code'])

    if 'open' in position.columns:
        del position['open']
    if 'rtn' in position.columns:
        del position['rtn']

    position = position.merge(price[['code', 'open', 'rtn']],
                              on='code', how='inner')
    position['open_price'] = position['open']
    position['close_price'] = position['open_price'] * (1 + position['rtn'])
    position['lots'] = position['account'] / (100 * position['open_price'])

    # 对于获取不到开盘价的股票,可买手数一律赋0
    position['lots'] = position['lots'].fillna(0)

    # 为了方便计算剩余资金,创造facked字段,开盘价为nan的赋为0
    position['open_price_faked'] = position['open_price'].fillna(0)
    position['lots'] = position['lots'].apply(lambda x: math.floor(x))
    position['account_realized'] = 100 * position['open_price_faked'] * position['lots']
    position['account_surplus'] = position['account'] - position['account_realized']

    return position
Ejemplo n.º 7
0
    'cir_mv_y': 'industry_total_sw1'
},
              inplace=True)

# 申万一级行业的比重*行业内部个股占整个行业的比重
result['weight_adj_sw1'] = result['industryweight_in_all'] * result[
    'weight_in_industry_sw1']
result['weight_adj_sw1'] = result['weight_adj_sw1'] / result[
    'weight_adj_sw1'].sum()

# 计算股票池的净值曲线
# 获得每只股票在回测期的日收益率(除权调整),累积日收益率数据
begin_date = '20160104'
end_date = "20190628"

data = get_data_panel("huangwei", "huangwei", list(result_top100mv['code']),
                      begin_date, end_date)
data_unlimited = get_data_panel("huangwei", "huangwei", list(result['code']),
                                begin_date, end_date)

dates = get_tradingdays("huangwei", "huangwei", begin_date, end_date)
dates = dates.rename(columns={'tradingdays': 'date'})
for i in range(len(dates)):
    dates['date'].iloc[i] = dates['date'].iloc[i][0:4] + '-' + \
                            dates['date'].iloc[i][4:6] + '-' + dates['date'].iloc[i][6:8]
df_group_data_limited = dates
df_group_data_unlimited = dates

# 限定在沪深300成分股内
for code in list(result_top100mv['code']):
    temp = data[data['code'] == code].reset_index(drop=True)
    unique_index = list(temp['date'].drop_duplicates(keep='first',
Ejemplo n.º 8
0
        if result_export:
            # 输出持仓信息
            export_result_(position, changeday, result_path, file_name1)

        # 记录当天的损益
        pnls, total_capitals = return_maker_(position, pnls, total_capitals,
                                             transaction_cost_rate)
        # last_stock_pool = stock_pool_class

    elif changeday != change_days[0] and changeday in change_days:  # 调仓日

        # 更新开盘价数据
        price = get_data_panel("huangwei",
                               "huangwei",
                               list(position['code']),
                               changeday,
                               changeday,
                               collection='stock_daily').drop_duplicates(
                                   ['code'])
        # 保存过去的持仓情况
        last_position = position
        if 'open' in last_position.columns:
            del last_position['open']
        if 'rtn' in last_position.columns:
            del last_position['rtn']
        last_position = last_position.merge(price[['code', 'open', 'rtn']],
                                            on='code',
                                            how='inner')
        last_position['open_price'] = last_position['open']
        last_position['close_price'] = last_position['open_price'] \
                                       * (1 + last_position['rtn'])
Ejemplo n.º 9
0
def industry_leader_maker_(cal_day, indicator, industry_weight, top_num,
                           index_for_simple_weight):
    """

    :param stock_info: 当下A股市场的所有股票名称、代码信息
    :param cal_day: 选股日期
    :param indicator: 选股时引入的财务指标,包括总市值(total_mv)、流通市值(circ_mv)
    :param industry_weight: 根据某指数,复制其行业权重。或者'market':按全市场行业权重
    :param top_num: 是否选择前几只
    :param index_for_simple_weight:对于按某指数成分简单赋权
    :return:
    """
    # 读取股票信息表
    stock_info = pd.read_excel(
        'C:/Users/Lenovo/PycharmProjects/my_project/frjj_codes/stock_info_20190801.xlsx'
    )

    stock_info = stock_info.dropna(axis=0, how='any').reset_index(drop=True)
    # 读取申万一级行业划分
    sw1 = sw_info_(cal_day, "sw1")
    sw1.rename(columns={'sw_name': 'sw1_name'}, inplace=True)
    # 读取申万三级行业划分
    sw3 = sw_info_(cal_day, "sw3")
    sw3.rename(columns={'sw_name': 'sw3_name'}, inplace=True)

    all = pd.DataFrame(columns=['code', 'code_name'],
                       index=range(len(stock_info)))
    all['code'] = stock_info['证券代码']
    all['code_name'] = stock_info['证券简称']
    all = all.merge(sw1[['code', 'sw1_code', 'sw1_name']],
                    on='code',
                    how='left')
    all = all.merge(sw3[['code', 'sw3_code', 'sw3_name']],
                    on='code',
                    how='left')

    # 使cal_day适应api
    cal_day = cal_day[0:4] + '-' + cal_day[4:6] + '-' + cal_day[6:8]
    # 直接从数据库收集股票的流通市值(或总市值)
    data = get_data_panel("huangwei",
                          "huangwei",
                          list(all['code']),
                          forwardchangeday2(cal_day),
                          forwardchangeday2(cal_day),
                          collection='stock_indicator')
    # 替换原表的cir_mv
    all = all.merge(data[['code', indicator]], on='code', how='left')
    all['cir_mv'] = all[indicator]
    del all[indicator]

    # 计算申万三级行业内部流通市值比例
    tot_industry = all.groupby('sw3_code').sum()

    tot_industry['sw3_code'] = tot_industry.index
    tot_industry = tot_industry.reset_index(drop=True)
    all = all.merge(tot_industry, on='sw3_code', how='inner')
    all['weight_in_industry'] = all['cir_mv_x'] / all['cir_mv_y']
    all.rename(columns={
        'cir_mv_x': 'cir_mv',
        'cir_mv_y': 'industry_total'
    },
               inplace=True)

    if industry_weight == 'market':
        # 获得全市场每个申万一级行业的比重
        tot_industry_sw1 = all.groupby('sw1_code').sum()
        tot_industry_sw1['sw1_code'] = tot_industry_sw1.index
        total_mv = tot_industry_sw1['cir_mv'].sum()
        tot_industry_sw1[
            'industryweight_in_all'] = tot_industry_sw1['cir_mv'] / total_mv
        tot_industry_sw1.index.name = 'sw1_codes'  # 更改level_name
        all = all.merge(tot_industry_sw1[['industryweight_in_all',
                                          'sw1_code']],
                        on='sw1_code',
                        how='inner')
    else:
        # 获得成分股中每个申万一级行业的比重
        zz500_weight = get_data_crosssection_genaral("huangwei", "huangwei",
                                                     "index_weight",
                                                     'index_code',
                                                     industry_weight)
        zz500_weight = zz500_weight[zz500_weight['date'] == list(
            zz500_weight['date'][zz500_weight['date'] >= cal_day])
                                    [0]].reset_index(drop=True)
        # 与成分股权重表匹配最接近的日期
        zz500_weight.rename(columns={'stock_code': 'code'}, inplace=True)

        # 获取中证500中成分股的申万一级行业信息及流通市值信息
        zz500_weight = zz500_weight.merge(all[['code', 'sw1_code', 'cir_mv']])
        tot_industry_sw1 = zz500_weight.groupby('sw1_code').sum()
        tot_industry_sw1['sw1_code'] = tot_industry_sw1.index
        total_mv = tot_industry_sw1['cir_mv'].sum()
        tot_industry_sw1[
            'industryweight_in_all'] = tot_industry_sw1['cir_mv'] / total_mv
        tot_industry_sw1.index.name = 'sw1_codes'  # 更改level_name
        all = all.merge(tot_industry_sw1[['industryweight_in_all',
                                          'sw1_code']],
                        on='sw1_code',
                        how='inner')

    # 添加申万三级行业总市值排名rank
    tot_industry = tot_industry.sort_values(
        by='cir_mv', ascending=False).reset_index(drop=True)
    tot_industry['rank'] = tot_industry.index + 1
    all = all.merge(tot_industry[['sw3_code', 'rank']],
                    on='sw3_code',
                    how='inner').sort_values(by='rank').reset_index(drop=True)
    # 追加行业个股数量字段
    count_industry = all.groupby('sw3_code').count()
    count_industry['indu_num'] = count_industry['code']
    count_industry['sw3_code'] = count_industry.index
    count_industry.index.name = 'sw3_codes'
    all = all.merge(count_industry[['sw3_code', 'indu_num']],
                    on='sw3_code',
                    how='inner')
    # 每个行业先保留前5个
    delete_list = []
    indu_list = list(all['sw3_code'].unique())
    for indu in indu_list:
        one_indu = all[all['sw3_code'] == indu]
        one_indu['global_index'] = one_indu.index
        if one_indu['indu_num'].iloc[0] > 5:
            one_indu = one_indu.sort_values(
                by='weight_in_industry',
                ascending=False).reset_index(drop=True)
            delete_list = delete_list + list(one_indu['global_index'].iloc[5:])

    top5_industry = all.drop(delete_list).reset_index(drop=True)
    top5_industry['ten_percent'] = round(top5_industry['indu_num'] * 0.1)

    delete_list = []
    for indu in indu_list:
        one_indu = top5_industry[top5_industry['sw3_code'] == indu]
        one_indu['global_index'] = one_indu.index
        if one_indu['ten_percent'].iloc[0] < 5:
            one_indu = one_indu.sort_values(by='weight_in_industry',
                                            ascending=False)
            one_indu_withoutbig = one_indu[
                one_indu['weight_in_industry'] < 0.2].reset_index(drop=True)
            if len(one_indu_withoutbig) > 0:
                remain_num = one_indu_withoutbig['ten_percent'].iloc[0] \
                             - (len(one_indu) - len(one_indu_withoutbig))
                if remain_num <= 0:
                    delete_list = delete_list + list(
                        one_indu_withoutbig['global_index'])
                else:
                    delete_list = delete_list + \
                                  list(one_indu_withoutbig['global_index'].iloc[int(remain_num):])

    result = top5_industry.drop(delete_list).reset_index(drop=True)

    if top_num == None:
        result_top100mv = result
    else:
        result_top100mv = result[result['rank'] <= top_num]

    # 按成分股权重对龙头加权
    hs300_weight = get_data_crosssection_genaral("huangwei", "huangwei",
                                                 "index_weight", 'index_code',
                                                 index_for_simple_weight)
    hs300_weight = hs300_weight[hs300_weight['date'] == list(
        hs300_weight['date'][hs300_weight['date'] >= cal_day])[0]].reset_index(
            drop=True)
    hs300_weight.rename(columns={'stock_code': 'code'}, inplace=True)

    # 与沪深300股票取交集
    result_top100mv = result_top100mv.merge(hs300_weight[['code', 'i_weight']],
                                            on='code',
                                            how='inner')
    weight_sum = result_top100mv['i_weight'].sum()
    result_top100mv['weight_adj'] = result_top100mv['i_weight'] / weight_sum

    # 不与指数取交集,按照申万一级行业划分计算权重
    tot_industry_sw1 = result.groupby('sw1_code').sum()
    tot_industry_sw1['sw1_code'] = tot_industry_sw1.index
    tot_industry_sw1 = tot_industry_sw1.reset_index(drop=True)
    result = result.merge(tot_industry_sw1[['sw1_code', 'cir_mv']],
                          on='sw1_code',
                          how='inner')
    result['weight_in_industry_sw1'] = result['cir_mv_x'] / result['cir_mv_y']
    result.rename(columns={
        'cir_mv_x': 'cir_mv',
        'cir_mv_y': 'industry_total_sw1'
    },
                  inplace=True)

    # 申万一级行业的比重*行业内部个股占整个行业的比重
    result['weight_adj_sw1'] = result['industryweight_in_all'] * result[
        'weight_in_industry_sw1']
    result['weight_adj_sw1'] = result['weight_adj_sw1'] / result[
        'weight_adj_sw1'].sum()

    # 还原cal_day
    # cal_day = cal_day[0:4] + cal_day[5:7] + cal_day[8:10]
    # file_name = 'result_' + cal_day + '.xls'
    # result.set_index('code').to_excel(file_name, encoding='utf-8')
    return result
for index, changeday in enumerate(change_days[:-2]):
    # 读入股票代码
    all_codes = pd.read_excel(
        'C:/Users/Lenovo/PycharmProjects/my_project/frjj_codes/result/industry_leader_df_md_80.xlsx',
        sheet_name=changeday)

    part_codes = pd.read_excel(
        'C:/Users/Lenovo/PycharmProjects/my_project/frjj_codes/result/industry_leader_df_md_50.xlsx',
        sheet_name=changeday)

    eighty_stock = set(all_codes['code'])
    fifty_stock = set(part_codes['code'])
    maybe_bad_stock = eighty_stock.difference(fifty_stock)
    all_data_fifty_stock = get_data_panel("huangwei",
                                          "huangwei",
                                          list(fifty_stock),
                                          changeday,
                                          change_days[index + 1],
                                          collection='stock_daily')
    all_data_fifty_stock['rtn'] += 1
    all_data_maybe_bad_stock = get_data_panel("huangwei",
                                              "huangwei",
                                              list(maybe_bad_stock),
                                              changeday,
                                              change_days[index + 1],
                                              collection='stock_daily')
    all_data_maybe_bad_stock['rtn'] += 1

    # 分组计算累计收益率
    fifty_stock_cum = all_data_fifty_stock.groupby(
        by=all_data_fifty_stock['code']).apply(
            lambda x: x['rtn'].cumprod().iloc[-1])
Ejemplo n.º 11
0
def factor_test(factor, types):
    # 导入股票名单和相应权重
    total_capitals = [10000000]
    pnls = []
    transaction_cost_rate = 0.003  # 交易费用
    factor_list = [factor]
    factor_type = [types]

    result_export = False  # 是否输出每天持仓信息
    ic_weighter = True  # 多因子是否按ic值加权平均
    include_ir = True
    orthogonalization = False

    if result_export:
        result_path = './result/'  # 当下根目录
        strategy_name = 'industry_leader'
        file_name1 = strategy_name + '_df_md_80.xlsx'

    # 获取所有调仓日
    start, end = '20180101', "20190801"
    change_days, my_tradingdays = get_time_data_(start, end)

    # 开始回测
    for changeday in tqdm(list(my_tradingdays['tradingdays'])):

        if changeday == change_days[0]:  # 建仓日

            # stock_pool = GD_location_maker_(changeday)
            stock_pool = leader_multifactor_maker(
                changeday,
                factor_list,
                factor_type,
                ic_weighter,
                include_ir=include_ir,
                orthogonalization=orthogonalization)
            # stock_pool = leader_factor_maker(changeday)

            # 持仓矩阵初始化
            position = position_init_(stock_pool, changeday, total_capitals)

            if result_export:
                # 输出持仓信息
                export_result_(position, changeday, result_path, file_name1)

            # 记录当天的损益
            pnls, total_capitals = return_maker_(position, pnls,
                                                 total_capitals,
                                                 transaction_cost_rate)
            # last_stock_pool = stock_pool_class
            # print(changeday, '开仓')

        elif changeday != change_days[0] and changeday in change_days:  # 调仓日

            # 更新开盘价数据
            price = get_data_panel("huangwei",
                                   "huangwei",
                                   list(position['code']),
                                   changeday,
                                   changeday,
                                   collection='stock_daily').drop_duplicates(
                                       ['code'])
            # 保存过去的持仓情况
            last_position = position
            if 'open' in last_position.columns:
                del last_position['open']
            if 'rtn' in last_position.columns:
                del last_position['rtn']
            last_position = last_position.merge(price[['code', 'open', 'rtn']],
                                                on='code',
                                                how='inner')
            last_position['open_price'] = last_position['open']
            last_position['close_price'] = last_position['open_price'] \
                                           * (1 + last_position['rtn'])
            # 按现在价格计算过去持仓的手数
            last_position['lots'] = last_position['account'] / (
                100 * last_position['open_price'])
            last_position['lots'] = last_position['lots'].fillna(
                0)  # 没有开盘价的股票被“冻结”
            last_position['lots'] = last_position['lots'].apply(
                lambda x: math.floor(x))

            # stock_pool = stock_select_(changeday)
            # stock_pool, stock_pool_class = leader_moderate(changeday, last_stock_pool, 0.02)
            stock_pool = leader_multifactor_maker(
                changeday,
                factor_list,
                factor_type,
                ic_weighter,
                include_ir=include_ir,
                orthogonalization=orthogonalization)
            # stock_pool = leader_factor_maker(changeday)
            # stock_pool = GD_location_maker_(changeday)

            # 持仓初始化
            position = position_init_(stock_pool, changeday, total_capitals)

            position, adj_pnl = position_manager(changeday, last_position,
                                                 position,
                                                 transaction_cost_rate)

            pnls.append(adj_pnl)
            # 记录总价值
            total_capitals.append(total_capitals[-1] + adj_pnl)
            # 更新每只股票的总市值
            position['account_realized'] = position['account_realized'] * (
                1 + position['rtn'])
            position['account'] = position['account_realized'] + position[
                'account_surplus']

            if result_export:
                # 输出持仓信息
                export_result_(position, changeday, result_path, file_name1)

            # last_stock_pool = stock_pool_class
            # print(changeday, '换仓')
        else:
            # 非调仓日
            # 更新价格数据
            position['date'] = changeday
            price = get_data_panel("huangwei",
                                   "huangwei",
                                   list(position['code']),
                                   changeday,
                                   changeday,
                                   collection='stock_daily').drop_duplicates(
                                       ['code'])
            if 'open' in position.columns:
                del position['open']
            if 'rtn' in position.columns:
                del position['rtn']

            position = position.merge(price[['code', 'open', 'rtn']],
                                      on='code',
                                      how='left')
            position['open_price'] = position['open']
            position['close_price'] = position['open_price'] * (
                1 + position['rtn'])

            # 计算当日持仓(可能不是正确值,因为open价格未经调整,但可以作为一个基准计算合理的收益率)
            position['account_realized'] = 100 * position[
                'open_price'] * position['lots']
            # 记录当天的损益
            temp = position.dropna(axis=0)
            pnl = (temp['close_price'] / temp['open_price'] -
                   1) * temp['account_realized']
            pnls.append(pnl.sum())
            # 记录总价值
            total_capitals.append(total_capitals[-1] + pnl.sum())
            # 更新每只股票的总市值
            position['account_realized'] = position['account_realized'] * (
                1 + position['rtn'])
            position['account'] = position['account_realized'] + position[
                'account_surplus']

            # if result_export == True:
            #     # 输出持仓信息
            #     export_result_(position, changeday, result_path, file_name1)
            # print(changeday, '持仓')

    # 累计总价值曲线(与指数累计收益曲线作对比)
    banchmark = "000300.SH"
    returns = np.array(total_capitals)[1:] / np.array(total_capitals)[0]
    hs300 = get_data_panel(
        "huangwei",
        "huangwei",
        [banchmark],  # 对标指数
        my_tradingdays['tradingdays'].iloc[0],
        my_tradingdays['tradingdays'].iloc[-1],
        collection='index_rtn')
    hs300['cum_chg'] = hs300['pct_chg'] / 100 + 1
    hs300['cum_chg'] = hs300['cum_chg'].cumprod().values
    extra = returns[:, np.newaxis] - hs300['cum_chg'].values[:, np.newaxis]
    performance_(hs300, banchmark, returns, extra, factor_list[0], 'spyl')
    return total_capitals