3月实习笔记(一)

月收益率的计算

  基金净值时间序列数据与benchmark数据概览:

fund.head()
Out[1]: 
             fund        100        200        500       1000         全指
date                                                                    
2016-03-17  1.002  2955.7422  3855.9222  5745.9750  7779.8753  4392.5355
2016-03-18  1.002  2980.0660  3963.8730  5949.2630  8097.2040  4514.1640
2016-03-21  1.002  3047.7244  4072.7380  6099.4805  8325.9770  4631.2287
2016-03-22  1.002  3022.5462  4050.1460  6075.4922  8311.2112  4610.1958
2016-03-23  1.002  3027.8622  4073.2864  6118.9664  8408.6385  4643.0294

  月百分比收益率=该月最后一个交易日的基金净值/上个月最后一个交易日的基金净值-1。先将日期index中的年和月分离出来,找出每一个"年月"下对应的索引并生成array,然后我们只需要用到前后两个array元素的最后一位来计算,可以使用字典逐个添加到dataframe中。为了第一个月的数据不浪费,第一个月的收益率为该月最后一个交易日的基金净值-1。

whatmonth=[]
for n in fund.index:
    whatmonth.append(n.strftime("%Y%m"))
m=pd.Series(whatmonth)
m_r=pd.DataFrame(columns=('日期','月收益率'))
m_index=[];a=-1
for i in m.unique():
    a+=1
    m_index.append(np.where(m==i)[0])
    if i==m.unique()[0]:
        rmonth=fund['fund'].iloc[m_index[0][-1]]-1
    else:
        rmonth=fund['fund'].iloc[m_index[a][-1]]/fund['fund'].iloc[m_index[a-1][-1]]-1
    #将计算结果逐行插入,注意变量要用[]括起来,同时ignore_index=True,否则会报错
    m_r=m_r.append(pd.DataFrame({'日期':[i],'月收益率':[rmonth]}),ignore_index=True)
m_r.set_index('日期',inplace=True)
m_r
Out[11]: 
            月收益率
日期              
201603  0.002000
201604 -0.003992
201605  0.017034
201606  0.032512
201607 -0.017176
......  ......
201910  0.020524
201911  0.003467
201912  0.060815
202001  0.111401
202002  0.009965

  月对数收益率=ln(该月最后一个交易日的基金净值/该月第一个交易日的基金净值)。下面用另一种思路计算:对数收益率具有可加性,每月的所有日对数收益率之和就是本月的月对数收益率。分离出“年月”后,可以用groupby函数来分组求和,同时修改第一个月的收益率即可。

month=[]
lograte=np.log(fund/fund.shift(1)).dropna()['fund']
index=lograte.index
for i in range(0,len(lograte)):
    month.append(''.join([index[i].strftime("%Y"),index[i].strftime("%m")]))
y=pd.DataFrame(lograte.values,index=month,columns=['月收益率'])
ret_monthly=y.groupby(y.index).sum()
ret_monthly.iloc[0]=np.log(fund['fund'].iloc[m_index[0][-1]])
ret_monthly
Out[35]: 
            月收益率
201603  0.001998
201604 -0.004000
201605  0.016891
201606  0.031995
201607 -0.017325
......  ......
201910  0.020316
201911  0.003461
201912  0.059038
202001  0.105621
202002  0.009916

周收益率的计算

  周百分比收益率=该周最后一个交易日的基金净值/上周最后一个交易日的基金净值-1。为了第一周的数据不浪费,第一周的收益率为该周最后一个交易日的基金净值-1。由于会受到节假日的影响,每周交易日可能不足5天,甚至有可能两周的交易日加起来都不足5天,这为我们的计算增加了难度,可以分类计算:

whatday=[]
w_r=[]
suoyin=[]#存放一周有5天的交易日索引号
for i in fund.index:
    whatday.append(i.strftime("%w"))
def delta_days(x,y):
    d1=fund.index[x]
    d2=fund.index[y]
    return (d2-d1).days
for i in range(len(fund.index)-1):
    if whatday[i:i+5]==['1','2','3','4','5'] and delta_days(i,i+4)==4:
        suoyin.append([i,i+1,i+2,i+3,i+4])
m=[]#存放一周没有5天的交易日索引号
for i in range(len(suoyin)-1):
    if suoyin[i][4]-suoyin[i+1][4]!=-5:
        m.append([j for j in range(suoyin[i][4]+1,suoyin[i+1][0])])
#两周小于5个交易日的会合成为一周,分成两周(可能发生于春节和国庆假期)
for i in m:
    for j in range(len(i)-1):
        if delta_days([i[j]],[i[j+1]])!=1:
            m.append([q for q in range(i[0],i[j]+1)])
            m.append([q for q in range(i[j+1],i[-1]+1)])
            m.remove([q for q in range(i[0],i[-1]+1)])
#将交易日不足5日的索引号插入对应位置
for i in m:
    for j in suoyin:
        if i[0]==j[-1]+1:
            suoyin.insert(suoyin.index(j)+1,i)
if suoyin[0][0]!=5:#检查第一周是否为5个交易日
    suoyin.insert(0,[j for j in range(0,suoyin[0][0])])
if suoyin[-1][-1]!=len(fund)-1:#检查最后一周是否为5个交易日
    suoyin.insert(len(suoyin),[j for j in range(suoyin[-1][-1]+1,len(fund))])
for i in range(1,len(suoyin)):
    w_r.append(fund['fund'].iloc[suoyin[i][-1]]/fund['fund'].iloc[suoyin[i-1][-1]]-1)
w_r.insert(0,fund['fund'].iloc[suoyin[1][-1]]/1-1)
weekr=pd.Series(w_r,index=[i for i in range(1,len(w_r)+1)])
weekr.index.name='周数'
weekr
Out[13]: 
周数
1      0.002000
2      0.000000
3      0.000000
4      0.004990
5      0.003972
  
197    0.020946
198    0.002931
199    0.024547
200    0.069595
201   -0.081067
Length: 201, dtype: float64

连续最大跌幅的计算

  在连续几日收益率幅为负的区间内,从收益率为负的第一天算起,一直累加到收益率为正的前一天为止,得到该区间的连续跌幅,求所有符合条件的区间连续跌幅的最小值。

maxdown=[]
c=0
from datetime import date
#rfund为fund的日百分比收益率数据,截止到2020年2月28日
rfund.loc[date(2020,2,29)]=5*[0]#解决最后一个收益率是负数求不了的问题
for i in range(len(rfund)-1):
    if rfund['fund'][i]<0 and rfund['fund'][i+1]<0:
        c+=rfund['fund'][i]
    elif rfund['fund'][i]<0 and rfund['fund'][i+1]>=0:
        if rfund['fund'][i-1]<0:
            c+=rfund['fund'][i]
            maxdown.append(c)
            c=0
        else:
            maxdown.append(rfund['fund'][i])
    else:
        pass
min(maxdown)
Out[20]: -0.10155444714139317
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值