Redian新闻
>
量化角度看春节:A股的春节效应

量化角度看春节:A股的春节效应

财经


量化投资与机器学习微信公众号,是业内垂直于量化投资、对冲基金、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()

def get_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==1 or x.month==2 or 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变量来自行设置春节效应的期间范围。
核心代码:
def ret_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% 以上的收益,而且也是节后收益贡献较大。
核心代码:
def get_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年的数据,所以当期间较长时,需要分段提取并合并,该函数是一年取一次,取得是日度数据
def get_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

def ret_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将在新年不定期为大家奉献精彩的内容~

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
突发!当你在看春晚时,大洋彼岸72岁老华裔枪杀近十人世间人情皆如是全球维度看中国经济这三年,让数据说话!2022彭博中国区量化大赛冠军风采:申万宏源金创量化衍拓队 | 策略分享能源问题不宜过度低估,价格不能过度看空柿话柿说,柿柿留心(7)怪柿(事)连连从文化和代际角度看中国后城镇化时代的发展与机遇从实力和地位的角度看,为什么中国支持沙伊和解?日本11.6万人在线看春晚,东京铁塔点亮中国红!量化冲刺|九大行及对冲基金导师合力研发“市面上唯一针对量化面试的刷题班”!明天立春节气!春到人间草木知,来看看春天的第一朵花吧↓文艺是为千千万万劳动人民服务经典回放|《量化求职公开课》限时免费领取中,搞定量化Offer全靠它!完美!知识点超全的《Cell》期刊66.89分的Wnt信号通路,速度看!金典、安慕希独家冠名竖屏看春晚,今夜当品牌成为流量本流我们等你在除夕看春晚!2023“载歌在谷”兔年春晚购票通道今日开启啦~欢乐春节:iSING!SUZHOU“唐诗的回响”新春音乐会将在美首演——开启2023中国传统新年庆祝活动的序幕谁还在看春晚?那些不打算看春晚的95后,都在想什么?量化刷题|独家精准量化题库+大摩招生官Mock Interview,从此面试备战无忧!Costco人参茶,纯椰子水+几个家常美味,北京糕点换个角度看ChatGPT:中国的OpenAI还差什么?央视总台官宣:开年金兔,「戴」你看春晚!聊一聊:你们现在还会看春晚吗?量化刷题|大摩招生官带你1遍刷完4大量化圣经,大幅提升面试通过率,冲刺Offer!来斯坦福看春晚,兔嗨兔精彩!我们等你除夕看春晚!2023“载歌在谷”兔年春晚购票通道今日开启央视总台官宣:开年金兔,“戴”你看春晚!春节:人民日报发布传统文化常识100题,你能答对几个?机场的吃喝时光~~~央视总台官宣:开年金兔,“戴”你看春晚小小量化,大大不同~浅浅测评7只量化基金英华号周播报|投顾产品越来越多,该怎么挑选?A股的日历效应,到底准不准?这样精彩的故事,换个角度看更不一般2022彭博中国区量化大赛精彩回顾:中国农业银行知行致远团队量化选股策略
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。