量化投资与机器学习微信公众号,是业内垂直于量化投资、对冲基金、Fintech、人工智能、大数据领域的主流自媒体公众号拥有来自公募、私募、券商、期货、银行、保险、高校等行业30W+关注者,曾荣获AMMA优秀品牌力、优秀洞察力大奖,连续4年被腾讯云+社区评选为“年度最佳作者”。

A 股市场在春节期间的表现通常优于平日,存在较为显著的春节效应。大家可以通过阅读下文图表来感受一下 A 股市场的春节效应。
华泰金工研报一般把腊月十八到次年的正月十八作为“农历春节效应月”。
兴业金工研报将“春节月”定义为包含春节假期在内的4周时间,即春节休市前的5个交易日和春节开市后的10个交易日。春节前后或春节月的收益率采用对数差分收益率的计算方式,其中𝑟𝑡表示第t期的收益率,𝑃𝑡表示第t期的收盘指数点位:
基于上述公式,我们可以推出,第 i 期收盘到第 j 期收盘这段时间的收益率就等于:
本文所指的“春节月”为包含春节假期在内的前后 4 周时间,即春节休市前的 5 个交易日和春节开市后的 10 个交易日,春节前后或春节月的收益率采用的是对数收益率。
核心代码:
from
 WindPy
import
 *

from
 WindCharts
import
 *

import
 pandas
as
 pd

import
 numpy
as
 np

from
 collections
import
 OrderedDict

w.start()


defget_spring_datas(df,method,n=10):#输入参数:df为提取的前收盘价和收盘价数据、method为获取的是时间段(spring_before为春节前,spring_later为春节后,spring_all为春节月)
    df.index.names=[
'date'
]
#给索引取名字
#part1:计算对数收益率
    datas=df.reset_index()
#将时间索引转化为日期date变量
#part2:提取春节开始前最后一个交易日和春节结束后的第一个交易日
    datas[
'date_bef'
]=datas[
'date'
].shift(
1
)
#提取前一日的交易日期
    datas[
'periods'
]=datas.date-datas.date_bef
#计算相邻两个交易日的时间差
    dates=datas[[
'date'
,
'date_bef'
,
'periods'
]].loc[datas.date.apply(
lambda
 x: x.month==
1or
 x.month==
2or
 x.month==
3
)]
#提取阳历为1、2、3月份的日期
    dates_=dates[dates.periods>=pd.Timedelta(
7
,unit=
'd'
)]
#提取时间间隔大于等于7的时间段,即为春节休市期间
    spr_beg=dates_[[
'date_bef'
]]
#提取各年春节开始休市的前一天交易日
    spr_end=dates_[[
'date'
]]
#提取各年春节休市结束后的首个交易日,注:此处的日期必须为dataframe形式,以为还要借助日期对应的索引提取休市前后N日的收益率
    datas_close=datas.iloc[:,:
2
]
#只提取第一、二列(日期和收盘价)
#part3:根据不同需求提取数据
if
 method==
'spring_before'
:
#提取春节前的数据
        spr_bef_datas=OrderedDict()

for
 index,date
in
 spr_beg.itertuples():
#返回的是索引值和日期
            spr_bef_datas[date.year]=datas_close.iloc[index-n:index].set_index(keys=
'date'
,drop=
True
)
#提取休市前N日的收益率,并重新将日期设置为索引
        datas_=pd.concat(spr_bef_datas.values(),keys=spr_bef_datas.keys())

elif
 method==
'spring_later'
:
#提取春节后的数据
        spr_end_datas=OrderedDict()

for
 index,date
in
 spr_end.itertuples():
#返回的是索引值和日期
            spr_end_datas[date.year]=datas_close.iloc[index:index+n].set_index(keys=
'date'
,drop=
True
)
#提取休市前N日的收益率,并重新将日期设置为索引
        datas_=pd.concat(spr_end_datas.values(),keys=spr_end_datas.keys())

elif
 method==
'spring_all'
:
#提取春节月的数据,春节月的时间采用的是兴业金工研报的定义方式
        n1=
5#设置春节前的交易日数
        n2=
10#设置春节后的交易日数
        spr_datas=OrderedDict()

for
 index,date
in
 spr_beg.itertuples():
#返回的是索引值和日期
            spr_datas[date.year]=datas_close.iloc[index-n1:index+n2].set_index(keys=
'date'
,drop=
True
)
#提取休市前N日的收益率,并重新将日期设置为索引
        datas_=pd.concat(spr_datas.values(),keys=spr_datas.keys())

return
 datas_ ,dates_
#返回春节期间收盘价数据datas_、提取的春节前后休市开市日期dates_
指数的“春节效应”
提取沪深两市中9大常用指数——"00001.SH"("上证综指")、"399001.SZ"("深证成指")、"000016.SH"("上证50")、"000903.SH"("中证100")、"000300.SH"("沪深300")、"000905.SH"("中证500")、"000852.SH"("中证1000")、"399005.SZ"("中小板指数")、"399006.SZ"("创业板指数") 的收盘数据。
春节效应期间的定义方式采用的是兴业金工研报的定义方式:春节休市前的5个交易日和春节开市后的10个交易日。
大家也可通过修改get_spring_datas函数中的n1和n2变量来自行设置春节效应的期间范围。
核心代码:
defret_comperate(begdate,enddate,codes,method,n=10):
    ret_all=pd.DataFrame()
#初始化收益序列
for
 code,name
in
 codes.items():

        _,datas=w.wsd(code,
"close"
,begdate, enddate,
"PriceAdj=F"
,usedf=
True
)
#提取各指数的收盘数据
        close_df,dates=get_spring_datas(method=method,n=n,df=datas)

        ret=close_df.groupby(level=
0
).apply(
lambda
 x: np.log(x.iloc[
-1
]/x.iloc[
0
]))
#计算春节期间的对数收益率
        ret.columns=[name]

        ret_all=pd.concat([ret_all,ret],axis=
1
)

    ret_all.loc[
'mean'
]=ret_all.mean(axis=
0
)
#按列求平均
    print(method+
" success"
)

return
 dates,round(ret_all,
4
)
#收益率计算结果保留4为小数

#初始化有关参数
indexs={
"000001.SH"
:
"上证综指"
,
"399001.SZ"
:
"深证成指"
,
"000016.SH"
:
"上证50"
,
"000903.SH"
:
"中证100"
,
"000300.SH"
:
"沪深300"
,
"000905.SH"
:
"中证500"
,
"000852.SH"
:
"中证1000"
,
"399005.SZ"
:
"中小板指数"
,
"399006.SZ"
:
"创业板指数"
}

begdate=
'2010-01-01'#起始时间
enddate=
'2022-12-31'#结束时间

dates,ret=ret_comperate(begdate,enddate,codes=indexs,method=
'spring_all'
)
#计算各指数春节日的收益率
最近 3 年 2020-2022 年的春节月期间,各指数收益都不理想,负收益居多;小盘股收益整体上优于大盘股收益。
从历史春节月期间的平均收益来看,各指数都呈现一定的春节效应,其中中证1000、中证500、创业板指、中小板指在春节月期间都能取得 5% 以上的收益。
各指数,春节后的表现都要优于春节前的表现;春节前10天里,越靠近春节,表现越优。
上证综指春节月和春节前后涨跌表现
沪深300春节月和春节前后涨跌表现
中证500春节月和春节前后涨跌表现
中证1000春节月和春节前后涨跌表现
创业板指春节月和春节前后涨跌表现
行业的“春节效应”
各行业也呈现春节效应,大部分行业春节月期间都能取得 5% 以上的收益,而且也是节后收益贡献较大。
核心代码:
defget_industry_name():
    industry=[
'b101000000000000'
,
'b102000000000000'
,
'b103000000000000'
,
'b104000000000000'
,
'b105000000000000'
,
'b106000000000000'
,
'b107000000000000'
,
'b108000000000000'
,
'b109000000000000'
,
'b10a000000000000'
,\

'b10b000000000000'
,
'b10c000000000000'
,
'b10d000000000000'
,
'b10e000000000000'
,
'b10f000000000000'
,
'b10g000000000000'
,
'b10h000000000000'
,
'b10i000000000000'
,
'b10j000000000000'
,
'b10k000000000000'
,\

'b10l000000000000'
,
'b10m000000000000'
,
'b10n000000000000'
,
'b10o000000000000'
,
'b10p000000000000'
,
'b10q000000000000'
,
'b10r000000000000'
,
'b10s000000000000'
,
'b10t000000000000'
]

    names=[
'石油石化'
,
'煤炭'
,
'有色金属'
,
'电力及公用事业'
,
'钢铁'
,
'基础化工'
,
'建筑'
,
'建材'
,
'轻工制造'
,
'机械'
,
'电力设备'
,
'国防军工'
,
'汽车'
,\

'商贸零售'
,
'餐饮旅游'
,
'家电'
,
'纺织服装'
,
'医药'
,
'食品饮料'
,
'农林牧渔'
,
'银行'
,
'非银行金融'
,
'房地产'
,
'交通运输'
,
'电子元器件'
,
'通信'
,
'计算机'
,
'传媒'
,
'综合'
]

    indus_dic={}

for
 (indus,name)
in
 zip(industry,names):

        indus_dic[indus]=name

return
 indus_dic


#定义板块提取时间序列数据函数:因为wses最多只能提取3年的数据,所以当期间较长时,需要分段提取并合并,该函数是一年取一次,取得是日度数据
defget_datas(begdate,enddate,code):
    beg_year=begdate[:
4
]

    end_year=enddate[:
4
]

    years=np.arange(int(beg_year),int(end_year))

    years_beg=[
"%d-01-01"
%i
for
 i
in
 years]
#形成每年1月1日的日期
    years_end=[
"%d-12-31"
%i
for
 i
in
 years]
#形成每年12月31日的日期
    datas=pd.DataFrame()

for
 beg,end
in
 zip(years_beg,years_end):

        data=w.wses(code,
"sec_close_avg"
,beg,end,
""
,usedf=
True
)[
1
]
#提取算术平均收盘价
        datas=pd.concat([datas,data],axis=
0
)

return
 datas


defret_comperate_industry(begdate,enddate,codes,method,n=10):
    ret_all=pd.DataFrame()
#初始化收益序列
for
 code,name
in
 codes.items():

        datas=get_datas(begdate,enddate,code)
#提取各行业的日度收盘数据
        close_df,dates=get_spring_datas(method=method,n=n,df=datas)

        ret=close_df.groupby(level=
0
).apply(
lambda
 x: np.log(x.iloc[
-1
]/x.iloc[
0
]))
#计算春节期间的对数收益率
        ret.columns=[name]

        ret_all=pd.concat([ret_all,ret],axis=
1
)

        print(code,name,
"success"
)

    ret_all.loc[
'mean'
]=ret_all.mean(axis=
0
)
#按列求平均
    print(method+
" success"
)

return
 dates,round(ret_all,
4
)
#收益率计算结果保留4为小数

indexs_ind=get_industry_name()

dates,ret=ret_comperate_industry(begdate,enddate,codes=indexs_ind,method=
'spring_all'
)
#计算各指数春节日的收益率

中信一级行业历年春节月涨跌明细
明天就是大年三十了
最后祝大家新年快乐,玩得开心!
QIML将在新年不定期为大家奉献精彩的内容~
继续阅读
阅读原文