V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
datayes2015
V2EX  ›  Python

如何利用因子模板测定因子生成的α策略是否稳定有效

  •  
  •   datayes2015 · 2016-09-13 14:39:30 +08:00 · 2511 次点击
    这是一个创建于 3027 天前的主题,其中的信息可能已经有所发展或是发生改变。
    本篇给出了一个分析因子分布情况、 Rank IC 序列、分位组合表现、分行业分位组合表现的模板,希望通过这一流程大体认识因子的基本特征、以及因子生成的α策略是否稳定和有效。

    因子分析模板

    优矿的因子库中提供了 400 多个因子,大概可以分为估值与市值类因子、偿债能力和资本结构类因子、分析师预期类因子、均线型因子、成交量型因子、成长能力类因子、每股指标因子、现金流指标因子、盈利能力和收益质量类因子、能量型因子、营运能力类因子、超买超卖型因子、趋势型因子这 13 类。

    α我所欲也,省事亦我所欲也。想要省事地构造α策略,从 200 多个因子中找出有效因子,一个合适的因子分析模板就显得不可或缺。最理想的状态莫过于此:输入一个所关心的因子的名字,模板乖乖报出因子的基本信息、行业分布、历史表现、(在某时段)是否能提供α...

    这里我做了一个尝试,建立 factorAnalyseMachine 类,力图采用一种模板化的方式让人尽快认识一个因子。

    分析流程
    给定因子名称、日期、股票池、时间间隔,初始化 factorAnalyseMachine 类的一个 object.

    类中提供接口:

    describeFactor(self, winsor = True, neutral = False, standard = False):给出因子在给定日期和股票池内的分布情况,并给出因子与一个基础因子组合的相关性。如果 winsor 为 True ,则给出的分布情况是对因子进行 winsorize 去极值化处理之后的,如果 neutral 为 True ,则对因子进行行业中性化处理,如果 standard 为 True ,则对因子进行标准化;

    displayIndustryDist(self, winsor = True, neutral = False, standard = False):给出因子在给定日期中,在各个行业的 20%分位数、中位数与 80%分位数图像;

    displayCorrTime(self, figsize = (16,6)):给出 2016 年初以来,指定时间间隔与股票池内因子与股票收益的秩相关系数的时间序列图像,即因子的 Rank IC.

    QuantileBt(self, beginQuantile = 0, endQuantile = 0.2, dropNegtive = False, start = '2014-01-01', end = '2016-08-13', benchmark = 'HS300', universe = set_universe('A', '2014-01-01'), capital_base = 3000000, freq = 'd', refresh_rate = 20, winsor = True, neutral = True, standard = True):

    1 、形成策略:每次调仓时买入因子值位于分位数范围内的股票
    2 、快速回测,返回回测 bt 与 perf
    3 、如果 dropNegtive 为 True ,表明在筛选分位数范围内股票时,去除因子值为负数的股票(在研究 PE 等可能为负值的因子时可以用到)
    multiQuantileBt(self, group = 5, dropNegtive = False, start = '2014-01-01', end = '2016-08-13', benchmark = 'HS300', universe = set_universe('A', '2014-01-01'), capital_base = 3000000, freq = 'd', refresh_rate = 20, winsor = True, neutral = True, standard = True):

    1 、根据组数 group ,确定多个分位点,对于每一段分位点快速回测 2 中策略
    2 、形成策略:每次调仓时买入因子值位于分位数范围内的股票
    3 、返回各分位段 bt 与 perf 的字典
    industryQuantileBt(self, beginQuantile = 0, endQuantile = 0.2, dropNegtive = False, start = '2014-01-01', end = '2016-08-13', benchmark = 'HS300', universe = set_universe('A', '2014-01-01'), capital_base = 3000000, freq = 'd', refresh_rate = 20, winsor = True, neutral = True, standard = True):

    与 QuantileBt 类似,不过筛选股票时是在各个行业内筛选因子值位于指定分位点内的股票
    industryMultiQuantileBt(self, group = 5, dropNegtive = False, start = '2014-01-01', end = '2016-08-13', benchmark = 'HS300', universe = set_universe('A', '2014-01-01'), capital_base = 3000000, freq = 'd', refresh_rate = 20, winsor = True, neutral = True, standard = True):

    与 industryMultiQuantileBt 类似,不过筛选股票时是在各个行业内筛选因子值位于指定分位点内的股票

    示例 - ROA
    以 ROA 因子为例展示模板
    高清源代码请移步: https://uqer.io/community/share/57b574eb228e5b79a2758ff9

    初始化 ROA 因子分析类,默认日期为两个工作日前,默认股票池为两个工作日前的全 A 股,默认时间间隔 10 工作日。

    给出 ROA 在 A 股中分布情况以及与基础因子池的相关性情况:在 A 股中有少数公司 ROA 值为负,其余公司 ROA 值基本显示幂律分布特点; ROA 与 5 年收益增长率(EGRO)、基本每股收益(EPS)等因子有显著正相关关系。

    FactorAnalyser = factorAnalyseMachine('ROA')
    corrBench = FactorAnalyser.describeFactor(winsor = True, neutral = False, standard = False)
    图片链接: https://uqer.io/community/share/57b574eb228e5b79a2758ff9

    给出因子在不同行业分布情况:传媒行业 ROA 值相对最高,钢铁、采掘行业 ROA 值最低。这也给我们一些提示,在全 A 股中选 ROA 比较大的股票可能会对传媒、医药生物等行业有较大的暴露度。

    FactorAnalyser.factorIndustryDist(winsor = True, neutral = False, standard = False)
    FactorAnalyser.displayIndustryDist()
    图片链接: https://uqer.io/community/share/57b574eb228e5b79a2758ff9

    现在运用以下黑科技 —— neutralize. 下图提供了 neutralize 后因子的分布情况,可见因子在各个行业的中位数基本都被标准化到 0 附近,分布也大致对称,之后的分位数选股回测中,也可以利用 neutralize 避免行业集中。进一步,也可以用 standardize 再对因子进行正态化处理。



    ROA 因子 Rank IC 随时间变化情况如下图所示:可见,因子与股价之间的相关性并不稳定,近期有负相关的表现。


    从经济的意义上看, ROA 越大公司的股票越有持有价值,因此考虑持有 ROA 最高 20%股票的策略:可见策略比 HS300 组合表现略强,α为 17.5%,但最大回撤较高,表现不够稳定。

    选股前可以利用通联 RDP 中 winsorize 、 neutralize 、 standardize 方法预处理因子值。





    接下来考虑 ROA 在不同分位组别的股票组合表现,分为 5 个组别:

    可见 ROA 最高的股票有明显较好的表现

    序关系不够稳定, ROA 最低的组合也有较好表现

    2016 年以来 ROA 最高组合相对 HS300 表现不错,对冲后年化收益 58.7%,最大回撤 8.1%,波动率 23.4%

    quansBt,quansPerf = FactorAnalyser.multiQuantileBt(group = 5,
    dropNegtive= True, start = '20160101', end = '20160810',universe = set_universe('A','20160101'), refresh_rate= 20,
    winsor = True, neutral = True, standard = True)




    上面的回归中使用了原本的 neutralize 方法解决可能的行业集中问题,同样,也可以考虑直接从不同行业选股来解决这一问题。

    考虑分别在不同行业中选取相应分位数股票进行回测,这样更能体现因子本身的有效性。

    可见选取各行业内 ROA 值最大 20%的股票这一策略从 2016 年来相对 HS300 表现较差,相对收益为负。





    再考虑不同行业内 ROA 各分位水平股票组合的表现:

    ROA 低的股票组合表现反而更好

    分位数组合表现的序关系混乱

    这表明 ROA 可能并不是稳定的α因子



    总结
    本篇给出了一个分析因子分布情况、 Rank IC 序列、分位组合表现、分行业分位组合表现的模板,希望通过这一流程大体认识因子的基本特征、以及因子生成的α策略是否稳定和有效。

    为了让模板更加强大,希望之后能引入更多功能,包括但不限于:

    加入因子打分体系,方便不同因子之间对比:在某时段,因子的行业均衡分(也可以各行业分开)、回测表现分(超额收益、最大回撤、波动性)、 Rank IC 稳定分、分位组合序关系稳定分

    分析模板应该适应组合加权因子、甚至自定义因子

    与归因模块融合,进一步剖析因子分位数组合的回测表现
    7 条回复    2016-10-20 17:20:18 +08:00
    doublleft
        1
    doublleft  
       2016-09-13 14:49:50 +08:00   ❤️ 4
    upczww
        2
    upczww  
       2016-09-13 15:03:50 +08:00 via Smartisan T1
    v 站什么时候变期刊了。
    RuyiYin
        3
    RuyiYin  
       2016-09-13 15:44:30 +08:00
    优矿实力广告
    vigoss
        4
    vigoss  
       2016-09-19 11:20:18 +08:00
    长期运营软广账号是否符合规范?@Livid
    Troevil
        5
    Troevil  
       2016-09-19 11:51:57 +08:00
    server
        6
    server  
       2016-09-27 15:03:50 +08:00
    tmd 能不发吗
    datayes2015
        7
    datayes2015  
    OP
       2016-10-20 17:20:18 +08:00
    Anyway
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2829 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:11 · PVG 22:11 · LAX 06:11 · JFK 09:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.