【中金固收·可转债】转债基金择时、择券能力如何区分?—— 及Python实现方法 20190729

论坛 期权论坛 期权     
中金固定收益研究   2019-9-8 06:51   6314   0
作者
  分析员,SAC执业证书编号:S0080515120002   SFC CE Ref: BOM868
吴若磊联系人,SAC执业证书编号:S0080119030020
陈健恒分析员,SAC执业证书编号:S0080511030011; SFC CE Ref: BBM220


转债基金择时、择券能力如何区分[quote]在转债周报《这半年,谁的择时精准,谁的择券有效》中,我们讨论了转债基金的择时、择券能力。我们在该周报也进行了简短的介绍,当然其中一个假设是没有多少投资者对这个业绩拆分的过程感兴趣。不过虽然与我们讨论程序实现方法的投资者比意料中多,我们在本专题中进行专门介绍。
基础模型实际很简单。我们采用了认可度比较高,又有着诸多其他优点(后面会详细说)的CL模型。基础框架如下:
Rp - Rf = alpha + beta1 * min(Rm - Rf, 0) + beta2 *max(Rm - Rf, 0) + e
几点解释:
1、实际这个式子没有比CAPM复杂很多,只是把Rm - Rf再拆分成“下跌”和“上涨”两种状态,分别对应beta1和beta2两个敏感系数。所以在这里,alpha 显著大于0,则可以认为是有择券效果,而在beta2 > 0的情况下,beta2 - beta1比较大,说明基金能在上涨和下跌阶段,体现出不同的beta值来。最理想的情况莫过于beta2很大,beta1接近0 —— 这就是一般情况下说的精准逃顶了;
2、但alpha和beta仍然不能完全被拆分开,比如有的品种就是拥有超大的Beta值,包括券商转债、某些情况下的周期转债(例如之前的三一、有色品种)以及溢价率很低的银行转债。再如,有的品种就是有很强的不对称性,例如诸多低估值品种,跌已无太多空间,而涨却也无溢价来压制弹性,最终以择券的形式,产出的择时的效果 —— 这也是模型无能为力的方面;
3、Rf怎么选一直是个问题,国开债收益率、企业债收益率都是个办法。不过实际还是基金倾向于拿哪一类当 “债”,哪一类就更合适(历史上或许是城投,最近来看基金更愿意拿利率债)。所以有一个还算稳定的方法是:用不拿转债\股票的长债基金收益率 —— 当然用哪个都不是重点;
4、这始终是个归因模型,不是测仓位手段,所以无论beta1还是beta2都与 “仓位”这个概念有差异。无论如何,这里讨论的是实际效果,或者 “有效仓位”的概念,不必纠结于实际仓位是多少 —— 满仓特发和满仓山高EB效果自然是不一样的。
下面进入实现的流程。在确定基金研究范围的情况下,我们需要的其实只是以下这些数据:基金调整后净值、转债指数、长债基金指数。我们还是用class将这些数据的初始化、获取、处理和最终的计算封装,初始化部分如下。里面涉及到_fetchAdjNav、_fetchCBIndex和_fetchBondIndex这三个私用函数(在私用函数前加一个"_",以区别于公用函数)。以及,self.dfNav = self.dfNav.reindex(columns=codes)这句是利用pandas中的reindex来对表格的列进行重排,比较好理解。最后会得到.dfNav和.dfIndex两个pandas下的DataFrame,分别是净值和转债、债基指数的表。
import pandas as pd
from sklearn.linear_model import LinearRegression

class fundAttr(object):
   
    '''写文档是美德
    初始化输入为:codesstartend,字面意思   
    '''
   
    def __init__(self,codes,start,end):
      
       self.codes=codes
       self.start=start
       self.end=end
      
       self.dfNav=self._fetchAdjNav()
       self.dfNav=self.dfNav.reindex(columns=codes)
      
       self.dfIndex=pd.DataFrame(index=self.dfNav.index,columns=['CB','BOND'])
      
       self.dfIndex['CB']=self._fetchCBIndex()
       self.dfIndex['BOND']=self._fetchBondIndex()
下面是_fetchAdjNav、_fetchCBIndex和_fetchBondIndex这三个私用函数,比较好理解,不用解释。有一些做法则是习惯的问题,比如df.sort_index(inplace=True)这句不一定要加,如果习惯于在sql的最后一句加上"order bytradedate"的话。以及,其实如果做对外接口的话,没有必要做三个函数,而是一个就够了,这里面存在有待商榷的地方。
    def _fetchAdjNav(self, method='sql'):
      
            if method =='sql':
            #这是sql版本
                   sql ='''select a.f_info_windcode windcode,

                   a.price_datetradedate,
                   a.f_nav_adjustednav

           
            from winddf.chinamutualfundnava
           
            where
            a.f_info_windcodein({_codes}) and
            a.price_date>={_start} and
            a.price_date={_start} and
            a.trade_dt ={_start} and
            a.trade_dt
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:170
帖子:39
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP