相关文章推荐
魁梧的机器人  ·  centos关闭5353端口·  11 月前    · 
旅途中的西装  ·  Dart ...·  1 年前    · 
深沉的钥匙扣  ·  @vue/composition-api ...·  1 年前    · 

我们尚不会对近期的反弹过多解读,但过程仍值得观察。 虽然转债指数截至周四已经回升了1.95%,但于趋势而言当周的反弹改变不大。经历过这一段的波折洗礼,在结构上,哪些品种能够经受考验——或者说,依然能在较弱的情绪环境下,保持住不错的趋势,是更值得关注的。但当下足有400只转债的情况下,即便是只关注价格走势的投资者,也难以较高效率完成对“趋势”的分类。在此我们介绍一类基于降噪处理的技术,从而高效地选出当下比较值得关注的品种。

图表1:转债指数一度跌破55日线,仍可维持趋势的品种值得注意

资料来源:万得资讯,中金公司研究部

降噪本身是较为成熟的技术,其中小波离散变换也是较为常用(Discrete Wavelet Transform)。 其从傅立叶变换(将原始信号分解为不同频次的波,即所谓基函数,投资者可以将其理解为不同周期长度的cos函数,较长周期的对应趋势信号)逐步发展而来,最主要的进步是在原始基函数的基础上加入衰减函数。使原本只能覆盖于全时间轴的基函数(类似cos一样的全局函数),可以只在某个局部有影响力(以应对少见的突变)。当然,正是由于技术本身成熟,高效简易的实现方式,投资者仅了解原理即可。

图表2:变换的基本逻辑示意图

资料来源:万得资讯,中金公司研究部

总之我们可以把价格走势信号拆解为低频的趋势项,以及在此基础上的高频噪声项,并进一步将趋势信号加入转债策略。DWT向下还分有haar,db, sym, coif 等各类细分方法。我们在此选用了变换原理相对较为简单的haar法,并进行迭代滤波来确定趋势,需要注意的是haar变换一次数据量就会相应减少一半,举例说64日的数据量经过4次变化将只有4个变量。

图表3:使用DWT降噪的原理示意图

资料来源:万得资讯,中金公司研究部

图表4:通过DWT haar算法多次迭代计算后的降噪结果

资料来源:万得资讯,中金公司研究部

实现方式非常简单,但为了方便后续使用,尤其是批量化应用到不同的转债标的上,我们在这里对价格的原始序列进行标准化,使其落在[0,1]范围内。

程序1:DWT的python实现

def getDwt (srs, rec= 4 ) :

srs = srs.reset_index(drop= True )

retCa = dict.fromkeys((range(rec + 1 )))

retCd = dict.fromkeys((range(rec + 1 )))

retCa[ 0 ] = rescale(srs)

# pywt.wavedec可以直接输出迭代结果,单其输出值为[cA_n, cD_n, cD_n - 1, …, cD2, cD1],

# 但由于其中途不能再做数值变换,同时为了保证我们实现多种迭代方式,因而我们这里仍采用for loop

# 下方cA代表approximation signal(趋势), cD代表detail signal(噪音)

for i, key in enumerate(list(retCa.keys)[ 1 :]):

cA, cD = pywt.dwt(retCa[i], 'haar' )

retCa[key] = pd.Series(rescale(cA))

retCd[key] = pd.Series(cD)

return retCa, retCd

资料来源:中金公司研究部

我们将转债的正股前128个交易日的数据进行5次降噪处理,这样将保留4个关键点,排列组合可得到一共24种可能性。结合技术上的经验,我们可以简易地将这些可能性分为上行趋势、下行趋势以及横盘震荡。

图表5:简易的形态分类

资料来源:中金公司研究部

基于这样的处理,相应地策略也比较简单。这里我们不以转债指数为对比,而是在简易EasyBall的基础上做策略强化,然后直接以EasyBall作为基准进行对比。

图表6:策略逻辑示意图

资料来源:万得资讯,中金公司研究部

实现方式则较为简单,实操中注意数据提取数量是否超限等问题。策略测试框架在我们此前发布的《简易的转债策略测试框架以及Python实践方法》中,供参考。

def getData2Show (codes, date, lag= 128 ) :

#用来取正股走势数据的辅助函数

if not w.isconnected: w.start

_, dfUnderlying = w.wss( ',' .join(codes), 'underlyingcode' , usedf= True )

start_date = w.tdaysoffset(-lag, date, "" ).Data[ 0 ][ 0 ].strftime( '%Y/%m/%d' )

uniStock = set(dfUnderlying.UNDERLYINGCODE)

_, dfRaw = w.wsd( "," .join(uniStock),

"close" ,

start_date, date, "Priceadj=True" , usedf= True )

retDict = {}

for code in codes:

stock = dfUnderlying.loc[code, "underlyingcode" ]

retDict[code] = dfRaw[stock]

return retDict

def close2premRank5 (obj, codes, date, tempCodes, dfAssetBook) :

#简单双低

srs = obj.DB[ 'Close' ].loc[date, tempCodes].rank(ascending= True )

srs += obj.DB[ 'ConvPrem' ].loc[date, tempCodes].rank(ascending= True )

t = srs < srs.quantile( 0.5 )

return t[t].index

def dwtSecUp2 (obj, codes, date, tempCodes, dfAssetBook) :

# 假设我们将tplUp中的几种模式定为上行趋势

date = _offset(obj, date)

t = close2premRank5(obj, codes, date, tempCodes, dfAssetBook)

rawData = getData(t, date)

tplUp = ([ 1 , 2 , 3 , 4 ], [ 1 , 2 , 4 , 3 ], [ 1 , 3 , 2 , 4 ], [ 1 , 4 , 2 , 3 ], [ 2 , 1 , 3 , 4 ], [ 3 , 1 , 2 , 4 ])

ret = []

for code, df in rawData.iteritems:

dwt, _ = getDwt(df.CLOSE, rec= 5 )

if dwt[ 5 ].rank.astype(int).tolist in tplUp: ret.append(code)

return ret

dfTest = frameStrategy(obj, start= "2017/12/29" , selMethod=dwtSecUp2, roundMethod= 21 )

资料来源:中金公司研究部

测试效果如下,可以明显看到上行趋势对EasyBall的加成效果,以及下行趋势的品种即便是在EasyBall的样本下,依然会给组合带来损害。

资料来源:万得资讯,中金公司研究部

最后,行情与调整之前最大的不同是什么? 具体来说,差异在于:在9月转债市场调整之前,转债溢价率、股市情绪指标都在较高的位置,但近期后者明显下滑——即便投资者没有自己编制的情绪指标监控,也能看到市场总成交额已经相比此前明显下滑。至少这个位置,没有包含很多“情绪过热”的风险。因此,转债市场的问题是溢价率仍高,但正股层面的风险解除了不少,我们上述介绍的策略,也是希望投资者能关注到变化,从而更多注意那些估值不高(尤其是溢价率)、形态完好的品种。毕竟,这些品种,已经经历过9月的试验了。

转债市场跟踪

本周市场小幅回升,截止周四(10月21日收盘),万得全A上涨0.69%,创业板指上涨0.1%,上证50下跌0.49%,两市合计成交3.96万亿元,日均成交水平较上周小幅提升。 行业层面,本周化工、公用事业、有色金属、电气设备涨幅领先,休闲服务、食品饮料、通信、医药板块领跌,市场热点轮动较快。 转债指数本周上涨2.18%,个券中清水、蒙电、金诺涨幅领先,众兴、旗滨、利德转债领跌。 市场平均平价溢价率抬升,但大规模品种整体估值下降。

走势切割与Python实践

至少有错位:“低估”策略优化与Python实现

挑战:EasyBall可以更稳吗?——转债退市风险测算与Python实现

简易的转债策略测试框架以及python实现方法

本文摘自:2021年10月22日已经发布的《低噪声下的转债强化策略及Python实现》

向上滑动参见完整法律声明及二维码 返回搜狐,查看更多

责任编辑: