资料来源:万得资讯,中金公司研究部
问题就在,分析师覆盖度是历史上对转债后续走势,较为无关紧要的因子—— 这里并不意味着一定要买入低覆盖度的券,
我们的意思是,结合成交量来看,转债市场上的投资者注意力已经比较涣散,定价系统处于非全负荷工作的状态,这就意味着相对低估值的做法应有回报。
有意思的是,近期也有一些投资者询问,到底“低估”策略应该怎样去做——毕竟已经经历过去年年底,那段真正“便宜没好券”的行情。
我们的一些理解:
1、低估不等于低价。
即便考虑去年那种情况,低估也总比高估强,参考下图。测算也支持的结论是,低估是偶尔出状况,而高估是一直在跑输——要考虑的只是补齐短板,比如加入趋势、退市风险或者成长性等方面的考虑。其中一个“特效”的方法,就是加入对高退市概率券的剔除,这也是我们写《转债退市风险测算与Python实现》的意义所在;
“双高”测验:价格与溢价率的综合排名
资料来源:万得资讯,中金公司研究部,数据摘自上周周报
2、我们对简单方法已经做过很多测算,包括双分位数法、双排名法和隐含波动率法。
其中:1)双分位数法即选择价格和溢价率都在全市场某个分位数或某个值以下的品种——这也是两年前我们提出EasyBall时的做法;2)双排名法即对转债的价格和溢价率分别从小到大排名,再加总得到总排名,最后选择“总排名”靠前的;3)隐含波动率更为简单,选择隐含波动率较低的一部分转债即可。
这里我们不再重复一些过程和测算,投资者可见去年的《转债策略库及测试》以及更早的《转债也能做多因子吗?——附简易Python框架》。
结论就是:考虑换仓、风格分布和参数敏感性等,双排名法是最为稳健、效果也最好的方法,这也是我们自己后来更多高阶策略的基础。
简易“低估值”方法比较(单位为%)
资料来源:万得资讯,中金公司研究部,数据摘自2020年《转债策略库及测试》报告
我们当然有一些“高门槛”的方法,在此也做一个介绍。
首先,此前几个简单方法都面临一个问题是,如果一味地去选“低估值”,就忽略了不同类型个券的禀赋问题:比如有时会更多地选小票,比如有时会更多地选正股趋势比较差的券——
选了“低估值”的同时,也无意中给了组合一些风格偏向,这也是此前出问题的主因。
实际上,我们不妨承认,不同类型的转债估值本应不同,如果我们去选“同类”转债中定价偏低的,就避免了上面这个问题。
例如当下,我们可以把转债分成三类:1)分析师覆盖度大于等于6的——6家以上给出买入或增持建议;2)分析师覆盖度小于6且正股过去60日下跌的;3)分析师覆盖度小于6且正股过去60日上涨的。在“平价——溢价率”平面上,上述三组会如下图分布。
转债分组平价、溢价率
资料来源:万得资讯,中金公司研究部
于是,理论上我们可以对上述三组分别拟合平价、溢价率关系曲线(以溢价率为y,以平价为x,y = a + bx + c/x + d x^2),
然后选择溢价率在该曲线下方的,就可以实现前述目标——选同类中被低估的,而非估值最低的。
但是,分组标准并非始终如一,这样做也要牺牲掉效率。这里我们要借用更早前在《新券定位:方法、边际变化与python实现》(2019年11月)中的方法:
对每一个个券,按照其关键属性——例如市值、分析师覆盖、成长性、技术指标——寻找其在转债中的“最近邻”,即与其最相近的若干个券。然后用“最近邻”的平价、溢价率拟合一个曲线,并以此计算该个券高估、低估的程度z。最后,我们选择z值较低的若干品种,形成策略。因此,整个实现过程多
基于《新券定位:方法、边际变化与python实现》中介绍过的方法,只是当时的方法仅针对个券,此处我们要计算所有个券及其z值,因此我们需要对一些函数进行改造,如下面函数所示。
当然也都非常简单,没有特别需要提示注意的地方。
前述方法需要改造的函数
def
neighborsCbGroups
(codes, date)
:
# 寻找紧邻的函数,方法类似Knn
df1 = getIssueAndConvValueGroup(codes, date)
#取转债发行额、日期与平价
df2 = getStockFactor(codes, date)
# 取正股因子,都请见《新券定价》
dfCampareData = pd.concat([df1,df2],axis=
1
)
dfCampareData[
u'规模'
] = dfCampareData[
u'规模'
].apply(
lambda
x: pd.np.log(x))
dfCampareData.dropna(inplace=
True
)
dfZ = (dfCampareData - dfCampareData.mean()) / dfCampareData.std()
dictRet = {}
for
newSec
in
codes:
srsDistance = (dfZ - dfZ.loc[newSec]).apply(
lambda
x: x **
2
).sum(axis=
1
)
k = int(min([max([
6
, pd.np.floor(len(codes) /
10.0
)]), pd.np.floor(len(codes) /
2.0
),
18
]))
lstRet = list(srsDistance.sort_values().index[
1
:k])
dictRet[newSec] = {
"lstRet"
: lstRet,
"df"
: dfCampareData.loc[lstRet]}
return
dictRet
def
olsForGroup
(dfKnnData, conv)
:
# 拟合曲线并返回定价的函数,需要近邻列表和平价值
dfKnnData[
'ones'
] =
1.0
dfKnnData[
'1/conv'
] =
1.0
/ dfKnnData[
"conv"
]
lr = LinearRegression(fit_intercept=
False
)
lr.fit(dfKnnData.loc[:,[
'ones'
,
'conv'
,
'1/conv'
]].values, dfKnnData[
'prem'
].values)
coef = lr.coef_
return
conv * (
1
+ (coef[
0
] + coef[
1
] * conv + coef[
2
] / conv) /
100.0
), lr.coef_
资料来源:万得资讯,中金公司研究部
随后,我们便可将前述操作封装入class对象以便调用。其中,groupValuation.ret中的“diff”即为估价价差,我们选择较小者。
Class对象:估值拟合与价差
class
groupValuation
(
object
):
def
__init__
(
self
, codes, date)
:
# 输入样本券、日期即可
self
.codes,
self
.date= codes, date
self
.knn()
# 寻找近邻
self
.getXY()
# 取平价和溢价率数据,见《新券定价》
self
.valuation()
# 计算估价,diff列即为差价,策略应取diff较小的达到低估值效果
def
knn
(
self
)
:
self
.dictNeighbor = neighborsCbGroups(
self
.codes,
self
.date)
def
getXY
(
self
)
:
self
.dfXY = getConvAndPremium(
self
.codes,
self
.date)
def
valuation
(
self
)
:
dfRet = pd.DataFrame(index=
self
.codes, columns=[
"v"
,
"close"
,
"diff"
])
for
code
in
self
.
codes:
lstKnn =
self
.dictNeighbor[code][
"lstRet"
]
dfKnnData =
self
.dfXY.loc[lstKnn]
conv =
self
.dfXY.loc[code,
"conv"
]
v, coef = olsForGroup(dfKnnData, conv)
dfRet.loc[code,
"v"
] = v
dfRet.loc[code,
"close"
] =
self
.dfXY.loc[code,
"conv"
] * (
1
+
self
.dfXY.loc[code,
"prem"
]/
100.0
)
dfRet[
"diff"
] = dfRet[
"close"
] - dfRet[
"v"
]
dfRet.dropna(how=
"any"
, inplace=True)
self
.ret = dfRet
资料来源:万得资讯,中金公司研究部
而相比于“双排名法”,这种考虑分组定价的优势在于单调性和关键风格基本中性。
以下为基于分位数的5组测算,可见按照这种方法计算,长期来看分位数越低、效果越好,而双排名法则是50%分位数以下没有档次差——不过有时候这也是个优点。同时,虽然“0~20%”组在去年年底依然遭遇一些挑战,但相对而言可以接受。
分组定价法:5组测算(分位数越低越代表低估)
资料来源:万得资讯,中金公司研究部
最后,我们对当前行情的看法与此前没有太大变化。
往年此时也是转债的弱势月份,投资者少有在3~5月赚钱的经历,而股市处于磨底期,最重要的反而是保持一个好的心态以迎接下一阶段的机会。但要注意的是,无论从股市还是转债的角度看,市场情绪都有出清的势头——除了开头提到的转债成交量以外,万得全A指数的单日成交额也在周四进入了我们的目标范围:我们希望看到十日平均成交额缩至6500亿元以内,而周四已经跌至6485亿元。
因此,结合转债已经不高的估值,我们倾向于认为现在虽然尚未到达底部,但已经可以开始更为积极地面对。至于底部的时点,观察大于预测,经验上可能会在2~3周后出现。而至少从技术上理解,当前市场的风险点在于前期抱团品种尚未真正完成调整,其他品种则可能在此过程中受累,因此结构上的战略是明确的,绕开前期抱团品种,这也是我们希望在此时多介绍一下低估值策略的原因
。
上证指数:典型磨底状态
资料来源:万得资讯,中金公司研究部
市场一周概况
本周市场总体维持窄幅震荡,截止周四(4月15日)收盘,万得全A下跌1.37%,创业板指下跌1.29%,
上证50
下跌2.35%,
中证1000
下跌1.86%。两市合计成交2.73万亿元,日均约6825亿元,低于上周,主要指数波动率低位钝化。板块方面,本周行业轮动速度较快,电力设备、综合金融、汽车、有色板块表现靠前,消费者服务、交运、轻工及公用事业排名靠后,周五早盘煤炭、传媒及商贸零售表现抢眼。主题概念方面,白酒、数字货币、新冠检测、二胎政策概念涨幅较大。转债指数本周下跌0.91%,小康、中矿、联泰、蓝帆及飞鹿转债涨幅居前,金能、英科、华锋、金禾转债领跌。