[关闭]
@Channelchan 2018-10-17T21:02:11.000000Z 字数 7174 阅读 75841

因子分析(by+alphalens)

目录

  1. Alphalens是什么?
  2. 使用Alphalens的数据准备工作?
  3. 如何用Alphalens测试选股因子效果?
  4. 什么是信息系数?
  5. 如何通过信息系数的可视化呈现进一步观测因子效果?
  6. 更多:因子在不同板块的选股能力比较分析

Alphalen是什么?

Alphalens是一个Python第三方库,专门用于选股因子alpha(α)的绩效分析。

下载方式: pip install alphalens==0.2.1

官方网站: http://quantopian.github.io/alphalens/index.html

使用Alphalens的数据准备工作?

下面以沪深300成分股为例,构造选股因子(factor)并

  1. from jaqs_fxdayu.data import DataView # 可以视为一个轻量级的数据库,数据格式基于pandas,方便数据的调用和处理
  2. from jaqs_fxdayu.data import RemoteDataService # 数据服务,用于下载数据
  3. import os
  4. import warnings
  5. warnings.filterwarnings("ignore")
  6. dataview_folder = '../Factor'
  7. if not (os.path.isdir(dataview_folder)):
  8. os.makedirs(dataview_folder)
  9. # 数据下载
  10. def save_dataview():
  11. data_config = {
  12. "remote.data.address": "tcp://data.quantOS.org:8910",
  13. "remote.data.username": "18566262672",
  14. "remote.data.password": "eyJhbGciOiJIUzI1NiJ9.eyJjcmVhdGVfdGltZSI6IjE1MTI3MDI3NTAyMTIiLCJpc3MiOiJhdXRoMCIsImlkIjoiMTg1NjYyNjI2NzIifQ.O_-yR0zYagrLRvPbggnru1Rapk4kiyAzcwYt2a3vlpM"
  15. }
  16. ds = RemoteDataService()
  17. ds.init_from_config(data_config)
  18. dv = DataView()
  19. props = {'start_date': 20140101, 'end_date': 20140201, 'universe': '000300.SH',
  20. 'fields': "pb,pe,ps,float_mv,sw1",
  21. 'freq': 1}
  22. dv.init_from_config(props, ds)
  23. dv.prepare_data()
  24. dv.save_dataview(dataview_folder) # 保存数据文件到指定路径,方便下次直接加载
  25. # save_dataview()
  1. # 加载数据
  2. dv = DataView()
  3. dv.load_dataview(dataview_folder)
Dataview loaded successfully.
  1. dv.fields
  ['low_adj',
 'index_weight',
 'ps',
 'index_member',
 'close_adj',
 'high_adj',
 'sw1',
 'float_mv',
 'high',
 'open_adj',
 'vwap_adj',
 'pb',
 'open',
 'pe',
 'vwap',
 'close',
 'adjust_factor',
 'low',
 'trade_status']
  1. import pandas as pd
  2. from datetime import datetime
  3. factor = dv.get_ts("pb")
  4. factor.index = pd.Index(map(lambda x: datetime.strptime(str(x),"%Y%m%d") , factor.index)) #索引调整为datetime日期格式
  5. factor = factor.stack()#处理成MultiIndex格式(alphalens分析因子必须的格式)
  6. factor.head()
            symbol   
2014-01-02  000001.SZ    1.0563
            000002.SZ    1.2891
            000008.SZ    4.8981
            000009.SZ    3.5794
            000012.SZ    2.3725
dtype: float64
  1. def change_index(df):
  2. df.index = pd.Index(map(lambda x: datetime.strptime(str(x),"%Y%m%d") , df.index)) #索引调整为datetime日期格式
  3. return df
  1. prices = dv.get_ts("close_adj") #获取价格
  2. prices = change_index(prices)
  3. prices.head()
symbol 000001.SZ 000002.SZ 000008.SZ 000009.SZ 000012.SZ 000024.SZ 000027.SZ 000039.SZ 000046.SZ 000059.SZ ... 601998.SH 603000.SH 603160.SH 603288.SH 603699.SH 603799.SH 603833.SH 603858.SH 603885.SH 603993.SH
2014-01-02 685.432796 869.28004 54.679500 57.244120 155.894015 97.545898 45.840241 348.968736 130.848969 7.635187 ... 4.617178 79.318951 NaN NaN NaN NaN NaN NaN NaN 6.541196
2014-01-03 668.619236 852.96064 54.375725 55.721670 153.407362 95.883723 44.750802 354.379104 128.507153 7.359216 ... 4.545408 78.055589 NaN NaN NaN NaN NaN NaN NaN 6.438347
2014-01-06 654.047484 813.79408 51.702505 55.234486 144.799717 90.754728 43.745166 342.656640 126.458064 7.006587 ... 4.473638 77.762489 NaN NaN NaN NaN NaN NaN NaN 6.191510
2014-01-07 651.805676 808.35428 50.973445 55.112690 144.034593 88.760118 43.577560 353.026512 124.408975 6.883933 ... 4.461677 79.743441 NaN NaN NaN NaN NaN NaN NaN 6.191510
2014-01-08 659.091552 807.26632 50.001365 54.138322 143.652031 86.338093 44.080378 351.448488 126.165337 6.853270 ... 4.473638 81.865890 NaN NaN NaN NaN NaN NaN NaN 6.098946

5 rows × 472 columns

  1. import alphalens
  2. #计算目标股票池每只股票的持有期收益,和对应因子值的quantile分类
  3. factor_data = alphalens.utils.get_clean_factor_and_forward_returns(factor, prices, quantiles=5, periods=(1,5,10))
  4. factor_data.head()
1 5 10 factor factor_quantile
date asset
2014-01-02 000001.SZ -0.024530 -0.033524 -0.044154 1.0563 1
000002.SZ -0.018773 -0.066333 -0.100125 1.2891 2
000008.SZ -0.005556 -0.102222 -0.054444 4.8981 4
000009.SZ -0.026596 -0.075532 -0.057447 3.5794 4
000012.SZ -0.015951 -0.093252 -0.039264 2.3725 3

如何用Alphalens测试选股因子效果?

  1. import matplotlib.pyplot as plt
  2. mean_return_by_q, std_err_by_q = alphalens.performance.mean_return_by_quantile(factor_data, by_date=True, demeaned=True)
  3. alphalens.plotting.plot_cumulative_returns_by_quantile(mean_return_by_q, 1)
  4. alphalens.plotting.plot_cumulative_returns_by_quantile(mean_return_by_q, 5)
  5. alphalens.plotting.plot_cumulative_returns_by_quantile(mean_return_by_q, 10)
  6. plt.show()

output_11_0.png-115.9kB
output_11_1.png-88.8kB
output_11_2.png-81.5kB

什么是信息系数?

度量变量的预测值与实际值之间的相关关系。信息系数是用来评估金融分析师预测技能的一种表现方法。

系数在-1到1之间,越大表示正相关程度强。

这里,我们可以用信息系数来评价一个选股因子效力的好坏。也即,用因子值大小与下一期股票收益大小的相关程度来评估因子。

经验来看,通常|mean(IC)|>0.02可以作为判定一个选股因子有收益预测效力的标准

什么是spearman相关系数?

chart1.png-3.4kB
其中d为秩次差。

什么是秩次差?

A = [1,3,5,7,9]
B = [3,2,4,5,1]

A的排序是1,2,3,4,5

B的排序是3,2,4,5,1

d为排序相减

chart2.png-2.4kB

chart3.png-3.4kB

接下来我们要计算的因子IC值,即为当期因子值与下期股票收益值的spearman相关系数。

  1. ic = alphalens.performance.factor_information_coefficient(factor_data)
  2. ic.head()
1 5 10
date
2014-01-02 0.325364 0.372408 0.346461
2014-01-03 0.094661 0.233455 0.287933
2014-01-06 0.211379 0.156397 0.210309
2014-01-07 0.375963 0.150975 0.144572
2014-01-08 -0.029050 0.167510 0.014627

如何通过信息系数的可视化呈现进一步观测因子效果?

  1. alphalens.plotting.plot_ic_hist(ic) #因子IC分布
  2. alphalens.plotting.plot_ic_ts(ic) #因子IC时间序列曲线
  3. plt.show()

output_16_0.png-43.1kB

output_16_1.png-336.8kB

  1. # 月均IC热度图
  2. mean_monthly_ic = alphalens.performance.mean_information_coefficient(factor_data, by_time='M')
  3. alphalens.plotting.plot_monthly_ic_heatmap(mean_monthly_ic)#因子月均IC表现
  4. plt.show()

output_17_0.png-46.5kB

将Quantile1的选股结果保存成excel

  1. import numpy as np
  2. excel_data = factor_data[factor_data['factor_quantile']==1]["factor_quantile"].unstack().replace(np.nan, 0)
  3. excel_data.to_excel('./pb_quantile_1_by_alphalens.xlsx')
  4. excel_data.head()
asset 000001.SZ 000002.SZ 000024.SZ 000027.SZ 000039.SZ 000059.SZ 000063.SZ 000069.SZ 000157.SZ 000338.SZ ... 601898.SH 601901.SH 601918.SH 601939.SH 601985.SH 601988.SH 601991.SH 601992.SH 601997.SH 601998.SH
date
2014-01-02 1.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0 ... 1.0 0.0 1.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
2014-01-03 1.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0 ... 1.0 0.0 1.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
2014-01-06 1.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0 ... 1.0 0.0 1.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
2014-01-07 1.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0 ... 1.0 0.0 1.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0
2014-01-08 1.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0 ... 1.0 0.0 1.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0

5 rows × 192 columns

更多:因子在不同板块的选股能力比较分析

  1. sectors = dv.get_ts("sw1")
  2. sectors = change_index(sectors)
  3. sectors.head()
symbol 000001.SZ 000002.SZ 000008.SZ 000009.SZ 000012.SZ 000024.SZ 000027.SZ 000039.SZ 000046.SZ 000059.SZ ... 601998.SH 603000.SH 603160.SH 603288.SH 603699.SH 603799.SH 603833.SH 603858.SH 603885.SH 603993.SH
2014-01-02 银行 房地产 休闲服务 综合 建筑材料 房地产 公用事业 机械设备 房地产 化工 ... 银行 传媒 电子 食品饮料 机械设备 有色金属 轻工制造 医药生物 交通运输 有色金属
2014-01-03 银行 房地产 休闲服务 综合 建筑材料 房地产 公用事业 机械设备 房地产 化工 ... 银行 传媒 电子 食品饮料 机械设备 有色金属 轻工制造 医药生物 交通运输 有色金属
2014-01-06 银行 房地产 休闲服务 综合 建筑材料 房地产 公用事业 机械设备 房地产 化工 ... 银行 传媒 电子 食品饮料 机械设备 有色金属 轻工制造 医药生物 交通运输 有色金属
2014-01-07 银行 房地产 休闲服务 综合 建筑材料 房地产 公用事业 机械设备 房地产 化工 ... 银行 传媒 电子 食品饮料 机械设备 有色金属 轻工制造 医药生物 交通运输 有色金属
2014-01-08 银行 房地产 休闲服务 综合 建筑材料 房地产 公用事业 机械设备 房地产 化工 ... 银行 传媒 电子 食品饮料 机械设备 有色金属 轻工制造 医药生物 交通运输 有色金属

5 rows × 472 columns

  1. factor_data = alphalens.utils.get_clean_factor_and_forward_returns(factor,
  2. prices,
  3. groupby=sectors.stack(),
  4. quantiles=5,
  5. periods=(1, 5, 10))
  1. factor_data.head()
1 5 10 factor group factor_quantile
date asset
2014-01-02 000001.SZ -0.024530 -0.033524 -0.044154 1.0563 银行 1
000002.SZ -0.018773 -0.066333 -0.100125 1.2891 房地产 2
000008.SZ -0.005556 -0.102222 -0.054444 4.8981 休闲服务 4
000009.SZ -0.026596 -0.075532 -0.057447 3.5794 综合 4
000012.SZ -0.015951 -0.093252 -0.039264 2.3725 建筑材料 3
  1. ic_by_sector = alphalens.performance.mean_information_coefficient(factor_data, by_group=True)
  2. ic_by_sector.head()
1 5 10
group
交通运输 -0.054600 -0.076287 -0.101861
休闲服务 -0.008219 -0.047374 -0.066913
传媒 -0.034612 -0.043479 -0.047153
公用事业 -0.029263 -0.038912 -0.046744
农林牧渔 -0.023074 -0.033296 -0.043930
  1. from matplotlib import pyplot as plt
  2. alphalens.plotting.plot_ic_by_group(ic_by_sector)
  3. plt.show()

output_25_0.png-12kB

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注